,

Radio Range Test with RFM69HCW

We offer 2 types of low cost radio module option for our Mini Ultra Pro boards. We always think that it is important to choose a suitable radio module based on the application. One of the most important feature when choosing a radio module is the transmission range and transmission rate. While we have basically run many range test on the LoRa capable RFM95W radio module on the Mini Ultra Pro, we are really curious how different the FSK RFM69HCW radio module would perform in terms of range. It is obvious that the RFM69HCW is unable to achieve the few kilometer range provided by the LoRa technology but faster transmission rate and cost effectiveness of the FSK RFM69HCW radio module might be very compelling for certain applications.

We prepared 2 units of Mini Ultra Pro equipped with RFM69HCW to operate at 915 MHz with our 5 dBi dipole antenna. This module has a maximum output power of 20 dBm. One of the units will be stationed at a fixed location 2 meters above the ground. We found a small tree with supporting stakes around the height we wanted and we basically just tape the board onto the stakes.

Base Station Mounted

Bearing in mind that the Mini Ultra Pro with a Li-Pol battery sure look like an explosive device in public, we were kind enough to stick a warning sign.

Explosive Device Warning

The other unit will be placed on the dashboard of a moving car. We added a simple beeping circuitry as audio feedback indicating a simple “ping pong” transmission is successful. Driving while looking at a laptop screen is the last thing you want to do on a Malaysia road!

Beeping Circuitry On Mini Ultra Pro

The test program is basically a modified version of the examples provided by the Radiohead library. Here’s a snippet of the stagnant base station code.

// ***** INCLUDES *****
#include <RHReliableDatagram.h>
#include <RH_RF69.h>
#include <SPI.h>

// ***** CONSTANTS *****
#define MOBILE_NODE_ADDRESS 1
#define BASE_STATION_ADDRESS 2

// ***** PIN DEFINITION *****
// ***** MINI ULTRA PRO CONFIGURATIONS *****
const int radioInterruptPin = 2;  // D2 is used as radio interrupt pin
const int flashChipSelectPin = 4; // D4 is used as serial flash chip select pin
const int radioChipSelectPin = 5; // D5 is used as radio chip select pin
const int ledPin = 13;            // D13 has an LED 

// Singleton instance of the radio driver
RH_RF69 radio(radioChipSelectPin, radioInterruptPin);

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(radio, BASE_STATION_ADDRESS);

void setup() 
{
  // Ensure serial flash is not interfering with radio communication on SPI bus
  pinMode(flashChipSelectPin, OUTPUT);
  digitalWrite(flashChipSelectPin, HIGH);
  
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
    
  SerialUSB.begin(115200);

  // If radio initialization fail
  if (!manager.init())
  {
    SerialUSB.println("Init failed");
  }

  // FSK, Rb = 2.4 kbps, Fd = 4.8 kHz 915 MHz, 20 dBm on RFM69HCW
  radio.setModemConfig(RH_RF69::FSK_Rb2_4Fd4_8);
  radio.setFrequency(915.0);
  radio.setTxPower(20);
}

uint8_t data[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
uint8_t counter = 1;

void loop()
{
  // Message available from mobile node?
  if (manager.available())
  {
    uint8_t len = sizeof(buf);
    uint8_t from;
    uint8_t* bufPtr;
    
    // Now wait for a reply from the mobile node
    if (manager.recvfromAck(buf, &len, &from))
    {
      digitalWrite(ledPin, HIGH);
      SerialUSB.print("RX: ");
      bufPtr = buf;
      while(len-- > 0)
      {
        SerialUSB.write(*bufPtr++);
      }
      SerialUSB.println();
      digitalWrite(ledPin, LOW);
      
      // Send message to mobile node
      if (!manager.sendtoWait(data, counter++, from))
        SerialUSB.println("sendtoWait failed");
      if (counter >= sizeof(data)) counter = 1;
    }
  }
}

And here’s the mobile node code.

// ***** INCLUDES *****
#include <RHReliableDatagram.h>
#include <RH_RF69.h>
#include <SPI.h>

// ***** CONSTANTS ***** 
#define MOBILE_NODE_ADDRESS 1 
#define BASE_STATION_ADDRESS 2 

// ***** PIN DEFINITION ***** 
// ***** MINI ULTRA PRO CONFIGURATIONS ***** 
const int radioInterruptPin = 2;  // D2 is used as radio interrupt pin 
const int flashChipSelectPin = 4; // D4 is used as serial flash chip select pin
const int radioChipSelectPin = 5; // D5 is used as radio chip select pin 
const int ledPin = 13;            // D13 has an LED 

// Singleton instance of the radio driver 
RH_RF69 radio(radioChipSelectPin, radioInterruptPin); 
// Class to manage message delivery and receipt, using the driver declared above 
RHReliableDatagram manager(radio, MOBILE_NODE_ADDRESS); 

void setup() 
{ 
  // Ensure serial flash is not interfering with radio communication on SPI bus 
  pinMode(flashChipSelectPin, OUTPUT); 
  digitalWrite(flashChipSelectPin, HIGH); 
  pinMode(ledPin, OUTPUT); 
  digitalWrite(ledPin, LOW); 
  SerialUSB.begin(115200); 

  // If radio initialization fail 
  if (!manager.init()) 
  { 
    SerialUSB.println("Init failed"); 
  } 
  
  // FSK, Rb = 2.4 kbps, Fd = 4.8 kHz 915 MHz, 20 dBm on RFM69HCW 
  radio.setModemConfig(RH_RF69::FSK_Rb2_4Fd4_8); 
  radio.setFrequency(915.0); 
  radio.setTxPower(20); 
} 

uint8_t data[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
uint8_t buf[RH_RF69_MAX_MESSAGE_LEN]; 
uint8_t counter = 1; 

void loop() 
{ 
  // Send message to base station 
  if (manager.sendtoWait(data, counter, BASE_STATION_ADDRESS)) 
  { 
    if (++counter >= sizeof(data)) counter = 1; 
    uint8_t len = sizeof(buf); 
    uint8_t from; 
    uint8_t* bufPtr; 
    
    // Now wait for a reply from the base station 
    if (manager.recvfromAckTimeout(buf, &len, 2000, &from)) 
    { 
      digitalWrite(ledPin, HIGH); 
      SerialUSB.print("RX: "); 
      bufPtr = buf; 
      while(len-- > 0) 
      {
        SerialUSB.write(*bufPtr++); 
      } 
      SerialUSB.println(); 
      delay(200); 
      digitalWrite(ledPin, LOW); 
    } 
    else 
    { 
      SerialUSB.println("Base station not responding!"); 
    } 
  } else SerialUSB.println("sendtoWait failed"); 
  delay(500); 
}

The RFM69HCW is configured to run with the following settings:

  • Modulation: FSK (RFM69HCW able to run in GFSK, MSK, GMSK and OOK modulations too!)
  • Rb = 2.4 kbps
  • Fd = 4.8 kHz
  • Frequency = 915 MHz
  • Output power = 20 dBm

The environment in the test can be considered as having a clear Line of Sight (LOS) although there are quite a bit of bushy trees along the path and of course moving vehicles on the road.

Bushy Trees

We managed to achieve 1.45 km of range under the test condition. Weather was hot with temperature around 35°C with humidity around 90%. We believe in a more open wide area without much obstructing objects (for example farm), the range can be further improved. The RFM69HCW can be further configured to use even lower data rate at 1.2 kbps with directional antenna (like a Yagi antenna) to achieve longer range. Further elevation above the ground will also help to improve the transmission range.

RFM69HCW Range Test Map

We hope this post will help in deciding whether to use the RFM69HCW radio module in your next wireless project. We are currently assembling the RFM69HCW version of the Mini Ultra Pro.

Take care and happy sharing!

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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