187 lines
5.7 KiB
C++
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);
|
|
}
|
|
|