Using the BSFrance Lora32U4 board to connect to the Things Network Lorawan

The BSFrance Lora32u4 II (Lora32U4II for helping Google out) board is an Atmega32U4 processor with a HDP13 Lora transceiver on the same board. As far as I’m aware, the HDP13 is similar to the RFM95W (including pinout), and in my case it seems it has an original Semtech SX1276 (868Mhz radio transceiver) chip installed on the HDP13 module. This board is similar to the Adafruit 32U4 Lora feather, if not equal… (possible schematics for the Lora32u4 board)

The board hardware includes beside the Lora HDP13 module a LiPo connector with an 2 pin JST PH 2.0mm pin spacing connector and the power supporting electronics.
There are two leds, on orange for LiPo and charger status, that blinks very fast when no LiPo is connected, and a very bright white led that fades in and out when the bootloader is in the programming mode or programming is ongoing. After the bootloader exists and starts the main program, the led shuts off.
This led, as usual in Arduino boards is connected to I/O pin 13, so it is software controllable.

Also the only way to power up the board is either trough the USB port, LiPo battery or 5V to an input pin. No other voltages, like RAW voltages above 5V are supported.

As a final note, the board that I’ve bought also came with an uFL adapter cable for SMA, an antenna and a link for accessing documentation, so, excluding the LiPo battery, the complete kit.

Starting up using the board:

I’m testing the board to send data to the Things Network and doing so by using PlatformioIO as the developing IDE. Platformio IDE is much better than the Arduino IDE, since each project has it’s own depending libraries directory .piolibdeps which we can modify and edit the library code without breaking other projects.

The platformio.ini board definition for the Lora32u4II board is just a clone of Adafruit feather 32u4:

[env:feather32u4]
platform = atmelavr
board = feather32u4
framework = arduino

As the code to send data to the TTN network, I’ve just used ABP lorawan device connection that I’ve used on my previous hand build node.

I’m testing the node with both the IBM LMIC Library (ID: 852) and the Arduino LMIC Library (ID: 1729).

After setting the correct keys and device ID, all we need is to change the LMIC pins configuration for this board: LoRa32u4II pinout diagram

According to documentation the pins are:

  1. nss (SS – Chip Select): Pin 8
  2. rst (Reset): Pin 4
  3. DIO (Lora TX/RX indicator): Pin 7

So the Lmic Pins configuration is:

const lmic_pinmap lmic_pins = {
    .nss = 8,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 4,
    .dio = {7, 6 , LMIC_UNUSED_PIN}
};

Regarding Pin 6, is the chosen pin to connect to the DIO1 pin. This pin signals receive timeouts generated by the radio module. The connection of this pin is required for LMIC and for the onEvent() function signaling of EV_TXCOMPLETE to be triggered/fired, otherwise the onEvent() funciton is never called.
Since this is a LoraWan Class A node, after the transmission, two receive windows are opened for any downlink data that might be sent to the node. The DIO1 pin signals the receive timeout, and at the end of the receive windows, triggers the EV_TXCOMPLETE event. I’ve tried to use other pins, for example, pin 3, but then the EV_TXCOMPLETE event was never fired… Strange. Anyway, with the above configuration and with DIO1 connected through a wire bridge to pin 6 works fine.

If we do not connect DIO1 by removing the DIO1 pin configuration:

 .dio = {7, LMIC_UNUSED_PIN , LMIC_UNUSED_PIN}

with the platformio IBM Lmic library (Id: 852), or with the Arduino LMIC Library the LMIC fails. An example:

pio device monitor --port /dev/ttyACM0 --baud 115200
[cortex@brightlight:TTN32u4ABP]$ pio device monitor --port /dev/ttyACM0 --baud 115200
--- Miniterm on /dev/ttyACM0  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Starting...
FAILURE
.piolibdeps/IBM LMIC framework_ID852/src/hal/hal.cpp:24

The line hal.cpp:24 point to an ASSERT that doesn’t allow a LMIC_UNUSED_PIN for DIO1.

Putting pin 6 and making sure that it is connected to DI1 is required. Otherwise if the pin is defined but not connected we have the following behaviour:

--- Miniterm on /dev/ttyACM0  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Starting...
Sending uplink packet...

As we can see the EV_TXCOMPLETE event is never fired, and the associated reschedule of another transmission never happens, since that code is inside the code for the EV_TXCOMPLETE event. The only way, in this case, is to reset the board so another transmission happens.

So if using the above LMIC pins configuration and connecting DIO1 to pin 6, sending data to the The Things Network works just fine:

Data received at the TTN side

Some final notes, tips and tricks:

The ATMega 32U4 USB Serial port:
The ATMega 32U4 USB serial port is a bit fiddly when using it from the Arduino framework. At reset or connection first the USB port is used by the bootloader (white led fading in and out). After a while the board starts to execute the flash program (white led off), but it resets the USB port. The host computer might have an issue with this and fails to assign an USB address.

The solution is just to add at the start of the setup function a delay:

void setup() {
  delay(2500);   // Give time to the ATMega32u4 port to wake up and be recognized by the OS.
  
  Serial.begin(115200);
...
...

Using minicom instead of PlatformIO serial monitor:
This one is quite simple to explain, since minicom survives to the USB port resets since they appear and disappear through the board reset.
Against it, is that we need to explicitly exit minicom to be able to program the board.

# minicom -D /dev/ttyACM0 -b 115200

The PlatformIO Arduino LMIC library is outdated:
The Arduino LMIC version (1729) on the PlatformIO is outdated, since, for example doesn’t have neither the LMIC_UNUSED_PIN definition and the LMIC_setClockError function needed for a successful OTAA TTN network join.

The solution is just clone the Arduino LMIC library and copy the src folder to .piolibdeps/IBM LMIC framework_ID852/ removing the original src folder version.

Comparing Library sizes:

Using the IBM LMIC Library (ID:852) with PINGS and BEACONS disabled on the config.h file, otherwise it doesn’t fit on the 32u4 32K flash space, our sketch uses the following space:

AVR Memory Usage
----------------
Device: atmega32u4

Program:   26040 bytes (79.5% Full)
(.text + .data + .bootloader)

Data:       1014 bytes (39.6% Full)
(.data + .bss + .noinit)

Using the Arduino LMIC library (ID: 1729) with PINGS and BEACONS enabled, but a more efficient AES implementation, we get:

AVR Memory Usage
----------------
Device: atmega32u4

Program:   22776 bytes (69.5% Full)
(.text + .data + .bootloader)

Data:        954 bytes (37.3% Full)
(.data + .bss + .noinit)

With PINGS and BEACONS disabled we get:

AVR Memory Usage
----------------
Device: atmega32u4

Program:   19032 bytes (58.1% Full)
(.text + .data + .bootloader)

Data:        903 bytes (35.3% Full)
(.data + .bss + .noinit)

So we get, with this last change, and while keeping support for OTTA, at least 8K/9K for program space not related to the Lorawan/TTN code support.

Advertisements

TTN LoraWan Atmega32U4 based node – ABP version

TTN is the The Things Network provides the needed backend services and infra-structure for supporting IoT (Internet of Things) connectivity that uses the LORAWAN protocol.
Anybody can participate by either providing the radio gateways that feed the received data to the TTN backend that then delivers it to the user applications, and so increasing the coverage of the TTN network, or just use the network by building TTN Lorawan nodes.

This post is regarding the later case, the build of a simple node based on an Arduino board: the Arduino Micro Pro. So why the Micro PRO, these are quite more expensive than the normal Arduinos, but come in two versions: 5V and 3.3V. Since the Lora radio works with 3.3V, I’ve chosen the 3.3V version so that I do needed to use level shifters from a 5V based board. At least was what I thought a few months ago. Anyway, the Micro PRO chip, the Atmega32u4 has embedded USB connectivity, so no need for serial adapters and boards which might lead to lower power consumption.

At least right now, on sites like eBay and Aliexpress, boards like the Lora32u4 come at least in two versions: with the Atmega328p and with the Atmega32u4. Both suffer the same problem, they Atmel uProcessor used only has 32K of RAM which might be too short to be used for some applications since the Lorawan stack takes a huge amount of space. We will see about that. The great advantage of these boards is they also have connection and charger for a LiPo battery, so in reality all we need is to add sensors, battery and our code.

The node build:
While I’m waiting for my Atmega32U4 based Lora32u4 board, I’m using an Hoperf RFM95 radio soldered on board/shield designed for the Wemos ESP8266: Wemos RFM95 Lora shield. this way I can use the RFM radio either on the ESP8266 Wemos based set of boards, or, as in this case, with the Arduino 32u4.

The Hallard shield as one interesting feature that is that merges all the Lora transceiver status pins by using diodes and hence only use on Arduino pin for inquiring that status. this is due to the lack of pins on the Wemos ESP8266 board. For this to work, we need to add a pull-down resistor to the Arduino pin that connects to the merged output. In my case I used a 10K resistor.
The RFM95 radio is controlled using SPI, so we need to use also the SPI Arduino Pins, and also need to connect the Chip Select pin.
The schematics is as follows:

Arduino Pro Micro and RFM95 Wemos Shield

The node software:
After the node hardware build is done, from the software perspective the node needs now at least another two things: the LMIC stack for implementing the Lorawan protocol support over the Lora radio and, at the TTN site, the device configuration.

Since I’m using Platformio to develop, the LMIC library is the library 852: pio lib show 852. We need to install it and add the reference to it on the file platformio.ini. Also since there is no ATMega 32U4 board on the Platformio IDE available boards, we can use the Adafruit Feather 32u4 board, which is the same thing:

[env:feather32u4]
platform = atmelavr
board = feather32u4
framework = arduino
lib_install= 852

The device registration can be done so that the node device access the TTN network in two different ways:

  1. ABP – Activation by personalisation – This means that all set of keys required to join the Lorawan network are embedded into the software.
  2. OTAA – Over the Air Activation – The network session keys needed to join the Lorawan network are generated when the device tries to join the network.

On this post we will ABP first, since I have no nearby TTN gateway capable o OTTA (I’m using a single channel gateway without downlink support.).

Anyway, the node code is really nothing special, except the necessary configuration for the LMIC to communicate with our RFM95 board.

On the ABP device registration TTN page we need to register our device, so that, on main.cpp code file we can fill the required keys and device ID.

As a quick introduction, after registering onto the TTN site, we go to the console and choose Applications. We can there create or reuse an existing application and register the device, making sure we choose ABP as the method to join the network.

On the Device EUI field, either we fill it or press the crossing arrows to generate an ID. We let the system generate an ID, and then we can finally press the Register button.

The newly register device is configured as an OTAA device:

So we go to Settings and change the OTAA to ABP. After this step we have the required data to put on our code.

Since our node doesn’t have any memory to track frame counting that survives reboots or power cycles, we disable the frame counter checks.

Don’t forget to press save. Again on the main device screen we can now copy the keys to the code:

We can now copy the keys:

static u1_t NWKSKEY[16] = { 0xEE, ... ... ... ... }; // <- Put here the NETWORK KEY
static u1_t APPSKEY[16] = { 0x4E, 0x12, ... ... ... ... };  // <- Put here the APPLICATION KEY
static u4_t DEVADDR = 0x26304050;   // Put here the device id in hexadecimal form.

Testing:

Compiling the code with the pio run command, we have the following output:

Calculating size .pioenvs/feather32u4/firmware.elf
AVR Memory Usage
----------------
Device: atmega32u4

Program:   28542 bytes (87.1% Full)
(.text + .data + .bootloader)

Data:        957 bytes (37.4% Full)
(.data + .bss + .noinit)

And we can flash the firmware with the command: pio run -t upload.

The result is data on the TTN console referring to our device:

The problem… :
So, everything runs OK, and we can send data to the TTN Network, everything looks good, right?

As soon we start to add functionality to our code, for example reading some I2C sensors, our some serial debug messages, we hit this problem:

Linking .pioenvs/feather32u4/firmware.elf
Checking program size
text       data     bss     dec     hex filename
Error: The program size (28756 bytes) is greater than maximum allowed (28672 bytes)
28548       208     749   29505    7341 .pioenvs/feather32u4/firmware.elf
*** [.pioenvs/feather32u4/firmware.elf] Explicit exit, status 1

So in reality we can’t add much functionality to our code if using a full LMIC stack, since it occupies a lot of the available flash memory.

Trimming down the LMIC stack:
Since our node is ABP only we can strip out some LMIC functionality for OTAA an other Lorawan features. For this we need to edit the config.h file from the LMIC library. Since we are using platformio, this file is located at project_root/.piolibdeps/IBM LMIC framework_ID852/src/lmic

We only leave support for ABP by enabling the disable lines for other LMIC functionality:

...
...
// Any runtime assertion failures are printed to this serial port (or
// any other Print object). If this is unset, any failures just silently
// halt execution.
#define LMIC_FAILURE_TO Serial

// Uncomment this to disable all code related to joining
#define DISABLE_JOIN
// Uncomment this to disable all code related to ping
#define DISABLE_PING
// Uncomment this to disable all code related to beacon tracking.
// Requires ping to be disabled too
#define DISABLE_BEACONS

// Uncomment these to disable the corresponding MAC commands.
// Class A
//#define DISABLE_MCMD_DCAP_REQ // duty cycle cap
//#define DISABLE_MCMD_DN2P_SET // 2nd DN window param
//#define DISABLE_MCMD_SNCH_REQ // set new channel
// Class B
#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING
#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatical disabled by DISABLE_BEACON

By uncommenting the above lines, our code now takes (we can and should ignore the LMIC compile warnings):

AVR Memory Usage
----------------
Device: atmega32u4

Program:   23324 bytes (71.2% Full)
(.text + .data + .bootloader)

Data:        796 bytes (31.1% Full)
(.data + .bss + .noinit)

So around 5KB less without the OTAA and Class B support.

So we have a bit more memory to do something useful.

Enabling OTAA by commenting the line //#define DISABLE_JOIN:

AVR Memory Usage
----------------
Device: atmega32u4

Program:   25048 bytes (76.4% Full)
(.text + .data + .bootloader)

Data:        912 bytes (35.6% Full)
(.data + .bss + .noinit)

We still have around 3K free. Tight but might be enough.

Conclusion:
The availability of boards with the AtMega32u4 processor, Lora Radio and LiPo charge and battery connectivity, is a great step to start using the TTN (or other) Lorawan networks. But with only with 32K or flash memory, for some applications, these boards might not be the best solution.
Also the price for such boards are still a bit on the expensive side, since a discrete 32u4 + RFM95 + Lipo charger is a bit cheaper than the single board solution.
Anyway, the STM32F103 blue pill boards, cost half of the 32U4 price and have double the flash size and 9x the clock, so it would be great that such single boards, instead of the 328p or 32u4 used the STM32F103…
So my conclusion is, without power considerations taken into account, a STM32F103 + RFM95 and LiPo charger, is a better alternative than the one that I’ve used here.

LPWAN – Starting up with LoraWAN and The Things Network

LPWAN Networks – A simple introduction
Low Power Wide Area Communications (LPWAN) classifies a group of communication protocols featuring low power usage and a high communication range. For Internet of Things communications, where battery powered devices and constrained devices (weak CPU, low RAM/ROM) are the norm, LPWAN use as the communication protocol for IoT makes sense, since it makes possible to have standalone devices with batteries that last years, instead of hours or days, and might be hundreds of meters to Kms away from a base station/gateway.

But LPWAN protocols, in contrast have low communication bandwidth, since from power, range and bandwidth, we can only have two of those, and while this might be a problem for certain applications, IoT devices don’t require high bandwidth and since most have sparse communication requirements, and when they do communicate they don’t need to transmit a lot of data.

Starting up with LoraWan and The Things Network
One of the possible ways of starting to use LPWAN networks in our IoT devices, is to use a LPWAN protocol named LoraWan, which is based on the Lora physical protocol, and if available at our area, the crowd sourced LPWAN network The Things Network as the backend network for receiving data.

Lora uses the 868Mhz ISM radio band and it uses a form of signal transmission called CSS. The ISM radio band can be used freely by everybody, but under certain rules that depends of the country where the devices are located. So to use that band, rules like maximum emission power and duty cycle (usage of the available spectrum) are defined, and in Europe, the maximum power is 20mW and 1% duty cycle per day. Additionally the back end operator can add other restrictions.

Over Lora, the Lorawan protocol is an open standard and source code for implementing it is available and already ported to several devices, including the Arduino, Raspberry PI and the ESP8266, among others.

The software for implementing the LoraWan protocol at the end devices (nodes) is IBM’s LMIC library, available at Github and on Platformio libs:

[ ID  ] Name             Compatibility         "Authors": Description
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[ 852 ] IBM LMIC framework arduino, atmelavr, atmelsam, espressif8266, intel_arc32, microchippic32, nordicnrf51, teensy, timsp430 "IBM, Matthijs Kooijman": Arduino port of the LMIC (LoraWAN-in-C, formerly LoraMAC-in-C) framework provided by IBM. | @1.5.0+arduino-1

Based on this library we can build code and nodes that are able to transmit data through LoraWan to a network backend. Specifically for the Arduino, the Atmega328 is the bare minimum to begin with, since the library, due to use of AES encryption functions occupies a lot of memory.

The backend can be provided by really anyone, including Telco operators, or private and crowd source operators like The Things Network (TTN). TTN provides the backend and management services, but depends on crowd sourced gateways, and might not be available at our area. Still it is possible, for testing, to build our own gateways, our buy them, and connect them to the Things Network. TTN doesn’t require any access fees (yet).

So with LoraWan an the Things Network, we can build our own nodes and gateways since code and hardware can be easily obtained, connect them and use it to build applications.

Regarding LoraWan we can also read this great introduction from Design Spark.

Lora hardware:

Anyway the easiest way for starting up using Lora and Lorawan, is to buy an Dragino Lora Shield and connect it to an Arduino Uno or Mega.

Dragino Lora Shield

Dragino Lora Shield

This is a great shield to startup since doesn’t need any soldering or complex configuration, just plug it on an Arduino shield and use the LMIC library and some code samples. Also the Dragino Shield can be used to build a simple gateway by connecting it to a Raspberry PI or ESP8266 to build what is called a single channel gateway, that allows to test gateway functionality, but it isn’t quite compatible with the LoraWan specifications. Anyway it gets the job done if there is no gateway nearby. Just make sure that you by version 1.3 or 1.4 of the shield. Mine also came with an SMA antenna.

Other alternatives to start using Lorawan are available at eBay/Aliexpress and other renowned name shops, namely Lora radio transceivers at around 8/16€, for example the HopeRF RFM95. Those we can also use them with Arduino or ESP8266 to build our nodes or single channel gateways.

Just make sure that the frequency for these modules and shields must match the allowed radio transmission frequency in your area. In my case, in Europe is 868Mhz, but for example at USA is 900Mhz.

Dragino Lora Shield Jumpers
The Shield has some jumpers and only looking at the schematic and cross referenced them with the RFM95 module (used by the shield as the Lora transceiver) I could see what they where for:

– There are two set of jumpers:

  • One defines the pins for SPI communication: SV# Jumpers;
  • The other set defines which data pins of the RFM95 module are exposed to the shield allowing them to be connected to the Arduino: JP# Jumpers.

The JP# jumpers connect the following if closed:

  • JP1 – RFM95 DI1 – Arduino pin D6
  • JP2 – RFM95 DI2 – Arduino pin D7
  • JP3 – RFM95 DI5 – Arduino pin D8

The RFM95 pin DI0 is permanently connected to Arduino pin D2.
The RFM95 pin RST (Reset) is permanently connected to Arduino pin D9.

Their function for Lora might be the following (The function depends how the RFM95 module is used)

  • RFM95 DI0 – Indicates if data was received and is ready to be read through the SPI bus. Indicates end of transmission for data that was previously sent: RXReady/TXReady
  • RFM95 DI1 – Receive timeout for Lora mode.
  • RFM95 DI2 – Receive timeout for FSK mode.
  • RFM95 DI5 – Used by Semtech Library. LMIC library doesn’t use it.

The SV# jumpers connect:

  • SV2 – SPI Clock line. Default on pin D13, otherwise on Arduino SPI CLK on the ICSP header.
  • SV3 – SPI Data line In (MOSI). Default on pin D11, otherwise on Arduino MOSI pin on the ICSP header.
  • SV4 – SPI Data line Out (MISO). Default on pin D12, otherwise on Arduino MISO pin on the ICSP header.

The SPI Chip Select line is always at pin D10.

So now we know that D10, D9 and D2 are used permanently connected and used by the shield, and the others can be connected or disconnected if needed or not.

LMIC software with Dragino Lora Shield:

To start using the Dragino Lora Shield so it connects to a LPWAN network, we can start using the following example: TTN node by ABP. ABP means Activation by Personalization, which means that all data for joining the network will be explicitly defined on the code. Other alternative would be OTAA: Over the air activation, where the gateway sends the configuration data to the node. Since we don’t know if we have a gateway in range, let’s start first with ABP mode.

The above code uses the LMIC library for implementing the LoraWan stack.
Since LMIC library doesn’t use DI05, we can remove the JP3 jumper, and free this IO line for other things, like another shield.

To use the LMIC library we must define first the pins that are used according to the shield configuration:

// Pin mapping
const lmic_pinmap lmic_pins = {
    .nss = 10,                   //Chip Select pin. In our case it is always D10.
    .rxtx = LMIC_UNUSED_PIN,     //Antenna selection pin: not used in our case.
    .rst = 9,                    //Reset pin used to reset the RFM95: D9
    .dio = {2, 6, 7}             //DIO pin mapping for DIO0, DIO1 and DIO2  
};

But DIO2 pin is only used for FSK modulation, and so if only using LoraWan we can also open up the JP2 jumper, and our LMIC pin configuration can be as follows:

// Pin mapping
const lmic_pinmap lmic_pins = {
    .nss = 10,                   //Chip Select pin. In our case it is always D10.
    .rxtx = LMIC_UNUSED_PIN,     //Antenna selection pin: not used in our case.
    .rst = 9,                    //Reset pin used to reset the RFM95: D9
    .dio = {2, 6, LMIC_UNUSED_PIN} //DIO pin mapping for DIO0, DIO1. DIO2 is not used  
};

Connecting to TTN
Connecting to The Things Network (TTN) depends of course of an available TTN gateway at the nodes range. Still we need to configure some parameters to allow the node to connect.

On this example the connection is done through Activation by Personalization. This means that we should put on our code the Network Session key and Application Session key on the code. To obtain these values we need to register on the TTN site, TTN Dashboard and add an ABP device..

From this site, then we can get the three configuration parameters that we need:

  • Device ID
  • Network Session key
  • Application Session key

Note by pressing the icon we can get the values in a form ready to paste it on the code:

/*************************************
 * TODO: Change the following keys
 * NwkSKey: network session key, AppSKey: application session key, and DevAddr: end-device address
 *************************************/
static u1_t NWKSKEY[16] = { 0xAA, 0x0F, 0x29, 0xD3, 0x9D, 0x7A, 0xAE, 0x3B, 0x54, 0xCF, 0xDF, 0x2F, 0x2A, 0x23, 0x55, 0xB5 };
static u1_t APPSKEY[16] = { 0x2F, 0x85, 0x43, 0x5B, 0x34, 0x9C, 0x80, 0xC6, 0xA8, 0xFA, 0x27, 0x49, 0x5A, 0x36, 0x82, 0x21 };
static u4_t DEVADDR = 0x95337738;

And that’s it, when running the sketch, and if in range of a gateway, the sent message should appear at the Dashboard:

Messages received for the device

Messages received for the device

Final thoughts:
In my area there are at least, supposedly, two active TTN gateways and I’m around 2Km’s away from them in a dense urban area.
But when running the sketch the first times, I had no results what so ever.

One of the configurations options for LoraWan is what is called a Spread Factor that, in a simplest way, exchanges range with on-air time for transmission, being SF7 the fastest speed and shorter range and SF12 the slowest speed and higher range. The sketch default value for the sprea factor was SF7, and changing it to SF12:

 ...
    // TTN uses SF9 for its RX2 window.
    LMIC.dn2Dr = DR_SF9;

    // Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
    LMIC_setDrTxpow( DR_SF12 ,14);

    // Start job
    do_send(&sendjob);

With SF12 the message started be received and the sequence numbers of the messages received where continuous, so no lost messages.

Dropping to SF11, also worked fine, and the message sequence received and shown on the TTN Dashboard where still continuous.

At SF10, some of the messages where lost, almost 75% of them. In this case, arranging the antenna position (to exactly vertical) and placement did alter the reception successes.

Processing received data
After the data is at the TTN backend there are several ways of getting it. For reference on the TTN site there are instructions in how to access the data.

Crash course on Lora
For further information the next one hour video is a great starting point:

The slides for the presentation are available here:

https://www.dropbox.com/s/87htha4dq5b32wa/ttn-lora-crash-course.pdf?dl=0

Communication over 433Mhz links

I’ve bought, about a year ago, maybe more, some 433Mhz transmitter and receivers , so I could build a mailbox monitoring solution, loosely based on LOFI Project. The base idea was when someone put something in my mailbox I was notified. Anyway, the ESP8266 came along, and after some experiments, there is no way that the ESP8266 can be used for implementing the monitoring mailbox project I was thinking due to power consumption but mainly because the high distance across several floors and walls between the mailbox and my access point. So back to basics and to the original simpler idea of using plain 433Mhz link for transmitting data.

I’ve started to do some experiments using these devices:

eBay 433Mhz RX TX

All I can say about these is while the transmitter is ok and works fine across floors and walls (I can see the signal clearly using my SDR), the receiver is absolute garbage and useless for the intended purpose.

The receiver is only able to receive in line of sight with the emitter when there are no obstacles, and even in this scenario with both emitter an receiver with attached antennas, the maximum distance between the emitter and the receiver is 4/5 meters at maximum.

The solution is to use the much better and higher cost RXB8 receiver that has according to the datasheet -114dBm sensitivity, but it does work and is very good.

rxb8

The code for interfacing with this receiver is the same code that works with the cheaper receiver and is the Arduino Manchester encoding library.

Using the RXB8 with an attached 433Mhz antenna (I’m using an antena with 5dBi and a SMA connector), the results are simply superior, with the end result that the signal/messages when the emitter is located several floors down and across several walls, are received correctly and are able to be decoded by the Arduino.

Anyway, one of the interesting things on the LOFI project is/was the Hamming Error Correction implementation found here in the RobotRoom blog.

So I’ve forked the original mchr3k Arduino Manchester encoding library and added the Hamming Code Error correction support: Arduino Manchester encoding library with Hamming EC support.

The usage is quite simple, and can be seen on the examples Hamming_TX e Hamming_RX.

The two new functions are:

uint8_t Manchester::EC_encodeMessage( uint8_t numBytes, uint8_t *data, uint8_t *ecout)

where the input data buffer is provided by the data parameter with the buffer size also provided by the numBytes parameter. The output buffer ecout should at least be one third bigger than the original buffer since for every two input bytes an additional parity byte is added.

For receiving the buffer with the data and parity data is decoded and corrected if any errors are detected. Errors are corrected if possible.

uint8_t Manchester::EC_decodeMessage( uint8_t numBytes, uint8_t *ecin, uint8_t *bytesOut, uint8_t *dataout )

The input data is the size and the buffer with the data and parity, namely the numBytes and ecin input buffer pointer, and the output is returned on the dataout buffer, with the decoded size also returned on the bytesOut parameter.

Above these functions we can build some logical protocol for the received data, but that really depends on the way we want to use the library.

ESP8266 – Developer board for the ESP-01 and ESP-12

Not sure what might be the expression in English to express my level of frustration, but I finally gave up on Lua and the Nodemcu firmware for the ESP8266. The combo of ESPlorer and Nodemcu with the fact that isn’t required to flash the ESP8266 to deploy and test new code is in fact a great advantage. But this comes with a price, a hefty price. Above certain levels of complexity or code size, the Nodemcu firmware just starts to reboot randomly or hangs, and this adds a high level of frustration to developing medium size program. Add one more instruction, or line, and presto. It doesn’t work anymore, and I’m starting to delete comments, spaces, empty lines, to make it work again… Why bother… I’m not alone on this one: 4 reasons for leaving nodemcu…. My opinion Nodemcu is great for simple things and fine for testing, even if there is the need to learn Lua. Anything above that, there are better alternatives now and on the horizon.

Solving the problem
The problem that Nodemcu solves is the fact that we don’t need to flash any new firmware to test new programs or code. To flash new firmware we need to pull GPIO0 to Ground and pulse reset and then use a program, like esptool.py to push the new firmware to the chip. With Nodemcu we do this only once, on the initial ESP8266 configuration.
For other alternative firmwares, we need to always flash the firmware with the new code/program.
But the esptool.py holds a secret, it can pulse the physical serial port lines DTR and RTS to command GPIO0 and RESET to initiate the ESP8266 in flash mode, transfer the firmware, and when it ends releases the lines and allows the ESP8266 to run the new code. All without changing any connections on the ESP8266 at the physical level. In fact with this we can have the same functionality as the Nodemcu witth other firmwares. Off course off the shelf (ebay…) chips don’t do that, but I’m aware that Nodemcu and Olimex boards do support this kind of flashing mode control through the serial port. I could just bought one of these, but after programming the ESP8266 remains attached to that support electronics (serial chip) that might not be needed anymore.
So off we go building a developer board that allows the easy flashing and programming the ESP8266 but then allows the chip, namely ESP-01 and ESP-12 to detach and be used on their final board.

The board
My idealized board and in semi state of final construction (proto board) supports the esptool.py firmware flashing, powers up either from a power supply or trough mini-usb, and can program the ESP-01 or ESP-12.
My design is based on a circuit available in the esp8266.ru site, with some modifications. Also, due to the fact the DTR and RTS lines do have a function now, it’s necessary that the serial terminal programs do control these lines correctly to see, if desired, the serial port output. The serial console of ESPlorer works just fine and it has specific buttons to control these lines. In fact by pressing the RTS line button we can reset by hardware the ESP8266…
All components of the board are sourced from available items on ebay, which means that building the board is just to solder and connect some components on a protoboard with connector headers for the ESP-01 and ESP-12. Also the board can program both types, but only one at the time…

The USB serial adapter
The USB serial adapter must be one that exposes the RTS and DTR lines, and provides the serial lines at 3.3V, the level for the ESP8266. There are CP2102 based boards available on ebay or DX, that expose all the lines and are 3.3v level.
I bought mine from Alice1101983 on ebay:
alice_cp2012
It’s data and control pins are 3.3v level, just right for the ESP8266, so no need to do any level conversion, and exposes the DTR and RTS pins. Notice the board holes on the side that have the other exposed pins:
alixpress_cp2102 (Image from Alixpress).
We need to solder a wire from the RTS pin to the ESP8266 RESET pin.

Power source
I’m not powering up the board through the USB/serial adapter. The serial port adapter does have a 3.3v power pin and also a 5v power pin. But the ESP8266 can demand high currents and the 3.3v regulator on the USB/serial adapter is almost certain not to be able to provide that current, even knowing that the USB port can provide 0.5A.
So I’m not using the power provided by the CP2102 serial adapter, and instead I’m using an MB102 bread board power supply with mini usb connector that can provide 5V and 3.3v outputs. I’ve also bought mine on alice1101983: alice_mb102
This specific board receives power through the usual DC jack, but with the mini-usb connector it also can receive power from an USB power supply (mobile charger), or, even better, an USB power bank.
One of the MB102 board outputs is set to 3.3v to power up the ESP8266 boards and any other 3.3v devices, and the other other power output is set to 5V and connected to an IIC I2C level converter allowing the use of I2C 5V level devices like the 16×02 LCD screens.
I’m using these level converter devices: ebay_i2c

Schematics
The schematics that I’m using are based on this schematics:

esp8266.ru

I’ve got this from the ESP8266.RU site, the same from ESPlorer, and done some modifications.
Selection_012
With this schema, I can use the Arduino IDE and esptool.py to program the ESP8266 without the need of explicitly enter the firmware flash mode.
Also I’m not showing in my schematics the ESP-12 connections, but they are in parallel for the RX, TX, RTS and DTR lines.

A word of caution
Since now the RTS and DTR lines do have a function, some serial programs to access the ESP8266 serial console do not work. ESPlorer terminal works fine, and it has a handy DTR and RTS toggle buttons.
I’m using my own brewed python pyserial based serial program, that correctly set the RTS and DTR lines, so that after flashing the firmware we can see the serial output if any.
Also the way that reset switch resistor is in series with the switch AFTER the reset pin, means that with the serial port adapter is connected, the reset switch doesn’t work. Without being connected to the USB port, the reset switch works fine. The resistor is there to protect the CP2102 RTS line.

Final thoughts
I’m still waiting for the female headers to connect and start programming the ESP-12 on this developing board.
But so far, every thing is good. I’ve already tested the Arduino firmware ESP8266 Arduino Firmware, Sming, and off I go for testing https://github.com/cesanta/smart.js/tree/master and Espruino, which is a Javascript interpreter for the ESP8266.

1.8 SPI TFT display for Arduino

If you need to buy a display to connect to Arduino (or other boards as the Raspberry PI) don’t waste your money on the Nokia 5110 display. While these Nokia displays are quite cheap, around 2.5€, they are monochrome, and suffer from an assembly issue (at least mine) that the display contacts to the supporting board become loose (it uses some kind of adhesive) and the display looses contrast. Pressing the display against the supporting board makes it ok, but only for a while. The only valid reason that I can see for using one of these displays, if you need one, is memory size available for your program, since driving it is quite easy.

So, for a bit more money, and at less than 4€, we can buy these gorgeous 1.8 SPI TFT display. It is a world apart from the Nokia 5110 display. It has a higher resolution, it has color, it is bright, it is much better.

I’ve bought mine from eBay but there are several versions of this display regarding the controller chip. These versions from the exterior are virtually indistinguishable. The eBay seller of mine, shows a QDTech picture and also provided a Arduino library, that off course didn’t work…

Anyway , to use this display:

Connect the VCC and BL (backlight) pin to your power source (in my case, 5V), and connect the GND to ground.

Connect the RST pin to the RST Arduino Pin directly.

The other data lines should be connected to Arduino through 1K resistors.

We can drive the display by using any pin from Arduino, but to have the best performance we should use the hardware SPI pins 13 and 11.

Note that the pins names on the TFT board can change, depending in what version was shipped, but in my case was:

  • TFT SCLK -> Arduino Pin 13  (Serial Clock)
  • TFT DIN -> Arduino Pin 11 (Data)
  • TFT D/C -> Arduino Pin 8 (Data/Command)
  • TFT CS -> Arduino Pin 10 (Chip Select)

All these pins are connected in serial with an 1K resistor.

After the connection it took a while to find out the correct library to use to drive my TFT version.

The eBay description provided the QDTech driver and UTFT library which didn’t work. In fact the UTFT library was too big that I couldn’t even upload the code to my Arduino Uno without cutting out some of the sample code.

In my case the correct library for my display was the Adafruit ST7735 library available here: https://github.com/adafruit/Adafruit-ST7735-Library  But this doesn’t mean that it is the correct library for your display. It seems there are some different chips for this display like the above ST7735, the S6D02A1 and the QDTech. We need to test several of the libraries to get the right version.

ESP8266: Setting up native SDK’s on Linux and exploring some applications

The information for installing and setting up the native SDK for the esp8266 from Expressif is readily available in the Internet:

With the native SDK we can develop our own firmware using the Espressif SDK and the C or C++ language. Then we can use directly the internal esp8266 processor, allowing to do interesting things in a more direct way, like implementing MQTT, driving hardware, and so on.

So why this post?  Basically is to put into writing some of my own annotations to the issues that I had installing the SDK and the cross compiler tools on my Linux machines.

Starting up:

The original instructions that I’ve followed where these: https://github.com/esp8266/esp8266-wiki/wiki/Toolchain
I installed the tool chains in two computers, both running Linux: an Arch Linux distribution and a Kubuntu 14.04 distribution (and time is up for this one because I’m moving it also to Arch Linux. All I’m missing is to install a SSD).

1st) Installed the required pre-requisites that are documented on the above link. On Arch Linux the package installation tool is pacman and probably the package names can be different. I didn’t need to install anything on Arch, but on Kubuntu I needed to install the 64-bit pre-requisites.

2nd) Create the /opt/Espressif directory. The owner should already be your user, except if you have no permissions on the /opt directory.

3rd) Install the Xtensa Crosstool-NG that has the cross compiler and tools for the esp8266 processor:

cd /opt/Espressif
git clone -b lx106-g++ https://github.com/jcmvbkbc/crosstool-NG.git
cd crosstool-NG
./bootstrap && ./configure --prefix=`pwd` && make && make install
./ct-ng xtensa-lx106-elf
./ct-ng build

Some notes regarding this:

  •  We are going to clone the git branch lx106-g++ that has the C compiler and the C++ compiler. There is another branch named lx106 that only has the C compiler.  There is some software out there like Ardunet that need the c++ compiler and so that is the reason why I’ve chosen this git branch.
  • I’ve also changed the url for the git repository from git:// to https:// because in I’m behind a web proxy that needs authentication. Just make sure that the http_proxy, https_proxy and ftp_proxy variables are set. The ftp_proxy variable is needed because at the ct-ng build step will connect to a ftp server to retrieve files. One example for setting these environment variables: export https_proxy=http://myproxyuser:myproxypass@proxyip:port. If you have an internet direct connection, like at home, no need to set these variables.
  • The ./ct-ng build step will take a long time, around 30 minutes in one of my computers and 15 in another.
  • The tool will connect to the ftp server on IP: http://208.118.235.20/ where are located the Gnu compiler sources.

At the end we need to add the path to the crosstools to our PATH variable.
export PATH=/opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin/:$PATH
You may want to add this line at your .bashrc file. In my case (I’m using KDE desktop, I’ve created a Konsole profile for this type of work and add the new settings to the PATH variable,)

Installing the Expressif SDK

The instructions on the above link are for the 0.9.3 version of the SDK. I’ve installed the most recent version at this time that was 0.9.4:

cd /opt/Espressif
wget -O esp_iot_sdk_v0.9.4_14_12_19.zip https://github.com/esp8266/esp8266-wiki/raw/master/sdk/esp_iot_sdk_v0.9.4_14_12_19.zip
unzip esp_iot_sdk_v0.9.4_14_12_19.zip
mv esp_iot_sdk_v0.9.4 ESP8266_SDK
mv License ESP8266_SDK/
cd /opt/Espressif/ESP8266_SDK
wget -O lib/libc.a https://github.com/esp8266/esp8266-wiki/raw/master/libs/libc.a
wget -O lib/libhal.a https://github.com/esp8266/esp8266-wiki/raw/master/libs/libhal.a
wget -O include.tgz https://github.com/esp8266/esp8266-wiki/raw/master/include.tgz
tar -xvzf include.tgz

Except the change of the SDK version, the instructions are the same as the original reference post.

Installing the esptool

The esptool will pick up the compiler output and extract/create the files needed for flashing the esp8266. The instructions for this step are the same as in the original reference post. In my case, I’ve got the tool from the sources and not installed the deb file:

cd /opt/Espressif
wget https://github.com/esp8266/esp8266-wiki/raw/master/deb/src/esptool_0.0.2.orig.tar.gz
tar xvzf esptool_0.0.2.orig.tar.gz
cd esptool

Let’s put the tool on the search path. In my case I’ve choose the Xtensa bin directory. (Edit: it should be put at /usr/bin. See below at building the blinky example)

cd /opt/Expressif/esptool
chmod +w /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
ln -s /opt/Espressif/esptool/esptool ../crosstool-NG/builds/xtensa-lx106-elf/bin
sudo cp /opt/Espressif/esptool/esptool /usr/bin

Installing the firmware uploader tool esptool-py

cd /opt/Espressif
git clone https://github.com/themadinventor/esptool esptool-py
chmod +w /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
ln -s /opt/Espressif/esptool-py/esptool.py crosstool-NG/builds/xtensa-lx106-elf/bin/

With this tool we can upload the generated firmware into the esp8266.

Building

So now we are ready and we can follow the instructions here: https://github.com/esp8266/esp8266-wiki/wiki/Building to starting building things.

There are some code examples, one of them named blinky but the make file assumes that the esptool is located /usr/bin. This is because I’ve not installed the esptool through the deb package. So we can copy the esptool command to the /usr/bin directory: sudo cp  /opt/Espressif/esptool/esptool   /usr/bin.

We can now build the AT demo and the IoT demo. Just follow the instructions. For example for the IoT example just do the following (Make sure that the path is set: export PATH=/opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin/:$PATH):

cd /opt/Espressif/ESP8266_SDK
sed -i -e 's/xt-ar/xtensa-lx106-elf-ar/' -e 's/xt-xcc/xtensa-lx106-elf-gcc/' -e 's/xt-objcopy/xtensa-lx106-elf-objcopy/' Makefile
mv examples/IoT_Demo .
cd /opt/Espressif/ESP8266_SDK/IoT_Demo 
make 
cd .output/eagle/debug/image
esptool -eo eagle.app.v6.out -bo eagle.app.v6.flash.bin -bs .text -bs .data -bs .rodata -bc -ec 
xtensa-lx106-elf-objcopy --only-section .irom0.text -O binary eagle.app.v6.out eagle.app.v6.irom0text.bin 

Uploading:

For uploading just follow the instructions here: https://github.com/esp8266/esp8266-wiki/wiki/Uploading but basically is using the esptool.py to upload the firmware to the esp8266. Just make sure tha GPIO0 is grounded at boot time.

The IoT RTOS based example:

There is a beta SDK for the esp8266 based on the freeRtos according to this: https://github.com/espressif.

To use this SDK (Make sure that the PATH environment variable is correctly defined):

cd /opt/Expressif
git clone https://github.com/espressif/esp_iot_rtos_sdk.git
git clone https://github.com/espressif/esp_iot_rtos_sdk_lib.git
cp esp_iot_rtos_sdk_lib/lib/*  esp_iot_rtos_sdk/lib
cd esp_iot_rtos_sdk

make

We should have now the IoT RTOS main image ready. To generate the firmware files:

cd app/.output/eagle/debug/image/
esptool -eo eagle.app.v6.out -bo eagle.app.v6.flash.bin -bs .text -bs .data -bs .rodata -bc -ec
xtensa-lx106-elf-objcopy --only-section .irom0.text -O binary eagle.app.v6.out eagle.app.v6.irom0text.bin

And we can flash it:

/opt/Espressif/esptool-py/esptool.py --port /dev/ttyUSB0 write_flash 0x00000 eagle.app.v6.flash.bin 0x40000 eagle.app.v6.irom0text.bin

The default baud rate for the IoT example is 74880…

 Exploring some application:

Now that we have all the tools for developing natively we can check out some applications:

  • esp-mqtt – A native MQTT client for the esp8266
  • Ardunet – A work in progress that mimics the Arduino way of making applications on the esp8266.

The download links are:

esp-mqtt:

For building it, first change your connection parameters at include/user_config.h

cd /opt/Espressif
git clone https://github.com/tuanpmt/esp_mqtt.git
cd esp_mqtt
cp Makefile.linux Makefile
make
make flash

Ardunet:

For building it:

cd /opt/Espressif
git clone https://github.com/Karang/Ardunet.git
cd Ardunet
cp -R /opt/Espressif/esp_iot_rtos_sdk/ld .
make
cd /opt/Espressif/Ardunet/src/.output/eagle/debug/image
esptool -eo eagle.app.v6.out -bo eagle.app.v6.flash.bin -bs .text -bs .data -bs .rodata -bc -ec
xtensa-lx106-elf-objcopy --only-section .irom0.text -O binary eagle.app.v6.out eagle.app.v6.irom0text.bin

And we can flash it.

Conclusion:

So after this long post I hope that things now are a bit more documented from the installation and setting up point of view.