462 lines
15 KiB
C++
Executable file
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
|