Dragino+pi3 node transmission problems

(Chickadee) #1

I’m working on a project to collect RFID tag data from chickadees. We plan to have 8 - 10 lora nodes in the woods transmitting the tags we read when the birds visit our bird feeders. Each bird feeder is going to be outfitted with the following hardware:

  • raspberry pi zero w (running raspian lite)
  • dragino Lora/gps hat for rpi (915_us)
  • proto board hat with our sensors soldered on.

We chose the RAK831_915 gateway modal to use as our gateway. It Will be running on a raspberry pi 3.

We have tried several repositories for both the node and the gateway. We have had trouble using every single one. Due to a combination of frustration and confusion we have re-imaged our gateway and testing nodes to start from scratch. I was hoping somone would be able to recommend which repos will work best with the hardware we are using for the nodes(dragino Lora/GPS hat + rpi) and the gateway (RAK831_915).


elaborate on that first, what exactly (repo’s) did you use, what problems did you encounter, antenna type, forrest ? antenna height gateway ect ect.

(Chickadee) #3

@BoRRoZ Thnaks for the reply!

The first repository we used was the dragino/rpi-lora-tranceiver. Using this was fairly simple and we were able to get one node to broadcast a signal at 915 while another node was set to receive a signal on the same frequency.

When our RAK831_915 gateway arrived we installed the ic880a-gateway repository. We were also able to get the gateway connected to the TTN and see that the gateway status is active from the TTN website. After some research we started to work with the util_pkt_logger that comes with the repo.

Our first test was to set up one of our nodes using the dragino/rpi-lora-tranceiver. We set the node to send out its signal on the 915 frequency. For the gateway, we successfully got the concentrator to start and then ran the util_pkt_logger program. This program started logging what we can only assume is the packets it was receiving from our node. The question we are having trouble answering is now that we are successfully receiving a payload from the node how do we de-crypt the “payload” so we can see what is being sent from the nodes? I am assuming this is where the TTN comes in. We just don’t really understand how.

This is an example of one of our log files we are getting.

The hard RAK831 cafe part 3
(Chickadee) #4


Ideally our goal is to be able to send out “payloads” from the nodes that have a standard format each time with unique values for the data that we are collecting. The format would be something like this:

packet: { (date), (time the tag was read), (name of the feeder the tag was read at), (RFID tag value) }

We then want to be able to take each individual payload and insert it into our mysql database of “visit” data we have been collecting. We have been struggling to figure out how we go about doing this. Which has caused us to question if this is even something that we can achieve with the current hardware we have and/or the repositories we have been using for them. I appreciate any advice you may be able to offer us.


can you explain that part a bit more ?

(Chickadee) #6

The proto board is a hat that we bought to make a standard design for the individual sensors we will be using for this project.
so far the components we have on it are:

  • DC to DC converter (allowing us to attach a 12V battery to the Pi)
  • RFID sensor ( reading the tags on the banded birds)
  • Weight sensor (Eventually we plan to collect the weight of each bird when it lands at our feeder)
  • LED (used to indicate a successful tag read)
    (note) you cannot see the RFID sensor and weight sensor in this picture because they are soldered onto the other side of the board. The only component you can see here is the LED and DC to DC converter

As it stands right now we are waiting to configure the weight sensor and are only implementing it onto the board for future purposes. The main job we need these devices to do is collect the tag data and send it to our gateway so we can populate our database and then retrieve that data from a website that will then graph and analyze the data.

(Arjan) #7

Please don’t paste images if they only hold text.

That very long dashed string is your LoRaWAN packet, shown as pairs of 4 bytes in hexadecimal format. That’s a few (about 13) bytes for the LoRaWAN header and then over 100 bytes for the application payload. Did you register the LoRaWAN device in TTN Console? You should see the decrypted application payload there too. (TTN will decrypt the data for you; all you need to do is decode the application payload then.)

Those 100+ bytes seem far too much for what you need:

  • The date/time does not need to be extremely accurate, so I’d guess that the time your receive the packet suffices?

  • Use a number rather than the name of the feeder, or better yet: just use the unique DevEUI of the LoRaWAN device to determine that after you received the measurements. (See also Is it possible to define an extra payload fields directly from TTN application different per device like an API Key)

  • All you really must send are the RFID tag value and the weight. But again: don’t send those as plain text. Like if reading the tag gives you some EUI in some hexadecimal text representation (using 2 characters per byte, and maybe some dashes?), then you could send that as true binary values, one byte for each byte.

So: what are you seeing in TTN Console in the gateway’s Traffic page, and in the device’s Data page? And what code are you using to create the payload?


Q ’ how do you plan to power this setup… battery / solar or a combination ?

The less data you transmit, the longer your setup will work on a battery, thats why its important that you processor goes to ‘sleep’ in between transmissions.

Problem is… how and when do you wake up the mcu (hence start using a lot more energy+transmit data)
So you figured that out yet, ultra sound /weight / light , how do you trigger a transmission ?

I don’t know how often these ‘chicadees’ will enter your setup, but its probably better to think of a system that collect data during a certain time , format that data and transmits in a clever packet once an hour/day whatever and not everytime a bird comes in.
for that to work you’ll need a 'preprocessor+some fram+RTC

(Arjan) #9

Oh, actually, the image shows two packets. Also, they might be anyone’s LoRa transmission if they’re not yours. Given the first bytes, 0xDA985AA0 and 0x66A58D15 I don’t think these are LoRaWAN uplinks. The CRC_BAD indicates problems also. Anyway, we need to see the code, and know what you see in TTN Console.

(Make sure to keep at least a few meters between node and gateway.)

(Chickadee) #10

We registered our gateway, not the node. In order to see the Decrypted message does each individual node need to be registered to the TTN console?

We see nothing, so far we have not gotten any traffic from the gateway, even though we have been logging packets from the nodes. Leading me to believe its because the packets being sent using this repo are not using the LoRaWAN protocol.

From our last development meeting we assumed that the rpi-lora-tranceiver repository was the reason we were not able to see any traffic on the TTN. Leading me to shift to using a new repository for our nodes. I am somewhat positive that this repository: lmic-rpi-lora-gps-hat will allow us to register our nodes and send out LoRaWAN protocols to our GW. Have you ever worked with this repository?

(Chickadee) #11


Thank you for these suggestions! I totally agree with them and will present them to the group. Really appreciate the help.

(Chickadee) #12


For right now we are going to use a 12V battery to power these setups. We plan to only have them collecting RFID tags from sunrise to sunset using a daylight sensor. We are considering implementing a solar trickle charger that will use the power it collects to slowly recharge each one of our batteries. Using the solar trickle charger will not keep each battery charged continuously but it will extend the time in which our setup will be running.

We have been discussing this for some time now. The professor who initially brought us in to work on this project wants the updates to be as fast as possible, ideally instantaneous. We explained to him that in order to achieve that it comes down to the power supply we choose to implement. With the batteries we are using we will be able to get 7 to 8 days running this setup for 12 hours a day at idle. That being said we are still trying to find the best way to send the data while still being conscious of our battery consumption. We are leaning towards logging each RFID tag into a file that we only transmit a few times each day. Or possibly every hour. That is still to be determined.

(Chickadee) #13

Although I do have a general question. When we started out this project we were planning to use raspberry pi 3’s for our host device on each node. Once we began considering power consumption it became obvious that the raspberry pi zero W is a better option for us to go with.

although someone just brought to my attention that the raspberry Pi Zero W is single core and will not be capable of running multiple programs at once. Is this true? I dont believe that it is from what I have been reading on other forms but can anyone confirm if this is true or not.

The reason this would be a problem is that in order to use our current setup we need the LoRa program (whatever program that will be responsible for transmitting our data) and the Master Code program ( the main program that will be running to control the RFID reader and collect the data from the read tags to be pushed to a log file for transmission) running at the same time.

(Arjan) #14


Without registering the devices (and an application for the devices) you should still see the packets in the gateway’s Traffic page in TTN Console though; you should even see packets for non-TTN users.

But given the CRC_BAD errors, I guess you should indeed focus on the gateway. I’ve not worked with your hardware. (And again: keep a few meters, say 10, between nodes and gateway.) Maybe post a longer log?

The LoRaWAN software on the device/node does not need to run all the time, but really only when it needs to transmit something. (It’s not some WiFi-like connection with the gateway that it needs to keep running.)

You might also run into Limitations: data rate, packet size, 30 seconds uplink and 10 messages downlink per day Fair Access Policy then.

Oh, and show us some code!

The hard RAK831 cafe part 3
(Chickadee) #15

This is true, but is it still possible to run both at the same time? We plan to only activate our LoRa board a few times each day in order to save power, but when we start transmitting the LoRa packets will we be able to continue reading tags with our “master code” program running simultaneously alongside the LoRa program?

(Arjan) #16

Actually I wonder if you even need a Pi. Maybe some ESP suffices already, but that depends on the software you need to read that RFID tag and to get the weight.

(Chickadee) #17

Its just a simple python program. Same thing for the Weight sensor. But right now we are just using the RFID sensor until we are able to get everything deployed and verify that its a functioning system. Once that happens we will calibrate and begin reprogramming the weight sensor to start functioning.

(Chickadee) #19
Click to see the full code
#include <string>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>

#include <sys/ioctl.h>

#include <wiringPi.h>
#include <wiringPiSPI.h>

// #############################################
// #############################################

#define REG_FIFO                    0x00
#define REG_OPMODE                  0x01
#define REG_FIFO_ADDR_PTR           0x0D
#define REG_FIFO_TX_BASE_AD         0x0E
#define REG_FIFO_RX_BASE_AD         0x0F
#define REG_RX_NB_BYTES             0x13
#define REG_FIFO_RX_CURRENT_ADDR    0x10
#define REG_IRQ_FLAGS               0x12
#define REG_DIO_MAPPING_1           0x40
#define REG_DIO_MAPPING_2           0x41
#define REG_MODEM_CONFIG            0x1D
#define REG_MODEM_CONFIG2           0x1E
#define REG_MODEM_CONFIG3           0x26
#define REG_SYMB_TIMEOUT_LSB  		0x1F
#define REG_PKT_SNR_VALUE			0x19
#define REG_PAYLOAD_LENGTH          0x22
#define REG_IRQ_FLAGS_MASK          0x11
#define REG_HOP_PERIOD              0x24
#define REG_SYNC_WORD				0x39
#define REG_VERSION	  				0x42

#define PAYLOAD_LENGTH              0x40

#define REG_LNA                     0x0C
#define LNA_MAX_GAIN                0x23
#define LNA_OFF_GAIN                0x00
#define LNA_LOW_GAIN		    	0x20

#define RegDioMapping1                             0x40 // common
#define RegDioMapping2                             0x41 // common

#define RegPaConfig                                0x09 // common
#define RegPaRamp                                  0x0A // common
#define RegPaDac                                   0x5A // common

#define SX72_MC2_FSK                0x00
#define SX72_MC2_SF7                0x70
#define SX72_MC2_SF8                0x80
#define SX72_MC2_SF9                0x90
#define SX72_MC2_SF10               0xA0
#define SX72_MC2_SF11               0xB0
#define SX72_MC2_SF12               0xC0

#define SX72_MC1_LOW_DATA_RATE_OPTIMIZE  0x01 // mandated for SF11 and SF12

// sx1276 RegModemConfig1
#define SX1276_MC1_BW_125                0x70
#define SX1276_MC1_BW_250                0x80
#define SX1276_MC1_BW_500                0x90
#define SX1276_MC1_CR_4_5            0x02
#define SX1276_MC1_CR_4_6            0x04
#define SX1276_MC1_CR_4_7            0x06
#define SX1276_MC1_CR_4_8            0x08

#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON    0x01

// sx1276 RegModemConfig2
#define SX1276_MC2_RX_PAYLOAD_CRCON        0x04

// sx1276 RegModemConfig3
#define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE  0x08
#define SX1276_MC3_AGCAUTO                 0x04

// preamble for lora networks (nibbles swapped)
#define LORA_MAC_PREAMBLE                  0x34

#ifdef LMIC_SX1276
#elif LMIC_SX1272

// FRF
#define        REG_FRF_MSB              0x06
#define        REG_FRF_MID              0x07
#define        REG_FRF_LSB              0x08

#define        FRF_MSB                  0xD9 // 868.1 Mhz
#define        FRF_MID                  0x06
#define        FRF_LSB                  0x66

// ----------------------------------------
// Constants for radio registers
#define OPMODE_LORA      0x80
#define OPMODE_MASK      0x07
#define OPMODE_SLEEP     0x00
#define OPMODE_STANDBY   0x01
#define OPMODE_FSTX      0x02
#define OPMODE_TX        0x03
#define OPMODE_FSRX      0x04
#define OPMODE_RX        0x05
#define OPMODE_RX_SINGLE 0x06
#define OPMODE_CAD       0x07

// ----------------------------------------
// Bits masking the corresponding IRQs from the radio

// DIO function mappings                D0D1D2D3
#define MAP_DIO0_LORA_RXDONE   0x00  // 00------
#define MAP_DIO0_LORA_TXDONE   0x40  // 01------
#define MAP_DIO1_LORA_RXTOUT   0x00  // --00----
#define MAP_DIO1_LORA_NOP      0x30  // --11----
#define MAP_DIO2_LORA_NOP      0xC0  // ----11--

// #############################################
// #############################################
typedef bool boolean;
typedef unsigned char byte;

static const int CHANNEL = 0;

char message[256];

bool sx1272 = true;

byte receivedbytes;

enum sf_t { SF7=7, SF8, SF9, SF10, SF11, SF12 };

 * Configure these values!

// SX1272 - Raspberry connections
int ssPin = 6;
int dio0  = 7;
int RST   = 0;

// Set spreading factor (SF7 - SF12)
sf_t sf = SF7;

// Set center frequency
uint32_t  freq = 868100000; // in Mhz! (868.1)

byte hello[32] = "HELLO";

void die(const char *s)

void selectreceiver()
    digitalWrite(ssPin, LOW);

void unselectreceiver()
    digitalWrite(ssPin, HIGH);

byte readReg(byte addr)
    unsigned char spibuf[2];

    spibuf[0] = addr & 0x7F;
    spibuf[1] = 0x00;
    wiringPiSPIDataRW(CHANNEL, spibuf, 2);

    return spibuf[1];

void writeReg(byte addr, byte value)
    unsigned char spibuf[2];

    spibuf[0] = addr | 0x80;
    spibuf[1] = value;
    wiringPiSPIDataRW(CHANNEL, spibuf, 2);


static void opmode (uint8_t mode) {
    writeReg(REG_OPMODE, (readReg(REG_OPMODE) & ~OPMODE_MASK) | mode);

static void opmodeLora() {
    uint8_t u = OPMODE_LORA;
    if (sx1272 == false)
        u |= 0x8;   // TBD: sx1276 high freq
    writeReg(REG_OPMODE, u);

void SetupLoRa()
    digitalWrite(RST, HIGH);
    digitalWrite(RST, LOW);

    byte version = readReg(REG_VERSION);

    if (version == 0x22) {
        // sx1272
        printf("SX1272 detected, starting.\n");
        sx1272 = true;
    } else {
        // sx1276?
        digitalWrite(RST, LOW);
        digitalWrite(RST, HIGH);
        version = readReg(REG_VERSION);
        if (version == 0x12) {
            // sx1276
            printf("SX1276 detected, starting.\n");
            sx1272 = false;
        } else {
            printf("Unrecognized transceiver.\n");
            //printf("Version: 0x%x\n",version);


    // set frequency
    uint64_t frf = ((uint64_t)freq << 19) / 32000000;
    writeReg(REG_FRF_MSB, (uint8_t)(frf>>16) );
    writeReg(REG_FRF_MID, (uint8_t)(frf>> 8) );
    writeReg(REG_FRF_LSB, (uint8_t)(frf>> 0) );

    writeReg(REG_SYNC_WORD, 0x34); // LoRaWAN public sync word

    if (sx1272) {
        if (sf == SF11 || sf == SF12) {
        } else {
        writeReg(REG_MODEM_CONFIG2,(sf<<4) | 0x04);
    } else {
        if (sf == SF11 || sf == SF12) {
        } else {
        writeReg(REG_MODEM_CONFIG2,(sf<<4) | 0x04);

    if (sf == SF10 || sf == SF11 || sf == SF12) {
    } else {
    writeReg(REG_FIFO_ADDR_PTR, readReg(REG_FIFO_RX_BASE_AD));

    writeReg(REG_LNA, LNA_MAX_GAIN);


boolean receive(char *payload) {
    // clear rxDone
    writeReg(REG_IRQ_FLAGS, 0x40);

    int irqflags = readReg(REG_IRQ_FLAGS);

    //  payload crc: 0x20
    if((irqflags & 0x20) == 0x20)
        printf("CRC error\n");
        writeReg(REG_IRQ_FLAGS, 0x20);
        return false;
    } else {

        byte currentAddr = readReg(REG_FIFO_RX_CURRENT_ADDR);
        byte receivedCount = readReg(REG_RX_NB_BYTES);
        receivedbytes = receivedCount;

        writeReg(REG_FIFO_ADDR_PTR, currentAddr);

        for(int i = 0; i < receivedCount; i++)
            payload[i] = (char)readReg(REG_FIFO);
    return true;

void receivepacket() {

    long int SNR;
    int rssicorr;

    if(digitalRead(dio0) == 1)
        if(receive(message)) {
            byte value = readReg(REG_PKT_SNR_VALUE);
            if( value & 0x80 ) // The SNR sign bit is 1
                // Invert and divide by 4
                value = ( ( ~value + 1 ) & 0xFF ) >> 2;
                SNR = -value;
                // Divide by 4
                SNR = ( value & 0xFF ) >> 2;
            if (sx1272) {
                rssicorr = 139;
            } else {
                rssicorr = 157;

            printf("Packet RSSI: %d, ", readReg(0x1A)-rssicorr);
            printf("RSSI: %d, ", readReg(0x1B)-rssicorr);
            printf("SNR: %li, ", SNR);
            printf("Length: %i", (int)receivedbytes);
            printf("Payload: %s\n", message);

        } // received a message

    } // dio0=1

static void configPower (int8_t pw) {
    if (sx1272 == false) {
        // no boost used for now
        if(pw >= 17) {
            pw = 15;
        } else if(pw < 2) {
            pw = 2;
        // check board type for BOOST pin
        writeReg(RegPaConfig, (uint8_t)(0x80|(pw&0xf)));
        writeReg(RegPaDac, readReg(RegPaDac)|0x4);

    } else {
        // set PA config (2-17 dBm using PA_BOOST)
        if(pw > 17) {
            pw = 17;
        } else if(pw < 2) {
            pw = 2;
        writeReg(RegPaConfig, (uint8_t)(0x80|(pw-2)));

static void writeBuf(byte addr, byte *value, byte len) {                                                       
    unsigned char spibuf[256];                                                                          
    spibuf[0] = addr | 0x80;                                                                            
    for (int i = 0; i < len; i++) {                                                                         
        spibuf[i + 1] = value[i];                                                                       
    wiringPiSPIDataRW(CHANNEL, spibuf, len + 1);                                                        

void txlora(byte *frame, byte datalen) {

    // set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP
    // clear all radio IRQ flags
    writeReg(REG_IRQ_FLAGS, 0xFF);
    // mask all IRQs but TxDone

    // initialize the payload size and address pointers
    writeReg(REG_FIFO_TX_BASE_AD, 0x00);
    writeReg(REG_FIFO_ADDR_PTR, 0x00);
    writeReg(REG_PAYLOAD_LENGTH, datalen);

    // download buffer to the radio FIFO
    writeBuf(REG_FIFO, frame, datalen);
    // now we actually start the transmission

    printf("send: %s\n", frame);

int main (int argc, char *argv[]) {

    if (argc < 2) {
        printf ("Usage: argv[0] sender|rec [message]\n");

    wiringPiSetup () ;
    pinMode(ssPin, OUTPUT);
    pinMode(dio0, INPUT);
    pinMode(RST, OUTPUT);

    wiringPiSPISetup(CHANNEL, 500000);


    if (!strcmp("sender", argv[1])) {
        // enter standby mode (required for FIFO loading))

        writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec


        printf("Send packets at SF%i on %.6lf Mhz.\n", sf,(double)freq/1000000);

        if (argc > 2)
            strncpy((char *)hello, argv[2], sizeof(hello));

        while(1) {
            txlora(hello, strlen((char *)hello));
    } else {

        // radio init
        printf("Listening at SF%i on %.6lf Mhz.\n", sf,(double)freq/1000000);
        while(1) {


    return (0);

I attached the entire code file but I am pretty sure this is the only part you need to see. Its the portion of the code where you can change what the payload is, set the freq, SF, and channel.

typedef bool boolean;
typedef unsigned char byte;

static const int CHANNEL = 0;

char message[256];

bool sx1272 = true;

byte receivedbytes;

enum sf_t { SF7=7, SF8, SF9, SF10, SF11, SF12 };

 * Configure these values!

// SX1272 - Raspberry connections
int ssPin = 6;
int dio0  = 7;
int RST   = 0;

// Set spreading factor (SF7 - SF12)
sf_t sf = SF7;

// Set center frequency
uint32_t  freq = 915100000; // in Mhz! (868.1)

byte hello[32] = "HELLO";

Is this helpful?

(Arjan) #20

…so you’re still using some peer-to-peer bare LoRa software for the device?

You’ll need some LoRaWAN library for the device/node, in which you will also need to configure the device’s DevEUI, AppEUI and AppKey (for OTAA) or DevAddr, NwkSKey and AppSKey (for ABP).

Ah, you already wrote that:

This might help, but I’ve not used it: https://github.com/wklenk/lmic-rpi-lora-gps-hat

(Oh, you mentioned that one too :joy: Time to get away from the keyboard for me. So, yes: try that!)

(Chickadee) #21

Haha no worries. We are meeting tonight to work on it as a group, hopefully We are able to make some progress.