Big ESP32 / SX127x topic part 1

They sent me the Github project for the firmware

No schematic but you can at least find the pinout in the source code

// GPIO5  -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)

#define SS      18
#define RST     14
#define DI0     26

The Arduino project only does raw LoRa, not LoRaWAN. I’ll try to port Pycom code to it, hopefully should get somewhere this week still.

Very good. I would really like to know if they connected DIO1
I think that LMiC v1.6 requires both DIO0 and DIO1

1 Like

I think LoRa-node used in the Pycom fw only uses DI0.

I also found this patch by @Charles that supposedly lets you run without any DIOs at all?

1 Like

Thanks, I will go try. Using LMiC V1.5, setting DIO0 and DIO1 to the same physical pin allows the node to JOIN OTAA, but hangs there and does not pass through to JOINED or send any packets.

const lmic_pinmap lmic_pins = {
    .nss = 18,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 14,
    .dio = {26, 26, LMIC_UNUSED_PIN},

I believe in the unchanged code DIO0 is triggered on TX and DIO1 on RX so the code may be missing the OTAA response (a RX) if you set it like that.

Does ABP work?

I will go back and try ABP. I have applied the patch you linked, to my local library, but I still get no further than EV_JOINING. I added the following to radio.c

// called by hal to check if we got one IRQ
u1_t radio_has_irq (void) {
    u1_t flags ;
    if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
        flags = readReg(LORARegIrqFlags);
            return 1;
    } else { // FSK modem
        flags = readReg(FSKRegIrqFlags2);
            return 1;
        flags = readReg(FSKRegIrqFlags1);
        if ( flags & IRQ_FSK1_TIMEOUT_MASK ) 
            return 1;
    return 0;

added declaration in oslmic.h

u1_t radio_has_irq (void);

changed this routine in hal.c

static void hal_io_check() {
    uint8_t i;
    for (i = 0; i < NUM_DIO; ++i) {
        if (lmic_pins.dio[i] == LMIC_UNUSED_PIN)
            // Check IRQ flags in radio module
            if ( radio_has_irq() ) 

            // We've soft checked IRQ reading Radio register no need to continue
            // Setting this will exit us from for loop
            i = NUM_DIO;
        } else {
            if (dio_states[i] != digitalRead(lmic_pins.dio[i])) {
                dio_states[i] = !dio_states[i];
                if (dio_states[i])

and commented out these two lines in hal_io_init

//ASSERT(lmic_pins.dio[0] != LMIC_UNUSED_PIN);
//ASSERT(lmic_pins.dio[1] != LMIC_UNUSED_PIN || lmic_pins.dio[2] != LMIC_UNUSED_PIN);

This all made sense tom me :slight_smile:

1 Like

Update - OTAA works with the fix as described - it just started working while I wrote my last comment :slight_smile:


lora… not lorawan :wink:



any idea what the currentdraw is ?

Current draw shows 0.07A running the default LMiC ttn-otaa sketch with code added to use the OLED display.
So far, I have done nothing to reduce power consumption.
Next steps are to move from Arduino framework to IDF with PlatformIO and then I will look to actively disable WiFi and BLE

ok tnx… 70 Ma is indeed a lot … need to trim that, maybe switch off the OLED when not needed…

@nicbkw Let’s discuss about some explanation on LMIC.

The way LMIC is coded is to check (in loop) for a pin change (software does not support IRQ yet) on each declared .dio pin. Then, if one pin has changed, stack is reading software IRQ register of RFM95. Reading RFM95 IRQ internal register will expose all IRQ available (so all DIO0 … DIO5).
That is why I created my “No DIO” patch (and also because I didn’t had any free I/O). this patch read this register and can work without any DIO pin connected, the con is that on each loop, we do SPI transfer to read IRQ register. It’s not fulltime task but it’s done only during LMIC transmission (send and receive) so it’s not so bad, and works !!!

So if you are using only one DIO pin connected this will do twice the check on same pin

        .dio = {26, 26, LMIC_UNUSED_PIN},

so you can leave as follow (same result)

        .dio = {26, LMIC_UNUSED_PIN, LMIC_UNUSED_PIN},

Another solution is to OR each DIO pins with diodes to trigger a IRQ on any DIO change (once again this is possible only because LMIC read RFM95 IRQ register on any DIO change. And since they are OR’ed, one will be enough.

Hope this bring some clarification :wink:

PS : has @jmarcelino will have excellent relationship with pycom, may be he could tell us how DIO are connected on Lopy? We can also open Lopy to see or look into micorpython stack code !


ESP32 is very versatile, has a sophisticated watchdog, but might not be ideal as a very low power data logger.

Of course, this video assumes comms over WiFi…

Thanks very much for this explanation - I was very pleased when @jmarcelino pointed me to your single interrupt polled solution as it works!

Low power and WiFi are not best friends.
Anyway without schematic it’s difficult to know what was consumming. May be his BME280 has 3V3/5V poor regulator conversion (has many) and adding quiescent current :wink:
Would be interesting having current consumption in deep sleep mode

I think he could have tweaked things a little bit.

Even without disabling it, reducing WiFi transmit power would help, the default ( 20 dBm IIRC) causes that sort draw - if you try to do LoRa @ 20 dBm on the SX127x it’s similar.

Also you can lower core clock speed etc. There are many tweaks, and that’s not even involving the ULP which he probably could use for his I2C sensor.

1 Like

Pycom’s LoPy uses the SX1272 chip rather than the SX1276 used in this device. A few months ago, I was able to implement a single channel gateway on the ESP32 and with the RFM95W LoRa Module by porting Pycom’s code for their Lopy, inserting libraries for the SX1276 and modifying the code to achieve this. If interested, the source code is available from github here

The pinouts are hard coded in the pycom firmware code but you can make changes. On the Lopy RADIO_DIO is connected to GPIO23. You will need to change this to GPIO26 to match this device. All other connections are same. The LoPy firmware does not use a reset for ESP32 chip revision > 0. My port was for chip revision > 0. Pin connections for chipset = 0 is different.

I implemented a single channel gateway using the pycom script for that as available here

ABP works but OTAA didnt seem to work. I haven’t been able to sort that out. Hope someone will be able to.

Do give it a try.


HELTEC HTIT-WB32LA 868-915 MHz board

I just received the board.
After examining the PCB I found that the following DIO ports are wired:
(pin numbers are chip pin numbers)

SX1276 (pin) – ESP32 (pin)
DIO0 (8)GPIO26 (15)
DIO1 (9)GPIO33 (13)
DIO2 (10)GPIO32 (12)

Hope this helps.


If you want to use those USB power banks, be aware that they can reate a fair bit of EMI, take a read of this;