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

244 lines
5.8 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;
int tempScanResultIndexes[MAX_TEMP_SENSORS];
int tempScanResultCount = 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;
}
tempScanResultCount = 0;
for (int i = 0; i < MAX_TEMP_SENSORS; i++) {
sensorAddressStrings[i] = "";
tempScanResultIndexes[i] = -1;
}
for (int i = 0; i < sensorCount; i++) {
if (!ds18b20.getAddress(sensorAddresses[i], i)) {
continue;
}
String addressString = addressToString(sensorAddresses[i]);
sensorAddressStrings[i] = addressString;
if (isTempAddressAssigned(addressString)) {
continue;
}
tempScanResultIndexes[tempScanResultCount] = i;
tempScanResultCount++;
}
return tempScanResultCount;
}
int getTempScanResultCount() {
return tempScanResultCount;
}
String getTempScanResultAddress(int index) {
if (index < 0 || index >= tempScanResultCount) {
return "";
}
int physicalIndex = tempScanResultIndexes[index];
if (physicalIndex < 0 || physicalIndex >= sensorCount) {
return "";
}
return sensorAddressStrings[physicalIndex];
}
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 >= tempScanResultCount) {
return false;
}
int physicalIndex = tempScanResultIndexes[scanIndex];
if (physicalIndex < 0 || physicalIndex >= sensorCount) {
return false;
}
String selectedAddress = sensorAddressStrings[physicalIndex];
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;
}