
In my last project I wrote a simple mobile app to control a relay (triggered by the hydrometer) and see what the temperature and moisture is using a DHT11 sensor. Granted it is cheap and there are other better sensors out there. It will not provide readings if you query it to often (two second limit) - this weakness could also apply to other sensors so maybe this will help someone. I mentioned that the solution would be to implement a "proxy" (fancy word I know).
So the fix goes something like this:
- receive a get request from a client,
- check if seven seconds have passed since last time a request has been made,
- if true -> request new readings from the sensor and update the cache
- else -> use the data from the cache (not querying the sensor = happy sensor),
- send the data back to the client
And guess what? This works like a dream. I have modified some of the garden project code to add more requests per second. In the "no proxy" version of the arduino sketch I am testing it with four active scripts that try to get the latest data from the sensor - the failure rate is 50% = bad. Later on I upgrade the sketch to see how that stacks up. And for the final test I go all nuts and create a page that has eight scripts asking for the data - the nano with the ethernet module doesn't seem to be bothered by that at all. Maybe some time in the future I will do some stress testing of the ENC28J60 and see how much punishment it can actually take in the real world.
A short video demo and the source code are provided below. Enjoy!
// This works for the nano only !!!! // The "proxy" version ! #include <SPI.h> #include <UIPEthernet.h> #include <dht.h> #define aPin A5 // Defines pin number to which the sensor is connected dht DHT; // Creats a DHT object boolean reading = false; unsigned long lastMillis; // global variable ! const unsigned long timeAllowed = 7000; // The sensor is allowed to be queried every 7 seconds ! String temperature = ""; // this will hold the temp from sensor // Setup the static network info for you arduino byte ip[] = { 192, 168, 7, 177 }; // IP Address byte subnet[] = { 255, 255, 255, 0 }; // Subnet Mask byte gateway[] = { 192, 168, 7, 1 }; // Gateway byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC Address EthernetServer server = EthernetServer(80); // Port 80 String HTTPget = ""; void setup() { Ethernet.begin(mac, ip, gateway, subnet); // setup ethernet with params from above server.begin(); lastMillis = millis(); // Allocate something at the start and compare later on... Serial.begin(9600); // The initial read ! int readData = DHT.read11(aPin); // Reads the data from the sensor float t = DHT.temperature; // Gets the temperature temperature = String(t); Serial.print("First temp reading: "); Serial.println(temperature); Serial.println("Setup process complete.."); } void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { // send http reponse header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Access-Control-Allow-Origin: *"); // if you ever work with phonegap... client.println(); // process request. processClient(client); } } void processClient(EthernetClient client) { // http request will end with a blank line boolean lineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if(reading && c == ' ') reading = false; if(c == '?') reading = true; // ? in GET request was found, start reading the info //check that we are reading, and ignore the '?' in the URL, then append the get parameter into a single string if(reading && c != '?') HTTPget += c; if (c == '\n' && lineIsBlank) break; if (c == '\n') { lineIsBlank = true; } else if (c != '\r') { lineIsBlank = false; } } } if (HTTPget == "sensor1") { // First... Let me check when was the last reading done... unsigned long currentMillis = millis(); if (currentMillis - lastMillis > 7000) { lastMillis = millis(); // replace with new figure // Get the temp from sensor ! int readData = DHT.read11(aPin); // Reads the data from the sensor float t = DHT.temperature; // Gets the values of the temperature temperature = String(t); // update... HTTPget = String(t); lastMillis = millis(); // replace with new figure Serial.print("It has been more than 7 seconds..."); Serial.println(t); } else { // Provided the requesting device with the last known value HTTPget = temperature; Serial.print("Cached figure..."); Serial.println(temperature); } } client.print(HTTPget); delay(1); // give the web browser a moment to receive client.stop(); // close connection HTTPget = ""; }