1

I bought this shield and trying to receive LoraWAN packets in my surrounding.

ESP32 Heltec Lora

Within their SDK there is examples of receiving data for Lora, joining LoraWAN, however i am interested in seeing data in the air for LoraWAN.

Is this chip enough to be able to receive LoraWAN packets in the air? I have it running hopping frequencies since a week, and haven't seen any packet at all.

The code i am using for this is a slight modification from their ping-pong example with channel hopping in place.

#include <ESP32_LoRaWAN.h>
#include "Arduino.h"


#define RF_FREQUENCY                                868000000 // Hz

#define TX_OUTPUT_POWER                             15        // dBm

#define LORA_BANDWIDTH                              0         // [0: 125 kHz,
//  1: 250 kHz,
//  2: 500 kHz,
//  3: Reserved]
#define LORA_SPREADING_FACTOR                       12         // [SF7..SF12]
#define LORA_CODINGRATE                             1         // [1: 4/5,
//  2: 4/6,
//  3: 4/7,
//  4: 4/8]
#define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT                         0         // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON                  false
#define LORA_IQ_INVERSION_ON                        true
#define LORA_IQ_INVERSION_OFF                       false
#define LORA_FHSS_ENABLED                           false
#define LORA_CRC_ENABLED                            false
#define LORA_NB_SYMB_HOP                            0
#define RX_TIMEOUT_VALUE                            1000
#define BUFFER_SIZE                                 1024 // Define the payload size here
std::vector<uint32_t> vFrequency;

char txpacket[BUFFER_SIZE];
char rxpacket[BUFFER_SIZE];
static RadioEvents_t RadioEvents;
void OnTxDone( void );
void OnTxTimeout( void );
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );

typedef enum
{
  STATUS_LOWPOWER,
  STATUS_RX,
  STATUS_TX
} States_t;

int32_t iTimer;
int iFreq;
int16_t txNumber;
States_t state;
bool sleepMode = false;
int16_t Rssi, rxSize;

uint32_t  license[4] = {a, b, c, d};

// Add your initialization code here
void setup()
{
  Serial.begin(115200);
  while (!Serial);

  vFrequency.push_back(868000000);
  vFrequency.push_back(868100000);
  vFrequency.push_back(868300000);
  vFrequency.push_back(868500000);
  vFrequency.push_back(867100000);
  vFrequency.push_back(867300000);
  vFrequency.push_back(867500000);
  vFrequency.push_back(867700000);
  vFrequency.push_back(867900000);
  vFrequency.push_back(868800000);
  vFrequency.push_back(869525000);


  SPI.begin(SCK, MISO, MOSI, SS);
  Mcu.init(SS, RST_LoRa, DIO0, DIO1, license);

  iFreq = 0;
  txNumber = 0;
  Rssi = 0;

  RadioEvents.TxDone = OnTxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  RadioEvents.RxDone = OnRxDone;

  Radio.Init( &RadioEvents );
  Radio.SetChannel( RF_FREQUENCY );
  // set radio parameter
  Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                     LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                     LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                     LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,LORA_IQ_INVERSION_OFF, 2000000 );

  Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                     LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                     LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 
                     0, LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,LORA_IQ_INVERSION_ON, true );
  state = STATUS_TX;
}


void loop()
{
  if (millis() - iTimer > 1000)
  {

    iFreq++;
    if (iFreq > vFrequency.size() - 1)iFreq = 0;
    Radio.SetChannel( vFrequency[iFreq] );
    iTimer = millis();
  }
  switch (state)
  {
    case STATUS_TX:
      delay(1000);
      txNumber++;

      Serial.printf("Resending packet , length %d, freq %li\r\n", rxSize, vFrequency[iFreq]);

      Radio.Send( (uint8_t *)rxpacket, rxSize );
      state = STATUS_LOWPOWER;
      break;
    case STATUS_RX:
      Serial.println("into RX mode");
      Radio.Rx( 0 );
      state = STATUS_LOWPOWER;
      break;
    case STATUS_LOWPOWER:
      LoRaWAN.sleep(CLASS_C, 0);
      break;
    default:
      break;
  }
}

void OnTxDone( void )
{
  Serial.print("TX done......");
  state = STATUS_RX;
}

void OnTxTimeout( void )
{
  Radio.Sleep( );
  Serial.print("TX Timeout......");
  state = STATUS_TX;
}
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
  Rssi = rssi;
  rxSize = size;
  memcpy(rxpacket, payload, size );
  //rxpacket[size]='\0';
  Radio.Sleep( );

  Serial.printf("Packet Received: %i\r\n", rxSize);

  for (int x = 0; x < rxSize; x++)
  {
    Serial.printf("%02X ", rxpacket[x]);
  }
  Serial.println("");
  iTimer += 1000; // stay on this channel
  state = STATUS_TX;
}

1 Answer 1

1

First of all, I'm pretty sure you are aware that LoRaWAN traffic is encrypted, so you wouldn't be able to actually read much of anything of the payloads.

Depending on where you are and your setup (indoors/outdoors, antenna...) it could be quite easy to not see any LoRaWAN traffic at all. LoRaWAN can travel dozens of km with line of sight, but it can stop very suddenly indoors depending on the construction. And while some areas are quite busy with lots of devices, others are probably extremely quiet.

Even if you are in range of some other devices, most are really quiet (that's the whole idea behind battery-powered LoRaWAN devices), and would send no more than one packet a day, possibly even less. Remember that contrary to WiFi or some BLE devices for instance, there are no constant broadcast/advertisements/beacons. Devices transmit only when they actually have something to transmit.

You would also need to be listening with the right combination of frequency and data rate (SF+BW), which reduces your chances quite a bit.

Your code only changes the frequency (and listens on frequencies which are not used for real channels, so you're losing some listening time), but does not change the data rate, so you're missing a good chunk of possible traffic.

You would also have to check if the rest of the parameters (coding rate, IQ..) match those for LoRa.

In addition, it seems you're switching frequency every second or so. At SF12, many packets will take longer than a second to transmit, so you're missing those as well.

I'm not familiar with the Heltec libraries/APIs, but:

  • You would have to check if changing the frequency or other parameters does not interfere with the listening mode (i.e. if you don't need to reactivate RX after that).
  • You seem to mix low-level radio, LoRa and LoRaWAN library calls. You should probably stick to LoRa calls only using the LoRa library for instance.
  • You should probably avoid anything sleep-related.
  • You should probably try to code next to known LoRaWAN transmitters to check that you actually catch that traffic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.