Skip to main content
shopping_basket Basket 0
Log in

LoRa Location Tracker Part 5: Transmitter (software)

In the last chapter, we stopped in the hardware part of the transmitter. In this chapter, I will start discussing how the program of the transmitter works. let's have a quick recap of the whole system first, the LoRa Location tracker is a position tracking device that works through the LPWAN LoRa, where the benefit of using LoRa is low power consumption and a long transmission range. There is a transmitter for the user to wear and receivers set up in each corner of the venue.

Communicate with each receiver; the transmitter will work through LoRa to send the message to the receiver. I used Round Robin to take turns for each transmitter to prevent the collision of messages received by each receiver. Hence, there are a few differences in the program in each transmitter.

First, let’s include the SPI and RH_RF95 libraries in the sketch.

The LoRa module I used to be the Adafruit RFM96W LoRa module, I can use the RadioHead RFM9x Library.

#include <SPI.h>
#include <RH_RF95.h>

Then, the Adafruit RFM96W LoRa module is using the SPI Logic pins to communicate with the Arduino. Here I set up the CS, RST, and INT pin for the Arduino Nano 33 IoT, and set the frequency at 433MHz.

Note. Remember which frequency you can use in your country. (RFM9x LoRa in either 433 MHz or 868/915MHz)

#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 2

// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 434.0

// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);

Here is the setup for the transmitter.

void setup()
  if (!rf95.init())
    Serial.println("init failed");

First, the LoRa module will keep waiting for the receiver's reply, if the LoRa module is available and receives the reply, it will print out the received message and start the round-robin. The received message is sent by the receiver, to take turns which transmitter can reply to the message. The program below, is for transmitter 1, if the transmitter received C1, then send a message back to the receiver, which includes the number of the transmitter.

If the transmitter is no longer available, it will be printed out "No reply, is rf95_server running?”.

Flow diagram of transmitter / receiver process

For each loop, the transmitter will loop it every 400ms.

void loop()
  //Wait for a reply
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);
  if (rf95.waitAvailableTimeout(100))
    // Should be a reply message for us now
    if (rf95.recv(buf, &len))
      int dataLength;
      String Request = (char*)buf;
      //Round robin
      if (Request == "C1") {  //Transmitter 1
        Serial.print("Client 1 Got Request, Answering Server...");  //Transmitter 1
        String data = "1";  //Transmitter 1
        int dataLength = data.length(); dataLength ++;
        uint8_t total[dataLength]; //variable for data to send
        data.toCharArray(reinterpret_cast<char *>(total), dataLength); //change type data from string uint8_t
        Serial.println(rf95.lastRssi(), DEC);
        for (int i = 0; i <=10 ; i++){
          rf95.send(total, dataLength); //send data
    Serial.println("No reply, is rf95_server running?");

For the others transmitter, we only need to change the “Client 1” to the appropriate number of transmitters.

This is how the transmitter communicates with each receiver and the coding. In the next chapter “LoRa Location Tracker Part 6 (Receiver hardware + Software)”, I will focus on the hardware and programming part of the receiver in this system.


JulianWong has not written a bio yet…
DesignSpark Electrical Logolinkedin