ESP8266-01 Temperature Logger With Multiple Inputs

by iotamajig in Circuits > Arduino

9467 Views, 39 Favorites, 0 Comments

ESP8266-01 Temperature Logger With Multiple Inputs

ESP8266-01 Temperature Sensor Addressing_bb.jpg

If you are familiar with Arduino, you may have used some of the analog temperature sensors that come in the starter kits. When using an ESP-01, we don't have ready access to an analog pin, so we need to use a digital sensor, like the DS18B20. There are two libraries you need to use with these sensors:

#include <OneWire.h>
#include <DallasTemperature.h>

The great thing about the OneWire library, is that it allows you to have multiple sensors on the same pin!

What I'm going to cover here is not a full-fledged data logger per se (though it will log to the serial monitor), but I'll show you the basics of getting up and running with these sensors.

For more on OneWire, you should read this. For much more on the DallasTemperature code, definitely read this. In fact, the code I'll present to you here all comes from that link - though I will be providing a condensed "get me up and running" version, as well as cover a few points that I think are not covered very intuitively in the original documentation.

Parts Needed

Assuming you already have a board set up to flash the program to your ESP (if not, see here), you only need a few items:

Build Your Board

ESP8266-01 Temperature Sensor Addressing_bb.jpg

Set up the board as outlined in this diagram. Make sure you wire the + and - lines of the temperature sensors properly, otherwise they won't be happy!

The 220 Ohm resistor is acting as a pull up resistor on GPIO2 on your ESP.

Code 1: Get Your Addresses

First, upload the following code to GET the addresses of the sensors.

#include 
#include 

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;

void setup(void)
{
  // start serial port
  Serial.begin(115200);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin();
  
  // locate devices on the bus
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // search for devices on the bus and assign based on an index.
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 


 
  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();
  
  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
}



// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}



void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");


  // show the temperatures:
  printData(insideThermometer);
  printData(outsideThermometer);

  delay(5000);

}


Write Down Your Addresses: Label the DS18B20

Make sure the serial monitor is open as your code executes. The serial monitor should show you two long strings of characters - these are the addresses.

Now, you've probably figured this out, but the easy way to know which one is which, is to heat one of them up. Put your finger on one. After a few readouts to the serial monitor, you now know who is who!

Label or somehow mark the sensors with the address. This way you will know the address if you ever recycle the sensor for another project.

Use the Address

Now that we know what the addresses are, we can use them directly in our code. You may ask: but can't we just keep the code generic and query them by index? Sure you can. But, imagine we have an indoor sensor and an outdoor sensor. Or maybe even more. Would you want to have to set them up and just guess which one is where you think it is? Coding the address in will make sure you know which sensor is which every time with no guesswork.

So, the code below is almost identical to what we used to get the addresses. The main difference is the setting of two variables with the now known addresses instead of looking them up:

#include 
#include 

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

  //First address received was 28FFAEF3701605B6
  uint8_t insideThermometer[8] = { 0x28, 0xFF, 0xAE, 0xF3, 0x70, 0x16, 0x05, 0xB6 };
  //Second address received was 28FF5E9C711604EF
  uint8_t outsideThermometer[8]   = { 0x28, 0xFF, 0x5E, 0x9C, 0x71, 0x16, 0x04, 0xEF };

void setup(void)
{
  // start serial port
  Serial.begin(115200);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin();
  
  // locate devices on the bus
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

 
  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();
  
  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
}



// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}



void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");


  // show the temperatures:
  printData(insideThermometer);
  printData(outsideThermometer);

  delay(5000);

}

Conclusion

Now that know how to use these sensors, if you have a web data logging service (or your own website you can post data to), you can use this code along with something like this to upload your data to the web.

Or, if you are just making a home weather monitoring station, plug your data in with this code to use your ESP as a web server to access your temperatures from your phone or PC. I see these sensors used a lot in home brewing applications. I'll be using them in a freezer monitoring project coming up soon.