目前我正在做一个项目,我需要监控一些传感器。我使用的传感器之一是TCS34725 RGBC光传感器。使用Blynk,我将数据记录到数据库中,并在浏览器仪表板和Blynk应用程序上显示。运行2个月后(大约)它停下来读取值。
////---------- 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
}
}此代码的有效期为2个月。除了迷你,我有SHT31-D,7805 5V稳压器和一个3030 5V风扇连接到WeMos D1迷你。唯一发生的事故是盒子(我放置所有电路的地方)下降了10 - 20厘米,仍然工作了几个星期。
我能得到的唯一值是当我重置我的Wemos D1 mini时,它将在发送0之前发送1读数。
发布于 2019-12-12 20:44:57
您的计时器可能已超时并从零开始。在BlynkTimer的source中,您可以看到这个计时器值是一个无符号的长整型。通过查看文档,您可以很容易地找到unsigned long的大小,但在arduino代码中执行此操作会更容易:
unsigned long test;
Serial.println(sizeof(test));我没有在arduino上测试,但它应该是4字节的大小。Unsigned表示变量只能采用的正值。对于4个字节,有4*8= 32位,因此计时器变量可以采用2^32个不同的值,即最多2^32 -1= 4294967295。BlynkTimer以毫秒为单位测量。因此,将4294967295转换回如下所示:
4294967295毫秒= 4294967秒= 1193小时~= 50天
现在离两个月只差10天了,所以这很可能会导致你所描述的行为。我现在不打算进入这个库,但我要告诉你:由计时器变量引起的奇怪行为通常是可以避免的。而不是查看计时器变量是否大于某个值,而是检查与该值的差异是否大于零。请允许我演示一下:
if(timer > SOME_THRESHOLD) // WRONG
if(timer - SOME_THRESHOLD > 0) // CORRECT假设timer的值等于429496729,接近其最大值4294967295。现在我们尝试检查timer是否大于4294967292,但在比较时,timer已达到最大值,并从0开始。因此,在上面描述的第一种情况下,您检查的是0> 4294967292。这会产生false,而实际上您会希望它产生true。在第二种情况下,您将执行以下操作:0- 4294967292 > 0,此计算的结果为2> 0,这显然是真。
有了这些信息,您可以手动尝试修改库。另一种更脏的解决方法是让esp8266在49天后重新启动。
另一个小技巧是将timer声明为**unsigned long long*。请注意,单词long出现了两次,因此这为您提供了64位的精度,这意味着计时器将在(2^64 - 1) / 1000 / 3600 / 24 = 213503982335天内到期。但是,Arduino中的millis()函数会产生一个32位的值,所以在大多数情况下,恐怕这不会对您有太大帮助。除非您在增加64位值时执行以下操作:
unsigned long long timer64 = 0;
unsigned long timer32 = millis();
unsigned long timer32_prev = timer32;
...
void incrementTimer64()
{
timer32 = millis();
timer64 += (unsigned long long)(timer32 - timer32_prev);
timer32_prev = timer32;
}https://stackoverflow.com/questions/59298132
复制相似问题