Currently i'm working on a project where i need to monitor some sensor. One of the sensor I'm using is TCS34725 RGBC light sensor. Using Blynk, i log the data to a database and display it on a browser dashboard and Blynk app. After let it run of 2 month (approx.) it stopped to read the value.
////---------- Blynk Setup
#define BLYNK_PRINT Serial // This prints to Serial Monitor
#include <ESP8266WiFi.h> // for ESP8266
#include <BlynkSimpleEsp8266.h> // for ESP8266
////----------
////---------- OTA Setup
#include <ESP8266mDNS.h> // For OTA w/ ESP8266
#include <WiFiUdp.h> // For OTA
#include <ArduinoOTA.h> // For OTA
char OTAName[] = "Node1";
////----------
////---------- Projects parameter
#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include "Adafruit_SHT31.h"
//#define TCS34725_INTEGRATION_TIME TCS34725_INTEGRATIONTIME_700MS
#define TCS34725_INTEGRATION_TIME TCS34725_INTEGRATIONTIME_24MS
//#define TCS34725_GAIN TCS34725_GAIN_1X
#define TCS34725_GAIN TCS34725_GAIN_60X
const float ATIME_ms = 24.0;
const float AGAINx = 60.0;
#define TCS34725_R_Coef 0.136
#define TCS34725_G_Coef 1.000
#define TCS34725_B_Coef -0.444
#define TCS34725_GA 1.0
#define TCS34725_DF 310.0
//https://www.apogeeinstruments.com/conversion-ppfd-to-lux/
#define LUX2PPFD 0.0135 //sunlight = 0.0185, Cool white CFL = 0.0135
#define PIN_PPFD V3
#define PIN_DLI V4
#define PIN_LUX V2
#define PIN_E_TEMP V0
#define PIN_E_RH V1
uint16_t r, g, b, c, LUX;
uint16_t ir;
uint16_t r_comp, g_comp, b_comp, c_comp;
float PPFD, T, H , CPL;
BlynkTimer timer;
Adafruit_SHT31 sht31 = Adafruit_SHT31();
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATION_TIME, TCS34725_GAIN);
////----------
///-----------Credentials
char auth[] = "YourAuth";
char ssid[] = "YourSSID";
const char* pass = "YourPassword";
char server[] = "192.168.141.230"; // IP for your Local Server
int port = 8080;
////----------
void myTimerEvent()
{
//modify this if you modify the TCS34725_INTEGRATION_TIME and TCS34725_GAIN
tcs.getRawData(&r, &g, &b, &c);
//LUX = tcs.calculateLux(r,g,b);
ir = (r + g + b > c) ? (r + g + b - c) / 2 : 0;
r_comp = r - ir;
g_comp = g - ir;
b_comp = b - ir;
c_comp = c - ir;
LUX = (TCS34725_R_Coef * float(r_comp) + TCS34725_G_Coef * float(g_comp) + TCS34725_B_Coef * float(b_comp)) / CPL;
PPFD = LUX * LUX2PPFD;
T = sht31.readTemperature();
H = sht31.readHumidity();
/*
Serial.print("[");Serial.print(millis());Serial.print("]");
Serial.print(F("Lux:"));Serial.print(LUX);Serial.println();;
Serial.print("[");Serial.print(millis());Serial.print("]");
Serial.print(F("PPFD:"));Serial.println(PPFD);
Serial.print("[");Serial.print(millis());Serial.print("]");
Serial.print(F("Temperature:"));Serial.print(T);Serial.print(F("C "));Serial.print(F("Humidity:"));Serial.print(H);Serial.println(F("%"));
Serial.println();
*/
Blynk.virtualWrite(PIN_LUX, LUX);
Blynk.virtualWrite(PIN_PPFD, PPFD);
Blynk.virtualWrite(PIN_E_TEMP, T);
Blynk.virtualWrite(PIN_E_RH, H);
}
void setup() {
Serial.begin(9600); // BLYNK_PRINT data
WiFi.begin(ssid, pass);
Blynk.config(auth, server, port);
Blynk.connect();
ArduinoOTA.setHostname("Node1"); // For OTA - Use your own device identifying name
ArduinoOTA.begin(); // For OTA
//timer.setInterval(5 * 60 * 1000L, myTimerEvent); // every 5 minutes
timer.setInterval(60 * 1000L, myTimerEvent); // every 1 minute
sht31.begin(0x44);
tcs.begin();
CPL = (ATIME_ms * AGAINx) /(TCS34725_GA * TCS34725_DF);
myTimerEvent();
}
void loop() {
ArduinoOTA.handle(); // For OTA
if(!Blynk.connected()){
Serial.println("Blynk has been disconnected");
Serial.print("Connecting");
while(!Blynk.connected()){ // reconnect if Blynk is disconnected
Serial.print(".");
boolean connection = Blynk.connect();
if(connection){
Serial.println();
break;
}
}
}
if(Blynk.connected()){
Blynk.run();
timer.run(); // Initiates BlynkTimer
ArduinoOTA.handle(); // For OTA
}
}
This code works for 2 month. Other than TCS34725, I have SHT31-D, 7805 5V regulator, and a 3030 5V fan in a circuit connected to WeMos D1 mini. The only accident ever happen is the box (where i put all the circuit) fell 10 - 20 cm and still working for few weeks.
The only value I can get is when I reset my Wemos D1 mini and It will send 1 reading before sending 0s.
Your timer has probably overflown and started from zero. In the source of BlynkTimer you can see that this timer value is an unsigned long. You can easily find out what is the size of an unsigned long by looking at the doc, but even easier is by doing this in your arduino code:
I didn't test on an arduino but it should be a size of 4 bytes. Unsigned means the variable can only take on positive values. With 4 bytes there are 4 * 8 = 32 bits, so the timer variable can take on 2^32 different values, that is a maximum of 2^32 - 1 = 4294967295. BlynkTimer is measured in milliseconds. So converting 4294967295 back this gives:
4294967295 milliseconds = 4294967 seconds = 1193 hours ~= 50 days
This is 10 days short of two months, so this could very well be causing the behavior you're describing. I'm not going into this library right now, but I will tell you this: weird behavior caused by timer variables can often be circumvented. Instead of looking wether a timer variable is bigger than a certain value, you check wether the difference with that value is bigger than zero. Allow me to demonstrate:
Say that the value of timer is equal to 4294967290, which is close to its max value of 4294967295. Now we're trying to check wether timer is bigger than 4294967292 but at the time of comparison, timer has reached its max value and started back from 0. So in the first case described above you're checking 0 > 4294967292. This yields false, while in fact you would have wanted it to yield true. In the second case you're doing the following: 0 - 4294967292 > 0, the result of this calculation yields 2 > 0, which is obviously true, as desired.
With this information you can manually try to fix the library. Another, somewhat more dirty, workaround would be to just have the esp8266 reboot itself after 49 days.
Another little hack would be to declare timer as an **unsigned long long*. Notice that the word long is in there twice, so this gives you 64 bits of precision, meaning the timer would runout in (2^64 - 1) / 1000 / 3600 / 24 = 213503982335 days. However, the millis() function in Arduino yields a 32 bit value, so in most cases this won't help you a lot I'm afraid. Unless you do something like this when increasing your 64 bit value: