John Hart
Published © GPL3+

Gecko Habitat Monitor/Thermostat - Arduino Style w/ WebPage

Arduino on ESP8266 NODEMCU reading 2 DS18B20's. One probe measures surface temp and one for ambient. Controlling relays for UTH & heat lamp.

IntermediateShowcase (no instructions)4 hours1,236
Gecko Habitat Monitor/Thermostat - Arduino Style w/ WebPage

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
Relay - 2 Channel 10Amp
×1
DS18B20 Temperature Sensor
×2

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

NODE_DS18B20_Fritx_28Aug17

Basic idea for using DS18B20 with relay and small appliance. Use at your own risk. Research splicing extension cord for usage in implementation.

Code

NODE_DS18B20_Gecko_Temp_Monitor_Share_28Aug17

Arduino
Arduino sketch will compile in its current state as long as all necessary libraries are available to it. Logic is present for one relay at this time. Add logic as needed. I did NOT use resistors for the DS18B20's as most recommend and all are working by design and as expected. Baseline tested for 2 weeks prior to implementation to prove calibration accuracy. All tests passed.
/*JohnnyFRX 28Aug17
   Designed for NODEMCU 0.9 on NODEMCU BASE Ver1.0 running Arduino.
   Compiled successfully on Arduino IDE ver 1.8.3 on 29Aug17 in current state.
*/

#include <elapsedMillis.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

WiFiServer server(80);//*************************************************************************************Default Port Set

#define ONE_WIRE_BUS_PIN D3//**********************************************************************************Your Pin

OneWire oneWire(ONE_WIRE_BUS_PIN);

DallasTemperature sensors(&oneWire);

/*-----( Declare Variables )-----*/
// Assign the addresses of your 1-Wire temp sensors. asdasdasdasxcxcxcx
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress heatpadThermo = { 0x28, 0xFF, 0x0C, 0x29, 0xA0, 0x16, 0x05, 0x05 };
DeviceAddress coolsideThermo = { 0x28, 0xFF, 0x04, 0x95, 0x83, 0x16, 0x03, 0x15 };

unsigned long currentMillis;
unsigned long previousMillis;
unsigned long duration;

const int relayPin =  4;//*****************************************************************************************YOUR PIN
const int heatingLed = D1;//***************************************************************************************YOUR PIN
const int coolingLed = D9;//***************************************************************************************YOUR PIN
int minutes;
int hours;
elapsedMillis statusTimer;
elapsedMillis rebootTimer;
unsigned long seconds = statusTimer;


byte oldSwitchState = HIGH;  // assume switch open because of pull-up resistor
bool toggle;
const int ledPin = LED_BUILTIN;

void setup()
{
  WiFi.hostname("Gecko_Watchdog");//*********************************************************************************YOUR HOSTNAME
  Serial.begin(9600);
  const char* ssid = "";//******************************************************************************************YOUR SSID

  pinMode(relayPin, OUTPUT);
  pinMode(heatingLed, OUTPUT);
  pinMode(coolingLed, OUTPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);


  const char* password = "";//*********************************************************************************************YOUR SSID PASSWORD
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");

    server.begin();
    Serial.println("Web server running. Waiting for the ESP IP...");
    delay(10000);
    Serial.println(WiFi.localIP());
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);

  sensors.begin();

  sensors.setResolution(heatpadThermo, 12);
  sensors.setResolution(coolsideThermo, 12);

}

void loop()
{
  stopWatch();
  //*******************************************************************************************************************STATE MACHINE START
  byte switchState = digitalRead (relayPin);

  // has it changed since last time?
  if (switchState != oldSwitchState)
  {
    oldSwitchState =  switchState;  // remember for next time
    toggle = !toggle;   // toggle the variable
    statusTimer = 0;
    delay (10);         // debounce
  }
  //*********************************************************************************************************************STATE MACHINE STOP

  //*******************************************************************************************************************UPTIME TIMER BEGIN

  unsigned long runMillis = millis();
  unsigned long allSeconds = millis() / 1000;
  int runHours = (allSeconds / (60 * 60)) % 24;
  int secsRemaining = allSeconds % 3600;
  int runMinutes = secsRemaining / 60;
  int runSeconds = secsRemaining % 60;
  int runDays = runMillis / 86400000;

  char buf[21];
  sprintf(buf, "%02d:%02d:%02d:%02d", runDays, runHours, runMinutes, runSeconds);


  //******************************************************************************************************************UPTIME TIMER END

  delay(1000);
  Serial.println();
  Serial.print("Number of Devices found on bus = ");
  Serial.println(sensors.getDeviceCount());
  Serial.print("Getting temperatures... ");
  Serial.println();

  sensors.requestTemperatures();
  //***************************************************************************************************************************DS18B20 LOGIC BEGIN
  Serial.print("heatpadThermo temperature is:   ");
  printTemperature(heatpadThermo);
  Serial.println();
  float heatpadTemp = sensors.getTempF(heatpadThermo);
  // float heatpadTemp = (95);
  Serial.print("coolsideThermo temperature is:   ");
  printTemperature(coolsideThermo);
  Serial.println();
  float coolsideTemp = sensors.getTempF(coolsideThermo);
//*******************************************************************************************************************************Relay used is Sainsmart 2 channel 'Active Low' w/ 'Normally Closed' circuit.
  if (heatpadTemp < 90) {
    digitalWrite(relayPin, HIGH);
    digitalWrite(coolingLed, LOW);
    digitalWrite(heatingLed, HIGH);
    toggle = true;
  }

  if (heatpadTemp >= 92) {
    digitalWrite(relayPin, LOW);
    digitalWrite(coolingLed, HIGH);
    digitalWrite(heatingLed, LOW);
    toggle = false;
  }
  //******************************************************************************************************************************DS18B20 LOGIC END

  //****************************************************************************************************************************WEB STARTS HERE
  WiFiClient client = server.available();
  if (client) {
    Serial.println("New client");
    // bolean to locate when the http request ends
    boolean blankLine = true;
    while (client.connected()) {
      if (client.available()) {
        String request = client.readStringUntil('\r');//**************************************************************************MANUAL RELAY CONTROL(CURRENTLY MAPPED TO LED_BUILTIN FOR TESTING)
        Serial.println(request);//************************************************************************************************MANUAL RELAY CONTROL(CURRENTLY MAPPED TO LED_BUILTIN FOR TESTING)

        // client.flush();
        char c = client.read();

        if (c == '\n' && blankLine) {

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.print  ("<body style=background-color:#E74C3C>");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<HTML>");
          client.println(" <HEAD>");
          client.println("  <TITLE> Leonardo's Lair  </TITLE>");
          client.println("</head>");
          client.println("<style>");
          client.println("</style>");
          client.println(" </HEAD>");
          client.println("<body>");
          client.println("<br>");
          client.print ("<font color=green size=7>");
          client.println("<H1><center>UPTIME TESTER</center></h1>");
          client.println("<center>");
          client.println("<H2>Current Status</H2>");
          client.println("<table id=""t01"">");
          client.print ("<font color=black size=7>");
          // client.println("<br />");
          // client.println("<br/>");
          client.print ("<font color=black size=7>");
          client.print("Heatpad Thermo: ");

          client.print(heatpadTemp, 3); //print temperature from DS18x20 sensor
          client.println("\xB0");
          client.println(" F");
          client.print ("<font color=green size=7>");

          client.print ("<font color=black size=7>");
          client.println("<br />");
          client.print ("<font color=black size=7>");
          client.print("Coolside Thermo: ");

          client.print(coolsideTemp, 3); //print temperature from DS18x20 sensor
          client.println("\xB0");
          client.println(" F");
          //client.print ("<font color=green size=7>");
          client.println();

          //*******************************************************************************************START HEATING STOPWATCH PRINT

          if (toggle == true) {  //  CHANGE BACK  TO 93 FOR PROD
            //if (digitalRead(relayPin) == LOW) {

            client.print("<table id=""t01"">");
            // client.print("<br />");
            client.print ("<font color=red size=7>");
            client.print("Elapsed heating time: ");
            client.print(minutes);
            client.print(':');
            if (seconds < 10) {
              client.print('0');
            }
            client.print(seconds);

          }



          //******************************************************************************************STOP HEATING STOPWATCH PRINT

          //*******************************************************************************************START COOLING STOPWATCH PRINT

          if (toggle == false) { //  CHANGE BACK  TO 89 FOR PROD
            //if (digitalRead(relayPin) == HIGH) {

            client.println("<table id=""t01"">");
            client.println("<br />");
            client.print ("<font color=blue size=7>");
            client.print("Elapsed cooling time: ");
            client.print(minutes);
            client.print(':');
            if (seconds < 10) {
              client.print('0');
            }
            client.println(seconds);

          }


          //******************************************************************************************STOP COOLING STOPWATCH PRINT

          //****************************************************************************************************************START RELAY TOGGLE

          int value = HIGH;
          if (request.indexOf("/LED=ON") != -1) {
            digitalWrite(ledPin, LOW);
            value = LOW;
          }
          if (request.indexOf("/LED=OFF") != -1) {
            digitalWrite(ledPin, HIGH);
            value = HIGH;
          }

          client.println("<br><br>");
          client.print ("<font color=black size=7>");
          client.print("Heat Override is now: ");

          if (value == LOW) {
            client.print ("<font color=red size=7>");
            client.print("ON");
          } else {
            client.print ("<font color=blue size=7>");
            client.print("OFF");
          }
          client.println("<br>");
          client.print ("<font color=black size=7>");


          client.println("<a href=\"/LED=ON\"><style=width:5000px;height:10000px><button><font color=red size=7>ON   </button></a>&nbsp;<sp><a href=\"/LED=OFF\"><button><font color=blue size=7>OFF</button></a></p>");

          client.println("</html>");

          delay(1);
          Serial.println("Client disconnected");
          Serial.println("");





          //**********************************************************************************************STOP RELAY TOGGLE HERE


          //********************************************************************************************************START UPTIME COUNTER
          client.println("<table id=""t01"">");
          //client.println("<br />");
          client.println("<br />");
          client.print ("<font color=green size=5>");
        
          client.println("<br />");
          client.print("I have been keeping Leonardo comfy for ");

          client.println(buf);
          client.print("since my last reboot.");
          //*************************************************************************************************************STOP UPTIME COUNTER

          break;
        }
        if (c == '\n') {
          blankLine = true;
        }
        else if (c != '\r') {
          blankLine = false;
        }
      }
    }
    delay(1);
    client.stop();
    Serial.println("client disconnected");
  }



  //**********************************************************************************************************************WEB STOPS HERE

}

/*-----( Declare User-written Functions )-----*/
void printTemperature(DeviceAddress deviceAddress)
{

  float tempC = sensors.getTempC(deviceAddress);

  if (tempC == -127.00)
  {
    Serial.print("Error getting temperature  ");
  }
  else
  {
    Serial.print("C: ");
    Serial.print(tempC);
    Serial.print(" F: ");
    Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}// End printTemperature
//*********( THE END )***********
void stopWatch()
{

  seconds = statusTimer / 1000;
  minutes = seconds / 60;
  seconds %= 60;
  hours = minutes / 60;


  Serial.print(minutes);
  Serial.print(':');
  if (seconds < 10) {
    Serial.print('0');
  }
  Serial.println(seconds);
  delay(1000);
}

Credits

John Hart

John Hart

5 projects • 12 followers
Blinked my first LED in August 2016...had never even heard of Arduino before then. Now I CAN'T STOP MAKING THINGS! Arduino UNO & ESP8266
Thanks to Michael J..

Comments