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

462 lines
15 KiB
C++
Executable file

#include <aJSON.h>
#include <SPI.h>
#include <Ethernet.h>
#include "aWOT.h"
#include "StaticFiles.h"
#include <DallasTemperature.h>
#include <utility/w5100.h>
#include <Adafruit_SCD30.h>
#include <Wire.h>
#include <Arduino.h>
#include <OneWire.h>
#include <CCS811.h>
#include <Adafruit_AHTX0.h>
#include <Adafruit_ADS1X15.h>
#include <Wire.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server(80);
Application app;
unsigned long connectTime[MAX_SOCK_NUM];
int WARNING_LOG_DELTA_THRESHOLD = 5; // > 5c temp diff in 0.500s is alarming and should be logged as anamolous
float HEAT_DELTA = 0.2; // Delta from goal Temp to neccessitate a change
float HUM_DELTA = 1; // Delta from goal Humidity to neccessitate a change
short UV_UP_TIME = 6; // 6/10
// const String ip = "10.0.0.28";
//272911496883
IPAddress ip(10,0,0,28);
byte gateway[] = { 10, 0, 0, 1 };
byte subnet[] = { 255, 255, 255, 0 };
struct OneSensor {
float history[5];
float currentAgg;
uint8_t address[8];
float goalVal;
};
struct GasSensor {
int history[5];
int currentAgg;
int goalVal;
Adafruit_SCD30 sensor;
float currentTemp;
float currentHum;
};
struct LvlSensor {
float history[5];
float currentAgg;
int trig;
int echo;
float goalVal;
};
struct IncubatorDrain {
int pin;
bool isActive;
char type; // "L" light, "P" pump, "H" heat
OneSensor sensor;
};
struct HTSensor {
float tempHistory[5];
float currentAggTemp;
float goalValTemp;
float humHistory[5];
float currentAggHum;
float goalValHum;
Adafruit_AHTX0 aht;
};
struct MarthaDrain {
int pin;
bool isActive;
char type; // "L" light, "P" pump, "H" heat
};
struct vReading {
int16_t readings1[size] = {0};
int16_t readings2[size] = {0};
Adafruit_ADS1115 sensor;
// ADC object at I2C address 0x48 for addr pin = GND
float avrProng1 = 0;
float avrProng2 = 0;
unsigned char readCnt = 0;
};
void setup() {
Serial.begin(115200);
setupIncubator(22, 22);
setupAutoHumidity(18, 80);
setupDataLogger();
// pinMode(46,OUTPUT) ;
// pinMode(44,OUTPUT) ;
// digitalWrite(44, LOW);
// digitalWrite(44, HIGH);
Ethernet.begin(mac, ip, gateway, subnet);
// while (!Ethernet.begin(mac, ip)) {
// delay(500);
// Serial.print(".");
// }
// Serial.println(Ethernet.localIP());
app.get("/Incubator/Section", &getIncubatorSectionData);
app.put("/Incubator/Section", &setIncubatorSectionData);
app.put("/Martha/Temp", &setMarthGoalTemp);
app.put("/Martha/Hum", &setMarthGoalHum);
app.get("/Martha", &getMarthaData);
app.get("/Connection", &getMarthaData);
app.get("/Logger", &getDataLogger);
// app.get("/", &index);
app.use(staticFiles());
Serial.println((int16_t)0);
server.begin();
unsigned long thisTime = millis();
for(int i=0;i<MAX_SOCK_NUM;i++) {
connectTime[i] = thisTime;
}
}
void loop() {
EthernetClient client = server.available();
AutoControlLoop();
IncubatorControlLoop();
DataLoggerControlLoop();
if (client.available()) {
Serial.println(F("new client"));
app.process(&client);
client.stop();
}
// int connectLoop = 0;
// bool processed = false;
// while(client.connected())
// {
// while(client.available())
// {
// if(!processed){
// processed = true;
// app.process(&client);
// }
// // inChar = client.read();
// Serial.println(client.read());
// // set connectLoop to zero if a packet arrives
// connectLoop = 0;
// }
// connectLoop++;
// // if more than 10000 milliseconds since the last packet
// if(connectLoop > 750)
// {
// // then close the connection from this end.
// Serial.println();
// Serial.println(F("Timeout"));
// client.flush();
// client.stop();
// }
// delay(1);
// }
// client.flush();
// client.stop();
checkSockStatus();
delay(1);
// Ethernet.begin(mac, ip, gateway, subnet);
// server.begin();
// delay(100);
}
byte socketStat[MAX_SOCK_NUM];
void checkSockStatus()
{
unsigned long thisTime = millis();
for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i);
// Serial.println(s);
if((s == 0x17) || (s == 0x1C)) {
if(thisTime - connectTime[i] > 5000UL) {
Serial.print(F("\r\nSocket frozen: "));
Serial.println(i);
W5100.execCmdSn(i, Sock_CLOSE);
}
}
else connectTime[i] = thisTime;
socketStat[i] = W5100.readSnSR(i);
}
}
void getSystemConnection(Request &req, Response &res){
Serial.println("**********************************");
char goalVal[64];
req.query("goalVal", goalVal, 64);
Serial.println(atof(goalVal));
setAllGoalTemps(atof(goalVal));
aJsonObject *root;
root=aJson.createObject();
aJson.addStringToObject(root, "status", "success");
res.set("Content-Type", "application/json");
aJsonStream stream(&req);
aJson.print(root, &stream);
res.end();
aJson.deleteItem(root);
Serial.println("**********************************");
}
void setMarthGoalHum(Request &req, Response &res){
Serial.println("**********************************");
char goalVal[64];
req.query("goalVal", goalVal, 64);
Serial.println(atof(goalVal));
setAllGoalHum(atof(goalVal));
aJsonObject *root;
root=aJson.createObject();
aJson.addStringToObject(root, "status", "success");
res.set("Content-Type", "application/json");
aJsonStream stream(&req);
aJson.print(root, &stream);
res.end();
aJson.deleteItem(root);
Serial.println("**********************************");
}
void setMarthGoalTemp(Request &req, Response &res){
Serial.println("**********************************");
char goalVal[64];
req.query("goalVal", goalVal, 64);
Serial.println(atof(goalVal));
setAllGoalTemps(atof(goalVal));
aJsonObject *root;
root=aJson.createObject();
aJson.addStringToObject(root, "status", "success");
res.set("Content-Type", "application/json");
aJsonStream stream(&req);
aJson.print(root, &stream);
res.end();
aJson.deleteItem(root);
Serial.println("**********************************");
}
void setIncubatorSectionData(Request &req, Response &res){
Serial.println("**********************************");
char sectionName[64];
char goalVal[64];
req.query("sectionName", sectionName, 64);
req.query("goalVal", goalVal, 64);
Serial.println(sectionName);
Serial.println(atof(goalVal));
if(strcmp(sectionName, "Main") == 0){
setTemperature("Main", atof(goalVal));
}else if(strcmp(sectionName, "Secondary") == 0){
setTemperature("Secondary", atof(goalVal));
}
aJsonObject *root;
root=aJson.createObject();
aJson.addStringToObject(root, "status", "success");
res.set("Content-Type", "application/json");
aJsonStream stream(&req);
aJson.print(root, &stream);
res.end();
aJson.deleteItem(root);
Serial.println("**********************************");
}
void getDataLogger(Request &req, Response &res){
float mainArray[8] = {0, 0, 0, 0, 0, 0, 0, 0};
Serial.println("**********************************");
getDataLoggerDump(mainArray);
aJsonObject *root;
root=aJson.createObject();
aJson.addNumberToObject(root, "LoggerA", mainArray[0]);
aJson.addNumberToObject(root, "LoggerB", mainArray[1]);
aJson.addNumberToObject(root, "LoggerC", mainArray[2]);
aJson.addNumberToObject(root, "LoggerD", mainArray[3]);
aJson.addNumberToObject(root, "LoggerE", mainArray[4]);
aJson.addNumberToObject(root, "LoggerF", mainArray[5]);
aJson.addNumberToObject(root, "LoggerG", mainArray[6]);
aJson.addNumberToObject(root, "LoggerH", mainArray[7]);
res.set("Content-Type", "application/json");
aJsonStream stream(&req);
aJson.print(root, &stream);
res.end();
aJson.deleteItem(root);
Serial.println("**********************************");
}
void getIncubatorSectionData(Request &req, Response &res){
float mainArray[8] = {0, 0, 0, 0, 0, 0, 0, 0};
float secondArray[8] = {0, 0, 0, 0, 0, 0, 0, 0};
Serial.println("**********************************");
char sectionName[64];
req.query("sectionName", sectionName, 64);
Serial.println(sectionName);
// if(strcmp(sectionName, "Main") == 0){
// getSectionData("Main", mainArray);
// }else if(strcmp(sectionName, "Secondary") == 0){
// getSectionData("Secondary", mainArray);
// }
getSectionData("Main", mainArray);
getSectionData("Secondary", secondArray);
aJsonObject *root,*tmps, *firstRt, *secondRt, *secondTmps, *drainStates;
root=aJson.createObject();
aJson.addItemToObject(root, "mainSection", firstRt = aJson.createObject());
aJson.addNumberToObject(firstRt, "avrTemp", mainArray[0]);
aJson.addNumberToObject(firstRt, "goalTemp", mainArray[6]);
// aJson.addBooleanToObject(firstRt, "isActive", mainArray[7] == 0.0? false : true);
aJson.addItemToObject(root, "DrainStates", drainStates = aJson.createObject());
aJson.addBooleanToObject(drainStates, "mainSection", mainArray[7] == 0.0? false : true);
aJson.addBooleanToObject(drainStates, "secondSection", secondArray[7] == 0.0? false : true);
// aJson.addItemToObject(firstRt, "temps", tmps = aJson.createArray());
// aJson.addItemToArray(tmps, aJson.createItem(mainArray[1]));
// aJson.addItemToArray(tmps, aJson.createItem(mainArray[2]));
// aJson.addItemToArray(tmps, aJson.createItem(mainArray[3]));
// aJson.addItemToArray(tmps, aJson.createItem(mainArray[4]));
// aJson.addItemToArray(tmps, aJson.createItem(mainArray[5]));
aJson.addItemToObject(root, "secondSection", secondRt = aJson.createObject());
aJson.addNumberToObject(secondRt, "avrTemp", secondArray[0]);
aJson.addNumberToObject(secondRt, "goalTemp", secondArray[6]);
// aJson.addBooleanToObject(secondRt, "isActive", secondArray[7] == 0.0? false : true);
// aJson.addItemToObject(secondRt, "temps", secondTmps = aJson.createArray());
// aJson.addItemToArray(secondTmps, aJson.createItem(secondArray[1]));
// aJson.addItemToArray(secondTmps, aJson.createItem(secondArray[2]));
// aJson.addItemToArray(secondTmps, aJson.createItem(secondArray[3]));
// aJson.addItemToArray(secondTmps, aJson.createItem(secondArray[4]));
// aJson.addItemToArray(secondTmps, aJson.createItem(secondArray[5]));
res.set("Content-Type", "application/json");
aJsonStream stream(&req);
aJson.print(root, &stream);
res.end();
aJson.deleteItem(root);
Serial.println("**********************************");
}
void getMarthaData(Request &req, Response &res){
float upperSensor[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float lowerSensor[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float co2Sensor[7] = {0, 0, 0, 0, 0, 0, 0};
bool heatState = false;
bool UVState = false;
bool foggerState = false;
Serial.println("**********************************");
getMarthaData(upperSensor, lowerSensor, co2Sensor, heatState, foggerState, UVState);
res.set("Content-Type", "application/json");
aJsonStream stream(&req);
aJsonObject *root, *upper, *upperTmps, *upperHum, *lower, *lowerTmps, *lowerHum, *co2, *co2Hist, *drainStates;
root=aJson.createObject();
aJson.addBooleanToObject(root, "fogger", foggerState);
aJson.addBooleanToObject(root, "heat", heatState);
aJson.addBooleanToObject(root, "uv", UVState);
aJson.addItemToObject(root, "DrainStates", drainStates = aJson.createObject());
aJson.addBooleanToObject(drainStates, "fogger", foggerState);
aJson.addBooleanToObject(drainStates, "heat", heatState);
aJson.addBooleanToObject(drainStates, "uv", UVState);
aJson.addItemToObject(root, "CO2", co2 = aJson.createObject());
aJson.addNumberToObject(co2, "avrCO2", co2Sensor[0]);
aJson.addNumberToObject(co2, "goalCO2", co2Sensor[6]);
// aJson.addItemToObject(co2, "history", co2Hist = aJson.createArray());
// aJson.addItemToArray(co2Hist, aJson.createItem(co2Sensor[1]));
// aJson.addItemToArray(co2Hist, aJson.createItem(co2Sensor[2]));
// aJson.addItemToArray(co2Hist, aJson.createItem(co2Sensor[3]));
// aJson.addItemToArray(co2Hist, aJson.createItem(co2Sensor[4]));
// aJson.addItemToArray(co2Hist, aJson.createItem(co2Sensor[5]));
aJson.addItemToObject(root, "UpperSensor", upper = aJson.createObject());
aJson.addNumberToObject(upper, "avrTemp", upperSensor[0]);
aJson.addNumberToObject(upper, "goalTemp", upperSensor[6]);
// aJson.addItemToObject(upper, "temps", upperTmps = aJson.createArray());
// aJson.addItemToArray(upperTmps, aJson.createItem(upperSensor[1]));
// aJson.addItemToArray(upperTmps, aJson.createItem(upperSensor[2]));
// aJson.addItemToArray(upperTmps, aJson.createItem(upperSensor[3]));
// aJson.addItemToArray(upperTmps, aJson.createItem(upperSensor[4]));
// aJson.addItemToArray(upperTmps, aJson.createItem(upperSensor[5]));
aJson.addNumberToObject(upper, "avrHum", upperSensor[7]);
aJson.addNumberToObject(upper, "goalHum", upperSensor[13]);
// aJson.addItemToObject(upper, "hum", upperHum = aJson.createArray());
// aJson.addItemToArray(upperHum, aJson.createItem(upperSensor[8]));
// aJson.addItemToArray(upperHum, aJson.createItem(upperSensor[9]));
// aJson.addItemToArray(upperHum, aJson.createItem(upperSensor[10]));
// aJson.addItemToArray(upperHum, aJson.createItem(upperSensor[11]));
// aJson.addItemToArray(upperHum, aJson.createItem(upperSensor[12]));
aJson.addItemToObject(root, "WaterSensor", lower = aJson.createObject());
aJson.addNumberToObject(lower, "avrLevel", lowerSensor[0]);
aJson.addNumberToObject(lower, "goalLevel", lowerSensor[6]);
// aJson.addItemToObject(lower, "temps", lowerTmps = aJson.createArray());
// aJson.addItemToArray(lowerTmps, aJson.createItem(lowerSensor[1]));
// aJson.addItemToArray(lowerTmps, aJson.createItem(lowerSensor[2]));
// aJson.addItemToArray(lowerTmps, aJson.createItem(lowerSensor[3]));
// aJson.addItemToArray(lowerTmps, aJson.createItem(lowerSensor[4]));
// aJson.addItemToArray(lowerTmps, aJson.createItem(lowerSensor[5]));
// aJson.addNumberToObject(lower, "avrHum", lowerSensor[7]);
// aJson.addNumberToObject(lower, "goalHum", lowerSensor[13]);
// aJson.addItemToObject(lower, "hum", lowerHum = aJson.createArray());
// aJson.addItemToArray(lowerHum, aJson.createItem(lowerSensor[8]));
// aJson.addItemToArray(lowerHum, aJson.createItem(lowerSensor[9]));
// aJson.addItemToArray(lowerHum, aJson.createItem(lowerSensor[10]));
// aJson.addItemToArray(lowerHum, aJson.createItem(lowerSensor[11]));
// aJson.addItemToArray(lowerHum, aJson.createItem(lowerSensor[12]));
aJson.print(root, &stream);
res.end();
aJson.deleteItem(root);
Serial.println("**********************************");
}
//Controls Mushroom Grow tent
/*
Fogger + (main Fan) (controlled)
UV light (controlled)
Humidity / Temp 1
Humidity / Temp 2
HeatMat (controlled)
Co2 sensor + Air supply Fan (constantly on)
General Circulation Fan (controlled)
*/
//Incubator
/*
Temp 1
Temp 2
HeatMat 1 (controlled)
HeatMat 2 (controlled)
*/
//Shrimp Aquaponica