GithubHelp home page GithubHelp logo

arduino's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

arduino's Issues

LedBar brightness is not getting low enough:

1% is still quite bright on the monitor. I don't think its 1%. This only affects the LedBar. Display looks ok.

local config shows:
http://airgradient_xxx.local/config

image

But from server comes:
...,"ledbarBrightness":1,"displayBrightness":18,"...}

Flashing via Web and Arduino yield different results (DIY Pro 4.2)

https://www.airgradient.com/open-airgradient/instructions/diy-pro-v42/

If you use Chrome to upload the firmware from the website, everything works fine. If you follow the instructions and manually compile and flash the "Example" file provided (DIY_PRO_V4_2) in Arduino IDE there are several issues:

  • The display is upside down.
  • The device boot loops unless you press the hardware button to enter the config.

Does anyone have the actual sketch that was used to generate the web flash bin file?

'pmStandard' value 'usaqi' invalid

When executing the following request, the server returns with

'pmStandard' value 'usaqi' invalid
curl --location --request PUT 'http://10.0.0.115/config' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
    "pmStandard": "usaqi"
}'

Even though the docs say this should be supported

LED inconsistency | Firmware v. 3.1.1

I've noticed some issues with the LED bar:
The pictures might not be very clear, but you can see green lights on the first and last LED lights, and in the middle, they are all yellow.
Maybe all LEDs should be yellow and not: "green | yellow | yellow | yellow | green" ?

Ticket1
Ticket2

There also could be some issues on other levels.

Boot counter not working in Dashboard

I'm not sure if this is most appropriate here or in the Forums, since it seems to be more related to the Dashboard page.

Going to the Hardware page I can see all of my devices and when they were last seen:
https://app.airgradient.com/settings/hardware

The "Current Boot Count" is not incrementing on my ONE that I recently upgraded to 3.1.1. I certainly see in the logs that it is sending a value for "bootCount" that is incrementing, but the Dashboard only shows 0.
I suspect it may be an incorrect value name, since this link shows that it should be called boot and not bootCount
https://github.com/airgradienthq/arduino/blob/master/docs/local-server.md

Display went dark and LED at low brightness

After flashing the latest 3.1.1 firmware, I had the display and LED working at normal levels, and now the display has gone completely off, and the LEDs are at a low brightness level

image

I assume this is some kind of night mode kicking in, but I haven't configured a night/sleep mode in the Dashboard, nor can I even find where that may be an option to enable or configure.

In my time zone it is only 8:00 pm and not when I would want the unit to be in a sleep mode, but the end user should

  1. Opt-in for sleep mode
  2. Be able to configure the sleep time window in the Dashboard

This is all assuming this isn't just a bug.

CO2 Calibration confusing in Dashboard

I'm not sure if this is most appropriate here or in the Forums, since it seems to be more related to the Dashboard page.

Going to the Hardware page I can see all of my devices and when they were last seen:
https://app.airgradient.com/settings/hardware

I see a column for "CO2 Calibration Requested" with a checkbox, but you cannot check the box here to request calibration. I think this is confusing as an end user, so if this is not supposed to be clickable, I think changing it to a Yes/No or True/False string would be better to understand.

I did find after poking around that if I click the three dot menu to the far right of a Monitor, I could select "Edit Location" and see another "Request CO2 calibration", which I checked and clicked Save. In the Hardware page, I briefly saw it checked, but clicking the blue Refresh button cleared the checkbox. After the first time I did this nothing updated on my sensor that I could tell, even though the checkbox had cleared. I still had incorrect numbers for CO2.

I tried it again about 5 minutes later, and maybe it did eventually work from the first attempt, but after requesting calibration a second time and going back to see the current values, it was updated.

Summary:

  • Checkbox in the hardware page is misleading since users can't check it and must Edit Location to request it
  • In the Hardware page, a Yes/No value for "CO2 Calibration Requested" would be more clear
  • In Edit Location, I think the c in calibration should be capitalized to match the Hardware page where it is capitalized. Consistency is key
  • If possible, once calibration is requested, the checkbox/true on the Hardware page should stay until the calibration is completed, rather than resetting immediately
  • I don't think "Edit Location" is an intuitive place to find the option to request CO2 calibration. Perhaps its own menu under the 3 dots in the Admin column, so it had "Edit Location", "Show Monitor Information", and "Request CO2 Calibration"

Split the libraries

Hi,

can you please split the libraries, so that there's a dedicated one for the SensAir S8 sensor?

ONE V9 Dependencies List Incomplete

Attempting to compile and flash from source, the ONE_V9.ino seems to be missing some of the dependent libraries. I run into missing headers PMS.h and s8_uart.h - it looks like the latter is from this library but I can't figure out what the former is from - I found this library but it has an incompatible DATA declaration:

/home/stevekuznetsov/Arduino/libraries/AirGradient_Air_Quality_Sensor/examples/ONE_V9/ONE_V9.ino: In function 'void updatePm()':
ONE_V9:290:26: error: 'struct PMS::DATA' has no member named 'PM_RAW_0_3'
       pm03PCount = data1.PM_RAW_0_3;
                          ^~~~~~~~~~
Multiple libraries were found for "WiFiClient.h"
 Used: /home/stevekuznetsov/.arduino15/packages/esp32/hardware/esp32/2.0.11/libraries/WiFi
 Not used: /app/Arduino/libraries/WiFi
exit status 1
'struct PMS::DATA' has no member named 'PM_RAW_0_3'

Narrowing Conversion in BoardDef.cpp

Hey guys,
I really appreciate the work you are doing! I'm in the midst of modifying the firmware of my AirGradient One. I came across an issue when compiling the 3.0.0 release:

Air Quality Sensor/src/bsp/BoardDef.cpp:323:6: error: narrowing conversion of '-1' from 'int' to 'uint8_t' {aka 'unsigned char'}

I'm on really thin ice here as I'm an absolute C++ noob, but I suspect the issue is that the resetPin in BoardDef.h is declared as uint8_t but assigned the value -1 in BoardDef.cpp?

I'm lacking the knowledge to make an actual fix, I was able to get around it with the compiler flag -Wno-narrowing.

functionality ceased?

The AirGradient DIY Air Quality Sensor (Pro Version PCB Version < 3.7) ceased showing voc or tvoc with SGP41 sensor

No NOx value

I upgraded my AirGradient One V9 from 3.0.0 to 3.0.1 trough the www.airgradient.com/documentation/one-v9/ page and realized that I now don't get a noxIndex value from the API from airgradient.com. Then I found the www.airgradient.com/documentation/factory/ page where 3.0.2 is available, but flashing this also did not fix the missing nox value. It is shown on the sensor display.

  • Where should I post this? Since I did not change anything else than the firmware, I think this has to be the reason.
  • Where is the correct place to find the actual latest (stable) firmware?

Define colors in seperate class

Currently the colors for the LED bar are not defined globally so if we e.g. want to change a color slightly, we need to go through a lot of code. Propose to centralise it, e.g. RGB code for red, green etc and then call the color name.

Add boot to keep HA integration compatability

Our current HA integration expects "bootCount" as a parameter. However for the airgradient server API we need "boot".

Local server on monitor for the time being should therefore return both properties: "boot" and "bootCount".

http://192.168.1.xxx/measures/current
{"wifi":-38,"serialno":"84fce61-----", ... ,"boot":2,"bootCount":2, ...}

At a later stage we will adjust the HA integration and depreciate "bootCount".

[docs] instructions to compile

Problem

Attempting to compile in the Arduino IDE results in the following error:

/home/user/air_gradient_open_air_firmware/examples/OneOpenAir/OneOpenAir.ino:40:10: fatal error: AirGradient.h: No such file or directory
   40 | #include "AirGradient.h"
      |          ^~~~~~~~~~~~~~~
compilation terminated.
exit status 1

Compilation error: AirGradient.h: No such file or directory

The tactical problem issue here is that some included files are in examples/OneOpenAir, while others are in src, and Arduino IDE is not looking in all these places.

However, the core problem is I can not find instructions on how to configure the Arduino IDE to compile. Since I expect others can compile the code, I expect this is just a setup problem and not a broken codebase.

Steps to reproduce

  1. Set up Arduino IDE to compile for the ESP32 board using the instructions on the blog
  2. Install the "serial" library for Python (e.g. sudo apt install python3-serial)
  3. Checkout this repo and open ./examples/OneOpenAir/OneOpenAir.ino in the Arduino IDE
  4. Click the verify button (check mark button in the upper left of the Arduino IDE) and see the posted error above

Attempts at resolving this

I tried a number of things to resolve this.

  • Make a symlink pointing to ./examples/OneOpenAir/OneOpenAir.ino, put it in ./src/, and open and compile that (so the file is next to the .h file we want to include)
  • Copy ./examples/OneOpenAir/OneOpenAir.ino into ./src/, and open and compile that (so the file is next to the .h file we want to include)
  • Make a symlink to ./src/Libraries named ./examples/OneOpenAir/libraries so the sketch directory has a libraries folder, as described in the arduino documentation
  • File -> Preference -> Change Sketchbook location to the root git repo, ./src, or ./examples/OneOpenAir to get it to find the libraries directory
  • copy OneOpenAir.ino into the ./src directory, rename ./src to OneOpenAir, open OneOpenAir.ino in the Arduino IDE and attempt to compile it (this was tried because Arduino insists on having the name of the directory match the name of the .ino file)

All of the above gave same error message except the last one, which give the error message below:

/home/user/air_gradient_open_air_firmware/OneOpenAir/OneOpenAir.ino:41:10: fatal error: OtaHandler.h: No such file or directory
   41 | #include "OtaHandler.h"
      |          ^~~~~~~~~~~~~~
compilation terminated.
exit status 1

Compilation error: OtaHandler.h: No such file or directory

Symlinking to ../examples/OneOpenAir/OtaHandler.h, ../examples/OneOpenAir/LocalServer.h and ../examples/OneOpenAir/OpenMetrics.h works around the "No such file" errors, but then exposes the more serious compilation errors below:

home/user/air_gradient_open_air_firmware/OneOpenAir/AgConfigure.cpp: In member function 'bool Configuration::parse(String, bool)':
/home/user/air_gradient_open_air_firmware/OneOpenAir/AgConfigure.cpp:277:45: error: ambiguous overload for 'operator==' (operand types are 'JSONVar' and 'String')
  277 |     if (jconfig[jprop_configurationControl] ==
In file included from /home/user/.arduino15/packages/esp32/hardware/esp32/3.0.0/cores/esp32/Arduino.h:192,
                 from /home/user/air_gradient_open_air_firmware/OneOpenAir/Main/PrintLog.h:4,
                 from /home/user/air_gradient_open_air_firmware/OneOpenAir/AgConfigure.h:5,
                 from /home/user/air_gradient_open_air_firmware/OneOpenAir/AgConfigure.cpp:1:
/home/user/.arduino15/packages/esp32/hardware/esp32/3.0.0/cores/esp32/WString.h:211:8: note: candidate: 'bool String::operator==(const String&) const' (reversed)
  211 |   bool operator==(const String &rhs) const {
      |        ^~~~~~~~
/home/user/.arduino15/packages/esp32/hardware/esp32/3.0.0/cores/esp32/WString.h:214:8: note: candidate: 'bool String::operator==(const char*) const' (reversed)
  214 |   bool operator==(const char *cstr) const {
      |        ^~~~~~~~
In file included from /home/user/air_gradient_open_air_firmware/OneOpenAir/Libraries/Arduino_JSON/src/JSON.h:25,
                 from /home/user/air_gradient_open_air_firmware/OneOpenAir/Libraries/Arduino_JSON/src/Arduino_JSON.h:23,
                 from /home/user/air_gradient_open_air_firmware/OneOpenAir/AgConfigure.cpp:2:
/home/user/air_gradient_open_air_firmware/OneOpenAir/Libraries/Arduino_JSON/src/JSONVar.h:85:8: note: candidate: 'bool JSONVar::operator==(const JSONVar&) const'
   85 |   bool operator==(const JSONVar& v) const;
      |        ^~~~~~~~
/home/user/air_gradient_open_air_firmware/OneOpenAir/AgConfigure.cpp:286:45: error: ambiguous overload for 'operator==' (operand types are 'JSONVar' and 'String')
  286 |     if (jconfig[jprop_configurationControl] ==
/home/user/.arduino15/packages/esp32/hardware/esp32/3.0.0/cores/esp32/WString.h:211:8: note: candidate: 'bool String::operator==(const String&) const' (reversed)
  211 |   bool operator==(const String &rhs) const {
      |        ^~~~~~~~
/home/user/.arduino15/packages/esp32/hardware/esp32/3.0.0/cores/esp32/WString.h:214:8: note: candidate: 'bool String::operator==(const char*) const' (reversed)
  214 |   bool operator==(const char *cstr) const {
      |        ^~~~~~~~
/home/user/air_gradient_open_air_firmware/OneOpenAir/Libraries/Arduino_JSON/src/JSONVar.h:85:8: note: candidate: 'bool JSONVar::operator==(const JSONVar&) const'
   85 |   bool operator==(const JSONVar& v) const;
      |        ^~~~~~~~
/home/user/air_gradient_open_air_firmware/OneOpenAir/AgApiClient.cpp: In member function 'bool AgApiClient::postToServer(String)':
/home/user/air_gradient_open_air_firmware/OneOpenAir/AgApiClient.cpp:108:7: error: 'WiFi' was not declared in this scope
  108 |   if (WiFi.isConnected() == false) {
      |       ^~~~
/home/user/air_gradient_open_air_firmware/OneOpenAir/AgApiClient.cpp:118:3: error: 'WiFiClient' was not declared in this scope
  118 |   WiFiClient wifiClient;
      |   ^~~~~~~~~~
/home/user/air_gradient_open_air_firmware/OneOpenAir/AgApiClient.cpp:120:20: error: 'wifiClient' was not declared in this scope
  120 |   if (client.begin(wifiClient, uri.c_str()) == false) {
      |                    ^~~~~~~~~~

exit status 1

Compilation error: ambiguous overload for 'operator==' (operand types are 'JSONVar' and 'String')

Documentation: Select "D1 mini (clone)"

The instructions here mention selecting a "Lolin (Wemos) D1 Mini board", but current versions of the ESP8266 toolchain for Arduino have multiple sub-variants with different amount of flash memory.

The D1 mini (clone) appears to match the board that comes with the kit (4MB flash).

airgradient

Senseair S8 lacks error checking (CRC) resulting in bad data

getCO2_Raw simply looks for a value of 254 in the first byte to check if a packet is good. Then parses bytes in the array slots 3 and 4 into a value.
A standard response from the S8 is Array[] { 0xFE, 0x68, 0x02, 0xXX, 0xXX, 0xXX , 0xXX }

The data in the 4th and 5th bytes are the CO2 response value while the bytes in the 6th and 7th are the CRC.

If this data stream is out of sync the simple check for the “Any sensor” address in the first byte can cause you to report an incorrect value of 17410. I have seen this issue on my sensor multiple times. Implementing a CRC check would validate the data an prevent bad values from being sent.

IPv6 support

Is the hardware / software combination able to handle IPv6? If so it would be nice to have it as an option in the Config secion…

Display PM / CO2 quality / color

Add support for displaying PM/CO2/etc. quality or color, instead of or alongside raw values.
Would require safely parsing the returned data.

PM2.5 display could be wider

The PM2.5 window in the middle of the display looks oddly squished, especially since there is so much blank space to the far right of tvoc:

I also wonder if PM2.5 would properly handle 3 digits, as it looks to only have sufficient space to look good for up to 2 digits.

What if it needed to display 288? Feels like it may not fit within the bars, or at least would be very cramped looking.

[build documentation] Sketch name appears to be incorrect

The build instructions for version 9.0 says the Arduino Sketch Name is OpenAirONE.ino, but this can not be found in the GitHub library linked to on this same page.

Wrong-sketch-filename

I first looked in the ./src directory and eventually found an example which I believe to be not just an example, but the entire firmware for a production device in the examples directory.

Changing that page to say the Arduino Sketch name is ./examples/OneOpenAir/OneOpenAir.ino and linking to the git repo would make it much less confusing to new users.

Also, it appears that all of the filenames are wrong and some of them don't appear to be in the repo at all. BASIC.ino may be the new name for what was DIY_BASIC.ino, but it's not clear what became of DIY_OUTDOOR and all the DIY_PRO ino files.

Display AQI

Add the display of current AQI, either calculated on the server or locally.

Server POST toggle in firmware configuration

Hello,

Thank you for a great product.

The new Prometheus /metrics endpoint is great, so I no longer need to POST periodically to a server. But the code requires successful POST to the server URL or it turns on an error LED.

Would it be possible to make periodic server POST reporting configurable in the server config? Then people can disable it if they don't need it.

Thanks! :)

Unable to change configurationControl

My monitor is set to local, but when executing:

curl --location --request PUT 'http://10.0.0.115/config' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
    "configurationControl": "cloud"
}'

It will return

Monitor set to accept only configuration from the cloud. Use property configurationControl to change.

Which is strange because I am doing what it's telling me to do

Open Air O-1PST logs showing various errors

First boot of a device after clean install of the 3.1.1 firmware. This was while I was connecting to the hotspot on my phone and configuring my Wifi information.

Note the request handler not found and No more processes errors

I did not have this unit setup in the Dashboard, so I also got some Error 400 but I don't think that is related to the errors mentioned, unless it is due to not being able to retrieve configuration from the Dashboard.

*wm:-2 networks found
*wm:2 networks found
[ 61179][E][WebServer.cpp:649] _handleRequest(): request handler not found
[ 61185][E][WebServer.cpp:649] _handleRequest(): request handler not found
[ 61240][E][WebServer.cpp:649] _handleRequest(): request handler not found
*wm:Connecting to NEW AP: NachoWifi
*wm:Connect to new AP [SUCCESS] 
*wm:Got IP Address: 
*wm:192.168.2.244 
[ 69910][E][WebServer.cpp:649] _handleRequest(): request handler not found
[WifiConnector] Info: Setting postToAirGradient set from True to True successful
[Configure] Info: postDataToAirGradient: Ignored set to 1
[LocalServer] Info: Init: airgradient_xxxxxxx.local
Mqtt uri is empty
Connect to MQTT broker failed
[ApiClient] Info: Post uri: http://hw.airgradient.com/sensors/airgradient:xxxxxxx/measures
[ApiClient] Info: Post data: {"wifi":-57,"boot":0}
[ 73868][E][WiFiClient.cpp:517] flush(): fail on fd 49, errno: 11, "No more processes"
[ 88502][E][WiFiClient.cpp:517] flush(): fail on fd 49, errno: 11, "No more processes"
[104879][E][WiFiClient.cpp:517] flush(): fail on fd 49, errno: 11, "No more processes"
[ApiClient] Info: Post uri: http://hw.airgradient.com/sensors/airgradient:xxxxxxx/measures
[ApiClient] Info: Post data: {"wifi":-57,"pm01":-1,"pm02":-1,"pm10":-1,"pm003Count":-1,"atmp":-1000.99,"rhum":-1,"bootCount":0}
[105800][E][WiFiClient.cpp:517] flush(): fail on fd 49, errno: 11, "No more processes"

Update ignored due to local unofficial changes

Looking at logs after installing the 3.1.1 firmware, I see a message that I was not expecting:

[Configure] Info: Parse configure: {"country":"US","pmStandard":"ugm3","co2CalibrationRequested":false,"ledBarTestRequested":false,"ledBarMode":"co2","displayMode":"on","placeOpen":false,"abcDays":8,"tvocLearningOffset":12,"noxLearningOffset":12,"temperatureUnit":"c","targetFirmware":"3.1.1","ledBarBrightness":10,"displayBrightness":0,"model":"I-9PSL-DE"}
[Configure] Info: Parse configure success
[Configure] Info: Update ignored due to local unofficial changes

I haven't attempted to make any local changes with the API or anything, just flashed the firmware and then opened the logs.

Is this message misleading or what would cause it to see local unofficial changes?

Turn Off Sensors

Hi all,

I'm putting the Wemos in deep sleep mode, but the sensors are still functioning. How can I disable them as well when in deepsleep?

Some improvements for the display output

In my fork of this library for the 4.2 pro, I've made these improvements:

  • Switch to unicode font
    • CO2 -> CO₂
    • PM -> PM₂₅
  • NOX -> NOx
  • Limit temperature to 1 instead of 2 digits precision
  • Optional compile time flag for minimum brightness
  • Vertically align the values correctly
  • Fix version comment at the top of the file (said 3.7 previously)

Should I create PRs for (some of) these changes?

Result (full brightness):

image

Why is CO2 RX and TX reversed in schematics

In the code the CO2_init is taking:

void AirGradient::CO2_Init(){
  CO2_Init(D4,D3);
}

CO2_Init(int rx_pin,int tx_pin){}

void AirGradient::CO2_Init(int rx_pin,int tx_pin){
  CO2_Init(rx_pin,tx_pin,9600);
}

However in schematics the rx/tx is connected as such:
D4 --- TX
D3 --- RX

which seems like contradicting with the code where rx_pin is passed in D4, tx_pin is passed in D3.

Did I miss something?

Don't blink LED when reading CO2

This library reads CO2 sensor data from pin D4 (GPIO2). Unfortunately, this pin is also connected to the ESP8266 onboard LED, causing it to blink whenever CO2 data is read. This is rather annoying when the sensor is someplace like a bedroom or nursery.

I can't see any way to fix this in code, but I'm putting this out there to see if anyone else has ideas. My workaround until then is black electrical tape 😄

Offset temperature of SHT3X sensor

Hello. I'm a complete noob cf arduino but I managed to complete this nice build thanks to your instructions. I now have an airgradient basic package that sends readings to a Grafana dashboard. Very nice

However, like many users (from what I've read), I noticed that the SHT31 sensor that I'm using, is offset by 0.6-1 degrees celsius. From the investigations of some users on the airgradient forum, it seems that it is caused by the wemos d1 chip itself, transmitting its heat through conduction through the wires themselves.

I've tried mitigating this issue by wiring the sht31 using long cables to the airgradient pcb and secluding the sensor out of the enclosure and air-tightening it from the rest of the components. But there is still some 0.6-1 degrees too much.

So would it be possible to implement an offset to the temperature reading inside of the airgradient.h library?

Missing return in periodicFetchData ?

First up - the code compiles fine in the usual arduino IDE.

But - in platformio - where it builds with certain warnings enabled - in this case -Werror=return-type - we get:

AirGradient.cpp: In member function 'TMP_RH AirGradient::periodicFetchData()':
AirGradient.cpp:306:16: error: control reaches end of non-void function [-Werror=return-type]
  306 |     returnError(error);

I can fix it locally by just changing line 306 to:

return returnError(error);

I guess that the arduino IDE doesn't enable that warning.

But - it does look like a return on that line would be a good idea?

Not entirely sure - but thought I'd mention it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.