Microcontroller projects

LoRa P2P with the RN2483 from Microchip

last updated: 2021-03-30

Introduction

The RN2483 from Microchip has an implemented WAN stack. So this chip is predominated to be used with LoRaWAN. But... The chip is accessed by a classical serial interface facilitating the wiring. And my hacked thermostat (HR20 from Honeywell) that I want to use with LoRa has a serial interface, so perhaps I can pimp the thermostat without even opening the housing.

To use the chip in LoRa P2P mode the WAN stack has to be deactivated. Even as it's only normal serial commands a library would made things easier. As I didn't find a library, I wrote one.

rn2483

Circuit

I will use a controller with a hardware serial interface, like an Arduino Leonardo, a Teensy 2.0, or as shown here an ESP32. So we can easily debug using Serial and use Serial1 or Serial2 for the RN2483.

Pay attention. The RN2483 works with 3 V! so level shifter are needed with Leonardo and Teensy.

LoRa chip ESP32
3.3V (Vin) 3.3V
GND GND
RX TX2
TX RX2
/RESET 25
ANT antenna

rn2483

Naturally, if we create a PCB we should use all the grounds, and add capacitors.

Use the latest firmware for your chip!

Arduino library LoRa_RN2483_p2p

Get and set the different parameter

To be able to communicate wit another chip, both chips need to be adjusted to the same communication parameter. The first sketch shows the used methods.

    /* RN2483_set_get_parameter.ino
     *
     * weigu.lu
     * RN2483 on hardware serial
     * RN2483 needs cr + lf (\r\n): println does this
     * Serial logging is Serial (0, USB)
     * we use methods log and log_ln so we are more flexible (e.g. UDP log)
     */

    #include <LoRa_RN2483_p2p.h>

    RN2483_p2p myrn;

    byte RN2483_PIN_RESET = 25; // Reset pin
    byte RN2483_SERIAL_NR = 2;  // 0: Serial, 1 Serial1, 2 Serial2

    String lora_response, lora_data;

    void setup() {
      myrn.set_serial_log(true);          // enable or disable Serial logging here
      myrn.log_ln("Hello");
      myrn.init(RN2483_SERIAL_NR, RN2483_PIN_RESET);
      myrn.factory_reset();
      delay(3000);
      myrn.init(RN2483_SERIAL_NR, RN2483_PIN_RESET);
      lora_response = myrn.get_version();
      lora_response = myrn.get_afcbw();   // get automatic frequency correction bandwidth
      lora_response = myrn.get_bitrate(); // get bitrate
      lora_response = myrn.get_bw();      // get radio bandwidth
      lora_response = myrn.get_cr();      // get coding rate
      lora_response = myrn.get_crc();     // get crc
      lora_response = myrn.get_fdev();    // get fdev
      lora_response = myrn.get_freq();    // get frequency
      lora_response = myrn.get_iqi();     // get if IQ inversion is used
      lora_response = myrn.get_mod();     // get mode
      lora_response = myrn.get_prlen();   // get prlen
      lora_response = myrn.get_pwr();     // get power
      lora_response = myrn.get_rxbw();    // get operational receive bandwidth
      lora_response = myrn.get_sf();      // get spreading factor
      lora_response = myrn.get_snr();     // set signal-to-noise ratio
      lora_response = myrn.get_sync();    // get syncbyte
      lora_response = myrn.get_wdt();     // get time-out limit for the radio Watchdog Timer
      // the following set methods are only for demonstration
      // default values are set
      myrn.set_afcbw();     // set auto freq corr bandwidth
      myrn.set_bitrate();   // set bitrate
      myrn.set_bw();        // set radio bandwidth
      myrn.set_cr();        // set coding rate
      myrn.set_crc();       // set crc
      myrn.set_fdev();      // set fdev
      myrn.set_freq();      // set frequency
      myrn.set_iqi();       // set if IQ inversion is used
      myrn.set_mod();       // set mode
      myrn.set_prlen();     // set prlen
      myrn.set_pwr("1");    // set power
      myrn.set_rxbw();      // set operational receive bandwidth
      myrn.set_sf("sf7");   // set spreading factor
      //myrn.set_sync();    // set syncbyte
      myrn.set_wdt("60000");     // set time-out limit for the radio Watchdog Timer
      myrn.log_ln("starting loop");
    }

    void loop() {
      delay(1000);
    }

Here we see the output after a RESET:

    getting ver: RN2483 1.0.5 Oct 31 2018 15:06:52
    getting afcbw: 41.7
    getting bitrate: 50000
    getting bw: 125
    getting cr: 4/5
    getting crc: on
    getting fdev: 25000
    getting freq: 868100000
    getting iqi: off
    getting mod: lora
    getting prlen: 8
    getting pwr: 1
    getting rxbw: 25
    getting sf: sf12
    getting snr: -128
    getting sync: 34
    getting wdt: 15000

If we look at the output, it is interesting to see that the chip uses channel 1 with 868100000 Hz, a spreading factor SF12 and 34 as sync word.

Simple sender

To be able to catch the data with an SX1276 chip using the LoRa lib from sandeepmistry, we need to use the same frequency (868000000 Hz), spreading factor (SF7) and sync word (12).

    /* RN2483_simple_sender.ino
    /*
     * weigu.lu
     * RN2483 on hardware serial
     * RN2483 needs cr + lf (\r\n): println does this
     * Serial logging on Serial (0, USB)
     * we use methods log and log_ln so we are more flexible (e.g. UDP log)
     */

    #include <LoRa_RN2483_p2p.h>

    RN2483_p2p myrn;

    byte RN2483_PIN_RESET = 25;       // Reset pin
    byte RN2483_SERIAL_NR = 2;        // 0: Serial, 1 Serial1, 2 Serial2

    String lora_response, lora_data;

    const byte LED_PIN = LED_BUILTIN;   // LED_BUILTIN or other pin
    bool LED_LOGIC = 0;                 // positive logic: 1, negative logic: 0
    const unsigned long NON_BLOCKING_DELAY_MS = 10000;
    const unsigned long LED_BLINK_DELAY_MS = 100;

    void setup() {
      myrn.set_serial_log(true); // enable or disable logging here
      myrn.log_ln("Hello");
      init_led();
      myrn.init(RN2483_SERIAL_NR, RN2483_PIN_RESET);
      lora_response = myrn.get_version();
      // set defaults for SX1276 (lora lib from sandeepmistry)
      myrn.set_crc("off");            // set crc
      myrn.set_freq("868000000");     // set frequency
      myrn.set_pwr("10");             // set power
      myrn.set_sf("sf7");             // set spreading factor
      myrn.set_sync("12");            // set syncbyte
      myrn.set_wdt("60000");          // set time-out limit for the radio Watchdog Timer
      myrn.log_ln("starting loop");
    }

    void loop() {
      myrn.send("Hello_from_RN2483_Nr1");
      delay(120000);
      if (non_blocking_delay(NON_BLOCKING_DELAY_MS)) {
        blink_led_x_times(3,LED_BLINK_DELAY_MS);
      }
    }

Simple receiver

To be able to catch the data with an SX1276 chip using the LoRa lib from sandeepmistry, we need to use the same frequency (868000000 Hz), spreading factor (SF7) and sync word (12).

    /* RN2483_simple_receiver.ino
    /*
     * weigu.lu
     * RN2483 on hardware serial
     * RN2483 needs cr + lf (\r\n): println does this
     * Serial logging on Serial (0, USB)
     * we use methods log and log_ln so we are more flexible (e.g. UDP log)
     */

    #include <LoRa_RN2483_p2p.h>

    RN2483_p2p myrn;

    byte RN2483_PIN_RESET = 25;       // Reset pin
    byte RN2483_SERIAL_NR = 2;        // 0: Serial, 1 Serial1, 2 Serial2

    String lora_response, lora_data;

    const byte LED_PIN = LED_BUILTIN;   // LED_BUILTIN or other pin
    bool LED_LOGIC = 0;                 // positive logic: 1, negative logic: 0
    const unsigned long NON_BLOCKING_DELAY_MS = 10000;
    const unsigned long LED_BLINK_DELAY_MS = 100;

    void setup() {
      myrn.set_serial_log(true); // enable or disable logging here
      myrn.log_ln("Hello");
      init_led();
      myrn.init(RN2483_SERIAL_NR, RN2483_PIN_RESET);
      lora_response = myrn.get_version();
      // set defaults for SX1276 (lora lib from sandeepmistry)
      myrn.set_crc("off");            // set crc
      myrn.set_freq("868000000");     // set frequency
      myrn.set_pwr("10");             // set power
      myrn.set_sf("sf7");             // set spreading factor
      myrn.set_sync("12");            // set syncbyte
      myrn.set_wdt("60000");          // set time-out limit for the radio Watchdog Timer
      myrn.log_ln("starting loop");
    }

    void loop() {
      myrn.receive(0);
      if (non_blocking_delay(NON_BLOCKING_DELAY_MS)) {
        blink_led_x_times(3,LED_BLINK_DELAY_MS);
      }
      yield();
    }

Downloads