From 3140ffcb3b3a04b6bde5ffb8be3a2a54c01b1a9b Mon Sep 17 00:00:00 2001 From: Christopher Wong Date: Tue, 23 May 2023 16:10:17 -0700 Subject: [PATCH] Add support for DS18B20 sensors (#907) Add support for DS18B20 sensors. This supports multiple sensors chained onto the same pin. --- platformio.ini | 4 ++ src/DS18B20.cpp | 163 ++++++++++++++++++++++++++++++++++++++++++++++++ src/DS18B20.h | 15 +++++ src/main.cpp | 5 ++ src/main.h | 1 + 5 files changed, 188 insertions(+) create mode 100644 src/DS18B20.cpp create mode 100644 src/DS18B20.h diff --git a/platformio.ini b/platformio.ini index cad15ab..8aa0cab 100644 --- a/platformio.ini +++ b/platformio.ini @@ -106,6 +106,10 @@ lib_deps = beegee-tokyo/DHT sensor library for ESPx@^1.18 sparkfun/SparkFun SGP30 Arduino Library@^1.0.5 sensirion/arduino-sht@^1.2.2 + paulstoffregen/OneWire@^2.3.7 + milesburton/DallasTemperature@^3.11.0 + + [env:esp32] extends = esp32 diff --git a/src/DS18B20.cpp b/src/DS18B20.cpp new file mode 100644 index 0000000..a8c2e0c --- /dev/null +++ b/src/DS18B20.cpp @@ -0,0 +1,163 @@ +#ifdef SENSORS +#include "DS18B20.h" + +#include "globals.h" +#include "mqtt.h" +#include "defaults.h" +#include +#include +#include "string_utils.h" + +#include +#include +#include + + +namespace DS18B20 +{ + int ds18b20Pin = -1; + float dsTempOffset; + int numSensors = 0; + + /** Initialize onewire and Dallas Temperature*/ + OneWire oneWire; + DallasTemperature sensors; + + /** Task handle for the light value read task */ + TaskHandle_t DSTempTaskHandle = NULL; + + /** Ticker for temperature reading */ + Ticker tempTicker; + + /** Flags for temperature readings finished */ + bool gotNewTemperature = false; + + /* Flag if main loop is running */ + bool dsTasksEnabled = false; + + /* update every 10 seconds */ + int dsUpdateTime = 10; + + /** + * Task to reads temperature from DS18B20 sensor + * @param pvParameters + * pointer to task parameters + */ + void tempTask(void *pvParameters) + { + while (1) // tempTask loop + { + if (dsTasksEnabled && !gotNewTemperature) + { + // Read temperature only if old data was processed already + sensors.requestTemperatures(); + gotNewTemperature = true; + } + vTaskSuspend(NULL); + } + } + + /** + * triggerGetTemp + * Sets flag dhtUpdated to true for handling in loop() + * called by Ticker tempTicker + */ + void triggerGetTemp() + { + if (DSTempTaskHandle != NULL) + { + xTaskResumeFromISR(DSTempTaskHandle); + } + } + + void Setup() + { + if (ds18b20Pin>=0) { + oneWire.begin(ds18b20Pin); + sensors.setOneWire(&oneWire); + sensors.begin(); + //Need to begin twice for some reason to get the sensors to start + sensors.begin(); + + numSensors = sensors.getDeviceCount(); + + // Start task to get temperature + xTaskCreatePinnedToCore( + tempTask, /* Function to implement the task */ + "DS", /* Name of the task */ + 1024, /* Stack size in words */ + NULL, /* Task input parameter */ + 5, /* Priority of the task */ + &DSTempTaskHandle, /* Task handle. */ + 1); /* Core where the task should run */ + + if (DSTempTaskHandle == NULL) + { + Serial.println("[ERROR] Failed to start task for temperature update"); + } + else + { + // Start update of environment data every 10 seconds + tempTicker.attach(dsUpdateTime, triggerGetTemp); + } + + // Signal end of setup() to tasks + dsTasksEnabled = true; + } + } + + void ConnectToWifi() + { + AsyncWiFiSettings.html("h4", "DS18B20:"); + ds18b20Pin = AsyncWiFiSettings.integer("ds18b20_pin", -1, "DS18B20 sensor pin (-1 for disable)"); + dsTempOffset = AsyncWiFiSettings.floating("dsTemp_offset", -40, 125, 0.0, "DS18B20 temperature offset"); + } + + void SerialReport() + { + if (ds18b20Pin<0) return; + Serial.print("DS18B20 Sensor: "); + Serial.println((ds18b20Pin>=0 ? "pin " + String(ds18b20Pin) : "disabled").c_str()); + Serial.print("DS18B20 Offset: "); + Serial.println(dsTempOffset); + } + + void Loop() + { + if (ds18b20Pin<0) return; + + if (gotNewTemperature) + { + for (int i = 0; i < numSensors; i++){ + float temperature = sensors.getTempCByIndex(i) + dsTempOffset; + Serial.println("DS18B20 Temp_"+ String(i+1) + ": " + String(temperature, 1) + "'C"); + + pub((roomsTopic + "/ds18b20_temperature_" + String(i+1)).c_str(), 0, 1, String(temperature, 1).c_str()); + } + + gotNewTemperature = false; + } + } + + bool SendDiscovery() + { + if (ds18b20Pin<0) return true; + bool returnVal = true; + + for (int i = 0; i < numSensors; i++){ + returnVal = sendSensorDiscovery("DS18B20 Temperature " + String(i+1), EC_NONE, "temperature", "°C") && returnVal; + } + return returnVal; + } + + bool Command(String& command, String& pay) + { + return false; + } + + bool SendOnline() + { + return true; + } +} +#endif diff --git a/src/DS18B20.h b/src/DS18B20.h new file mode 100644 index 0000000..1dd8a65 --- /dev/null +++ b/src/DS18B20.h @@ -0,0 +1,15 @@ +#pragma once +#ifdef SENSORS +#include + +namespace DS18B20 +{ + void Setup(); + void ConnectToWifi(); + void SerialReport(); + void Loop(); + bool SendDiscovery(); + bool SendOnline(); + bool Command(String& command, String& pay); +} +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 377adf8..07f2a93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,6 +54,7 @@ bool sendTelemetry(unsigned int totalSeen, unsigned int totalFpSeen, int unsigne && TSL2561::SendDiscovery() && SensirionSGP30::SendDiscovery() && HX711::SendDiscovery() + && DS18B20::SendDiscovery() #endif ) { sentDiscovery = true; @@ -188,6 +189,7 @@ void setupNetwork() { TSL2561::ConnectToWifi(); SensirionSGP30::ConnectToWifi(); HX711::ConnectToWifi(); + DS18B20::ConnectToWifi(); #endif @@ -248,6 +250,7 @@ void setupNetwork() { TSL2561::SerialReport(); SensirionSGP30::SerialReport(); HX711::SerialReport(); + DS18B20::SerialReport(); #endif Serial.print("Query: "); @@ -527,6 +530,7 @@ void setup() { TSL2561::Setup(); SensirionSGP30::Setup(); HX711::Setup(); + DS18B20::Setup(); #endif xTaskCreatePinnedToCore(scanTask, "scanTask", SCAN_TASK_STACK_SIZE, nullptr, 1, &scanTaskHandle, CONFIG_BT_NIMBLE_PINNED_TO_CORE); reportSetup(); @@ -561,5 +565,6 @@ void loop() { TSL2561::Loop(); SensirionSGP30::Loop(); HX711::Loop(); + DS18B20::Loop(); #endif } diff --git a/src/main.h b/src/main.h index 6494e70..56e1aa2 100644 --- a/src/main.h +++ b/src/main.h @@ -41,6 +41,7 @@ #include "SHT.h" #include "SensirionSGP30.h" #include "TSL2561.h" +#include "DS18B20.h" #endif TimerHandle_t reconnectTimer;