Tapatalk

Whisper Node to RFM69 Communication

Whisper Node to RFM69 Communication

81

PostSep 18, 2017#1

Hi I am a beginner and I have a whisper node (433MHz) and plan to use several more as sensor nodes reporting back to a gateway, being an ESP8266 or similar.
My question is can I use a standard RFM69 (434)radio to communicate with the whisper node. If so do I use the whispernode library on both, or just whisper node and then the RF library on the gateway...
Any help appreciated. thanks

1885
1885

PostSep 18, 2017#2

Hi Lucky,

Sure the Whisper Node RFM69 can communicate with any other device based on the same RFM69 radio if both are in the same frequency. About the libraries, the Whisper Node Library is based on the RadioRead library, and you can easily implement all communication on top of the RH library without problem.

To communicate with another device, like an ESP8266 or RPI, I would suggest having a serial communication between the MCU+RFM69 and the "minicomputer". For example, make the Whisper Node print in the Serial all messages received via radio and vice-versa. In this case you don't need to worry about drivers on the other platform.

81

PostSep 20, 2017#3

Thanks Talk2.
Would you mind posting some example code for this, say a modified version of the battery voltage sense and base would do.

1885
1885

PostSep 25, 2017#4

Hi Lucky, find below a simple example how the messages could be received by the Radio (RFM69 or RFM95) and be printed on the Serial so a computer (or a RPI) could read and process it.

The code will print the raw messages in a HEX ASCII format, including some additional radio details. This can be adapted according to your project.

LoRaSerialGateway.h

Code: Select all

/*
 * LoRaSerialGateway.h
 *
 *  Created on: 10Aug.,2017
 *      Author: Wisen
 */

#ifndef LORASERIALGATEWAY_H_
#define LORASERIALGATEWAY_H_

#include "Arduino.h"
#include <RH_RF95.h>

RH_RF95 radio;
uint8_t rfBuffer[RH_RF95_MAX_MESSAGE_LEN];

void PrintHex83(uint8_t *data, uint8_t length) // prints 8-bit data in hex
{
  char tmp[length * 2 + 1];
  byte first;
  int j = 0;
  for(uint8_t i = 0; i < length; i++)
  {
    first = (data[i] >> 4) | 48;
    if(first > 57)
      tmp[j] = first + (byte) 39;
    else
      tmp[j] = first;
    j++;

    first = (data[i] & 0x0F) | 48;
    if(first > 57)
      tmp[j] = first + (byte) 39;
    else
      tmp[j] = first;
    j++;
  }
  tmp[length * 2] = 0;
  Serial.print(tmp);
}

void runGateway()
{
  // RFM95 Receive
  uint8_t rfBufferLen = sizeof(rfBuffer);

  if(radio.recv(rfBuffer, &rfBufferLen))
  {
    // Starts with '>' character indicating it's a hex content, so we could include other messages to be ignored by the receiving software.
    Serial.print(F(">")); 

    // Print Received messages back to Serial, adding some extra data
    //uint32_t time = micros();
    Serial.print(radio.lastRssi());Serial.print(F(" "));
    Serial.print(radio.lastSNR());Serial.print(F(" ")); // I believe SNR is not valid for RFM69, so can be replaced by 0
    Serial.print(radio.headerFrom());Serial.print(F(" "));
    Serial.print(radio.headerTo());Serial.print(F(" "));
    Serial.print(radio.headerId());Serial.print(F(" "));
    Serial.print(radio.headerFlags());Serial.print(F(" "));
    Serial.print(rfBufferLen);Serial.print(F(" "));
    PrintHex83(rfBuffer, rfBufferLen);Serial.println();
    //Serial.println(micros() - time);
  }

}

#endif /* LORASERIALGATEWAY_H_ */
LoRaSerialGateway.ino

Code: Select all

#include "LoRaSerialGateway.h"
#include "utils/T2Utils.h"

#define T2_WPN_LED_1            6     // D6 - Blue
#define T2_WPN_LED_2            9     // D9 - Yellow

#define myAddress 200
#define gwAddress 200
#define radioFrequency 919.100

void setup()
{

  Serial.begin(115200);
  Serial.println(F("Starting LoRa Serial Gateway"));

  radio.init();
  radio.setFrequency(radioFrequency);
  radio.setModemConfig(RH_RF95::Bw125Cr45Sf128);
  radio.setThisAddress(myAddress);
  radio.setHeaderFrom(myAddress);
  radio.setHeaderTo(gwAddress);
  radio.setTxPower(20, false);

  pinMode(T2_WPN_LED_1, OUTPUT);
  pinMode(T2_WPN_LED_2, OUTPUT);

}

uint8_t statsBuffer[8];
uint32_t statsMillis = 0;
#define STATS_INTERVAL 300000

uint32_t uptimeMillis = 0;
#define UPTIME_INTERVAL 1000
uint32_t uptimeSeconds = 0;

void loop()
{

  uint32_t loopMillis = millis();

  // Increment Uptime in seconds
  if(loopMillis - uptimeMillis >= UPTIME_INTERVAL)
  {
    uptimeMillis = loopMillis;
    uptimeSeconds++;
    digitalWrite(T2_WPN_LED_1, !digitalRead(T2_WPN_LED_1));
  }

  // We make the base node itself "print" some stats messages, like uptime and voltages.
  // This can be moved to a better place in the code
  if(loopMillis - statsMillis >= STATS_INTERVAL)
  {
    statsMillis = loopMillis;

    uint16_t voltageBat = T2Utils::readVoltage(A6, A0);
    uint16_t voltageVin = T2Utils::readVoltage(A7, A0);

    memcpy(statsBuffer, &uptimeSeconds, 4);
    memcpy(statsBuffer + 4, &voltageBat, 2);
    memcpy(statsBuffer + 6, &voltageVin, 2);

    Serial.print(F(">")); // Starts with '>' character indicating it's a hex content
    Serial.print(0);Serial.print(F(" "));
    Serial.print(0);Serial.print(F(" "));
    Serial.print(myAddress);Serial.print(F(" "));
    Serial.print(myAddress);Serial.print(F(" "));
    Serial.print(0x10);Serial.print(F(" "));
    Serial.print(0);Serial.print(F(" "));
    Serial.print(sizeof(statsBuffer));Serial.print(F(" "));
    PrintHex83(statsBuffer, sizeof(statsBuffer));Serial.println();

  }

  // Run the Gateway Routine, which listens for message on Radio and prints on Serial
  // runGateway() is in the header file.
  runGateway();

}

3

PostOct 04, 2017#5

Does it have any advantage to send the data in hexadecimal versus binary format? Because in the receiver you have to convert it back to binary, right?
Thanks!

1885
1885

PostOct 04, 2017#6

Binary format would be better, as it would reduce the communication size. Just need to be careful when parsing binary format, as you won't be able to use delimiter characters, like CR to find the end of your message.

If you wish to use binary format, you probably should consider also adding a "signature", the whole message length, and a CRC to validate the content. Otherwise, you might get out of sync and will be difficult to re-sync. A signature can be any two bytes, for example.

I recently worked with the Ublox UBX Protocol and they have done a great job on their protocol while keeping it simple. You might decide to have a look and get some inspiration.

Cheers