Temperature and humidity thing

The temperature and humidity thing is based on one ESP-01 device.
The idea is to have a device, connected to WIFI, broadcasting both values to my web server.
Design is not a state-of-the-art, niter software nor hardware. It was designed to be simple and easy to maintain.

The hardware

  • The hardware is composed by a mini USB socket (just for power proposes), connected to a step down, regulated to 3.3V. Inside the core there is a small prototype board with some headers soldered, to make removal a less painful. On one the headers there is a dth11 temperature and humidity sensor (I will shortly change it to dht22 for better accuracy). On the other there is a esp8288-01.




The software

  • To develop the sketch I've used Arduino IDE. The code is, once again, simple and nothing fancy. I hate having to load a bunch of libruary's, thousand and thousand of code lines just to upload a value to a web server, so I've opted for the old and still useful GET. Main program is running in a loop and every X minutes post's a message to my raspberry. The code is not responsible for any decision.

// ESP8266 boards installed via the boards manager but GIT is here - https://github.com/esp8266/Arduino

#include <ESP8266WiFi.h>
#include <DHT.h>
#include <ESP8266WebServer.h>
#include <DHT_U.h>
#include <Adafruit_Sensor.h>

#define DHTTYPE DHT11
#define DHTPIN        0
#define LED_PIN       2

DHT_Unified dht(DHTPIN, DHTTYPE);

float humidity, temp_f;                 // Values read from sensor
float last_humidity, last_temp_f;                 // Values read from sensor
char humidity_str[7], temp_f_str[7];    // Values read from sensor
unsigned long previousMillis = 0;       // will store last temp was read
unsigned long previousMillisLED = 0;    // will store last LED time
unsigned long previousReaderMillis = 0; // will store last temp was read
const long interval = 2000;             // interval at which to read sensor
const int frequencyMinutes = 30;        // Update Frequency
String macAddressStr = "";                 // MAC Address
byte mac[6];                            // Temporary MAC Address
int tempDisabled = 0;                   // temperature disabled
int humDisabled = 0;                    // humidity disabled
const char* ssid = "<SID>";
const char* password = "<WIFI PASSWORD>";
const char* host1 = "192.168.XXX.XXX"; //Server IpAddress
const int httpPort1 = 80;
String url = "<URL where to send data>";
String urlActive = "<URL where to send I'm alive>";
int LedEnabled = 0;
String IPAddressToUse = "";

ESP8266WebServer server(80);

void setup() {

  WiFi.mode(WIFI_STA);

  Serial.begin(115200);
  delay(10);

  //if (LedEnabled == 1)
  if (LED_PIN != 99)
  {
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, LOW);
  }

  if (RELAY_PIN2 != 99)
    digitalWrite(RELAY_PIN2, LOW);
  if (RELAY_PIN != 99)
    digitalWrite(RELAY_PIN, LOW);

  connectWifi();

  server.on("/", []() {
    server.send(200, "text/html", getWebPage());
  });

  if (LED_PIN != 99)
  {
    server.on("/enableLed", []() {
      LedEnabled = 1;
      server.send(200, "text/html", getWebPage());
      delay(1000);
    });
    server.on("/disableLed", []() {
      LedEnabled = 0;
      digitalWrite(LED_PIN, HIGH);
      server.send(200, "text/html", getWebPage());
      delay(1000);
    });
  }
  if (DHTPIN != 99)
  {
    server.on("/enableTemp", []() {
      tempDisabled = 0;
      server.send(200, "text/html", getWebPage());
      gettemperature();       // read sensor
      SendToURL(host1, httpPort1, urlActive, 2, 1, "");
      delay(1000);
    });
    server.on("/disableTemp", []() {
      tempDisabled = 1;
      server.send(200, "text/html", getWebPage());
      SendToURL(host1, httpPort1, urlActive, 2, 0, "");
      delay(1000);
    });
    server.on("/enableHum", []() {
      humDisabled = 0;
      server.send(200, "text/html", getWebPage());
      gettemperature();       // read sensor
      SendToURL(host1, httpPort1, urlActive, 3, 1, "");
      delay(1000);
    });
    server.on("/disableHum", []() {
      humDisabled = 1;
      server.send(200, "text/html", getWebPage());
      SendToURL(host1, httpPort1, urlActive, 3, 0, "");
      delay(1000);
    });
  }

  server.begin();
  Serial.println("HTTP server started");

  if (DHTPIN != 99)
  {
    SendToURL(host1, httpPort1, urlActive, 2, 1, ""); //this will inform there is a device of type Temperature avaliable
    SendToURL(host1, httpPort1, urlActive, 3, 1, ""); //this will inform there is a device of type Humidity avaliable
  }

  gettemperature();

  if (LED_PIN != 99)
    digitalWrite(LED_PIN, HIGH);
}

void loop() {

  unsigned long currentMillis = millis();

  if (currentMillis - previousReaderMillis >= frequencyMinutes * 1000 * 60) {
    previousReaderMillis = currentMillis;
    gettemperature();       // read sensor
    delay(50);
  }

  if (LedEnabled == 1)
  {
    if (currentMillis - previousMillisLED >= 1000)
    {
      if (LED_PIN != 99)
        digitalWrite(LED_PIN, !digitalRead(LED_PIN));
      previousMillisLED = currentMillis;
    }
  }

  server.handleClient();
}

String getWebPage ()
{
  String webPage = "";

  webPage += "<html>";
  webPage += "<head>";
  webPage += "<meta name='apple-mobile-web-app-capable' content='yes' />";
  webPage += "<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />";
  webPage += "<style>";
  webPage += "body {background:#f5f5f5; -webkit-font-smoothing: antialiased;}";
  webPage += "div.title{width:300px; display: inline-block; text-align: left;}";
  webPage += "div.title2{width:102px; display: inline-block; text-align: left;}";
  webPage += "input, a:link, a:visited {background-color: white; color: black; border: 2px solid green; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block;}";
  webPage += "input:hover, a:hover, a:active {background-color: green;  color: white;}";
  webPage += "</style>";
  webPage += "</head>";
  webPage += "<body>";
  webPage += "<center>";
  webPage += "  <h1>Esp8266 Device Control</h1>";
  webPage += "  <div class=\"title\">Internal Led</div>";
  webPage += "  <a href=\"/enableLed\"><div>On</div></a>";
  webPage += "  <a href=\"/disableLed\"><div>Off</div></a><br />";
  
  if (DHTPIN != 99)
  {
    webPage += "  <div class=\"title\">Temperature (";
    webPage += temp_f_str;
    webPage += "&#186C)</div>";
    webPage += "  <a href=\"/enableTemp\"><div>On</div></a>";
    webPage += "  <a href=\"/disableTemp\"><div>Off</div></a><br />";
    webPage += "  <div class=\"title\">Humidity (";
    webPage += humidity_str;
    webPage += "&#37;)</div>";
    webPage += "  <a href=\"/enableHum\"><div>On</div></a>";
    webPage += "  <a href=\"/disableHum\"><div>Off</div></a><br />";
  }

  webPage += "</center>";
  webPage += "</body>";
  webPage += "</html>";

  return webPage;
}

void gettemperature() {
  if (DHTPIN == 99)
    return;

  if (LED_PIN != 99)
    digitalWrite(LED_PIN, LOW);
  sensors_event_t event;
  dht.temperature().getEvent(&event);

  // Reading temperature for humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
  temp_f = event.temperature;     // Read temperature

  if (!isnan(temp_f) && abs(temp_f - last_temp_f) > 3) //strange high rise/lower in short time
  {
    delay(2000);
    temp_f = event.temperature;     // Read temperature again
  }


  // Check if any reads failed and exit early (to try again).
  if (isnan(temp_f)) {
    Serial.println("Failed to read from DHT sensor!");
    temp_f = 0;
    // return;
  }
  else
  {
    Serial.println( temp_f );
    if (tempDisabled == 0)
      SendToURL(host1, httpPort1, url, 2, temp_f, "");
  }

  last_temp_f = temp_f;

  dht.humidity().getEvent(&event);
  humidity = event.relative_humidity;          // Read humidity (percent)

  if (!isnan(humidity) && abs(humidity - last_humidity) > 10) //strange high rise/lower in short time
  {
    delay(2000);
    humidity = event.relative_humidity;     // Read humidity again
  }

  if (isnan(humidity) ) {
    Serial.println("Failed to read from DHT sensor!");
    humidity = 0;
    // return;
  }
  else
  {
    Serial.println( humidity );
    if (humDisabled == 0)
      SendToURL(host1, httpPort1, url, 3, humidity, "");
  }

  last_humidity = humidity;

  dtostrf(humidity, 6, 2, humidity_str);
  dtostrf(temp_f, 6, 2, temp_f_str);

  if (LED_PIN != 99)
    digitalWrite(LED_PIN, HIGH);
}


void SendToURL(const char* host, int httpPort, String url, int type, int data, String mac) {

  if (LED_PIN != 99)
    digitalWrite(LED_PIN, LOW);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;

  if (!client.connect(host, httpPort)) {
    // Serial.println("connection failed");

    delay(60000);
    if (LED_PIN != 99)
      digitalWrite(LED_PIN, HIGH);
    return;
  }

  // We now create a URI for the request

  url += data;
  if (mac == "")
    url += "&ip=" + IPAddressToUse + "&thing=" + macAddressStr + "&type=";
  else
    url += "&ip=" + IPAddressToUse + "&thing=" + mac + "&type=";

  url += type;

  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      //Serial.println(">>> Client Timeout !");
      client.stop();
      if (LED_PIN != 99)
        digitalWrite(LED_PIN, HIGH);
      return;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
  while (client.available()) {
    String line = client.readStringUntil('\r');
  }

  if (LED_PIN != 99)
    digitalWrite(LED_PIN, HIGH);
}

void connectWifi() {
  WiFi.begin(ssid, password);
  // put your setup code here, to run once:
  int iRetry = 0;
  while (WiFi.status() != WL_CONNECTED || iRetry == 10) {
    delay(500);
    iRetry++;
    // Serial.print(".");
  }
  iRetry = 0;
  if (WiFi.status() != WL_CONNECTED)
  {
    WiFi.begin(ssid2, password2);
    int iRetry = 0;
    while (WiFi.status() != WL_CONNECTED || iRetry == 10) {
      delay(1000);
      iRetry++;
      // Serial.print(".");
    }
  }
  if (WiFi.status() != WL_CONNECTED)
  {
    connectWifi();
  }

  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  IPAddressToUse = WiFi.localIP().toString();

  uint8_t MAC_array[6];
  char MAC_char[18];

  Serial.println();

  WiFi.macAddress(MAC_array);
  for (int i = 0; i < sizeof(MAC_array); ++i) {
    sprintf(MAC_char, "%s%02x:", MAC_char, MAC_array[i]);
  }

  macAddressStr = String(MAC_char);
  macAddressStr = macAddressStr.substring(0, macAddressStr.length() - 1);

  Serial.print("MAC: ");
  Serial.println(macAddressStr);

}

Comments

Popular posts from this blog

DIY IKEA Tradfri lamp