xreef / EByte_LoRa_E220_Series_Library

Arduino LoRa EBYTE E220 LLCC68 device library complete and tested with Arduino, esp8266, esp32, STM32 and Raspberry Pi Pico (rp2040 boards)..
https://www.mischianti.org/category/my-libraries/lora-e220-llcc68-devices/
Other
90 stars 22 forks source link

Possible Issue: ESP8266 setting Configuration results in soft WDT reset. #28

Open ClausRogisch opened 3 months ago

ClausRogisch commented 3 months ago

Trying to set the configuration on ESP8266 (Wemos D1 Mini) with E220-900T22D. E220 in config mode. Reading the config with Success, but setting config results always in soft reset. EByte LoRa E220 library@^1.0.8 Plattform Espressif 8266 v4.2.1

Error also exists when just calling setConfiguration() with the accquired configuration, wihtout changing any parameter.

Stacktrace:

Soft WDT reset

Exception (4):
epc1=0x401061d0 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

Level1Interrupt: Level-1 interrupt as indicated by set level-1 bits in the INTERRUPT register
  epc1=0x401061d0 in system_get_time at ??:?

>>>stack>>>

ctx: cont
sp: 3ffffd50 end: 3fffffd0 offset: 0160
3ffffeb0:  00000000 00002469 049ba5e3 00001388  
3ffffec0:  00002469 00001388 00002469 40205c4e  
3ffffed0:  0000000b 00001388 3ffeedb8 40205cb1  
3ffffee0:  000000c0 00000028 000023bd 3ffef150  
3ffffef0:  0000000b 3ffeedb8 0000000f 40205d32  
3fffff00:  000000c0 00000000 3ffeedb8 40205fed  
3fffff10:  40208524 3ffe8f42 3ffeefc8 3ffef150  
3fffff20:  020800c0 12006200 4c000043 40208c60  
3fffff30:  3fffdad0 3ffeedb8 3ffeefc8 40202eee  
3fffff40:  3ffe8f44 fffffffc 3ffeefc8 020802c1  
3fffff50:  12006200 4c000043 3ffeefc8 3ffef150  
3fffff60:  3fffdad0 0000001d 3ffeefc8 40208c60  
3fffff70:  3fffdad0 3ffeedb8 3ffeefc8 4020308d  
3fffff80:  00000000 00737365 00000000 020800c1  
3fffff90:  12006200 3c000043 423fff12 00000001  
3fffffa0:  3fff122c 00000100 0308c100 3f160b10  
3fffffb0:  3fffdad0 00000000 3ffef124 4020b044  
3fffffc0:  feefeffe feefeffe 3fffdab0 40101069  
<<<stack<<<

0x40205c4e in LoRa_E220::managedDelay(unsigned long) at ??:?
0x40205cb1 in LoRa_E220::waitCompleteResponse(unsigned long, unsigned int) at ??:?
0x40205d32 in LoRa_E220::sendStruct(void*, unsigned short) at ??:?
0x40205fed in LoRa_E220::setConfiguration(Configuration, PROGRAM_COMMAND) at ??:?
0x40208524 in HardwareSerial::write(unsigned char const*, unsigned int) at ??:?
0x40208c60 in Print::println(char const*) at ??:?
0x40202eee in LoraModule::setParameters() at ??:?
0x40208c60 in Print::println(char const*) at ??:?
0x4020308d in LoraModule::setup() at ??:?
0x4020b044 in loop_wrapper() at core_esp8266_main.cpp:?
0x40101069 in cont_wrapper at ??:?

Implementation:

namespace LoraModule{
    //SoftwareSerial loraSerial(D2,D3);
    LoRa_E220 e22ttl(D2,D3);

    void setup() {
        // Startup all pins and UART
        Serial.println("LoraModule: starting setup");
        e22ttl.begin();

        ResponseStructContainer c;
        c = e22ttl.getConfiguration();
        // It's important get configuration pointer before all other operation
        Configuration configuration = *(Configuration*) c.data;
        Serial.println(c.status.getResponseDescription());
        Serial.println(c.status.code);

        printParameters(configuration);

        ResponseStructContainer cMi;
        cMi = e22ttl.getModuleInformation();
        // It's important get information pointer before all other operation
        ModuleInformation mi = *(ModuleInformation*)cMi.data;

        Serial.println(cMi.status.getResponseDescription());
        Serial.println(cMi.status.code);

        printModuleInformation(mi);
        if(DeviceConfig::configMode){
            Serial.println("LoraModule: setting Paramters");
            setParameters(configuration);
            Serial.println("LoraModule: done setting parameters");
        }
        Serial.println("LoraModule: end setup");
        c.close();
    }

    void loop() {

    }
    void getParameters(){
        ResponseStructContainer c;
        c = e22ttl.getConfiguration();
        // It's important get configuration pointer before all other operation
        Configuration configuration = *(Configuration*) c.data;
        Serial.println(c.status.getResponseDescription());
        Serial.println(c.status.code);

        printParameters(configuration);

        ResponseStructContainer cMi;
        cMi = e22ttl.getModuleInformation();
        // It's important get information pointer before all other operation
        ModuleInformation mi = *(ModuleInformation*)cMi.data;

        Serial.println(cMi.status.getResponseDescription());
        Serial.println(cMi.status.code);

        printModuleInformation(mi);

    }
    void printParameters(struct Configuration configuration) {
        Serial.println("----------------------------------------");

        Serial.print(F("HEAD : "));  Serial.print(configuration.COMMAND, HEX);Serial.print(" ");Serial.print(configuration.STARTING_ADDRESS, HEX);Serial.print(" ");Serial.println(configuration.LENGHT, HEX);
        Serial.println(F(" "));
        Serial.print(F("AddH : "));  Serial.println(configuration.ADDH, HEX);
        Serial.print(F("AddL : "));  Serial.println(configuration.ADDL, HEX);
        Serial.print(F("NetID : "));  Serial.println(configuration.STARTING_ADDRESS, HEX);
        Serial.println(F(" "));
        Serial.print(F("Chan : "));  Serial.print(configuration.CHAN, DEC); Serial.print(" -> "); Serial.println(configuration.getChannelDescription());
        Serial.println(F(" "));
        Serial.print(F("SpeedParityBit     : "));  Serial.print(configuration.SPED.uartParity, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getUARTParityDescription());
        Serial.print(F("SpeedUARTDatte     : "));  Serial.print(configuration.SPED.uartBaudRate, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getUARTBaudRateDescription());
        Serial.print(F("SpeedAirDataRate   : "));  Serial.print(configuration.SPED.airDataRate, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getAirDataRateDescription());
        Serial.println(F(" "));
        Serial.print(F("OptionSubPacketSett: "));  Serial.print(configuration.OPTION.subPacketSetting, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getSubPacketSetting());
        Serial.print(F("OptionTranPower    : "));  Serial.print(configuration.OPTION.transmissionPower, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getTransmissionPowerDescription());
        Serial.print(F("OptionRSSIAmbientNo: "));  Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
        Serial.println(F(" "));
        Serial.print(F("TransModeWORPeriod : "));  Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
        Serial.print(F("TransModeEnableLBT : "));  Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
        Serial.print(F("TransModeEnableRSSI: "));  Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
        Serial.print(F("TransModeFixedTrans: "));  Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());

        Serial.println("----------------------------------------");
    }
    void printModuleInformation(struct ModuleInformation moduleInformation) {
        Serial.println("----------------------------------------");
        Serial.print(F("HEAD: "));  Serial.print(moduleInformation.COMMAND, HEX);Serial.print(" ");Serial.print(moduleInformation.STARTING_ADDRESS, HEX);Serial.print(" ");Serial.println(moduleInformation.LENGHT, DEC);

        Serial.print(F("Model no.: "));  Serial.println(moduleInformation.model, HEX);
        Serial.print(F("Version  : "));  Serial.println(moduleInformation.version, HEX);
        Serial.print(F("Features : "));  Serial.println(moduleInformation.features, HEX);
        Serial.println("----------------------------------------");

    }
    void setParameters(struct Configuration configuration){
        Serial.println("LoraModule: setting module address params");
        configuration.ADDL = DeviceConfig::loraAddl;
        configuration.ADDL = DeviceConfig::loraAddl;
        configuration.STARTING_ADDRESS = DeviceConfig::loraAddChan;
        Serial.println("LoraModule: setting flequency channel information");
        configuration.CHAN = 18;

        configuration.SPED.uartBaudRate = UART_BPS_9600;
        configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
        configuration.SPED.uartParity = MODE_00_8N1;

        configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED;
        configuration.OPTION.transmissionPower = POWER_22;

        configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED;
        configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
        configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED;
        configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
        Serial.println("LoraModule: write parameters to device");
        ResponseStatus rs = e22ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);
        Serial.println(rs.getResponseDescription());
        Serial.println(rs.code);

    }
    void preparePacket(String content){
        Serial.println("LoraModule: sending packet");
        ResponseStatus rs = e22ttl.sendFixedMessage(DeviceConfig::loraGatewayAddh, DeviceConfig::loraAddl, DeviceConfig::loraGatewayAddChan, content);
        // Check If there is some problem of succesfully send
        Serial.println(rs.getResponseDescription());
        Serial.println("LoraModule: done sending packet");
    }
}
ClausRogisch commented 3 months ago

Working solution: adding yield(); in while loop to avoid blocking behaviour.

void LoRa_E220::managedDelay(unsigned long timeout) {

    unsigned long t = millis();

    // make darn sure millis() is not about to reach max data type limit and start over
    if (((unsigned long) (t + timeout)) == 0){
        t = 0;
    }

    while ((millis() - t) < timeout)    { 
        yield();
        }

}
xreef commented 3 months ago

Hi ClausRogisch; I try to reproduce with Arduino Core 3 , but they work correctly. But I think there is also a problem because it is the same problem here.

It's very strange. Can you try to do a test with an older version of core? Bye Renzo

ClausRogisch commented 3 months ago

I am currently not able to debug. Did you try to reproduce it with an esp8266? I think this is esp8266 specific, to my understanding, because it can not handle background tasks if the one and only main thread blocks for more than 3.6s or something in that range. So if the timeout is too long, it's throwing the exception. Esp32 is able to offload to other task and arduinos(atmegas) I'm not Shure this timeout limitation in the loop/setup exists.

Hence I posted my working solution introducing the yield(); to allow the esp8266 to handle the stuff that it has to do

xreef commented 3 months ago

Ahh, ok, I see now that you don't use an AUX pin that prevents long attendance. I'm going to do some other test. Thanks, Renzo

ClausRogisch commented 3 months ago

Corre t, failed to mention the connection setup. My bad