How to Code for the RAK811 and Lora P2P in Arduino IDE

The RAK811 is an old friend of mine, released a little before I joined RAKwireless. I came in three versions: the stamp module, the Arduino Shield, and the XBee-style breakout. The first iterations of the Arduino shield had issues, which were corrected after I was given a couple of them, and pointed out the flaws. They have lots of pins broken out, which is why I wanted to use these not as an Arduino shield, but as an Arduino-format board. The XBee breakout has fewer pins, but is compact, and can be put on a Grove base – connected to another board via Serial – or on a USB-TLL converter board, in which case you can connect it to a computer. But I really wanted to use them as independent boards…

I was told No bro, you can’t. Which I took with a smile, but not very kindly. Turns out, back then it was indeed impossible – you had to use Keil. No fankyee. But then came the Arduino_Core_STM32 by STM32duino. It has a LOT of STM32 MCUs enabled, including the STM32L151CB-A (don’t ask) powering the RAK811. So suddenly a world of possibilities emerged.

Once you have the Arduino BSP installed, there are only a couple of gotchas to be able to code the RAK811 as a standalone board.

Turn it on!

Sounds dumb but, yes, you need to turn on the SX1276 inside the RAK811.

  // https://github.com/stm32duino/wiki/wiki/lora
  pinMode(RADIO_XTAL_EN, OUTPUT); //Power LoRa module
  digitalWrite(RADIO_XTAL_EN, HIGH);

The RADIO_XTAL_EN define is in the variant file for the RAK811. You don’t need to define it, not the others that appear below.

Listen or Send

There is another switch that controls sending and receiving. I wrote two short functions that do this for you.

void listenMode() {
  pinMode(RADIO_RF_CRX_RX, OUTPUT);
  digitalWrite(RADIO_RF_CRX_RX, HIGH); // set LoRa to receive
  pinMode(RADIO_RF_CTX_PA, OUTPUT);
  digitalWrite(RADIO_RF_CTX_PA, LOW);
  LoRa.writeRegister(REG_LNA, 0x23); // TURN ON LNA FOR RECEIVE
  LoRa.receive();
}

void sendMode() {
  pinMode(RADIO_RF_CRX_RX, OUTPUT);
  digitalWrite(RADIO_RF_CRX_RX, LOW); // set LoRa to send
  pinMode(RADIO_RF_CTX_PA, OUTPUT);
  digitalWrite(RADIO_RF_CTX_PA, HIGH); // control LoRa by PA_BOOST
  LoRa.writeRegister(REG_LNA, 00); // TURN OFF LNA FOR TRANSMIT
}

Call listenMode() at the end of setup(), and when you are done sending. Call sendMode() before sending. That’s about it.

The pins

The pins required for the LoRa library are:

  // https://github.com/RAKWireless/RAK811_LoRaWAN_Arduino
  LoRa.setPins(RADIO_NSS, RADIO_RESET, RADIO_DIO_0);

Again these are pre-defined. For other libraries that require more pins, like LMIC, the full set is:

  // nss = 26 - aka RADIO_NSS PB0
  // rxtx = 32 - aka RADIO_RF_CRX_RX PB6
  // rst = 21 - aka RADIO_RESET PB13
  // PA BOOST = 34 - AKA RADIO_RF_CTX_PA PA4
  // dio0/1/2 = 27, 28, 29
  //  RADIO_DIO_0 PA11 27
  //  RADIO_DIO_1 PB1 28
  //  RADIO_DIO_2 PA3 29
  //  RADIO_DIO_3 PH0 30
  //  RADIO_DIO_4 PC13 31

With this you can run most examples of the LoRa lib without issues.

Uploading the Code

The easiest is via JLink. Connect wires to the TMS (SWDIO), CLK (SDCLK), RST, Vcc and GND pins. In JFlash Lite, choose STM32L151CB-A for the MCU. Select the .hex file produced by Arduino IDE during compilation – I use a small app I made for Mac OS X, but you can pick up the file system path in the logs. Click on Program Device.

JFlash Lite

JLink pinout

Arduino Shield

I actually DON’T connect the Vcc pin on the Arduino Shield RAK811, as I keep the USB cable connected. So I can upload and see right away what’s happening. Try and avoid to connect two power sources at the same time. It has a tendency to make the device sweat…

As you can see here I am using I2C to drive an OLED.

XBee Breakout

On the XBee breakout I need to do a little more gymnastics.

The 2 bottom-right pins, below SWDIO & SWCLK, are the same pins I use for I2C above.

THEN I can put it back on its base board…

One of the most convenient baseboards have found so far…

I2C

Doesn’t work readily on either model, BUT I managed to make it work, a little, with the BitBang_I2C library, as shown above: the Arduino shield is running demo code from the ss_oled library (which uses BitBang_I2C, same guy). I needed to find two available pins, and went with PA0 and PA1, which are available on both the Arduino Shield (P5 male headers) and the XBee (bottom right).

The BitBang_I2C library is a bit rudimentary, so you won’t be able to do as much as with the regular Wire library, and mimicking its features probably requires more work than I am willing to do, but I’ll poke around. Creating a TwoWire object with the PA0/PA1 pins doesn’t work either.

On the XBee

There are quite a few pins available.

On the Arduino Shield

I2C1 SDA/SCL didn’t work for me, but PA0/1 did…

Posted

in

, ,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *