Board Esp8266 Nodemcu 1.0
Blynk 0.61
Mushroom growining terrarium
I’m just starting my adventure with arduino programming. I’m not a programmer but by trial and error I managed to create something like this. It meets my expectations and even exceeds them and is still developing. Not all code is mine, I was inspired by other similar projects.
I’m looking for inspiration. If you see any mistakes in the code or something can be improved, I look forward to your suggestions :D.
Edit . corrected few things in heatmat control logic .
/**************************************
* V0 == DHT Temperature *
* V1 == DHT Humidity *
* V2 == DHT HEATINDEX *
* V3 == StatusLED == led *
* V4 == StatusLED == fanIn *
* V5 == StatusLED == fanOut *
* V6 == StatusLED == humidifier *
* V7 == StatusLED == heatmat *
* V8 == StatusLED == dhtReaderror*
* V11 == Led ON/OFF Button *
* V12 == FanIn ON/OFF Button *
* V13 == FanOut ON/OFF Button *
* V21 == Temoerature slider *
* V22 == Humidity slider *
* V30 == Terminal *
* *
*************************************/
#include <FS.h>
#include <ESP8266WebServer.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#include <DNSServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h> //last v5 build
#include <ArduinoOTA.h>
#include <EEPROM.h>
//DEFINE RELAY PINS
#define relayLED D2
#define relayFANin D3
#define relayFANout D4
#define relayFOGGER D5
#define relayHEATMAT D7
//DHT setup
#define DHTPIN D1
#define DHTTYPE DHT22
DHT dhtA(DHTPIN, DHTTYPE);
//Debug Console
#define BLYNK_PRINT Serial
//Timer
BlynkTimer timer;
// Attach virtual serial terminal to Virtual Pin V1
WidgetTerminal terminal(V30);
//VARIABLES
char blynk_token[34] = "YOUR_BLYNK_TOKEN"; //added from WiFiManager - AutoConnectWithFSParameters
bool shouldSaveConfig = false; //flag for saving data
float humidity;
float temp;
float heatindex;
float tempDiff = 0.3;
int desiredTemp = 0;
int desiredHum = 0;
int humDiff = 5;
int previousDesiredTemp = 0;
int previousDesiredHum = 0;
int maximumTemp = 31;
//temperature comparition
bool tempRising = false;
bool tempDroping = false;
bool tempStady = false;
float temp90sec;
float currentTemperature;
unsigned long previousMillis = millis();
long ninetySeconds = 90000L;
//Status Leds
WidgetLED led(V3);
WidgetLED fanIn(V4);
WidgetLED fanOut(V5);
WidgetLED humidifier(V6);
WidgetLED heatmat(V7);
WidgetLED dhtReaderror(V8);
// Buttons
BLYNK_WRITE(V11) // Led ON/OFF Button
{
if (param.asInt())
{
digitalWrite(D2, HIGH);
led.on();
}
else
{
digitalWrite(D2, LOW);
led.off();
}
}
BLYNK_WRITE(V12) // FanIn ON/OFF Button
{
if (param.asInt())
{
digitalWrite(D3, HIGH);
fanIn.on();
}
else
{
digitalWrite(D3, LOW);
fanIn.off();
}
}
BLYNK_WRITE(V13) // FanOut ON/OFF Button
{
if (param.asInt())
{
digitalWrite(D4, HIGH);
fanOut.on();
}
else
{
digitalWrite(D4, LOW);
fanOut.off();
}
}
BLYNK_WRITE(V14) // Reset
{
if (param.asInt()==1)
{
ESP.reset();
}
}
//Temoerature and humidity sliders
BLYNK_WRITE(V21)
{
desiredTemp = param.asInt();
}
BLYNK_WRITE(V22)
{
desiredHum = param.asInt();
}
//VOIDS
void sensorRead()
{
humidity = dhtA.readHumidity();
temp = dhtA.readTemperature();
heatindex = dhtA.computeHeatIndex(temp, humidity, false);
}
void temperatureComparision()
{
if (millis() - previousMillis >= ninetySeconds)
{
previousMillis += ninetySeconds;
temp90sec = currentTemperature;
currentTemperature = dhtA.computeHeatIndex(temp, humidity, false);
terminal.clear();
terminal.print("Actual temperature = ");
terminal.print(currentTemperature);
terminal.println("°C ");
terminal.print("Temperature 90s Ago = ");
terminal.print(temp90sec);
terminal.println("°C ");
terminal.flush();
if (currentTemperature > temp90sec)
{
Serial.println(F(" - Warming"));
terminal.print("Temperature is Warming");
terminal.flush();
tempRising = true;
tempDroping = false;
tempStady = false;
}
else if (currentTemperature < temp90sec)
{
Serial.println(F(" - Cooling"));
terminal.print("Temperature is Cooling ");
terminal.flush();
tempRising = false;
tempDroping = true;
tempStady = false;
}
else if (currentTemperature == temp90sec)
{
Serial.println(F(" - Steady"));
terminal.print("Temperature is Steady");
terminal.flush();
tempRising = false;
tempDroping = false;
tempStady = true;
}
}
}
void blynkSendSensor()
{
Blynk.virtualWrite(V0, temp);
Blynk.virtualWrite(V1, humidity);
Blynk.virtualWrite(V2, heatindex);
}
void logData()
{
Serial.print(F("Humidity: "));
Serial.print(humidity);
Serial.print(F("% Temperature: "));
Serial.print(temp);
Serial.print(F("°C Heat index: "));
Serial.print(heatindex);
Serial.println(F("°C"));
}
void heatmatSliderControl() //logic used to determine whether or not temperature should be raised
{
temp = dhtA.readTemperature();
if (temp <= 0 || isnan(temp)) //HeatMat OFF - DHT22 Read Error
{
digitalWrite(D7, LOW); //Heater Relay OFF.
heatmat.off(); //HeatMat Led OFF
dhtReaderror.on(); //DHT Error Led ON
Serial.println("DHT22 Sensor Malfunction - HEATING/MISTING operation terminated");
Blynk.notify("DHT22 Sensor Malfunction - HEATING/MISTING operation terminated");
}
if (temp >= maximumTemp) //If the Temp is too High turn on the exhaust fan and Bypassing Heatmat
{
digitalWrite(D4, HIGH); //FanOut Relay ON.
digitalWrite(D7, LOW); //Heater Relay OFF.
desiredTemp = 23; //Sets Desired temperature 23
fanOut.on(); //FanOut ON
heatmat.off(); //HeatMat Led OFF
Blynk.notify("Temperature to High !! - Venting OUT ON - Heatmat OFF - Humidifier OFF - New desired temperature saved: 23°C");
Serial.println("Temperature to High !! - Venting OUT ON - Heatmat OFF - Humidifier OFF - - New desired temperature saved: 23°C");
}
else
{
if ((temp < desiredTemp && tempDroping == true) || (temp < desiredTemp - tempDiff && tempStady == true)) // HeatMat ON
{
digitalWrite(D7, HIGH); //Heater Relay ON.
heatmat.on(); //HeatMat Led ON
dhtReaderror.off(); //DHT Error Led OFF
}
if ((temp < desiredTemp - tempDiff && tempRising == true) || (temp > desiredTemp - tempDiff && tempStady == true)) //HeatMat OFF
{
digitalWrite(D7, LOW); //HeatMat Relay OFF.
heatmat.off(); //HeatMat Led OFF
dhtReaderror.off(); //DHT Error Led OFF
}
}
}
void humidifierSliderControl() //logic used to determine whether or not humidity should be raised
{
if (humidity <= 0 || isnan(humidity)) //HeatMat OFF - DHT22 Read Error
{
digitalWrite(D5, LOW); //Hunidifier Relay OFF.
humidifier.off(); //Humidifier Led OFF
dhtReaderror.on(); //DHT Error Led ON
}
else if (temp >= maximumTemp) //If the Temp is too High Bypassing Humidifier
{
digitalWrite(D5, LOW); //Humidifier Relay OFF.
fanOut.on(); //FanOut ON
humidifier.off(); //Humidifier Led OFF
}
else
{
if (humidity < desiredHum - humDiff) //Humidifier ON
{
digitalWrite(D5, HIGH); //Humidifier Relay ON.
humidifier.on(); //Humidifier Led ON
dhtReaderror.off(); //DHT Error Led OFF
}
if (humidity > desiredHum) //HUMIDIFIER OFF - Desired Range
{
digitalWrite(D5, LOW); //Hunidifier Relay OFF.
humidifier.off(); //Humidifier Led OFF
dhtReaderror.off(); //DHT Error Led OFF
}
}
}
void saveConfigCallback () //callback notifying the need to save config
{
Serial.println("Should save config");
shouldSaveConfig = true;
}
void GetPresets() // Pre-set Humidity/Temperature values are stored in ESP8266 memory.
{
if (desiredTemp != previousDesiredTemp) //update the EEPROM if desired temperature has changed.
{
EEPROM.write(1, desiredTemp);
EEPROM.commit();
Serial.print(F("New desired temperature saved: "));
Serial.println(desiredTemp);
previousDesiredTemp = desiredTemp;
}
if (desiredHum != previousDesiredHum) //update the EEPROM if desired humidity has changed.
{
EEPROM.write(2, desiredHum);
EEPROM.commit();
Serial.print(F("New desired humidity level saved: "));
Serial.println(desiredHum);
previousDesiredHum = desiredHum;
}
desiredTemp = EEPROM.read(1);
if ((desiredTemp < 18) || (desiredTemp > 30))
{
desiredTemp = 20;
Serial.println(F("No saved temperature setting."));
}
desiredHum = EEPROM.read(2);
if ((desiredHum < 0) || (desiredHum > 120))
{
desiredHum = 50;
Serial.println(F("No saved humidity setting."));
}
}
void setupSpiffs()
{
Serial.println("mounting FS...");
if (SPIFFS.begin())
{
Serial.println("mounted file system");
if (SPIFFS.exists("/config.json"))
{
Serial.println("reading config file");
File configFile = SPIFFS.open("/config.json", "r");
if (configFile)
{
Serial.println("opened config file");
size_t size = configFile.size();
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
json.printTo(Serial);
if (json.success())
{
Serial.println("\nparsed json");
strcpy(blynk_token, json["blynk_token"]);
}
else
{
Serial.println("failed to load json config");
}
}
}
}
else
{
Serial.println("failed to mount FS");
}
}
void WifiManager()
{
WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);
WiFiManager wifiManager;
wifiManager.setSaveConfigCallback(saveConfigCallback);
wifiManager.addParameter(&custom_blynk_token);
wifiManager.setMinimumSignalQuality();
wifiManager.setTimeout(300);
if (!wifiManager.autoConnect("SMART-TERRA AP"))
{
Serial.println("failed to connect and hit timeout");
delay(3000);
ESP.reset();
delay(5000);
}
// always start configportal for a little while
wifiManager.setConfigPortalTimeout(60);
wifiManager.startConfigPortal("SMART-TERRA AP","terrarium");
Serial.println("TERRA connected :)");
strcpy(blynk_token, custom_blynk_token.getValue());
if (shouldSaveConfig)
{
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["blynk_token"] = blynk_token;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile)
{
Serial.println("failed to open config file for writing");
}
json.printTo(Serial);
json.printTo(configFile);
configFile.close();
shouldSaveConfig = false;
}
Serial.println("local ip");
Serial.println(WiFi.localIP());
Blynk.connect();
Blynk.config(blynk_token);
Blynk.syncAll();
delay(1000);
if (!blynk_token)
{
Serial.println("Failed to connect to Blynk server");
wifiManager.resetSettings(); //ESP.reset();
delay(1000);
}
}
void setup()
{
//Initialise EEPROM for storing values
EEPROM.begin(20);
Serial.println(F("LOADING SETTINGS FROM MEMORY"));
Serial.println(F(""));
delay(1000);
//Set Output pins to outputs
pinMode(relayLED, OUTPUT);
pinMode(relayFANin, OUTPUT);
pinMode(relayFANout, OUTPUT);
pinMode(relayFOGGER, OUTPUT);
pinMode(relayHEATMAT, OUTPUT);
//Debug console
Serial.begin(115200);
//Starting the DHT-22
dhtA.begin();
//Timer Events
timer.setInterval(2000L, sensorRead);
timer.setInterval(1000L, heatmatSliderControl);
timer.setInterval(1000L, humidifierSliderControl);
timer.setInterval(5000L, blynkSendSensor);
timer.setInterval(5000L, GetPresets);
timer.setInterval(10000L, logData);
timer.setInterval(91000L, temperatureComparision);
ArduinoOTA.begin();
setupSpiffs();
WifiManager();
}
void loop()
{
Blynk.run();
timer.run();
ArduinoOTA.handle();
}