ESPHome LoRa receiver reboots on every other message [SOLVED]

After much googling I managed to create a custom component for receiving LoRa messages with my ESPHome receiver from a LoRa soil moisture sensor. It works and also I can see the entities in Home Assistant, however the ESPHome receiver restarts itself upon every second message, so after booting it receives without a problem, but on the second incoming message it restarts.

Here is the log after the first message:

[D][custom:049]: Packet received!
[D][text_sensor:064]: 'sensorID': Sending state 'ID011271'
[D][sensor:094]: 'humi': Sending state 100.00000 % with 1 decimals of accuracy
[D][sensor:094]: 'temp': Sending state 22.95000 °C with 1 decimals of accuracy
[D][sensor:094]: 'adc': Sending state 888.00000  with 0 decimals of accuracy
[D][sensor:094]: 'batt': Sending state 993.00000 V with 0 decimals of accuracy

And after the second message I get this over the serial monitor:

[D][custom:049]: Packet received!
Guru Meditation Error: Core  1 panic'ed (StoreProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x400891df  PS      : 0x00060730  A0      : 0x8015a315  A1      : 0x3ffb2690  
A2      : 0x0000002f  A3      : 0x3ffb275d  A4      : 0x00000007  A5      : 0x0000002f  
A6      : 0x00000049  A7      : 0x31373231  A8      : 0x00000000  A9      : 0x3ff44000  
A10     : 0x0000001f  A11     : 0x00000000  A12     : 0x00000019  A13     : 0x00000001  
A14     : 0x00060720  A15     : 0x00000001  SAR     : 0x00000007  EXCCAUSE: 0x0000001d  
EXCVADDR: 0x0000002f  LBEG    : 0x4008921c  LEND    : 0x40089232  LCOUNT  : 0xffffffff  


Backtrace:0x400891dc:0x3ffb26900x4015a312:0x3ffb26a0 0x4015a3b1:0x3ffb26c0 0x4015a457:0x3ffb26e0 0x400da578:0x3ffb2710 0x400e04ca:0x3ffb2750 0x4016dcb9:0x3ffb2790 0x4016dd41:0x3ffb27b0 0x400dd994:0x3ffb27d0 0x400dfc9e:0x3ffb2800 0x400ec495:0x3ffb2820 




ELF file SHA256: 0000000000000000

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4

So far no amount of googling helped me to solve the issue, apart from that I know that something “illegal” is happening.
As my programing skills are at their end at this, I kindly ask for support.

My custom component code is the following:

#include "esphome.h"
#include <SPI.h>
#include <LoRa.h>

#define LORA_RST 2
#define LORA_DIO0 35
#define LORA_CS 25

#define SPI_MOSI 13
#define SPI_MISO 12
#define SPI_SCK 14

namespace MyTextData {
  TextSensor *sensorID = new TextSensor();
}

class MyTextSensor : public Component, public TextSensor {
  public:
    TextSensor *sensorID = MyTextData::sensorID;
};

class MyLoRaSensor : public Component, public Sensor {
 public:
  Sensor *temp = new Sensor();
  Sensor *humi = new Sensor();
  Sensor *adc = new Sensor();
  Sensor *batt = new Sensor();

  void setup() override {
    SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI, LORA_CS);
    LoRa.setPins(LORA_CS, LORA_RST, LORA_DIO0);
    while (!LoRa.begin(866E6)) {
    delay(500);
    }
    LoRa.setSyncWord(0xF3);
  }

  void loop() override {
    int packetSize = LoRa.parsePacket();
    if (packetSize) {
      ESP_LOGD("custom", "Packet received!");
      const int max_line_length = 80;
      static char buffer[max_line_length];
      static int pos = 0;
      while (LoRa.available()) {
        char incoming = LoRa.read();
        buffer[pos++] = incoming;
      }
      MyTextData::sensorID->publish_state(strtok(buffer, ","));
      strtok(NULL, ":");
      humi->publish_state(atof(strtok(NULL, ",")));
      strtok(NULL, ":");
      temp->publish_state(atof(strtok(NULL, ",")));
      strtok(NULL, ":");
      adc->publish_state(atoi(strtok(NULL, ",")));
      strtok(NULL, ":");
      batt->publish_state(atoi(strtok(NULL, ",")));
    }
  }
};

And my ESPHome yaml is:

esphome:
  name: lora
  friendly_name: LoRa
  libraries:
    - SPI
    - sandeepmistry/LoRa@^0.8.0
  includes:
    - my_LoRa_sensor.h

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "****"

ota:
  password: "*****"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lora Fallback Hotspot"
    password: "****"

captive_portal:

text_sensor:
  - platform: custom
    lambda: |-
      auto textsensor = new MyTextSensor();
      App.register_component(textsensor);
      return {textsensor->sensorID};
    text_sensors:
      - name: sensorID
    
sensor:
  - platform: custom
    lambda: |-
      auto sensor = new MyLoRaSensor();
      App.register_component(sensor);
      return {sensor->temp, sensor->humi, sensor->adc, sensor->batt};

    sensors:
      - name: "temp"
        unit_of_measurement: "°C"
        accuracy_decimals: 1
      - name: "humi"
        unit_of_measurement: "%"
        accuracy_decimals: 1
      - name: "adc"
      - name: "batt"
        unit_of_measurement: V

Thank you.

1 Like

So, I managed to fix it. I figured out that it was something wrong with how I read the LoRa buffer, so I’ve changed it to the following and that fixed the reboot issue:

#include "esphome.h"
#include <SPI.h>
#include <LoRa.h>

#define LORA_RST 2
#define LORA_DIO0 35
#define LORA_CS 25

#define SPI_MOSI 13
#define SPI_MISO 12
#define SPI_SCK 14

namespace MyTextData {
  TextSensor *sensorID = new TextSensor();
}

class MyTextSensor : public Component, public TextSensor {
  public:
    TextSensor *sensorID = MyTextData::sensorID;
};

class MyLoRaSensor : public Component, public Sensor {
  public:
    Sensor *temp = new Sensor();
    Sensor *humi = new Sensor();
    Sensor *adc = new Sensor();
    Sensor *batt = new Sensor();

  void setup() override {
    SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI, LORA_CS);
    LoRa.setPins(LORA_CS, LORA_RST, LORA_DIO0);
    while (!LoRa.begin(866E6)) {
      delay(500);
    }
    LoRa.setSyncWord(0xF3);
  }

  void loop() override {
    int packetSize = LoRa.parsePacket();
    if (packetSize && packetSize < 50) {
      ESP_LOGD("custom", "Packet received!");

      String LoRaData = "";      
      while (LoRa.available()) {
        LoRaData += (char)LoRa.read();
        LoRaData.trim();
      }

      if (packetSize = LoRaData.length()) {
        char* strtokIndx;
        strtokIndx = strtok(&LoRaData[0],",");

        MyTextData::sensorID->publish_state(strtokIndx);

        strtok(NULL, ":");
        strtokIndx = strtok(NULL, ",");
        humi->publish_state(atof(strtokIndx));

        strtok(NULL, ":");
        strtokIndx = strtok(NULL, ",");
        temp->publish_state(atof(strtokIndx));

        strtok(NULL, ":");
        strtokIndx = strtok(NULL, ",");
        adc->publish_state(atof(strtokIndx));

        strtok(NULL, ":");
        strtokIndx = strtok(NULL, ",");
        batt->publish_state(atof(strtokIndx));
      }
      else {
        ESP_LOGD("custom", "Packet error!");
      }
    }
  }
};
1 Like

Curious which one you’re using. How is it powered? Got a link? Cheers.

Sure. I bought one from MakerFabs. I had to modify their firmware as I couldn’t get it to work with ESPHome custom SPI component, so I had to change from RadioLib to Arduino LoRa library.

1 Like

Hi, May I ask which ESP device you used as a LoRa receiver?
Thanks :slight_smile:

It’s a ESP32 Wrover module with RFM95W LoRa module attached to it. You can find something similar also at MakerFabs or do it yourself based on instructions from RandomNerdTutorials. In my final setup I will attach the RFM95W to a RobotDyn relay board to have a sprinkler controller that is not reliant on any server.

2 Likes

Sounds interesting. Do you have a GitHub page where you can share the custom code?

I’d also be interested in hearing long term testing of battery life in due course.

Mi Flora can be a bit of a hassle in this regard.

I do have, but there’s not much on it as I’m not a programmer. You can find the code in the second post of this topic.

I’m also interested as MakerFabs promises 1 year on 2 x AAA batteries. We’ll see once I deployed it. Also, I might not leave it in the soil for winter as it doesn’t make sense leaving it there rotting away without purpose, so for me a season worth (3-4 month) of battery life would be sufficient.

1 Like

More than 2yrs is the claim from your link!

the Lora moisture sensor can work at least 2 years, with 2xAAA batteries;

Oh yeah, I remembered 1 year, but we’ll see about that.

1 Like