Greetings
I have stared at this until my eyes are crossed and can’t figure it out, so I’m hoping one of you actual experts can help me out. This code runs a greenhouse, monitoring three DHT22 temp sensors. If the average temp (taveF) exceeds a set point (FanOnTemp), it turns on a fan and opens a louver. If it exceeds another set point (MIsterOnSetPt) it turns on a set of misters for (misterRunTime) minutes, with a pause of (misterPause) minutes in between mister-ings. There are two irrigation systems (Irr1 and Irr2); a pair of lines that spray water on two different sets of plants. And anytime the mister, Irr1, or Irr2 are turned on, a pump turns on to draw water from a pair of rain barrels.
The code is supposed to do two main things: 1) run autonomously, performing functions to control the temperature, and 2) respond to the Blynk app to turn the misters, Irr1, or Irr2 on on command. It also sends Tweets to my wife’s phone if the average temperature goes out of acceptable limits.
Everything works great, with one exception. There are three buttons on the Blynk app that are supposed to turn on the misters, Irr1, or Irr2. I have them set up to read a value into a variable when pressed, and then send an “off” to the button on the phone. The buttons are set to “switch” so that you press them and they light up ON, and then they turn OFF on command from the hardware to confirm that the hardware received the command.
Problem is - they turn off as commanded, but then nothing happens. The misters, Irr1, or Irr2 don’t actually turn on. The hardware is controlled with an eight-relay board, and is working fine. It comes on when commanded by the hardware via the autonomous monitoring as I’ve described above. It just won’t turn on when I press the button in the app.
So I can use your help - what am I missing?
This is running on a Sparkfun Redboard (UNO clone), with a CC3000 shield. Arduino IDE build is 1.6.3, and the CC3000’s firmware is v. 1.14. Blynk is the latest version. The command buttons on the Blynk app are set to 0 at OFF and to send 255 at ON.
I have written the code to run from three timers. One reads the temperature sensors once per second. Another checks the Blynk connection every five minutes and reconnects if necessary. Another runs a one-minute timer for timing the misters and irrigation systems.
Thanks in advance,
Q_Mech
// -----------
// Initialize iteration variables
//Defaults
float t1 = 22; //Top temp sensor initialize
float t2 = 22; //Middle temp sensor initialize
float t3 = 22; //Bottom temp sensor initialize
int t1F=70; //Top temp in F
int t2F=70; //Mid temp in F
int t3F=70; //Btm temp in F
int taveF = 60; //Average temperature
int FanOnTemp = 80; //set point for turning the fan on
int FanOffTemp = 75; //Fan set point for turning the fan off
int misterRunTime = 5; //how long to run the misters, in minutes
int misterPause =30; //how long to wait between mistings, in minutes
int MisterOnSetPt = 90; //set point for turning the Mister system on
//Controls
int MistersOn=0; //for running misters from Blynk commands
int Irr1On = 0; //for running Irr1 from Blynk commands
int Irr2On = 0; //for running Irr2 from Blynk commands
byte PumpNeeded1 = 0; //used to turn on pump when needed for misters
byte PumpNeeded2 = 0; //used to turn on pump when needed for Irr1
byte PumpNeeded3 = 0; //used to turn on pump when needed for Irr2
//Pins
int louverPin = 3; //digital pin to run the louver
int mainfanPin = 4; //digital pin to run the main fan
int pumpPin = 5; //digital pin to run the 110V outlet for the pump
int misterPin = 9; //digital pin to run the mister solenoid
int irr1Pin = A5; //digital pin to run the irr1 solenoid
int irr2Pin = A0; //digital pin to run the irr2 solenoid
//Timing
int Irr1RunTime = 5; //time in minutes to run Irr1
int Irr2RunTime = 5; //time in minutes to run Irr2
int loopCount=0; //needed to query temps at regular intervals
int MisterTimer1=0; //minutes since last misting
int MisterTimer2=0; //run time for misters operation
int Irr1Timer=0; //run time for Irr1 operation
int Irr2Timer=0; //run time for Irr2 operation
//Connection
boolean checkBlynk = true; //is GH connected to Blynk server?
// -----------
// Initialize connection to internet using CC3300 shield
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
// #define BLYNK_NO_BUILTIN // Disable built-in analog & digital pin operations
// #define BLYNK_NO_FLOAT // Disable float operations
#define ADAFRUIT_CC3000_IRQ 2 // Needs to be an interrupt pin (D2/D3)
#define ADAFRUIT_CC3000_VBAT 7 // Can be any digital pin
#define ADAFRUIT_CC3000_CS 10 // Preferred is pin 10 on Uno
#include <SPI.h>
#include <Adafruit_CC3000.h>
#include <BlynkSimpleCC3000.h>
#include <SimpleTimer.h>
// -----------
// Initialize Blynk
[wifi and Blynk setup redacted]
SimpleTimer Timer;
// -----------
// Initialize DH22 sensors
#include <DHT.h>
DHT dht1(A2, DHT22); //TOP sensor
DHT dht2(A3, DHT22); //MID sensor
DHT dht3(A1, DHT22); //BTM sensor
void setup()
{
Serial.begin(115200); //comment out once sketch is working properly
// -----------
// Set up digital output lines
pinMode(3, OUTPUT); //Louver, GRN/WHT wire
pinMode(4, OUTPUT); //Fan GRN wire
pinMode(5, OUTPUT); //Pump YLW wire
pinMode(6, OUTPUT); //(not used) ORN/WHT wire
pinMode(9, OUTPUT); //Misters ORN wire
pinMode(A5, OUTPUT); //Irr1 BLU/WHY wire
pinMode(A0, OUTPUT); //Irr2 BLU wire
pinMode(A4, OUTPUT); //(not used) GRN wire
// -----------
// Setup delay - allow board to settle
delay(5000);
// -----------
// Set up Blynk
Blynk.begin(auth, ssid, pass, wifi_sec);
while (!Blynk.connect())
{
//Wait until connected
}
// Tweet a message announcing startup
Blynk.tweet("Connected to Blynk");
//Turn Blynk LEDS off, write default values
Blynk.virtualWrite(V6,0);
Blynk.virtualWrite(V7,0);
Blynk.virtualWrite(V8,0);
Blynk.virtualWrite(V9,0);
Blynk.virtualWrite(V10,0);
Blynk.virtualWrite(V21,0);
Blynk.virtualWrite(V4,FanOnTemp);
Blynk.virtualWrite(V5,FanOffTemp);
Blynk.virtualWrite(V11,0);
Blynk.virtualWrite(V12,0);
Blynk.virtualWrite(V14,0);
Blynk.virtualWrite(V15,misterRunTime);
Blynk.virtualWrite(V21,0);
// -----------
// Start up DH22 Temp/Humidity sensors
dht1.begin();
dht2.begin();
dht3.begin();
// -----------
// Run the main body of the sketch at half-second intervals for stability
Timer.setInterval(1000, MainLoop);
// -----------
// Set up one-minute timer
Timer.setInterval(60000, minuteTimer);
// -----------
// Set up five-minute timer
Timer.setInterval(300000, connectCheck);
}
void loop()
{
// -----------
// Start SimpleTimer
Timer.run();
}
void minuteTimer()
{
// -----------
// Add one to minute counter once every minute (60,000 ms)
MisterTimer1=MisterTimer1+1;
MisterTimer2=MisterTimer2+1;
Irr1Timer=Irr1Timer+1;
Irr2Timer=Irr2Timer+1;
}
void MainLoop()
{
// -----------
// Iterate Blynk
Blynk.run();
// -----------
// Operate the DH22 sensors
if (loopCount>10)
{
TempRead();
loopCount=0;
} else
{
loopCount=loopCount+1;
}
// -----------
// Temperature-based control:
// Control fan and louver
if (taveF>FanOnTemp) // If average temp exceeds set point, turn on fan and louver
{
digitalWrite(louverPin,HIGH);
digitalWrite(mainfanPin,HIGH);
Blynk.virtualWrite(V6,255); //inform Blynk that the Fan is on
Blynk.virtualWrite(V7,255); //inform Blynk that the Louver is on
} else
{
if (taveF<FanOffTemp) // If average temp drops below lower set point, turn off fan and louver
{
digitalWrite(louverPin,LOW);
digitalWrite(mainfanPin,LOW);
Blynk.virtualWrite(V6,0); //inform Blynk that the Fan is off
Blynk.virtualWrite(V7,0); //inform Blynk that the Louver is off
}
}
// -----------
// Operate the misters if average T is over the set point
// If this is the first time over the set point (MisterToggle=0), then
// Run misters immediately then start 30-min timer for repeated mistings
// When the temperature drops below the set point, set MisterToggle back to zero
if (taveF>MisterOnSetPt) // if temp is above the mister set point...
{
if (MisterTimer1>misterPause) // ...and it has been at least misterPause minutes since the last misting
{
MistersOn=1; //trigger the misters
MisterTimer1=0; // reset the count of number of minutes since last misting
}
}
// -----------
// If Misters are triggered, turn them on for MisterRunTime length of time
if (MistersOn>0)
{
if (MisterTimer1<misterRunTime) //If the misters are triggered but the timer hasn't run out..
{
digitalWrite(misterPin,HIGH);
PumpNeeded1=1;
Blynk.virtualWrite(V8,255); //inform Blynk that the Misters are ON
} else // If the timer has run out, turn misters off
{
digitalWrite(misterPin,LOW);
PumpNeeded1=0;
Blynk.virtualWrite(V8,0); //inform Blynk that the Misters are OFF
}
} else
{
MisterTimer1=0; //keep resetting MisterTimer1 to zero if MistersOn isn't triggered
}
// -----------
// If Irr1 is triggered, turn them on for Irr1RunTime length of time
if (Irr1On>0)
{
if (Irr1Timer<Irr1RunTime) //If Irr1 is triggered but the timer hasn't run out..
{
digitalWrite(irr1Pin,HIGH);
PumpNeeded2=1;
Blynk.virtualWrite(V9,255); //inform Blynk that Irr1 is ON
} else // If the timer has run out, turn Irr1 off
{
digitalWrite(irr1Pin,LOW);
PumpNeeded2=0;
Blynk.virtualWrite(V9,0); //inform Blynk that Irr1 is OFF
}
} else
{
Irr1Timer=0; //keep resetting Irr1Timer to zero if Irr1On isn't triggered
}
// -----------
// If Irr2 is triggered, turn them on for Irr2RunTime length of time
if (Irr2On>0)
{
if (Irr2Timer<Irr2RunTime) //If Irr2 is triggered but the timer hasn't run out..
{
digitalWrite(irr2Pin,HIGH);
PumpNeeded3=1;
Blynk.virtualWrite(V10,255); //inform Blynk that Irr2 is ON
} else // If the timer has run out, turn Irr2 off
{
digitalWrite(irr2Pin,LOW);
PumpNeeded3=0;
Blynk.virtualWrite(V10,0); //inform Blynk that the Irr2 is OFF
}
} else
{
Irr2Timer=0; //keep resetting Irr2Timer to zero if Irr2On isn't triggered
}
// -----------
// If Misters, Irr1, or Irr2 are on, turn on the pump
if ((PumpNeeded1+PumpNeeded2+PumpNeeded3)>0)
{
digitalWrite(pumpPin,HIGH);
Blynk.virtualWrite(V21,255); //inform Blynk that the pump is ON
} else
{
digitalWrite(pumpPin,LOW);
Blynk.virtualWrite(V21,0); //inform Blynk that the pump is OFF
}
// -----------
// Send a tweet if TaveF goes out of bounds
if (taveF>95)
{
Blynk.tweet("Greenhouse is over 95 degrees F!");
}
if (taveF<50)
{
Blynk.tweet("Greenhouse is under 50 degrees F!");
}
}
void TempRead()
{
// Read DHTs and push to Blynk app
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
// float h1 = dht1.readHumidity();
float t1 = dht1.readTemperature();
// float h2 = dht2.readHumidity();
float t2 = dht2.readTemperature();
// float h3 = dht3.readHumidity();
float t3 = dht3.readTemperature();
t1F=(int)(1.8*t1)+32;
t2F=(int)(1.8*t2)+32;
t3F=(int)(1.8*t3)+32;
taveF = (int)((t1F+t2F+t3F)/3);
Blynk.virtualWrite(V0, t1F);
Blynk.virtualWrite(V1, t2F);
Blynk.virtualWrite(V2, t3F);
Blynk.virtualWrite(V3, taveF);
Serial.print("Top temp = "); //comment out once sketch is working properly
Serial.println(t1F);
Serial.print("Mid temp = ");
Serial.println(t2F);
Serial.print("Btm temp = ");
Serial.println(t3F);
Serial.print("Average = ");
Serial.println(taveF);
}
void connectCheck()
{
boolean checkBlynk = Blynk.connected();
if (checkBlynk = false) //check Blynk connection. If absent, reconnect
{
Blynk.connect(); //Try to reconnect, but don't stop running the greenhouse
Blynk.tweet("Reconnection attempt"); // Tweet a message announcing startup
}
}
// -----------
// Set up calls for when values are entered on the Blynk app
BLYNK_WRITE(V4) //read Fan On setpoint from Blynk
{
int FanOnTemp = param.asInt(); // assigning incoming value from pin V4 to a variable
}
BLYNK_WRITE(V5) //read Fan Off setpoint from Blynk
{
int FanOffTemp = param.asInt(); // assigning incoming value from pin V5 to a variable
}
BLYNK_WRITE(V11) //read Mister control from Blynk
{
int MistersOn = param.asInt(); // assigning incoming value from pin V11 to a variable
Blynk.virtualWrite(V11,0); // once the hardware has received the command, reset the app button to "OFF"
// set button to "switch" - it will turn off to confirm the command was received
}
BLYNK_WRITE(V12) //run irr1 when control button is pressed on Blynk
{
int Irr1On = param.asInt(); // assigning incoming value from pin V12 to a variable
Blynk.virtualWrite(V12,0); // once the hardware has received the command, reset the app button to "OFF"
// set button to "switch" - it will turn off to confirm the command was received
}
BLYNK_WRITE(V14) //run irr2 when control button is pressed on Blynk
{
int Irr2On = param.asInt(); // assigning incoming value from pin V14 to a variable
Blynk.virtualWrite(V14,0); // once the hardware has received the command, reset the app button to "OFF"
// set button to "switch" - it will turn off to confirm the command was received
}
BLYNK_WRITE(V15) //read Mister run time control from Blynk
{
int misterRunTime = param.asInt(); // assigning incoming value from pin V15 to a variable
}
BLYNK_WRITE(V16) //read Irr1 time from Blynk
{
int Irr1RunTime = param.asInt(); // assigning incoming value from pin V16 to a variable
}
BLYNK_WRITE(V17) //read Irr2 time from Blynk
{
int Irr2RunTime = param.asInt(); // assigning incoming value from pin V17 to a variable
}
BLYNK_WRITE(V18) //run irr1 when Time Input widget activates on Blynk
{
int Irr1On = param.asInt(); // assigning incoming value from pin V18 to a variable
}
BLYNK_WRITE(V19) //run irr2 when Time Input widget activates on Blynk
{
int Irr2On = param.asInt(); // assigning incoming value from pin V19 to a variable
}
BLYNK_WRITE(V20) //read mister set temp
{
int MisterOnSetPt = param.asInt(); // assigning incoming value from pin V19 to a variable
}