LoraComms/SensorTransceiverNode/Sensors.cpp
2025-03-10 18:58:58 -05:00

187 lines
5.7 KiB
C++

#include "Sensors.h"
OneWire wire(SENSOR_TYPE_SOIL_TEMPERATURE);
DallasTemperature soilTempSensor(&wire);
Sensors::Sensors() : sensorFlags(0x000) {}
void Sensors::initialize() {
initBarometer();
initSCD30();
initRainSensor();
initWindSensor();
initSoilSensors();
initLightSensor();
int count = 0;
for (int i = 0; i < 32; i++) {
if (sensorFlags & (1 << i)) count++;
}
// Allocate memory for messages
messageArraySize = count;
messages = new Message[messageArraySize];
}
void Sensors::setAddress(uint8_t id) {
NODE_ID = id;
}
void Sensors::initBarometer() {
if (bme.begin(/*0x76*/)) {
sensorFlags |= BAROMETER_BIT;
}
}
void Sensors::initSCD30() {
if (scd30.begin(Wire)) {
sensorFlags |= SCD30_TEMPERATURE_BIT;
sensorFlags |= SCD30_HUMIDITY_BIT;
sensorFlags |= SCD30_CO2_BIT;
}
}
void Sensors::initRainSensor() {
pinMode(RAIN_PWR_PIN, OUTPUT);
pinMode(RAIN_PIN, INPUT);
// Initially keep the sensor OFF
digitalWrite(RAIN_PWR_PIN, LOW);
sensorFlags |= RAIN_BIT;
}
void Sensors::initWindSensor() {
sensorFlags |= WINDSPEED_BIT;
}
void Sensors::initSoilSensors() {
pinMode(SOIL_HUMIDITY_PWR_PIN, OUTPUT);
pinMode(SOIL_HUMIDITY_PIN, INPUT);
// Initially keep the sensor OFF
digitalWrite(SOIL_HUMIDITY_PWR_PIN, LOW);
sensorFlags |= SOIL_HUMIDITY_BIT;
soilTempSensor.begin();
delay(10);
if(soilTempSensor.getDeviceCount() > 0){
sensorFlags |= SOIL_TEMPERATURE_BIT;
}
}
void Sensors::initLightSensor() {
sensorFlags |= LIGHT_BIT;
}
float Sensors::mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
int Sensors::readSensorsAndSend() {
float value;
int messageCount = 0;
if (sensorFlags & BAROMETER_BIT && messageCount < messageArraySize) {
value = readBarometer();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_BAROMETER,(uint16_t) value * 100);
}
if (sensorFlags & SCD30_TEMPERATURE_BIT && scd30.dataAvailable() && messageCount < messageArraySize) {
value = readSCD30Temperature();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_SCD30_TEMPERATURE,(uint16_t) value * 100);
}
if (sensorFlags & SCD30_HUMIDITY_BIT && scd30.dataAvailable() && messageCount < messageArraySize) {
value = readSCD30Humidity();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_SCD30_HUMIDITY,(uint16_t) value * 100);
}
if (sensorFlags & SCD30_CO2_BIT && scd30.dataAvailable() && messageCount < messageArraySize) {
value = readSCD30CO2();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_SCD30_CO2,(uint16_t) value * 100);
}
if (sensorFlags & RAIN_BIT && messageCount < messageArraySize) {
value = readRain();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_RAIN, (uint16_t) value * 100);
}
if (sensorFlags & WINDSPEED_BIT && messageCount < messageArraySize) {
value = readWindSpeed();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_WINDSPEED, (uint16_t) value * 100);
}
if (sensorFlags & SOIL_TEMPERATURE_BIT && messageCount < messageArraySize) {
value = readSoilTemperature();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_SCD30_TEMPERATURE, (uint16_t) value * 100);
}
if (sensorFlags & SOIL_HUMIDITY_BIT && messageCount < messageArraySize) {
value = readSoilHumidity();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_SCD30_HUMIDITY, (uint16_t) value * 100);
}
if (sensorFlags & LIGHT_BIT) {
value = readLight();
messages[messageCount++] = sendSensorData((uint8_t) SENSOR_TYPE_LIGHT_DIODE, (uint16_t) value * 100);
}
return messageCount;
}
char* Sensors::generateMessageID() {
static char id[10]; // 9 characters + null terminator
const char* charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for(int i = 0; i < 9; i++) {
id[i] = charset[random(0, 62)]; // 62 possible alphanumeric characters
}
id[9] = '\0'; // Null terminate the string
return id;
}
Message Sensors::sendSensorData(uint8_t sensorType, uint16_t value) {
Message msg;
msg.sensorType = sensorType;
msg.sensorValue = value;
msg.type = MESSAGE_TYPE_SENSOR_DATA;
msg.senderID = NODE_ID;
strncpy(msg.id, generateMessageID(), sizeof(msg.id));
msg.targetID = MASTER_NODE_ID;
msg.hops = 0;
return msg;
}
float Sensors::readBarometer() {
return bme.readPressure();
}
float Sensors::readSCD30Temperature() {
return scd30.getTemperature();
}
float Sensors::readSCD30Humidity() {
return scd30.getHumidity();
}
float Sensors::readSCD30CO2() {
return scd30.getCO2();
}
float Sensors::readRain() {
digitalWrite(RAIN_PWR_PIN, HIGH);
delay(10);
float val = digitalRead(RAIN_PIN);
digitalWrite(RAIN_PWR_PIN, LOW);
return val;
}
float Sensors::readWindSpeed() {
float sensorValue = analogRead(WIND_PIN);
float voltage = (sensorValue / 1023) * 5;
float wind_speed = mapfloat(voltage, 0.4, 2, 0, 32.4);
float speed_kph = ((wind_speed *3600));
return speed_kph;
}
float Sensors::readSoilTemperature() {
soilTempSensor.getDeviceCount();
soilTempSensor.requestTemperatures();
float temperature = soilTempSensor.getTempCByIndex(0);
return temperature;
}
float Sensors::readSoilHumidity() {
digitalWrite(SOIL_HUMIDITY_PWR_PIN, HIGH);
delay(10);
float sensorValue = analogRead(SOIL_HUMIDITY_PIN);
digitalWrite(SOIL_HUMIDITY_PWR_PIN, LOW);
return sensorValue;
}
float Sensors::readLight() {
return analogRead(LIGHT_PIN);
}