Since assembling the RGB LCD Shield, I’ve been thinking about what types of data could take advantage of being able to easily change the backlight color. Air quality index is a good fit; AIRNow provides colored ranges for the index which indicate air quality at a broad level using green, yellow, and red. I revisited the code for having the Internet of Things Printer fetch a data feed from Pachube and updated it to optionally track a single datastream within the feed. I’m using:
I inserted the pins on the shield stacking headers into the headers on the Arduino, then inserted the shield’s pins into the stacking headers. The added height of the stacking headers means the RGB LCD shield clears the Ethernet jack on the Arduino; but, the overall structure is still stable and reasonably compact.
During setup, the backlight is set to teal to distinguish from the green / yellow / red of the actual data screens. I’m also displaying the IP address for a few seconds to help with troubleshooting any network issues.
// Short delay so the IP can be spot checked. lcd.setCursor(0, 1); lcd.print(Ethernet.localIP()); delay(3000);
With the backpack and accompanying library, it’s straightforward to change the color of the backlight. These calls can be wrapped in an if-else structure to map ranges of values to different colors:
if (curValue <= 50) { lcd.setBacklight(GREEN); } else if (curValue <= 100) { lcd.setBacklight(YELLOW); } else { lcd.setBacklight(RED); }
The result is that, at a glance, I can see that the air quality is good today. If I’m interested, I can take a closer look and see when the data was collected and the exact value of the index.
Fortunately for me (but unfortunately for grabbing example images), our air quality was good every time I checked. I ended up mocking up some data to show how things would look if the air quality were moderate.
And then again if the air quality were poor.
This general approach can be modified and used with a variety of data. One example is display temperature and using blue to indicate when the temperature is too cold and red to indicate too hot. It’s also possible to use a local sensor reading to generate the value which determines the backlight color.
Modifying the original code to handle datastream entries resulted in a few areas that need some explanation. The most straightforward change was in the request URL; which now conditionally includes a datastream ID:
client->print("GET /v2/feeds/"); client->print(feedId); if (datastreamId != NULL) { client->print("/datastreams/"); client->print(datastreamId); } client->print(".json");
When working with the feed API, I made use of the Last-Modified header in the HTTP response to decide if the data had changed. Unfortunately, the response for the datastream does not include a Last-Modified header field. Fortunately, it does include an ETag header field which changes when the data changes.
if (datastreamId == NULL) { foundHeader = client->findUntil("Last-Modified:", "\r\n\r\n"); } else { foundHeader = client->findUntil("ETag:", "\r\n\r\n"); }
Finally, the original JSON parsing code viewed the end of the outermost object as the end of the parse and assumed all data had already been processed:
if(!depth) return true; // End of file ... // process data ...
In order to handle a JSON feed where the outermost object contains the data, I changed this conditional to continue to the processing code and exit afterward if the flag variable isDataObjectRoot has been set (this flag defaults false, and is set to true if and only if a datastream ID has been specified):
if(!depth && !isDataObjectRoot) return true; // End of file ... // process data ... if(!depth && isDataObjectRoot) return true; // End of file
Otherwise, processing one datastream entry was very similar to processing the entire feed. The full source code is available on GitHub and can be modified to track other data by opening the LCDFeed example and filling in the following fields:
char *apiKey = ""; // Developer API key char *feedId = ""; // Feed ID char *datastreamId = ""; // Datastream ID
I’m interested in seeing what other data can be displayed using this general approach and what types of conditions could be indicated by other colors.
Making a display for a PCR machine would also work for this display
I used the exact same shield and Arduino combo to fetch the weather data from our local airfield’s station here in the desert from http://www.rssweather.com.
If it’s yellow then it’s a sand/dust storm. Blue means less than 80F. Green is 80F-89F. Red is temps above 90F.
Code is posted somewhere in the forums.
@anonymous – Interesting idea, are you thinking in terms of measuring the current temperature in the PCR machine? Or some aspect of the cycle?
@DavidM – I looked up your forum post http://forums.adafruit.com/viewtopic.php?f=31&t=27003 and read through the code – I see in addition to using the color at that level you’re also using the text for details (type of dust condition, temperature, wind speed, etc.) Very nice!
Nice, I assume you could use the same setup for any value such as pollen or mold count locally if there is a source of data for that.
Chris – Thanks! Yup, should work for those types of values if there’s a source of data. I’m actually having trouble finding an official JSON APIs to fetch pollen/mold counts.