Hi guys,
I’m having a lot headaches trying to solve an issue is happening with my project.
I have an Aquarium Led Lamp Controlled by an ESP8266 NodeMCU Lolin.
In order to achieve a gradual and soft change of the light power during the day, I have stored on the same memory of the ESP8266 a set of photoperiod curves that I can select. They are stored as binary data.
Normally everything works fine, but sometimes (it’s a consistent error), the ESP resets or simply it hangs and stop working (right now is hanged).
I added some serial.print instructions in order to determine where exactly happens the issue, and it’s looks clear that sometimes and for an unknow reason, the Blynk.virtualWrite is causing the problem.
Let me describe my sketch. It’s big, then I’ll put what I believe are the main parts.
Initial declares and libraries:
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <BlynkSimpleEsp8266.h>
//#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
//#define ONE_WIRE_BUS 14 // DS18B20 pin D5(ESP8266) Compatible con tarjetas nuevas
#define ONE_WIRE_BUS 2 // DS18B20 pin D4(ESP8266) compatible tarjeta antigua
#define GraphTemp 8
#define VIRTUAL_PIN_Terminal 9
#define VIRTUAL_PIN_Menu_Modo 26
#define VIRTUAL_PIN_Luz_Luna 27
#define Update_Firmware 15 // Push Button virtual en Blynk para solicitar upgrade de Firmware OTA vía Http
extern "C"{
#include "pwm.h"
}
////// PWM
// Period of PWM frequency -> default of SDK: 5000 -> * 200ns ^= 1 kHz
#define PWM_PERIOD 5000
// PWM channels
#define PWM_CHANNELS 4
// PWM setup (choice all pins that you use PWM)
uint32 io_info[PWM_CHANNELS][3] = {
// MUX, FUNC, PIN
{PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5, 5}, // D1
{PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4, 4}, // D2
{PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0, 0}, // D3
{PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2, 2}, // D4
// {PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14, 14}, // D5
// {PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12, 12}, // D6
// {PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13, 13}, // D7
// {PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15 ,15}, // D8
// D0 - not have PWM :-(
};
// PWM initial duty: all off
uint32 pwm_duty_init[PWM_CHANNELS];
// Dimmer variables
//int16_t duty = 0;
//int16_t step = 1;
const size_t len_curvas = 6126;
const uint8_t curvas[] PROGMEM = {0x00,0x00,0x00,0x01,0x00,0x01,..... a lot of binary data.... }
BlynkTimer timer;
WidgetRTC rtc;
WidgetTerminal terminal(VIRTUAL_PIN_Terminal); // Attach virtual serial terminal to Virtual Pin
//OneWire oneWire(ONE_WIRE_BUS);
//DallasTemperature DS18B20(&oneWire);
float oldTemp = -1;
float temp;
int PWM_Digital_Canal[4] = { 4, 0, 5, 14};
int VIRTUAL_PIN_Fotoperiodo_Canal[4] = { 18, 19, 20, 21};
int Graph_Canal[4] = { 10, 11, 12, 13};
int PWM_Virtual_Canal[4] = { 0, 1, 2, 3};
int Luz[4];
int luz_anterior[4];
int deltaLuz[4];
int potCanal[4] = {0, 0, 0, 0};
int posmem;
int Modo = 1;
int Luz_Luna = 1;
String Modo_txt[5] = {"Manual", "Despejado", "Nubes Suaves", "Nubes Intensas"};
char auth[] = "a20e960c059046f4bff8daf51381fbe0"; // Auth Token Blynk Luis Rossel
int FotoPeriodo_Inicio_Canal[4] = { 300, 300, 300, 300};
int FotoPeriodo_Fin_Canal[4] = { 1320, 1320, 1320, 1320};
int Minuto_Ajustado;
const char* host = "esp8266-webupdate";
int updateWeb = 0;
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
I have a function called every 60 seconds to update the light power according to the time of the day and some time inputs setups:
void actualizaLuzTemp()
{
int t = now(); // Guarda la hora actual en t
String currentTime = String(hour()) + ":" + minute();
int h = hour(t); // returns the hour for the given time t
int m = minute(t);// returns the minute for the given time t
int i;
switch (Modo)
{
case 1:
for (i = 0; i < 4; i = i + 1)
{
potCanal[i] = Luz[i];
pwm_set_duty(potCanal[i], i );
pwm_start(); // commit
}
break;
default:
for (i = 0; i < 4; i = i + 1)
{
if ( (FotoPeriodo_Fin_Canal[i] - FotoPeriodo_Inicio_Canal[i]) != 0 )
{
Minuto_Ajustado = ( h*60 + m - FotoPeriodo_Inicio_Canal[i]) * 1020 / (FotoPeriodo_Fin_Canal[i] - FotoPeriodo_Inicio_Canal[i]);
}
else
{
Minuto_Ajustado = ( h*60 + m - FotoPeriodo_Inicio_Canal[i]);
Serial.println("Error de fotoperiodo");
}
if ( Minuto_Ajustado < 0 ) Minuto_Ajustado = 0;
if ( Minuto_Ajustado > 1020) Minuto_Ajustado = 1020;
posmem = (Modo-2)*2042 + (Minuto_Ajustado)*2;
uint8_t byteval_1 = pgm_read_byte(curvas + posmem);
posmem = posmem + 1;
uint8_t byteval_2 = pgm_read_byte(curvas + posmem);
if ( Luz[i] > 100) Luz[i] = 100;
potCanal[i] = (byteval_1*256 + byteval_2)*Luz[i]/100;
if ( (i == Luz_Luna - 2) && (potCanal[i] <= 10) ) potCanal[i] = 50;
int x;
x = luz_anterior[i] - potCanal[i];
if ( abs(x) >= 500 )
{
deltaLuz[i] = ( potCanal[i] - luz_anterior[i] ) / 10;
int Conteo_Segundos = 0;
int millis_anterior = 0;
int millis_actual = 0;
// terminal.println(F("-----------------"));
Serial.println("* Cambio Suave *");
terminal.println(F("* Cambio Suave *"));
terminal.flush();
Blynk.disconnect();
while (Conteo_Segundos < 10)
{
millis_actual = millis();
yield();
if ( (millis_actual - millis_anterior) > 1000 )
{
millis_anterior = millis_actual;
Conteo_Segundos = Conteo_Segundos + 1;
potCanal[i] = luz_anterior[i] + deltaLuz[i];
if ( ( i == Luz_Luna - 2 ) && ( potCanal[i] <= 50 ) && ( potCanal[i] <= luz_anterior[i] ) ) potCanal[i] = 50;
pwm_set_duty(potCanal[i], i );
pwm_start(); // commit
luz_anterior[i] = potCanal[i];
}
}
Blynk.connect();
}
pwm_set_duty(potCanal[i], i );
pwm_start(); // commit
luz_anterior[i] = potCanal[i];
}
break;
}
// leeTemperatura();
// Blynk.virtualWrite(GraphTemp, temp);
// terminal.print(String( temp)+"°C - ");
Serial.println(currentTime);
Serial.println(Modo_txt[Modo-1]);
for (i = 0; i < 4; i = i+1 )
{
Serial.print("Canal ");
Serial.print(String(i+1));
Serial.print(": ");
Serial.print(String(potCanal[i]));
if ( ( i == Luz_Luna - 2 ) && ( potCanal[i] <= 50 ) ) Serial.print(" Luna");
Serial.println("");
}
Serial.println(F("-----------------"));
if (Blynk.connected()==true) {
Serial.print("*Blynk");
Blynk.virtualWrite(V10, potCanal[0]);
delay(50);
Blynk.virtualWrite(V11, potCanal[1]);
delay(50);
Blynk.virtualWrite(V12, potCanal[2]);
delay(50);
Blynk.virtualWrite(V13, potCanal[3]);
delay(50);
Serial.println("Blynk*");
}
I determined that the problem happens at the last part:
if (Blynk.connected()==true) {
Serial.print("*Blynk");
Blynk.virtualWrite(V10, potCanal[0]);
delay(50);
Blynk.virtualWrite(V11, potCanal[1]);
delay(50);
Blynk.virtualWrite(V12, potCanal[2]);
delay(50);
Blynk.virtualWrite(V13, potCanal[3]);
delay(50);
Serial.println("Blynk*");
}
This is the serial console ouput:
11:19
Nubes Suaves
Canal 1: 0
Canal 2: 4364
Canal 3: 4990
Canal 4: 0
-----------------
*BlynkBlynk*
[2050152] Time sync: OK
11:20
Nubes Suaves
Canal 1: 0
Canal 2: 4386
Canal 3: 4989
Canal 4: 0
-----------------
*BlynkBlynk*
11:21
Nubes Suaves
Canal 1: 0
Canal 2: 4408
Canal 3: 4987
Canal 4: 0
-----------------
*BlynkBlynk*
11:22
Nubes Suaves
Canal 1: 0
Canal 2: 4419
Canal 3: 4983
Canal 4: 0
-----------------
*Blynk
As you can see, the first serial print was executed, but after that, the ESP just stopped working, not reset, not turn off, just stopped.
At this moment, the leds are ON, and luckily, my corals and fishes are with good light from the lamp.
Any Ideas?