Blynk y Nodemcu v3

Estoy realizando mi TFG sobre control de calidad ambiental con una placa nodemcu v3 y varios sensores, además de un RTC DS3231 y un adaptador de tarjetas micro SD.
Tengo varias dudas. En primer lugar me gustaría saber la forma para que el programa no se quede atascado en el comando Blynk.begin(auth,ssid,pass); si no se conecta al WiFi ya que la idea es que si hay problemas de conexión, el programa siga avanzando y almacene los datos en la tarjeta microSD. He probado con el fragmento de las líneas 338 - 344 pero no lo soluciona.
Relacionado con la app Blynk tampoco sé por qué no se actualizan los valores de los sensores en mi proyecto, se quedan todo el rato a 0.
Y por último, comentar que tengo el RTC DS3231, el sensor de luminosidad TSL2591 y el de radiación gamma GDK101, conectados con comunicación I2C. Cuando pruebo por separado el TSL2591 y el GDK101, funcionan correctamente dando unos valores razonables pero al probar el código al completo, el TSL2591 marca -1 lux y el GDK101 56 Bq/m^3. Buscando información, en principio no debería de pasar esto porque tienen direcciones I2C diferentes. Agradecería mucho si alguien saber algo sobre esto.
Muchas gracias de antemano a toda la comunidad.

#define BLYNK_PRINT Serial                         // Definición para poder mostrar los datos en la 
                                                   // aplicación Blynk

// Se incluyen las librerías necesarias:
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>

// Para los sensores DHT22
#include <DHT.h>

// Para el sensor de luminosidad
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

// Para el adaptador de tarjetas microSD
#include <SPI.h>
#include <SdFat.h>                                 // Mejor que la SD.h en cuanto al consumo

// Para el uso del reloj RTC DS3231
#include "RTClib.h"

/*  
 *   Direcciones I2C por defecto:
 *   RTC DS3231  :: 0x57   0x68
 *   GDK 101     :: 0x18
 *   TSL2591     :: 0x29
 */

char auth[] = "YDWKmVVIEWo_hJE42ZPg7O7niEVtN5hm";  // Identificador del proyecto en Blynk
//char ssid[] = "MOVISTAR_B802";                   // Introducir el nombre de la red Wifi
//char pass[] = "n22WaAZWmN822fma83QU";            // Contraseña de la red Wifi
//char ssid[] = "FTE-DDE8";
//char pass[] = "twsw72Y3";
//char ssid[] = "Redmi";
//char pass[] = "12345678";

SimpleTimer timer;                                 // Sincroniza el reloj Arduino con Blynk

#define DHTPIN 2                                   // Se define el pin de conexión del sensor DHT22, D4 (GPIO2)

#define DHTTYPE DHT22                              // Se elige el sensor de la familia DHT que se utiliza
DHT dht(DHTPIN, DHTTYPE);                          // Configuración de la librería DHT
float Ha, Ta;                                      // Declaración de variables del DHT22

#define CO2 A0                                     // Se define la entrada analógica del sensor MH-Z14A
float ppm;                                         // Declaración de variable del MH-Z14A

int addr = 0x18;                                   // Dirección por defecto del sensor GDK101
byte buffer[2] = {0,0};                            // Se establece el bus que se utilizará en la interfaz I2C
int day,hour,minute,sec = 0;                       // Se establecen los datos secundarios del sensor, para
int status = 0;                                    // visualizar por monitor serie       
float value2;                                      // Declaración variable del GDK101                                              

Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);     // Pasar un número para el identificador del sensor
uint16_t lux;                                      // Declaración variable del TSL2591

#define DHTPIN_g 0                                 // Pin de conexión del sensor DHT22 para la Tg, D3 (GPIO0)
DHT dht_g(DHTPIN_g, DHTTYPE);                      // Configuración de la librería DHT para la Tg
float Hg, Tg, To;                                  // Declaración de variables del sensor de temperatura operativa

const int chipSelect = 4;                          // Lector SD
SdFat SD;                                          // Necesario para sustituir SdFat.h por SD.h
File logFile;
char fileName[] = "datalog.csv";                   // Nombre del fichero de salida donde se guardarán las medidas
#define LOGFILE "datalog.csv"

RTC_DS3231 rtc;
char buf[] = "DD/MM/YY \t hh:mm:ss";

// Función para leer los sensores
void SendSensor(){

  Ha = dht.readHumidity();                         // Se obtiene la humedad relativa del ambiente
  Ta = dht.readTemperature();                      // Se obtiene la temperatura seca del ambiente

  if (isnan(Ha) || isnan(Ta)){
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  
  Serial.println();
  Serial.print(F("Humedad relativa: \t\t"));
  Serial.print(Ha);
  Serial.println(F(" %"));
  Serial.print(F("Temperatura seca: \t\t"));
  Serial.print(Ta);
  Serial.println(F(" °C"));
  
  float v = analogRead(CO2)*3.3/1023.0;            // Convertir a voltaje la entrada A0
  ppm = int((v-0.4)*3125.0);                       // Calcular concentración CO2 en ppm con la tensión de entrada A0

  Serial.println();
  Serial.print(F("Concentración CO2: \t\t"));
  Serial.print(ppm);
  Serial.println(F(" ppm"));

  // Asociar los datos con las variables virtuales de Blynk
  Blynk.virtualWrite(V1, Ha);                      // V1 es para humedad relativa ambiental
  Blynk.virtualWrite(V2, Ta);                      // V2 es para la temperatura seca ambiental
  Blynk.virtualWrite(V3, ppm);                     // V3 es para ppm de CO2

  // Llamada a la función Gamma_Mod_Read_Value() del sensor GDK101
  Serial.println();
  Gamma_Mod_Read_Value();

  // Función para leer a la vez el espectro completo e infrarrojo y convertirlo a lux
  Serial.println();
  advancedRead();
  delay(500);
  
  // Mediciones del sensor DHT22 colocado en la semiesfera negra mate para la Tg
  Hg = dht_g.readHumidity();                       // Se obtiene la humedad relativa en el interior de la semiesfera (de globo)
  Tg = dht_g.readTemperature();                    // Se obtiene la temperatura de globo

  if (isnan(Hg) || isnan(Tg)){
    Serial.println("Failed to read from balloon sensor!");
    return;
  }

  // Velocidad del aire
  float Va = 0.2;                                 
  // Cálculo de la temperatura radiante media a partir de la temperatura de globo (Tg) y del aire (t)
  double Trm = pow((pow((Tg+273.0),4.0) + 2.5*pow(10.0,8.0)*pow(Va,0.6)*(Tg-Ta)),0.25) - 273.0;
  // Cálculo de la temperatura operativa
  To = (Ta+float(Trm))/2;

  Serial.println();
  Serial.print(F("Temperatura operativa: \t\t"));
  Serial.print(To);
  Serial.println(F(" ºC"));
  Serial.println();
  Serial.println(F("*****************************************************************"));
  
  Blynk.virtualWrite(V6, To);                      // V6 es para la temperatura operativa
}

void Gamma_Mod_Read_Value(){
  Gamma_Mod_Read(0xB0);         // Función para mostrar el funcionamiento del sensor GDK101
  Gamma_Mod_Read(0xB1);         // Función para mostrar el tiempo de medición
  Gamma_Mod_Read(0xB2);         // Función para realizar la media de las mediciones cada 10 minutos
  Gamma_Mod_Read(0xB3);         // Función para la lectura de los valores medidos cada minuto
}

// Función para leer los datos del sensor GDK101
void Gamma_Mod_Read(int cmd){

  Wire.beginTransmission(addr);                    // Se comienza a escribir la secuencia
  Wire.write(cmd);
  Wire.endTransmission();                          // Fin de escritura de la secuencia
  delay(10);

  Wire.requestFrom(addr, 2);                       // Comienza a leer la secuencia

  // Bucle para leer cada uno de los datos
  byte i = 0;
  while(Wire.available())
  {
    buffer[i] = Wire.read();
    i++;
  }
  // Fin de lectura de la secuencia

  // Llamada a función para mostrar los resultados del GDK101
  Print_Result(cmd);
}

void Print_Result(int cmd){
  float value = 0.0f;                              // Declaracion de las variables que se utilizarán

   switch(cmd){                                    // Selección del comando
    case 0xA0:                                     // Si se resetea (comando 0xA0) muestra por
                                                   // el monitor serie si se ha realizado o no
      Serial.print(F("Reset Response\t\t\t"));
      if(buffer[0] == 1) Serial.println("Reset Success.");
      else               Serial.println("Reset Fail(Status - Ready).");
    break;

    case 0xB0:
      Serial.print(F("GDK101 Status\t\t\t"));      // Muestra el funcionamiento del sensor
      switch(buffer[0]){                           // En función de los bits del buffer
        case 0: Serial.println("Ready"); break;
        case 1: Serial.println("10min Waiting"); break;
        case 2: Serial.println("Normal"); break;
      }
      status = buffer[0];
      Serial.print(F("VIB Status\t\t\t"));
      switch(buffer[1]){                           // Se comprueba si se ha detectado vibración
        case 0: Serial.println("OFF"); break;      // Si el bit 1 del buffer es 0, se mostrará PFF
        case 1: Serial.println("ON"); break;       // Si el bit 0 del buffer es 1, se mostrará ON   
      }
    break;

    case 0xB1:
      if(status > 0){
        sec++;                                     // Aumenta cada segundo
        Cal_Measuring_Time();                      // Llamada a la función de medición de tiempo
      }
    break;

    case 0xB2:
      Serial.print(F("Measuring Value(10min avg)\t"));
      value = buffer[0] + (float)buffer[1]/100;    // Valor medio cada 10 minutos
      Serial.print(value); Serial.println(" uSv/hr");
    break;

    case 0xB3:                                     // Comando para obtener los valores medidos
      Serial.print(F("Measuring Value(lmin avg)\t"));
      value = buffer[0] + (float)buffer[1]/100;    // Valor medido en uSv / hr
      Serial.print(value); Serial.println(F(" uSv/hr"));
      Serial.print(F("Concentración de Radón: \t"));
      float value2;
      if (value == 0){
        value2 = 0;
      }
      else{
      // Definición de las variables que se utilizan para el cálculo de CRn
        float lambda = 0.0000021;
        float densidad = 1600;
        float H = 3.5;
        float E = 0.25;
        float tv = 0.0027;
        float D = 0.000002;
        value2 = (value*114-0.451)*E*densidad*sqrt(lambda*D)/(0.1887*H*(lambda+tv)); // Obtención del valor en Bq / m^3
      }
      Serial.print(value2); 
      Serial.println(F(" Bq/m^3"));
      
      Blynk.virtualWrite(V4,value2);               // V4 es el valor medido en Bq / m^3
    break;

    case 0xB4:
      Serial.print(F("FW Version\t\t\t"));
      Serial.print(F("V")); Serial.print(buffer[0]);
      Serial.print(F(".")); Serial.println(buffer[1]);
    break;
    }  
}

void Cal_Measuring_Time(){
  if(sec == 60) { sec = 0; minute++; }
  if(minute == 60) { minute = 0; hour++; }
  if(hour == 24) { hour = 0; day++; }

  Serial.print(F("Measuring Time\t\t\t"));
  Serial.print(day); Serial.print(F("d "));
  if(hour < 10) Serial.print(F("0"));
  Serial.print(hour); Serial.print(F(":"));
  if(minute < 10) Serial.print(F("0"));
  Serial.print(minute); Serial.print(F(":"));
  if(sec < 10) Serial.print(F("0"));
  Serial.println(sec);
}

// Función para leer los datos del sensor TSL2591
void advancedRead(void)
{
  // More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
  // That way you can do whatever math and comparisons you want!
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;
  lux = tsl.calculateLux(full, ir);
  Serial.print(F("Luminosidad: \t"));
  Serial.print(F("IR: ")); Serial.print(ir);  Serial.print(F("  "));
  Serial.print(F("Full: ")); Serial.print(full); Serial.print(F("  "));
  Serial.print(F("Visible: ")); Serial.print(full - ir); Serial.print(F("  "));
  Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir));

  Blynk.virtualWrite(V5, lux);                     // V5 es para la luminosidad
}

// Función para los detales del sensor TSL2591
void displaySensorDetails(void)
{
  sensor_t sensor;
  tsl.getSensor(&sensor);
  Serial.println(F("--------------------------------"));
  Serial.print  (F("Sensor:       ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:   ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:    ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:    ")); Serial.print(sensor.max_value); Serial.println(F(" lux"));
  Serial.print  (F("Min Value:    ")); Serial.print(sensor.min_value); Serial.println(F(" lux"));
  Serial.print  (F("Resolution:   ")); Serial.print(sensor.resolution, 4); Serial.println(F(" lux"));  
  Serial.println(F("--------------------------------"));
  delay(500);
}

// Función para configurar el sensor TSL2591
void configureSensor(void)
{
  tsl.setGain(TSL2591_GAIN_MED);                   // 25x gain
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);    // integration time
  
  /* Display the gain and integration time for reference sake */  
  Serial.print  (F("Gain:         "));
  tsl2591Gain_t gain = tsl.getGain();
  switch(gain)
  {
    case TSL2591_GAIN_LOW:
      Serial.println(F("1x (Low)"));
      break;
    case TSL2591_GAIN_MED:
      Serial.println(F("25x (Medium)"));
      break;
    case TSL2591_GAIN_HIGH:
      Serial.println(F("428x (High)"));
      break;
    case TSL2591_GAIN_MAX:
      Serial.println(F("9876x (Max)"));
      break;
  }
  Serial.print  (F("Timing:       "));
  Serial.print((tsl.getTiming() + 1) * 100, DEC); 
  Serial.println(F(" ms"));
  Serial.print(F("==============================================="));
  Serial.println(F(""));
}

void setup() {
  Serial.begin(9600);                              // Velocidad de transmisión para monitor serie
  Wire.begin(4,5);                                 // Se establecen las entradas para la interfaz I2C
                                                   // GPIO4 (D2) = SDA y GPIO5 (D1) = SCL
  rtc.begin();                                     // Inicializa el reloj RTC DS3231
  // Cabecera de presentación
  Serial.println(F(" "));
  Serial.println(F("Datalogger. Elena Martínez 2021"));
  Serial.println(F("Sensores de radón y temperatura operativa en nodos para controlar la calidad ambiental en entornos interiores")); 
  Serial.println(F("TFG. Ingenieria Electrónica, Robótica y Mecatrónica"));
  Serial.println(F("Placa Node MCU"));
  DateTime date = rtc.now();
  Serial.println(date.toString(buf));
  Serial.println(" "); 
  
  Blynk.begin(auth,ssid,pass);                     // Configuración para conectarse a BLynk

// Prueba 
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
  if(i == 21){
    Serial1.print("Could not connect to"); Serial1.println(ssid);
    delay(500);
  }
  
// Para el adaptador SD
  pinMode(chipSelect,OUTPUT);

// Para lo sensores DHT22
  dht.begin();
  dht_g.begin();

// Llamada a la función leer sensores cada 5 minutos (1000 s * 60 s * 5 min = 300.000)
  timer.setInterval(60000L, SendSensor);

// Parte del sensor GDK101
  Serial.println(F("==============================================="));
  Serial.println(F("Gamma Sensor Sensing Start"));
  // Read Firmware version
  Gamma_Mod_Read(0xB4);
  // Llamada a la función leer datos del sensor GDK101 para resetearlo
  Gamma_Mod_Read(0xA0);
  Serial.println(F("==============================================="));

// Parte del sensor TSL2591
  Serial.println(F("Starting Adafruit TSL2591!"));
  if (tsl.begin()) {
    Serial.println(F("Found a TSL2591 sensor"));
  } 
  else {
    Serial.println(F("No sensor found ... check your wiring?"));
    while (1);
  }    
  // Display some basic information on this sensor
  displaySensorDetails();  
  // Configure the sensor
  configureSensor();

// Parte del adaptador SD
  if (!SD.begin(chipSelect,SPI_HALF_SPEED)) {      // Chequeo
    Serial.println(F("Fallo en el adaptador de tarjetas microSD"));
  }
  else {
    logFile = SD.open(fileName, FILE_WRITE);       // Abrir fichero
    if (logFile) {                                 // Si está disponible, escribir en él
      logFile.println(F("Fecha\tHora\tHR(%)\tTa(ºC)\tCO2(ppm)\tRn(Bq/m^3)\tLuminosidad(lux)\tHg(%)\tTg(ºC)\tTo(ºC)"));
      logFile.close();                             // Cerrar el fichero
      Serial.println(F("... Cabecera de datos grabados"));
      Serial.println(F("... Dispositivos inicializados"));
      Serial.println(F("==============================================="));
      // Cabecera de inicio de datos
      // Serial.println(F("Fecha\t\tHora\tHR(%)\tTa(ºC)\tCO2(ppm)\tRn(Bq/m^3)\tLuminosidad(lux)\tHg(%)\tTg(ºC)\tTo(ºC)"));
    }
    else {
      Serial.println(F("Fallo en el adaptador de tarjetas microSD"));  
    }
  }
} 

void loop() {
  Blynk.run();                                     // Inicializar Blynk  
  timer.run();                                     // Inicializar SimpleTimer
  
  delay(90000L);                                   // Dar tiempo a mostrar los datos en el monitor serie
  
  // Datos para la tarjeta SD y para mostrar en el monitor serie
  // Cabecera de inicio de datos
  Serial.println(F("Fecha\t\tHora\tHR(%)\tTa(ºC)\tCO2(ppm)\tRn(Bq/m^3)\tLuminosidad(lux)\tHg(%)\tTg(ºC)\tTo(ºC)"));
  DateTime now = rtc.now();
  String nowStr = now.toString(buf);
  String dataString = nowStr +"\t"+String(Ha)+"\t"+String(Ta)+"\t"+String(ppm)+"\t"+String(value2)+"\t"+String(lux)+"\t"+String(Hg)+"\t"+String(Tg)+"\t"+String(To)+"\t";
  Serial.println(dataString);
  if (!SD.begin(chipSelect,SPI_HALF_SPEED)){     // Chequeo
    Serial.println(F("Fallo en el adaptador de tarjetas microSD"));
  }
  else {
    logFile = SD.open(fileName, FILE_WRITE);     // Abrir fichero
    if (logFile) {                               // Si está disponible, escribir en él
      logFile.println(dataString);               // Enviar al fichero un string con los datos
      logFile.close();                           // Cerrar el fichero
      Serial.println(dataString);                // Enviar al monitor serie el mismo string
    }
    else {
      Serial.println(F("Fallo en el adaptador de tarjetas microSD"));  
    }
  }
 }

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.