BioController/AutoHumidity.ino
2025-03-10 19:31:28 -05:00

371 lines
12 KiB
C++
Executable file

// #define DHTTYPE DHT11 // DHT 11
//Controls Mushroom Grow tent
/*
Fogger (main Fan)
UV light
Humidity / Temp 1
Humidity / Temp 2
Heatemitter
Potential CO2 meter
*/
Adafruit_AHTX0 aht;
Adafruit_SCD30 scd30; // address: 0x61
// int upperDHT = 5;// address: 0x38
// int lowerDHT = 6;
int heatPin = 44;
int foggerFanPin = 46;
int uvPin = 7;
int mainFan = 42;
// DHT upper(upperDHT, DHTTYPE);
// DHT lower(lowerDHT, DHTTYPE);
GasSensor co2Sensor = { {0, 0, 0, 0, 0}, 0, 0, scd30};
HTSensor upperSensor = {{0, 0, 0, 0, 0}, 0, 0, {0, 0, 0, 0, 0}, 0, 0, aht};
LvlSensor waterSensor = { {0, 0, 0, 0, 0}, 0, 4, 3, 20};
// HTSensor lowerSensor = {{0, 0, 0, 0, 0}, 0, 0, {0, 0, 0, 0, 0}, 0, 0, lower};
MarthaDrain heatLamp = {heatPin, false, 'H'};
MarthaDrain fogger = {foggerFanPin, false, 'W'};
MarthaDrain UVLight = {uvPin, false, 'L'};
MarthaDrain AirFlowFan = {mainFan, false, 'F'};
unsigned long lastAutoReading;
int autoReadIntervalMs = 500;
unsigned long loopIndex = 0;
//TODO: add General Airflow fan
void setupAutoHumidity(float goal, float goalh){
aht.begin();
// lowerSensor.aht.begin() ;
pinMode(waterSensor.trig, OUTPUT); // Initializing Trigger Output and Echo Input
pinMode(waterSensor.echo, INPUT_PULLUP);
pinMode(heatLamp.pin, OUTPUT);
pinMode(fogger.pin, OUTPUT); //Fogger connects to the mister + fan
pinMode(UVLight.pin, OUTPUT);
pinMode(AirFlowFan.pin, OUTPUT);
digitalWrite(heatLamp.pin, HIGH);
digitalWrite(fogger.pin, HIGH);
digitalWrite(UVLight.pin, HIGH);
digitalWrite(AirFlowFan.pin, HIGH);
lastAutoReading = millis();
initHTSensor(upperSensor);
// initHTSensor(lowerSensor);
setAllGoalTemps(goal);
setAllGoalHum(goalh);
while(!co2Sensor.sensor.begin()){
Serial.println("failed to init chip, please check if the chip connection is fine");
delay(1000);
}
// co2Sensor.sensor.setMeasCycle(co2Sensor.sensor.eCycle_250ms);
turnOnAutoDrain(AirFlowFan);
}
void AutoControlLoop() {
unsigned long currentTime = millis();
if(currentTime - lastAutoReading >= autoReadIntervalMs){
loopIndex += 1;
updateAutoSensors();
updateAutoDrains();
updateWaterLevel();
if(loopIndex % 4 == 0){ //Updates every1.5 second
updateCO2Sensor();
}
lastAutoReading = currentTime;
}
}
void updateWaterLevel(){
digitalWrite(waterSensor.trig, LOW); // Set the trigger pin to low for 2uS
delayMicroseconds(2);
digitalWrite(waterSensor.trig, HIGH); // Send a 10uS high to trigger ranging
delayMicroseconds(20);
digitalWrite(waterSensor.trig, LOW); // Send pin low again
int distance = pulseIn(waterSensor.echo, HIGH,26000); // Read in times pulse
Serial.print("distance: ");
Serial.print(distance);
// distance= distance/58;
// Serial.print(", ");
// Serial.print(distance);
Serial.println("");
// if(abs(device.sensor.history[0] - tempC) > WARNING_LOG_DELTA_THRESHOLD){
// //SOME SORT OF LOGGING HERE
// }
for(byte i = (sizeof(waterSensor.history) / sizeof(waterSensor.history[0])) - 1; i >= 1; i--){
waterSensor.history[i] = waterSensor.history[i - 1];
}
waterSensor.history[0] = distance;
int sum = 0;
for(byte i = 0; i < (sizeof(waterSensor.history) / sizeof(waterSensor.history[0])); i++){
sum += waterSensor.history[i];
}
int newAgg = sum / (sizeof(waterSensor.history) / sizeof(waterSensor.history[0]));
waterSensor.currentAgg = newAgg;
}
void updateCO2Sensor(){
if(co2Sensor.sensor.dataReady() && co2Sensor.sensor.read()){ // handle not ready or error reading
int co2 = (int)co2Sensor.sensor.CO2;
float hum = co2Sensor.sensor.relative_humidity;
float temp = co2Sensor.sensor.temperature;
Serial.print("CO2: ");
Serial.print(co2);
Serial.print("ppm, Temp: ");
Serial.print(temp);
Serial.print(" C, Hum: ");
Serial.print(hum);
Serial.println("%");
// if(abs(device.sensor.history[0] - tempC) > WARNING_LOG_DELTA_THRESHOLD){
// //SOME SORT OF LOGGING HERE
// }
for(byte i = (sizeof(co2Sensor.history) / sizeof(co2Sensor.history[0])) - 1; i >= 1; i--){
co2Sensor.history[i] = co2Sensor.history[i - 1];
}
co2Sensor.history[0] = co2;
int sum = 0;
for(byte i = 0; i < (sizeof(co2Sensor.history) / sizeof(co2Sensor.history[0])); i++){
sum += co2Sensor.history[i];
}
int newAgg = sum / (sizeof(co2Sensor.history) / sizeof(co2Sensor.history[0]));
co2Sensor.currentAgg = newAgg;
co2Sensor.currentTemp = temp;
co2Sensor.currentHum = hum;
} else {
Serial.println("Data is not ready!");
if(!co2Sensor.sensor.begin()){
Serial.println("failed to init chip, please check if the chip connection is fine");
}
// co2Sensor.sensor.setMeasCycle(co2Sensor.sensor.eCycle_250ms);
}
/*!
* @brief Set baseline
* @param get from getBaseline.ino
*/
// co2Sensor.sensor.writeBaseLine(0x847B);
}
void updateAutoDrains(){
if(abs(upperSensor.goalValTemp - upperSensor.currentAggTemp) > HEAT_DELTA){
if(upperSensor.goalValTemp > upperSensor.currentAggTemp){
turnOnHeat();
}else if(upperSensor.goalValTemp < upperSensor.currentAggTemp){
turnOffHeat();
}
}
if(abs(upperSensor.goalValHum - upperSensor.currentAggHum) > HUM_DELTA){
if(upperSensor.goalValHum > upperSensor.currentAggHum){
// if(!fogger.isActive){
// Serial.println("*************FOGGER ON *************");
// fogger.isActive = true;
// // analogWrite(fogger.pin, 255);
// delay(1000);
// }
turnOnAutoDrain(fogger);
}else if(upperSensor.goalValHum < upperSensor.currentAggHum){
// if(fogger.isActive){
// Serial.println("*************FOGGER off *************");
// fogger.isActive = false;
// // analogWrite(fogger.pin, 0);
// delay(1000);
// }
turnOffAutoDrain(fogger);
}
}
if(loopIndex % 10 < UV_UP_TIME){ //
turnOnAutoDrain(UVLight);
}else{
turnOffAutoDrain(UVLight);
}
}
void updateAutoSensors(){
getHTData(upperSensor);
}
float *getMarthaData(float (& upperArray)[14], float (& lowerArray)[14], float (& co2Array)[7], bool (& heatState), bool (& foggerState), bool (& UVState)){
heatState = heatLamp.isActive;
foggerState = fogger.isActive;
UVState = UVLight.isActive;
upperArray[0] = upperSensor.currentAggTemp;
upperArray[1] = upperSensor.tempHistory[0];
upperArray[2] = upperSensor.tempHistory[1];
upperArray[3] = upperSensor.tempHistory[2];
upperArray[4] = upperSensor.tempHistory[3];
upperArray[5] = upperSensor.tempHistory[4];
upperArray[6] = upperSensor.goalValTemp;
upperArray[7] = upperSensor.currentAggHum;
upperArray[8] = upperSensor.humHistory[0];
upperArray[9] = upperSensor.humHistory[1];
upperArray[10] = upperSensor.humHistory[2];
upperArray[11] = upperSensor.humHistory[3];
upperArray[12] = upperSensor.humHistory[4];
upperArray[13] = upperSensor.goalValHum;
lowerArray[0] = waterSensor.currentAgg;
lowerArray[1] = waterSensor.history[0];
lowerArray[2] = waterSensor.history[1];
lowerArray[3] = waterSensor.history[2];
lowerArray[4] = waterSensor.history[3];
lowerArray[5] = waterSensor.history[4];
lowerArray[6] = waterSensor.goalVal;
co2Array[0] = co2Sensor.currentAgg;
co2Array[1] = co2Sensor.history[0];
co2Array[2] = co2Sensor.history[1];
co2Array[3] = co2Sensor.history[2];
co2Array[4] = co2Sensor.history[3];
co2Array[5] = co2Sensor.history[4];
co2Array[6] = co2Sensor.goalVal;
}
void getHTData(HTSensor &device)
{
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
Serial.print("Temperature: "); Serial.print(temp.temperature);
Serial.println(" degrees C");
Serial.print("Humidity: "); Serial.print(humidity.relative_humidity);
Serial.println("% rH");
float h = humidity.relative_humidity;
float c = temp.temperature;
// Check if any reads failed
if (isnan(h) || isnan(c)) {
// Serial.println(F("Failed to read from DHT sensor!"));
}else {
if(abs(device.tempHistory[0] - c) > WARNING_LOG_DELTA_THRESHOLD){
//SOME SORT OF LOGGING HERE
}
for(byte i = (sizeof(device.tempHistory) / sizeof(device.tempHistory[0])) - 1; i >= 1; i--){
device.tempHistory[i] = device.tempHistory[i - 1];
device.humHistory[i] = device.humHistory[i - 1];
}
device.tempHistory[0] = c;
device.humHistory[0] = h;
float tempSum = 0;
float humSum = 0;
for(byte i = 0; i < (sizeof(device.tempHistory) / sizeof(device.tempHistory[0])); i++){
tempSum += device.tempHistory[i];
humSum += device.humHistory[i];
}
float newAggTemp = tempSum / (sizeof(device.tempHistory) / sizeof(device.tempHistory[0]));
float newAggHum = humSum / (sizeof(device.humHistory) / sizeof(device.humHistory[0]));
device.currentAggTemp = newAggTemp;
device.currentAggHum = newAggHum;
Serial.print("H ");
Serial.println(newAggHum);
}
}
void turnOnAutoDrain(MarthaDrain &device)
{
if(!device.isActive){
if(device.type == 'W'){ //water
turnOnAutoDrain(AirFlowFan);
}
device.isActive = true;
digitalWrite(device.pin, LOW);
}
}
void turnOffAutoDrain(MarthaDrain &device)
{
if(device.isActive){
if(device.type == 'W'){ //water
turnOffAutoDrain(AirFlowFan);
}
device.isActive = false;
digitalWrite(device.pin, HIGH);
}
}
void turnOnHeat()
{
if(!heatLamp.isActive){
heatLamp.isActive = true;
digitalWrite(heatLamp.pin, LOW);
}
}
void turnOffHeat()
{
if(heatLamp.isActive){
heatLamp.isActive = false;
digitalWrite(heatLamp.pin, HIGH);
}
}
void setAllGoalHum(float g1){
upperSensor.goalValHum = g1;
// lowerSensor.goalValHum = g1;
}
void setAllGoalTemps(float g1){
upperSensor.goalValTemp = g1;
// lowerSensor.goalValTemp = g1;
}
void setGoalCO2(int g){
co2Sensor.goalVal = g;
}
void initHTSensor(HTSensor &device)
{
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
Serial.print("Temperature: "); Serial.print(temp.temperature);
Serial.println(" degrees C");
Serial.print("Humidity: "); Serial.print(humidity.relative_humidity);
Serial.println("% rH");
float h = humidity.relative_humidity;
float c = temp.temperature;
// Check if any reads failed
if (isnan(h) || isnan(c)) {
Serial.println(F("Failed to read from DHT sensor!"));
device.currentAggTemp = 0;
device.tempHistory[0] = 0;
device.tempHistory[1] = 0;
device.tempHistory[2] = 0;
device.tempHistory[3] = 0;
device.tempHistory[4] = 0;
device.currentAggHum = 0;
device.humHistory[0] = 0;
device.humHistory[1] = 0;
device.humHistory[2] = 0;
device.humHistory[3] = 0;
device.humHistory[4] = 0;
}else {
device.currentAggTemp = c;
device.tempHistory[0] = c;
device.tempHistory[1] = c;
device.tempHistory[2] = c;
device.tempHistory[3] = c;
device.tempHistory[4] = c;
device.currentAggHum = h;
device.humHistory[0] = h;
device.humHistory[1] = h;
device.humHistory[2] = h;
device.humHistory[3] = h;
device.humHistory[4] = h;
}
}