Files
overland-controller/firmware/esp32/overland-controller/sensors.cpp
T

232 lines
5.4 KiB
C++

#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "config.h"
#include "sensors.h"
#include "app_config.h"
SensorData sensors;
OneWire oneWire(ONEWIRE_PIN);
DallasTemperature ds18b20(&oneWire);
DeviceAddress sensorAddresses[MAX_TEMP_SENSORS];
String sensorAddressStrings[MAX_TEMP_SENSORS];
int sensorCount = 0;
float cToF(float c) {
return (c * 9.0 / 5.0) + 32.0;
}
bool validTempC(float tempC) {
return tempC != DEVICE_DISCONNECTED_C && tempC > -55 && tempC < 125;
}
String addressToString(DeviceAddress address) {
String output = "";
for (uint8_t i = 0; i < 8; i++) {
if (address[i] < 16) output += "0";
output += String(address[i], HEX);
if (i < 7) output += ":";
}
output.toUpperCase();
return output;
}
void printAddress(DeviceAddress address) {
Serial.print(addressToString(address));
}
bool addressMatches(DeviceAddress address, const String& expected) {
if (expected.length() == 0) {
return false;
}
String actual = addressToString(address);
String normalizedExpected = expected;
normalizedExpected.toUpperCase();
return actual == normalizedExpected;
}
bool isTempAddressAssigned(const String& address) {
if (address.length() == 0) {
return false;
}
String normalizedAddress = address;
normalizedAddress.toUpperCase();
for (int i = 0; i < MAX_TEMP_SENSORS; i++) {
String assigned = appConfig.tempSensors[i].address;
assigned.toUpperCase();
if (assigned == normalizedAddress) {
return true;
}
}
return false;
}
void clearSensorRuntimeData() {
for (int i = 0; i < MAX_TEMP_SENSORS; i++) {
sensors.tempsF[i] = -127.0;
sensors.online[i] = false;
}
}
int scanTempSensors() {
ds18b20.begin();
sensorCount = ds18b20.getDeviceCount();
if (sensorCount > MAX_TEMP_SENSORS) {
sensorCount = MAX_TEMP_SENSORS;
}
for (int i = 0; i < MAX_TEMP_SENSORS; i++) {
sensorAddressStrings[i] = "";
}
int availableCount = 0;
for (int i = 0; i < sensorCount; i++) {
DeviceAddress address;
if (!ds18b20.getAddress(address, i)) {
continue;
}
String addressString = addressToString(address);
if (isTempAddressAssigned(addressString)) {
continue;
}
memcpy(sensorAddresses[availableCount], address, 8);
sensorAddressStrings[availableCount] = addressString;
availableCount++;
}
sensorCount = availableCount;
return sensorCount;
}
int getTempScanResultCount() {
return sensorCount;
}
String getTempScanResultAddress(int index) {
if (index < 0 || index >= sensorCount) {
return "";
}
return sensorAddressStrings[index];
}
void printSensorAddresses() {
Serial.println("DS18B20 Sensors Found:");
for (int i = 0; i < sensorCount; i++) {
Serial.print(i + 1);
Serial.print(") ");
Serial.println(sensorAddressStrings[i]);
}
if (sensorCount == 0) {
Serial.println("No DS18B20 sensors found.");
} else {
Serial.println("Use: assign temp <slot> <number>");
}
}
void initSensors() {
clearSensorRuntimeData();
scanTempSensors();
printSensorAddresses();
}
void updateSensors() {
clearSensorRuntimeData();
ds18b20.requestTemperatures();
for (int configIndex = 0; configIndex < MAX_TEMP_SENSORS; configIndex++) {
if (!appConfig.tempSensors[configIndex].enabled) {
continue;
}
String configuredAddress = appConfig.tempSensors[configIndex].address;
if (configuredAddress.length() == 0) {
sensors.tempsF[configIndex] = -127.0;
sensors.online[configIndex] = false;
continue;
}
for (int physicalIndex = 0; physicalIndex < sensorCount; physicalIndex++) {
if (!addressMatches(sensorAddresses[physicalIndex], configuredAddress)) {
continue;
}
float tempC = ds18b20.getTempC(sensorAddresses[physicalIndex]);
if (validTempC(tempC)) {
sensors.tempsF[configIndex] = cToF(tempC);
sensors.online[configIndex] = true;
}
break;
}
}
}
bool assignTempSensorByIndex(int configIndex, int scanIndex) {
if (configIndex < 0 || configIndex >= MAX_TEMP_SENSORS) {
return false;
}
if (scanIndex < 0 || scanIndex >= sensorCount) {
return false;
}
String selectedAddress = sensorAddressStrings[scanIndex];
for (int i = 0; i < MAX_TEMP_SENSORS; i++) {
if (i == configIndex) {
continue;
}
if (appConfig.tempSensors[i].address == selectedAddress) {
appConfig.tempSensors[i].address = "";
appConfig.tempSensors[i].enabled = false;
sensors.tempsF[i] = -127.0;
sensors.online[i] = false;
}
}
appConfig.tempSensors[configIndex].address = selectedAddress;
appConfig.tempSensors[configIndex].enabled = true;
return true;
}
bool clearTempSensor(int configIndex) {
if (configIndex < 0 || configIndex >= MAX_TEMP_SENSORS) {
return false;
}
appConfig.tempSensors[configIndex].address = "";
appConfig.tempSensors[configIndex].enabled = false;
appConfig.tempSensors[configIndex].weather = false;
sensors.tempsF[configIndex] = -127.0;
sensors.online[configIndex] = false;
return true;
}