Problems with ESP32 WROOM 32U, SIMCOM A7670 and LoRa cores

Description:
My current project uses the two cores of the ESP32 WROOM 32U to run two tasks in parallel: one for LoRa communication, where I receive text strings, and another for connection to an MQTT server via a SIMCOM modem that connects to 4G using AT commands. I faced two main problems:

– Watchdog Timer Reboot Issue: I experience ESP32 reboots due to Watchdog Timer, especially when disconnecting from the server, internet, or when starting the ESP32 for the first time.

– Error receiving LoRa issue when using the internet connection core: When the core dedicated to the MQTT server is active, the initial reception of LoRa messages is incorrect, although they are later processed correctly. Previously, with a standard ESP32 WROOM 32, this did not happen.

Problem details:

  • Hardware used: ESP32 WROOM 32U and SIMCOM A7670.
  • Libraries used: I use TinyGsmClient.h and PubSubClient.h.
  • IDE: Arduino.

Detailed description of the problem:
The main problem lies in the failures when using both cores: the restart by the Watchdog and the incorrect initial reception of LoRa messages, which is corrected after a few seconds.

Steps taken:
I have extensively reviewed my code over several days to ensure that it is properly adapted to the hardware and network configuration. Additionally, I have verified the physical hardware connections and network settings on the MQTT server. I have tried several solutions suggested on forums, such as using timers like ‘vTaskDelay’, but none have effectively solved the problem.

Error Logs:

  • Watchdog Timer:

09:52:24.052 -> E (38279) task_wdt: CPU 1: loopTask
09:52:24.052 -> E (38279) task_wdt: Aborting.
09:52:24.052 -> E (38279) task_wdt: Print CPU 0 (current core) backtrace
09:52:24.052 -> 
09:52:24.052 -> 
09:52:24.052 -> 
09:52:24.052 -> 
09:52:24.052 -> Backtrace: 0x40082d29:0x3ffb47f0 0x40089a22:0x3ffb4810 0x400d5ce9:0x3ffb4830 0x400d1c92:0x3ffb4850 0x400d1e82:0x3ffb4880 0x400d1ed1:0x3ffb48e0 0x400d27e8:0x3ffb4910 0x400d2829:0x3ffb4930 0x400d2d21:0x3ffb4950 0x400d2d75:0x3ffb4970 0x400d2e63:0x3ffb49b0
09:52:24.087 -> 
09:52:24.087 -> 
09:52:24.087 -> 
09:52:24.087 -> 
09:52:24.087 -> ELF file SHA256: 717e4228e872b1c6
09:52:24.087 -> 
09:52:24.087 -> Rebooting...
09:52:24.087 -> ets Jul 29 2019 12:21:46
09:52:24.087 -> 
09:52:24.087 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

  • LoRa:
10:32:06.792 -> ��������
10:32:06.792 -> No Coincide
10:32:06.870 -> ��������
10:32:06.870 -> No Coincide
10:32:07.010 -> ��������
10:32:07.010 -> No Coincide
10:32:07.897 -> Se envio confirmación
10:32:08.083 -> Almacenar datos en EEPROM
10:32:08.083 -> ffaa01bb020720241031

code

//Sistema
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include <string.h>

//EEPROM
#include <EEPROM.h>

//Lora
#include <SPI.h>
#include <LoRa.h>

//Simcom ~ mqtt
#define TINY_GSM_MODEM_SIM7600 //a7670xx
#define TINY_GSM_RX_BUFFER 1024
#define SerialAT Serial1
#define TINY_GSM_USE_GPRS true
#define TINY_GSM_USE_WIFI false

#include <TinyGsmClient.h>
#include <PubSubClient.h>

//Pin Lora
#define ss 4
#define rst 25
#define dio0 27

//config EEPROM -- Registros Date
#define ARRAY_SIZE 80 // Tamaño del array para las fechas
#define EEPROM_START_ADDRESS 0 // Dirección de inicio en la EEPROM
struct DataStruct {
  char data[21];
};

DataStruct dateTimeRegistrerMaster[ARRAY_SIZE];
#define DATOS_SIZE sizeof(dateTimeRegistrerMaster[0].data)
#define EEPROM_SIZE (ARRAY_SIZE * sizeof(DataStruct))
int counterRecived = 0;

// Configuración EEPROM -- Registros Order
#define ARRAY_SIZE_NEW 10 // Tamaño del array para los nuevos registros
#define EEPROM_START_ADDRESS_NEW (EEPROM_START_ADDRESS + EEPROM_SIZE) // Nueva dirección de inicio en la EEPROM para los nuevos registros

struct OrderDataStruct {
  char data[8]; // Nueva estructura para los nuevos registros
};

OrderDataStruct orderMqttStorage[ARRAY_SIZE_NEW];
#define NEW_DATOS_SIZE sizeof(orderMqttStorage[0].data)
#define NEW_EEPROM_SIZE (ARRAY_SIZE_NEW * sizeof(OrderDataStruct))
int counterRecivedMqtt = 0;

//Sistena
const int ledPin = 2;

//Lora identificación dispositivo
byte localAddress = 0xFF;   // Dirección de este dispositivo
const char* customDeviceID = "aa01";

char completeLocalAddress[7]; 


// byte destination = 0xBB;    // Dirección a la que enviar mensajes

//Config Simcom - mqtt
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
PubSubClient mqttClient(client);

const char* mqtt_server = "Myserver mqtt"; 
const int mqtt_port = 7010;//for example 1884
const char* mqtt_sub_topic = "TopicNa";
const char* mqtt_pub_topic = "Topic2";

//Config APN
const char apn[] = "Apncfg";
const char gprsUser[] = "user";
const char gprsPass[] = "pass"; 

//Config  perdurancia internet
bool networkConnected = false;
bool gprsConnected = false;


//Creamos 2 tareas
TaskHandle_t simComMqtt;
TaskHandle_t loraProtocol;


void setup() {
  Serial.begin(115200);
  SerialAT.begin(115200, SERIAL_8N1, 16, 17); // RX y TX  -- Comunicación SimCom 
  delay(3000); // Espera para que el módem se inicialice correctamente

  //Desactivar pines bornOut
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

  // SetUp pines
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);


 //Memoria EEPROM
  EEPROM.begin(EEPROM_SIZE + NEW_EEPROM_SIZE);
  initializeEEPROMData<DataStruct>(ARRAY_SIZE, EEPROM_START_ADDRESS); //Registros
  initializeEEPROMData<OrderDataStruct>(ARRAY_SIZE_NEW, EEPROM_START_ADDRESS_NEW); //Ordenes

  //SetUp Lora
  while (!Serial);
  Serial.println("LoRa Duplex");
  LoRa.setPins(ss, rst, dio0);
  while (!LoRa.begin(433E6)) {
    Serial.println(".");
    delay(500);
  }
  
  // Ajusta el nivel de potencia de salida (en dBm)
  LoRa.setTxPower(0); // Prueba con diferentes valores, 20 dBm es el máximo para SX1278
  // Establece el factor de esparcimiento en 10
  LoRa.setSpreadingFactor(10);
  // Ancho de banda de 125 kHz
  LoRa.setSignalBandwidth(125E3);
  // Tasa de codificación de 4/5
  LoRa.setCodingRate4(5);
  // Longitud del preámbulo de 8 símbolos
  LoRa.setPreambleLength(8);
  LoRa.setSyncWord(0xF3);
  Serial.println("LoRa Initializing OK!"); 

  // Setup SimCom
  String name = modem.getModemName();
  Serial.print("Modem Name: ");  
  Serial.println(name);

  String ccid = modem.getSimCCID();
  Serial.println("CCID: " + ccid);

  String imei = modem.getIMEI();
  Serial.println("IMEI: " + imei);

  String cop = modem.getOperator();
  Serial.println("Operator: " + cop);

  IPAddress local = modem.localIP();
  Serial.println("Local IP: " + String(local));

  int csq = modem.getSignalQuality();
  Serial.println("Signal quality: " + String(csq));

  Serial.print("Esperando a la red...");
  // reconnectNetwork(); // Asegura la conexión de red en el setup

  Serial.print(F("Conectando a "));
  Serial.print(apn);

  //SetUp Mqtt 
  mqttClient.setServer(mqtt_server, mqtt_port);
  mqttClient.setCallback(callback);

  //Tarea para Wifi & Mqtt
  xTaskCreatePinnedToCore(
                    simComMqttcode,   /* Task function. */
                    "simComMqtt",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,           /* priority of the task */
                    &simComMqtt,      /* Task handle to keep track of created task */
                    0);          /* pin task to core 0 */                  
  delay(500); 

  //Tarea para solo lora
  xTaskCreatePinnedToCore(
                    loraProtocolcode,   /* Task function. */
                    "loraProtocol",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,           /* priority of the task */
                    &loraProtocol,      /* Task handle to keep track of created task */
                    1);          /* pin task to core 1 */
    delay(500); 

}

//~ Funcion SimCom Conexion 4G
void reconnectNetwork() {
  if (!modem.isNetworkConnected()) {
    Serial.println("Red 4G desconectada");
    while (!modem.isNetworkConnected()) {
      if (!modem.waitForNetwork(10000L, true)) {  // 10 segundos de espera
        Serial.println("Fallo en conexion a red 4G");
        delay(5000);  // Espera 10 segundos antes de intentar de nuevo
      }
    }
    Serial.println("Red reconectada");
    networkConnected = true;
  }

  if (!modem.isGprsConnected()) {
    Serial.println("GPRS desconectado!");
    while (!modem.isGprsConnected()) {
      Serial.println("Conectando a GPRS");
      if (!modem.gprsConnect(apn, gprsUser, gprsPass)) { // Añadido: Llama a gprsConnect() con los argumentos apropiados
        Serial.println("Fallo en conexion");
        delay(5000);  // Espera 10 segundos antes de intentar de nuevo
      }
    }
    Serial.println("GPRS reconectado");
    gprsConnected = true;
  }
}

// ~ Funciones Mqtt
void reconnectMQTT() {
  reconnectNetwork();
  while (!mqttClient.connected()) {
    Serial.println("Conectando al broker MQTT...");
    mqttClient.setServer(mqtt_server, mqtt_port);
    mqttClient.setCallback(callback);  // Establecer la función de callback

    if (mqttClient.connect("ESP32Client")) {
      Serial.println("Conectado al broker MQTT");
      mqttClient.subscribe(mqtt_sub_topic);
    } else {
      Serial.print("Error de conexión al broker MQTT, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" Intentando de nuevo en 2 segundos");
      delay(2000);  // Espera 15 segundos antes de intentar de nuevo
    }
  }
  
}

//CallBack de topico mqtt
void callback(char* topic, byte* payload, unsigned int length) {
  // Convertir el payload a una cadena de caracteres
  char payloadStr[length + 1];
  for (int i = 0; i < length; i++) {
    payloadStr[i] = (char)payload[i];
  }
  payloadStr[length] = ''; // Añadir el carácter nulo al final de la cadena
  String payloadString = String(payloadStr); //Casteo a String
  Serial.println("Esta es la trama que recibo del mqtt: ");
  Serial.println(payloadString);

  //Extraer los primeros cuatro caracteres como una subcad
  String mqttMasterAdress = payloadString.substring(0, 6); //Direccion maestro
  String mqttSlaveOrder = payloadString.substring(6,10); //esclavo y orden

  //Obtener la dirección completa del dispositivo
  sprintf(completeLocalAddress, "%02X%s", localAddress, customDeviceID);
  String completeLocalAddressString = String(completeLocalAddress);


  if (mqttMasterAdress == completeLocalAddressString){
    Serial.println("Coincide");
    Serial.println("Almacenando orden MQTT en EEPROM...");
    strcpy(orderMqttStorage[counterRecivedMqtt].data, mqttSlaveOrder.c_str());
    storeDataInEEPROM<OrderDataStruct>(counterRecivedMqtt, orderMqttStorage[counterRecivedMqtt], EEPROM_START_ADDRESS_NEW);
    counterRecivedMqtt++;
    
    if (counterRecivedMqtt >= ARRAY_SIZE_NEW) {
      counterRecivedMqtt=0;
    }

  }else{
    Serial.println("La orden enviada no coincide con la dirección del maestro");

    readDataFromEEPROM<OrderDataStruct>(ARRAY_SIZE_NEW, EEPROM_START_ADDRESS_NEW);
  }

}

//Enviar EEPROM mqtt 
void sendDataEepromMqtt() {
  for (int i = 0; i < ARRAY_SIZE; i++) {
    int address = EEPROM_START_ADDRESS + (i * sizeof(DataStruct));
    DataStruct data;
    EEPROM.get(address, data);
    if(strlen(data.data) == 0){
      continue;
    }else {
      //Enviar datos al mqtt
      Serial.println(data.data);
      mqttClient.publish("AlertaETB",data.data);
      delay(200);

      // Borrar el dato de la EEPROM
      DataStruct emptyData;
      memset(emptyData.data, 0, sizeof(emptyData.data)); // Inicializar los datos con 0
      EEPROM.put(address, emptyData); // Escribir datos vacíos en la EEPROM
      EEPROM.commit(); // Guardar los cambios en la EEPROM
    }
  }
}


//Funciones Lora
void onReceive(int packetSize) {
  if (packetSize == 0) return; // Salir si no hay datos
  
  byte recipient = LoRa.read(); // Leer la dirección del destinatario
  byte sender = LoRa.read(); // Leer la dirección del remitente
  
  // Leer la fecha y hora como una cadena de caracteres
  char dateTime[18]; // Tamaño suficiente para almacenar la fecha y hora en formato YYYYMMDDHHMMSS
  for (int i = 0; i < 12; i++) {
    dateTime[i] = LoRa.read();
  }
  dateTime[12] = ''; // Añadir un carácter nulo al final para indicar el final de la cadena

  // Leer el valor adicional
  uint8_t value = LoRa.read();

  // Imprimir la información recibida
  Serial.print("Received from: 0x");
  Serial.println(sender, HEX);
  Serial.print("Date and Time: ");
  Serial.println(dateTime);
  Serial.print("Additional Value: ");
  Serial.println(value);
  Serial.print("RSSI: ");
  Serial.println(LoRa.packetRssi());
  Serial.println();

  //Envio mqtt & confirmación a esclavo Alerta
  if (value == 1) {
    digitalWrite(ledPin, HIGH); // Enciende el LED si el mensaje recibido es 1
    //Guardar datos en la memoria ~~ Se envian cuando haya conexion mqtt
    String datosApertura =  String(localAddress, HEX) + String(customDeviceID) + String(sender, HEX) + String(dateTime);

    //Enviar confirmación & orden SOTA a Slave especifico
    sendOrderSlave(sender);

    int dataToSend=1;
    sendMessage(sender, dataToSend);//Envio de confrimacion


    delay(200);
    digitalWrite(ledPin, LOW);
    Serial.println("Almacenar datos en EEPROM");
    strcpy(dateTimeRegistrerMaster[counterRecived].data, datosApertura.c_str());
    storeDataInEEPROM<DataStruct>(counterRecived, dateTimeRegistrerMaster[counterRecived], EEPROM_START_ADDRESS);

    // Incrementar el contador
    counterRecived++;
    if (counterRecived >= ARRAY_SIZE) {
      counterRecived=0;
    }
  }
}

void sendMessage(byte destination,int outgoing) {
  LoRa.beginPacket();
  LoRa.write(destination);
  LoRa.write(localAddress);
  LoRa.write(sizeof(outgoing)); // Enviar el tamaño del entero
  LoRa.write((uint8_t*)&outgoing, sizeof(outgoing)); // Enviar el entero
  delay(500); // Puedes ajustar el tiempo según tus necesidades
  LoRa.endPacket();
  Serial.println("Se envio confirmación");
}

//~ Tareas
//simComMqttcode: Intenta conectarse a wifi & mqtt - Envia los datos de almacenados
void simComMqttcode(void *pvParameters) {
  while (true) {
    // Manejar reconexión si se pierde la conexión MQTT
    if (!mqttClient.connected()) {
        // reconnectNetwork();
        reconnectMQTT();
        // readDataFromEEPROM<DataStruct>(ARRAY_SIZE, EEPROM_START_ADDRESS);
        // readDataFromEEPROM<OrderDataStruct>(ARRAY_SIZE_NEW, EEPROM_START_ADDRESS_NEW);
    } else {
        // Envía datos al servidor si está conectado a MQTT
        sendDataEepromMqtt();
    }
    
    mqttClient.loop();
    delay(10); // Pequeña pausa para permitir que otras tareas se ejecuten
  }
}

//loraProtocolcode: Escucha entradas Lora
void loraProtocolcode( void * pvParameters ){
  while (true) {
    int packetSize = LoRa.parsePacket();
    if (packetSize) {
      onReceive(packetSize);
    }
    delay(10); // Pequeña pausa para permitir que otros hilos se ejecuten
  }
}

//DEBE ESTAR VACIO
void loop() {
}

Code note: I do not upload some parts of the code to have better readability, these parts are related to the storage of the information obtained from the Lora protocol in the EEPROM memory

Purpose of the post:

I am seeking assistance from the community to find a solution to these problems. Preferably, solving the Watchdog problem should also solve the LoRa reception problem.

I appreciate any help or suggestions to resolve these issues!

New contributor

Alexander idid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật