I have a Photon controlling a few things in my greenhouse outside. I bought a netgear wifi extender and put in the garage so the signal reaches out there, but it goes offline every couple days or so and won’t come on until I reset it. I added some code in the sketch the published the RSSI signal the Photon has, and it’s around 65-70, which seems good (My phone shows good wifi out there, too). I send a little data to the Particle server every 10 seconds. Temp, humidity, LED status in my Blynk app. That’s about it. Any ideas why this is happening? Here’s my code:
//LIBRARIES
#include "Particle.h"
#include <blynk.h>
#include "Adafruit_DHT.h"
//PINS
#define analogMQ7 A4 //CO2 sensor pin
#define DHTPIN 2 // what pin we're connected to
#define heat 6 //relay for heater
#define lamp 5 //relay for heater
#define fan 4 //fresh air fan
#define aux 3 //aux relay
//TEMP SENSOR INIT
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
//Temp sensor connections:
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
//CO2 sensor connections:
//Connect pin A0 to A4 on the PHOTON
//Connect Gnd to ground
//Connect Vcc to Vin
//Blynk init
char auth[] = "xxxxxxxxxxxxxxxxxxxx";
WidgetLED led_heat(V2);
WidgetLED led_lamp(V3);
WidgetLED led_fan(V4);
WidgetLED led_aux(V7);
// Attach virtual serial terminal to Virtual Pin V0
WidgetTerminal terminal(V0);
//Variables
float h; //humidity
float t; //temperature
unsigned long loopMillis; //loop timer
int tempErr; //count error readings on the temp sensor
struct settings {
int heater_setpoint; //lower than this, heater comes on
int fan_setpoint; //higher than this, exhaust fan comes on
unsigned long lampDelay; //timer delay for lamp recept
int enableHeat; //enable or disable the low temp heat control
int lampReceptState; //manual off (0), on (1), or timed with heat (3)
int enableFan; //enable or disable the high temp exhaust fan control
int lowTempWarming; //notify if temp drops 5 degrees below setpoint
int auxReceptState; //manual ON/OFF state of the 4th recept, controlled by V40
} s;
int rssi = 0;
void wifi_status() {
rssi = WiFi.RSSI();
Particle.publish("rssi", String(rssi), 60, PRIVATE);
Blynk.virtualWrite(V50, rssi);
}
void setup() {
//Serial.begin(9600);
delay(1000); // Allow board to settle
EEPROM.get(1, s); //get the settings from EEPROM
Blynk.begin(auth); //begin Blynk
dht.begin(); //begin temp sensor
pinMode(heat, OUTPUT); //set pin modes
pinMode(lamp, OUTPUT); //set pin modes
pinMode(fan, OUTPUT); //set pin modes
pinMode(aux, OUTPUT); //set pin modes
digitalWrite(heat, LOW); //turn off heater 1
digitalWrite(lamp, LOW); //turn off heater 2
digitalWrite(fan, LOW); //turn off the fan
digitalWrite(aux, LOW); //turn off the aux relay
//set the external antenna
WiFi.selectAntenna(ANT_EXTERNAL);
Particle.variable("RSSI", &rssi, INT);
}
void loop() {
Blynk.run();
if (millis() - loopMillis > 10000UL) { //do this every 10 seconds
loopMillis = millis(); //update the timer
read_temp(); //read temp and humidity
update_heater(); //control to heater relay
update_fan(); //control the fan relay
update_lampRecept(); //set the 3rd relay state
update_auxRecept(); //set the 4th relay state
wifi_status(); //publish RSSI
}
}
void read_temp() {
// Read the humidity
h = dht.getHumidity();
// Read temperature as Farenheit
t = dht.getTempFarenheit();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
tempErr++;
if (tempErr > 10) { //10 errors takes about 50 seconds
Blynk.notify("We're not getting a correct reading from the temperature sensor! Please call technical support!");
tempErr = 0; //reset the error counter
}
return;
}
else {
tempErr = 0; //reset the error counter
}
t = t - 3; //temp reads about 3 degrees high
Blynk.virtualWrite(V5, t); //V5 is temperature
Blynk.virtualWrite(V6, h); //V6 is humidity
//low temp warning
if (t <= s.heater_setpoint - 5 && s.lowTempWarming) { //it's 5 degrees colder than it should be, heat isn't keeping up!
Blynk.notify("The heaters can't keep up! It's more than 5 degrees colders in the greenhouse than the heater setpoint!");
}
}
void update_heater() {
static unsigned long startTime; //time the heat turns on
if (s.enableHeat) {
if (t < s.heater_setpoint) { //it's too cold
if (digitalRead(heat) == 0) { //heat wasn't on
startTime = millis(); //heat is just starting
}
digitalWrite(heat, HIGH); //so turn on the heat
led_heat.on();
if (millis() - startTime > s.lampDelay && s.lampReceptState == 3) {
//has it been on long enough for heat2 & is the lamp recept option set to timer?
digitalWrite(lamp, HIGH); //start aux heat
led_lamp.on();
}
}
if (t > s.heater_setpoint) { //temp is above setpoint
digitalWrite(heat, LOW); //turn off heat 1
led_heat.off(); //turn off the heat LED
if (s.lampReceptState == 3) { //lamp controlled by heat timer
digitalWrite(lamp, LOW); //and heat 2 in case it was on too
led_lamp.off();
}
}
}
else { //heat is turned off
digitalWrite(heat, LOW); //turn off heat 1
led_heat.off(); //LED off
if (s.lampReceptState == 3) { //lamp is controlled via heat timer
digitalWrite(lamp, LOW); //so turn it off since heat is disabled
led_lamp.off(); //LED off
}
}
}
void update_fan() {
if (s.enableFan) {
if (t > s.fan_setpoint) { //it's too hot
digitalWrite(fan, HIGH); //so turn on the fan
led_fan.on(); //turn on the fan LED
}
if (t < s.fan_setpoint) { //it's cooled off
digitalWrite(fan, LOW); //turn off the fan
led_fan.off(); //turn off the fan LED
}
}
else { //not using fan
digitalWrite(fan, LOW); //turn off the fan
led_fan.off(); //turn off the fan LED
}
}
void update_lampRecept() {
if (s.lampReceptState == 2) { //Off
digitalWrite(lamp, LOW); //turn off relay
led_lamp.off(); //turn off LED
}
else if (s.lampReceptState == 1) { //ON
digitalWrite(lamp, HIGH); //turn on relay
led_lamp.on(); //turn on LED
}
}
void update_auxRecept() {
if (s.auxReceptState) { //ON from the manual button in the app
digitalWrite(aux, HIGH); //turn on the relay
led_aux.on(); //turn on the LED
}
else {
digitalWrite(aux, LOW); //turn off the relay
led_aux.off(); //turn off the LED
}
}
BLYNK_CONNECTED() {
terminal.clear();
terminal.println(F("Blynk connected"));
terminal.flush();
Blynk.virtualWrite(V20, s.enableHeat);
Blynk.virtualWrite(V21, s.heater_setpoint);
Blynk.virtualWrite(V22, s.heater_setpoint);
Blynk.virtualWrite(V23, s.lampReceptState);
Blynk.virtualWrite(V24, s.lowTempWarming);
Blynk.virtualWrite(V30, s.enableFan);
Blynk.virtualWrite(V31, s.fan_setpoint);
Blynk.virtualWrite(V32, s.fan_setpoint);
//HEAT1 LED
if (digitalRead(heat) == HIGH) led_heat.on();
else led_heat.off();
//HEAT2 LED
if (digitalRead(lamp) == HIGH) led_lamp.on();
else led_lamp.off();
//FAN LED
if (digitalRead(fan) == HIGH) led_fan.on();
else led_fan.off();
}
BLYNK_WRITE(18) { //aux heat delay
//1: no delay 2: 5 min 3: 15 min 4: 30 min 5: 60 min
int i = param.asInt();
if (i == 1) s.lampDelay = 0;
if (i == 2) s.lampDelay = 300000;
if (i == 3) s.lampDelay = 900000;
if (i == 4) s.lampDelay = 1800000;
if (i == 5) s.lampDelay = 3600000;
EEPROM.put(1, s); //save the settings to EEPROM
}
BLYNK_WRITE(20) { //turn on/off heater function
s.enableHeat = param.asInt();
EEPROM.put(1, s); //save the settings to EEPROM
if (s.enableHeat == 0) {
Blynk.notify("You turned off the freeze protection. The heater(s) will not come on in cold weather.");
}
}
BLYNK_WRITE(V22) { //Heater temp select SLIDER
//sets the low temp for the heater to kick on
s.heater_setpoint = param.asInt();
EEPROM.put(1, s); //save the settings to EEPROM
Blynk.virtualWrite(V21, s.heater_setpoint);
}
BLYNK_WRITE(23) { //turn on/off/Timer for the lamp recept
s.lampReceptState = param.asInt();
EEPROM.put(1, s); //save the settings to EEPROM
}
BLYNK_WRITE(24) { //turn on/off low temp notification
s.lowTempWarming = param.asInt();
EEPROM.put(1, s); //save the settings to EEPROM
}
BLYNK_WRITE(30) { //turn on/off fan function
s.enableFan = param.asInt();
EEPROM.put(1, s); //save the settings to EEPROM
if (s.enableHeat == 0) {
Blynk.notify("You turned off the exhaust fan. It will not come on when the terperature gets hot.");
}
}
BLYNK_WRITE(V32) { //Fan temp select SLIDER
//sets the high temp for the fan to kick on
s.fan_setpoint = param.asInt();
EEPROM.put(1, s); //save the settings to EEPROM
Blynk.virtualWrite(V31, s.fan_setpoint);
}
BLYNK_WRITE(V40) { //4th receptacle ON/OFF manually
s.auxReceptState = param.asInt();
EEPROM.put(1, s); //save the settings to EEPROM
}