Big ESP32 + SX127x topic part 3

Can hardware interrupts be enabled for LMIC without requiring further changes to Arduino application code?
When would enabling hardware interrupts for LMIC be useful and when not?
Is this valid for both the original LMIC-Arduino library and for the MMCI LoRaWAN LMIC library?
Is that independent of type of MCU used?

Until recently I have only seen remarks like ‘enabling interrupts for LMIC is best avoided because it can cause issues’ while you seem to promote it (use it in Paxcounter).
I understand that interrupt based is usually better than polling but if so, why hasn’t that been the norm with LMIC previously?

Can you please elaborate on that?

It’s pretty easy with current MCCI LMIC code, you just have to enable the function in lmic_config.h:


The original LMIC arduino library does - as far as i see - not and did never include this function.

Using hardware interrupts instead of polling has in my opinion more advantages than disadvantages: Is frees up CPU from polling and thus allows a more “sharp” timing for the time critical opening of RX-windows. This saves power and thus is relevant for all real low power applications. While power savings maybe not significant with Class A devices, it will with Classes B / C.

Another advantage, also for Class A, might be that in busy multithreaded applications (like paxcounter) timing by hardware works better than by software, because by software will cause more jitter, and this could result to missed RX packets. That’s the reason why i decided to switch paxcounter code to use interrupts.

Only disadvantage in my opinion is, that the used GPIO pins for LORA_IRQ (= DIO0) , and LORA_DIO1 must be connected to interrupt capable pins of CPU. This might be an issue on hardware with small CPU footprint, but on a ESP32 system you have lots of suitable GPIOs, and as far as i see it works with all Heltec, TTGO, Pycom etc. development boards. So why not using it?

There was an issue, that broke the interrupt function working in MCCI LMiC on ESP32, but recently i spotted the bug in the HAL code, and made a PR for it. This was merged in MCCI LMIC master last week and since then i have some test clients up and running on interrupts, so far working smooth and i don’t see any RX packet loss any more.

1 Like

Next level would be to have ESP32 proprietary interrupt function, which captures the timestamp of the interrupt by hardware. This should be somehow possible with ESP32 hardware, i guess, but i did not yet find out the way how to. This would allow a further sharpening of timing, what opens up opportunity to have a high precision (< 1ms) “NTP” via LORAWAN.

TTGO Beam V1.0 now supported by paxcounter.
To get this running, i did register power management chip AXP202X Library by LilyGo to platformio (after asking them for permission) and added it to paxcounter.
This chip has a bunch of power management features; unfortunately we still miss a schematic for TTGO Beam V1.0 to use all functions.

1 Like

You need interrupts if want to sleep all the time between events (e.g. TX begin, TX complete, RX begin, RX complete, etc.). Pretty sure no-one uses LMIC this way.

Sleep aside, using interrupts might allow you to reduce your clock error compensation since there will be less jitter in determining RX begin compared to polling at both ends. Reducing compensation might mean the radio is waiting to receive for less time.

I got a TTGO T-Beam V1.0 and enhanced the paxcounter software to support some of the new board features:

  • GPS PPS interrupt line
  • PMU (power management unit)
  • Two Buttons

As PMU an AXP192 chip is used. Although this is an older model dated around 2011, is has a bunch of interesting features, look at the data sheet (unfortunately chinese only, does anyone has english version?)

In paxcounter code i added some examples for the various power interrupts - works! Now you can easyly trigger on power events, like battery connected/removed, USB plug connected/removed, battery overheated/charged etc.

The second user button is also controlled by the PMU.

You may try to (partially) translate it here: onlinedoctranslator

Did that already, but doesn’t work well with that technical datasheet.
Meanwhile i found that the datasheet to the very similary AXP202 chip is available in english, so i can use the register map from this source.

Recent TTGO product T-Watch belongs to a ‘wearable appliance’ category. And like majority of their products, the T-watch is also based on ESP32 SoC.
This is an option to buy the watch together with ‘GNSS+LoRa daughterboard’ which has SX1276 RF IC (been wrapped inside S76G SoC) and LoRaWAN compliant firmware built-in.
The RF daughterboard performs quite well, provided that external SMA antenna is in use.

Below is an illustration of how SoftRF firmware is driving the watch to transmit and receive packets with LoRa modulation (FANET protocol):

3D design of ‘cargo bay’ for the T-Watch is available on my Thingiverse page.
It is designed to fit for two SMA <=> uFL/IPEX adapters.

Is there a software for the S76G, which replicates the SX1276 signals on GPIO pins? This way LMIC stack could be run on the watch.

I have a TTGO LORA32 board that I am going to use as a soil moisture sensor, however the results of esp_deep_sleep_start() is underwhelming. I have the consumption down to ~15mA when sleeping, but I was hoping/expecting to get down to double-digit uA.

I’ve noticed that the moisture sensor continues to draw current when the ESP32 is in sleep (~5mA), so it looks like there is more to be done with the config.

My current setup is:


and rtc_gpio_isolate doesn’t compile.

Does anyone have a working config or suggestions on how I can better reduce deep sleep power consumption?


Long discussion about similar problems on the ESP32 support forums;

A bare bones ESP32 board, with a carefully selected regulator, may well get down to 30uA or so in deep sleep, but very often the boards are not designed for that.

Most ESP32 boards have components that may consume current even when the ESP32 device itself is in deep sleep; USB-Serial devices, displays, charger ICs.

I’ll have a read.

Thanks for the pointer.

I have LMIC which runs entirely inside the S76G-based T-Watch daughterboard (on it’s STM32L073 MCU) as a part of my SoftRF port on STM32 platform.
But this topic is out of scopes for this ESP32 thread.


1 Like

Great! Can you share your LMIC port? In your github repo i found binaries only.

The LMIC is integrated into SoftRF as one library of many.
Direct link onto the library is below:

SoftRF/S76G is to be built with Arduino Core STM32 for Nucleo L073RZ target.

Build instructions


This means your whole application, including LMIC, is running on the daughterboard of T-Watch, i guess?

I’m looking for a solution which emulates a native SX1276 on the S76g, thus the S76g is controllable like a RFM95 module.

I’m having problems with my recendly purcharsed board - its exact name is:
SX1276 V2 Lora ESP32 LX6 Dual-Core 0,96" OLED Bluetooth LE Wifi Kit 32 Modul CP2012 IOT 868-915MHz

EDIT: from Heltec
I’ve tried ttn-abp.ino for activating with differend pin settings and i’m never receiving anything in the Data Console … :frowning:
I’ve set up anything properly in my Account with ABP as activation method.

I think for V2 this should be correct:

const lmic_pinmap lmic_pins = {
.nss = 18,
.rst = 14,
.dio = {/dio0/ 26, /dio1/ 35, /dio2/ 34 }

Could it be that I’m already having V2.1 and it requires different settings? (It has only printed “V2” on it)

In my Serial Monitor I’m having something like this:

14:14:02.410 -> Starting
14:14:02.410 -> RXMODE_RSSI
14:14:02.410 -> 9585: engineUpdate, opmode=0x808
14:14:02.410 -> 9618: EV_TXSTART
14:14:02.444 -> 9686: TXMODE, freq=903900000, len=26, SF=7, BW=125, CR=4/5, IH=0
14:14:02.444 -> Packet queued
14:14:03.458 -> 75200: setupRx1 txrxFlags 00 --> 01
14:14:03.492 -> start single rx: now-rxtime: 4
14:14:03.492 -> 75331: RXMODE_SINGLE, freq=923300000, SF=7, BW=500, CR=4/5, IH=0
14:14:03.492 -> rxtimeout: entry: 76664 rxtime: 75325 entry-rxtime: 1339 now-entry: 4 rxtime-txend: 61775
14:14:04.492 -> 138172: setupRx2 txrxFlags 0x1 --> 02
14:14:04.492 -> start single rx: now-rxtime: 4
14:14:04.492 -> 138303: RXMODE_SINGLE, freq=923300000, SF=9, BW=125, CR=4/5, IH=0
14:14:04.526 -> rxtimeout: entry: 140624 rxtime: 138297 entry-rxtime: 2327 now-entry: 4 rxtime-txend: 124747
14:14:04.526 -> 140640: processRx2DnData txrxFlags 0x2 --> 00
14:14:04.526 -> 140700: processDnData_norx txrxFlags 00 --> 20
14:14:04.526 -> 140960: EV_TXCOMPLETE (includes waiting for RX windows)
14:14:04.526 -> 141269: engineUpdate, opmode=0x900

Any ideas what’s wrong?

This looks more like some AliExpress product title than the actual make and model of a board.
Start with getting the exact make (manufacturer), model and version of your board first (read the start of this topic for an impression of a subset of available boards).
The board make, model and version are essential for determining:

  • What pin mappings to use
  • If manual wiring of DIO ports is required
  • If additional code is required to get the board running (e.g. like required for TTGO T-Beam V1.0)

Also take care that the TTN LoRaWAN keys/id’s in the sketch are entered correctly and in the correct byte order. See: Format of Keys and ID's for Arduino LMIC library [HowTo]

Please read the following for how to format code and logs in your posts:
How do I format my forum post? [HowTo]



I have a heltec v1 board, they are not providing the license code so i cannot use the heltec files.
i loaded ttgo file in the heltec that worked well, i see the hello world in hex code in the ttn gateway manager.

the problem i have now is that the rssi is not showing on the display.
i use this code:

any toughts ?