Hydroponic Controller w/ LiLon NodeMCU (ESP 8266)

Hi all,

I’d walked away from Cayenne for the summer as I was frustrated with the scheduling problems. However, the Cayenne team had put out maybe a month or so ago that scheduling and ESP8266 was supported! I was pretty excited. So I reconnected up my old project and setup scheduling. Seemed like everything worked great! The lights worked on schedule, pump/fans cycled every hour… however, it seemed to be only a few days of success… turned out scheduling hasn’t been working anymore. I’ve also found that accessing through mobile gives me a constant server offline message every 30sec or so. If I actuate a relay to turn a light on manually, it works and I see the light turn on.
Then I’ll get the server offline message appears for a few seconds, goes away. If I leave my project screen on mobile, and come back to it. The Light button will show the old setting of ‘off’, even though I’m staring at the light physically on. If I press the mobile button to turn the light on, I receive an on button that coincides with what already was on.

I’ve thought about using this project for the ESP8266 contest… but I feel like i’m getting more of the same issues I’ve had before scheduling was fixed, just in a different way.

Is it my code? I’d love a second review/coaching to see if I’m doing something wrong. I just purchased an ESP32 so I could finally marry my wemos D1 and nodemcu sensors into one item… but I’d like to ensure they can both function separately before tying them together.

//#define CAYENNE_DEBUG
//#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
#include "ESP8266WiFi.h"
#include <DHT.h>//
#include "Adafruit_Sensor.h"
#include <NewPing.h>
//Relays
#define RELAY_DIGITAL_PIN 4  //D2
#define RELAY_DIGITAL_PIN 5  //D1
#define RELAY_DIGITAL_PIN 12  //D6
#define RELAY_DIGITAL_PIN 13  //D7
////temp sensor
#define DHTPIN 14 //D5
#define DHTTYPE DHT22
//rangefinder
//#define TRIGGER_PIN  4 //RX // Arduino pin tied to trigger pin on the ultrasonic sensor.
//#define ECHO_PIN     5 //TX // Arduino pin tied to echo pin on the ultrasonic sensor.
//#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters).


// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "token here";
//char token[] = "xx";
// Your network name and password.
char ssid[] = "ssid";
char password[] = "pass";

DHT dht(DHTPIN, DHTTYPE);
//NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup()
{
  pinMode(RELAY_DIGITAL_PIN, OUTPUT);
  Serial.begin(9600);
  Cayenne.begin(token, ssid, password);
  dht.begin();
}
CAYENNE_IN(VIRTUAL_PIN)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 1

  // assuming you wire your relay as normally open
  if (currentValue == 0) {
    digitalWrite(RELAY_DIGITAL_PIN, LOW);
  } else {
    digitalWrite(RELAY_DIGITAL_PIN, HIGH);

  }
}
void loop()
{
  Cayenne.run(); 
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
 // float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(f)) 
  {
    return;
  }
float hif = dht.computeHeatIndex(f, h);

//sonar.ping_cm();  
// delay(100);   

}


CAYENNE_OUT(V0)
{  
  Cayenne.virtualWrite(V0, dht.readTemperature(true)); //virtual pin 
}

CAYENNE_OUT(V1)
{  
  Cayenne.virtualWrite(V1, dht.readHumidity()); //virtual pin
}
CAYENNE_OUT(V2)
{
  float f = dht.readTemperature(true);
  float h = dht.readHumidity();
  Cayenne.virtualWrite(V2, dht.computeHeatIndex(f, h)); //virtual pin
}
//CAYENNE_OUT(V3)
//{  
//  Cayenne.virtualWrite(V3, sonar.ping_cm()); //virtual pin
//}

The only thing I would change in the code is how you read the sensors. I have a project here that reads a DHT11 and in each virtual out checks if the values are null. Probably a better way to do it is read the sensor at the top of the loop and set a global variable which you can then use in the CAYENNE_OUT functions. This reduces the amount of reads which reduces the amount of time waiting for a valid result.

Declare t, h, and hif at the top of the sketch as global variables then try the code below.

void loop()
{
  //Check if read failed and try until success
  do {
    //Read humidity (percent)
    h = dht.readHumidity();
    //Read temperature as Fahrenheit
    t = dht.readTemperature(true);
    //Calculate Heat Index as Fahrenheit
    hif = dht.computeHeatIndex(t, h);
	//Delay to reset WDT
	delay(250);
  } while  (isnan(t) || isnan(h));
  
  Cayenne.run(); 
}


CAYENNE_OUT(V0)
{  
  Cayenne.virtualWrite(V0, t); //virtual pin 
}

CAYENNE_OUT(V1)
{  
  Cayenne.virtualWrite(V1, h); //virtual pin
}
CAYENNE_OUT(V2)
{
  Cayenne.virtualWrite(V2, hif); //virtual pin
}

Thanks Adam, I’ll take a look at that tonight. Do you think that would cause a connection issue with the arduino/esp8266 for server connection/scheduling, or only cause an issue with potential bad data/‘spiked’ data being sent. (I do get some odd off the wall values read every once in a while in the history, your code updates look like they would fix that)

Thank you!
-Tom

I would expect it to only fix the bad data, but if you get in a loop of bad sensor reads you could be getting WDT resets which cause the device to restart. Never mind, I see that you are not using a loop only an if statement. Note to self…update that horribly out of date project page!

I’m not sure about the current state of schedules. We were having some issues with them a while back but I think that has all been resolved now. @rsiegel is that accurate?

I just noticed that my desktop version of the dashboard shows the pump turning on for 5 minutes after the hour/every hour. Looking at what my mobile dashboard shows (Android) looks like the relays for Pump and Fan are flip flopped. So the pump is scheduled accurately on a computer Desktop Chrome browser, but in mobile, I see that same actuator flip flopped with the Fan. (desktop, pump runs 5 minutes every hour and fan runs 20 minutes) (Android mobile dashboard shows schedule of pump running 20 min and fan running 5 min).

That must be why my scheduling hasn’t been working… though the light schedule is right for both (and doesn’t work, either) I’ll post up some screenshots.

1 Like

This is the desktop, and shows what the schedule is supposed to be. Pump runs from 1:05-1:10 and does this every hour. The Fan is supposed to come on from 1:20-1:40 every hour.

The mobile desktop is showing the reverse for scheduling. I’ll get that photo up in a sec.

Here you can see the mobile app thinks the pump should run from 21:20-21:40. Looks like between the desktop and mobile dashboard the actuators are flip flopped on the scheduled times.

Is this a bug? How would my desktop and mobile dashboard show different values? …be out of sync with each other? @rsiegel

I’ve been trying to reproduce this on my end with little luck, apologies. What seems odd to me is that in your Web image, the actuators being scheduled are named “Light-1” “Pump-2” “Fan-3”, but in your Android screenshot the widgets are named only “Pump” “Fan” “Light”. I suspect this has something to do with it, and that it could be related to the ‘Server Error’ messages you saw previously from the Android app.

Here’s what I would try: On the Android side, go to your Android app manager and Force Stop the app, then Clear Data/Clear Cache. Then relaunch the app (you’ll need to re-login). This will at least ensure that the latest data is pulled form the web and that the two are synced. I’d check the schedule again at that time to see if they actually match. If they don’t, do you mind to Private Message me with your account login/password so I can use your account to reproduce the issue and investigate?

I performed the clear cache and clear data and logged back in. I’ve attached the screenshot from viewing scheduling on Android mobile. Still receiving the ‘server error’ flag popping up every so many seconds. Scheduling is not turning on (or not seeing the relays active on time when they should)