DHT11 Sensor accessed by many clients

25th February 2019
Arduino
0

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 = "";
}

Hey, like this? Why not share it with a buddy?