2

Good day,

I am making a wireless sensor network prototype using communication technology, the RFM69HCW module [3]. I use an Arduino nano for the processing unit for the sensor nodes, and for controlling the module with the Arduino, I am using the RadioHead library [4]. For the gateway, I am trying to use a Raspberry. The schematics for the node is the following: Schematic

Note: in the schematics the radio shown is the RFM95W, but as the layout is the exact same as that of the RFM69HCW, I decided to use it and not create a new component. The code I use is the following:

#include <SPI.h>
#include <RHReliableDatagram.h>
#include <RH_RF69.h>
#include <DHT.h>

#define RFM69_FREQ 915.0

#define RFM69_INT 2
#define RFM69_CS 10
#define RFM69_RST 3 // 

#define NODEID 2
#define NETWORKID 69
#define GATEWAY 1

#define LED           9 // LED positive pin
#define GND           8 // LED ground pin

#define DHTPIN 7
#define DHTTYPE DHT22

// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT);

DHT dht(DHTPIN, DHTTYPE);

void Blink(byte PIN, int DELAY_MS);
String getReadings();

void setup() 
{
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);

  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
  pinMode(GND,OUTPUT);
  digitalWrite(GND,LOW);

  // Manual reset of rfm
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);
  
  if (!rf69.init())
    ;
  // Frequency at 915.00 MHz, no encryption.
  // No encryption
  if (!rf69.setFrequency(RFM69_FREQ))
    ;
  rf69.setTxPower(20, true);

  // The encryption key has to be the same as the one in the server
  uint8_t syncwords[2];
  syncwords[0] = 0x2d;
  syncwords[1] = NETWORKID;
  rf69.setSyncWords(syncwords, sizeof(syncwords));

  // Init the dht sensor
  dht.begin();
}

uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
uint8_t from;
void loop()
{
  // Set up a "buffer" for characters that we'll send:
  static char sendBuffer[62];
  static int sendLength = 0;
  bool sendF = false;

  // Get the data from the sensors and send it to the server}
  String data = getReadings();
  uint8_t t = rf69.temperatureRead();
  if (data != '\0')
  {
    data += " " + String(NODEID);
    for (int i = 0; i < data.length(); i++)
    {
      sendBuffer[i] = data[i];
      sendLength++;
    }
    sendF = true;
  }

  if (sendF)
  {
    if (rf69.send(sendBuffer, sendLength))
    {
      uint8_t len = sizeof(buf);
      if (rf69.recv(buf, &len))
        ;
    }
  }

  Blink(LED, 100);
  
  delay(10000); // 10 seconds
}

String getReadings()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    return String('\0');
  }
  return String(h) + " " + String(t) + " ";
}

// Blink an LED for a given number of ms
void Blink(byte PIN, int DELAY_MS)
{
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

The radio does seem to work with the Arduino. When I call readTemperature() to get the module's temperature, I get a similar value to that of the DHT sensor (with a variation of 0.5 to 1 °C). I first tested it with an Arduino Uno as a gateway, and it did get the data I sent.

Then, I tried to use a Raspberry Pi 3 B with 32-bit raspbian OS, and I got no data from the sensors. I tried with two different libraries, an adaptation of the RadioHead library to Raspberry [5], and a Python interface [6]. For the connection, I am using the following: Wiring the RFM69 with Raspberry

The code that uses the RadioHead library is:

#include "../RasPiBoards.h"

// Our RFM69 Configuration 
#define RF_FREQUENCY  915.00
#define RF_NODE_ID    1  // Node ID 1 (Gateway)
#define RF_GROUP_ID   69

// Create an instance of a driver
RH_RF69 rf69(RF_CS_PIN, RF_IRQ_PIN);

//Flag for Ctrl-C
volatile sig_atomic_t force_exit = false;

void sig_handler(int sig)
{
  printf("\n%s Break received, exiting!\n", __BASEFILE__);
  force_exit=true;
}

//Main Function
int main (int argc, const char* argv[] )
{
  unsigned long led_blink = 0;
  
  signal(SIGINT, sig_handler);
  printf( "%s\n", __BASEFILE__);

  if (!bcm2835_init()) {
    fprintf( stderr, "%s bcm2835_init() Failed\n\n", __BASEFILE__ );
    return 1;
  }
  
  printf( "RF69 CS=GPIO%d", RF_CS_PIN);

#ifdef RF_IRQ_PIN
  printf( ", IRQ=GPIO%d", RF_IRQ_PIN );
  // IRQ Pin input/pull down
  pinMode(RF_IRQ_PIN, INPUT);
  bcm2835_gpio_set_pud(RF_IRQ_PIN, BCM2835_GPIO_PUD_DOWN);
  // Now we can enable Rising edge detection
  bcm2835_gpio_ren(RF_IRQ_PIN);
#endif
  
#ifdef RF_RST_PIN
  printf( ", RST=GPIO%d", RF_RST_PIN );
  // Pulse a reset on module
  pinMode(RF_RST_PIN, OUTPUT);
  digitalWrite(RF_RST_PIN, LOW );
  bcm2835_delay(150);
  digitalWrite(RF_RST_PIN, HIGH );
  bcm2835_delay(100);
#endif

  if (!rf69.init()) {
    fprintf( stderr, "\nRF69 module init failed, Please verify wiring/module\n" );
  } else {
    printf( "\nRF69 module seen OK!\r\n");
    rf69.setTxPower(20);

    // set Network ID (by sync words)
    uint8_t syncwords[2];
    syncwords[0] = 0x2d;
    syncwords[1] = RF_GROUP_ID;
    rf69.setSyncWords(syncwords, sizeof(syncwords));

    // Adjust Frequency
    rf69.setFrequency( RF_FREQUENCY );

    // This is our Node ID
    rf69.setThisAddress(RF_NODE_ID);
    rf69.setHeaderFrom(RF_NODE_ID);
    
    printf("RF69 GroupID=%d, node #%d init OK @ %3.2fMHz\n", RF_GROUP_ID, RF_NODE_ID, RF_FREQUENCY );

    rf69.setPromiscuous(true);

    // listen for incoming message
    rf69.setModeRx();

    printf( " OK NodeID=%d @ %3.2fMHz\n", RF_NODE_ID, RF_FREQUENCY );
    printf( "Listening packet...\n" );

    //Begin the main body of code
    while (!force_exit) {
      
#ifdef RF_IRQ_PIN
      // Rising edge fired?
      if (bcm2835_gpio_eds(RF_IRQ_PIN)) {
        // Now clear the eds flag by setting it to 1
        bcm2835_gpio_set_eds(RF_IRQ_PIN);
#endif

        if (rf69.available()) {
          uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
          uint8_t len  = sizeof(buf);
          uint8_t from = rf69.headerFrom();
          uint8_t to   = rf69.headerTo();
          uint8_t id   = rf69.headerId();
          uint8_t flags= rf69.headerFlags();;
          int8_t rssi  = rf69.lastRssi();
          
          if (rf69.recv(buf, &len)) {
            printf("Packet[%02d] #%d => #%d %ddB: ", len, from, to, rssi);
            printbuffer(buf, len);
          } else {
            Serial.print("receive failed");
          }
          printf("\n");
        }
        
#ifdef RF_IRQ_PIN
      }
#endif
      bcm2835_delay(5);
    }
  }
  printf( "\n%s Ending\n", __BASEFILE__ );
  bcm2835_close();
  return 0;
}

The code using python is the following:

from RFM69 import Radio, FREQ_433MHZ import datetime import time

node_id = 2 network_id = 69 recipient_id = 1

with Radio(FREQ_433MHZ, node_id, network_id, isHighPower=True, verbose=True) as radio: print ("Starting loop...") rx_counter = 0 tx_counter = 0

while True:
    if rx_counter > 10:
        rx_counter = 0
        
        # Process packets
        for packet in radio.get_packets():
            print (packet)

    # Every 5 seconds send a message
    if tx_counter > 5:
        tx_counter=0
        # Send
        print ("Sending")
        if radio.send(2, "TEST", attempts=3, waitTime=100):
            print ("Acknowledgement received")
        else:
            print ("No Acknowledgement")
    print("Listening...", len(radio.packets), radio.mode_name)
    delay = 0.5
    rx_counter += delay
    tx_counter += delay
    time.sleep(delay)

Both codes indicate that the radio is working. When I try to read the radio temperature, the RadioHead library just freezes, and the python code returns a value double that of the Arduino. According to this website [7], it is a problem of power, I tried its solution and still, it did not work.

Can someone please provide me with guidance? I am stuck with this.

[3] https://cdn.sparkfun.com/datasheets/Wireless/General/RFM69HCW-V1.1.pdf

[4] https://github.com/hallard/RadioHead

[5] https://github.com/hallard/RadioHead

[6] https://rpi-rfm69.readthedocs.io/en/latest/index.html

[7] https://stackoverflow.com/questions/51727482/rfm69-radio-transciever-arduino-is-not-registering-acknowledgement-for-transmis

0

I did a similar project with RFM69HCW. Transmitter build with Arduino Pro Mini 8Mhz 3.3V sends a DS18B20 temperature data to a receiver build with Raspberry Pi and python sketch. Transmitter libs, I took from: https://github.com/LowPowerLab/RFM69. For the receiver I used the libs from: https://github.com/etrombly/RFM69, which is a port from the LowPowerLab to python for raspberry pi. Have a look at this! By the way: In your arduino code you definde a frequency of 915MHz. You should use the same frequeny in your Python sketch!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.