Table of Contents
Getting measurements
The desired output will be in JSON format, this is a lightweight human readable data structure that allows us to use the data later in other devices or programs.
{ "node": "84:F3:EB:EE:65:92", "measurements": { "temperature": [ { "type": "DS18B20", "id": 0, "value": 24.8 }, { "type": "DS18B20", "id": 1, "value": 25 }, { "type": "SHT11", "value": 25.4 } ], "humidity": [ { "type": "SHT11", "value": 37 } ] } }
I use PlatformIO to program my microcontrollers but the used sketch should also work in the Arduino IDE.
Arduino code
The code I use to get the JSON output is:
main.cpp
#include <ESP8266WiFi.h> #include "Ticker.h" // Library for scheduling tasks without using delay() #include <ArduinoJson.h> // Needed to store configuration as JSON: https://github.com/bblanchon/ArduinoJson #include <Sensirion_SHT1x.h> // Declarations for the Sensirion SHT11 Temperature/Humidity sensor #include <DS18B20_Sensors.h> // Declarations for the Sensirion DS18B20 Temperature sensor void getMeasurements(); Ticker timerMeasurement(getMeasurements, 5000); // execute getMeasurements() every 5000ms void setup() { Serial.begin(74880); // Print the Node identifier Serial.print("ESP Board MAC Address: "); Serial.println(WiFi.macAddress()); // Start up the DS18B20 library DS18B20.begin(); // Find available DS18B20 sensors report_DS18B20_sensors(); // Set the temperature resolution for each DS18B20 sensor for (int i=0; i<deviceCount; i++){ DS18B20.setResolution(T[i].addr, TEMPERATURE_PRECISION_10_BIT); print_DS18B20_resolution(T[i].addr); } // start the timer for periodic measurements timerMeasurement.start(); } void loop() { // check to see if the timer has elapsed timerMeasurement.update(); } void getMeasurements(){ // create a JSON object const int capacity = JSON_OBJECT_SIZE(1024); StaticJsonDocument<capacity> obj; // add the node identifier to the JSON object obj["node"] = WiFi.macAddress(); // request a measurement form each DS18B20 sensor Serial.println("Requesting temperatures..."); DS18B20.requestTemperatures(); // add the measured temperatures to the JSON object for (int i=0; i<deviceCount; i++){ obj["measurements"]["temperature"][i]["type"] = "DS18B20"; obj["measurements"]["temperature"][i]["id"] = i; obj["measurements"]["temperature"][i]["value"] = round(DS18B20.getTempCByIndex(i)*10) / 10; } // Read values from the SHT11 sensor temp_c = sht1x.readTemperatureC(); temp_f = sht1x.readTemperatureF(); humidity = sht1x.readHumidity(); // add the SHT11 temperature values to the JSON object obj["measurements"]["temperature"][deviceCount]["type"] = "SHT11"; obj["measurements"]["temperature"][deviceCount]["value"] = round(temp_c*10)/10; // add the SHT11 humidity values to the JSON object obj["measurements"]["humidity"][0]["type"] = "SHT11"; obj["measurements"]["humidity"][0]["value"] = round(humidity); // print the JSON object to the serial port serializeJsonPretty(obj, Serial); Serial.println(""); Serial.println("DONE"); }
DS18B20_Sensors.h
#include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS D3 // define possible precisions #define TEMPERATURE_PRECISION_9_BIT 9 #define TEMPERATURE_PRECISION_10_BIT 10 #define TEMPERATURE_PRECISION_11_BIT 11 #define TEMPERATURE_PRECISION_12_BIT 12 // 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 DS18B20(&oneWire); // arrays to hold device addresses DeviceAddress insideThermometer, outsideThermometer; // define a structure to store the unique DS18B20 addresses uint8_t deviceCount = 0; struct { int id; DeviceAddress addr; } T[255]; // function to print a device address void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { // zero pad the address if necessary if (deviceAddress[i] < 16) { Serial.print("0"); } i == 0 ? Serial.print("{0x"):Serial.print(""); Serial.print(deviceAddress[i], HEX); i < 7 ? Serial.print(", 0x"):Serial.print(""); i == 7 ? Serial.print("}"):Serial.print(""); } } // function to print a device's resolution void print_DS18B20_resolution(DeviceAddress deviceAddress) { printAddress(deviceAddress); Serial.print(" resolution = "); Serial.print(DS18B20.getResolution(deviceAddress)); Serial.println(); } void report_DS18B20_sensors() { deviceCount = DS18B20.getDeviceCount(); Serial.println("Locating DS18B20 devices..."); Serial.print("Found "); Serial.print(deviceCount, DEC); Serial.println(" sensors:"); // Read ID's per sensor // and put them in T array for (uint8_t index = 0; index < deviceCount; index++) { // go through sensors DS18B20.getAddress(T[index].addr, index); T[index].id = index; } // Check sensors are set for (uint8_t index = 0; index < deviceCount; index++) { Serial.print("DS18B20["); Serial.print(T[index].id); Serial.print("] = "); printAddress(T[index].addr); Serial.println(""); } Serial.println("................."); }
Sensirion_SHT1x.h
#include <SHT1x.h> // Specify data and clock connections and instantiate SHT1x object #define dataPin D2 #define clockPin D1 SHT1x sht1x(dataPin, clockPin); float temp_c; float temp_f; float humidity;