Transmit Basic: Rasmatic/RFM69-Arduino-Library
While I was searching for a suitable library on GitHub I downloaded the RFM-Arduino-Library by Rasmatic which had a link to sample library on the HopeRF website which I also downloaded.
/*
@author Tadeusz Studnik https://rasmatic.pl
MIT License
...
This library is a port of HopeRF's library:
https://www.hoperf.com/data/upload/back/20181122/HoepRF_HSP_V1.3.rar
*/
I made the minimum possible modifications to the C/C++ code to get it to compile, then to run on my Arduino Nano Radio Shield RFM69/95 device. I had to change the RFM69 DIO pin mode, the SPI config, and I added a method to dump all the registers.
/**********************************************************
**Name: vInitialize
**Function: initialize rfm69 or rfm69c
**Input: none
**Output: none
**********************************************************/
void RMRFM69::vInitialize(void)
{
pinMode (_csPin, OUTPUT);
pinMode (_rstPin, OUTPUT);
pinMode (_dio0Pin, INPUT_PULLDOWN); // Changed from INPUT_PULLDOWN
digitalWrite(_csPin, HIGH);
digitalWrite(_rstPin, LOW);
vSpiInit();
//�˿ڳ�ʼ�� for 32MHz
FrequencyValue.Freq = (Frequency << 11) / 125; //Calc. Freq
BitRateValue = (SymbolTime << 5) / 1000; //Calc. BitRate
DevationValue = (Devation << 11) / 125; //Calc. Fdev
BandWidthValue = bSelectBandwidth(BandWidth);
vConfig();
vGoStandby();
}
/**********************************************************
**Name: vSpiInit
**Function: init SPI
**Input: none
**Output: none
**********************************************************/
void RMRFM69::vSpiInit()
{
digitalWrite(_csPin, HIGH);
// _spiPort->setFrequency(1000000);
_spiPort->setBitOrder(MSBFIRST);
_spiPort->setDataMode(SPI_MODE0);
_spiPort->begin();
}
void RMRFM69::dumpRegisters(Stream& out)
{
for (int i = 0; i <= 0x3d; i++) {
out.print("0x");
out.print(i, HEX);
out.print(": 0x");
out.println(this->bSpiRead(i), HEX);
}
}
I created an application based on the RFM69-ESP32-arduino-example which received messages.
#include <SPI.h>
#include <RMRFM69.h>
RMRFM69 radio(SPI, 10, 2, 9);
void setup()
{
Serial.begin(9600);
radio.Modulation = FSK;
radio.COB = RFM69;
radio.Frequency = 915000;
radio.OutputPower = 10+18; //10dBm OutputPower
radio.PreambleLength = 16; //16Byte preamble
radio.FixedPktLength = false; //packet in message which need to be send
radio.CrcDisable = false; //CRC On
radio.AesOn = false;
radio.SymbolTime = 416000; //2.4Kbps
radio.Devation = 35; //35KHz for devation
radio.BandWidth = 100; //100KHz for bandwidth
radio.SyncLength = 3; //
radio.SyncWord[0] = 0xAA;
radio.SyncWord[1] = 0x2D;
radio.SyncWord[2] = 0xD4;
radio.vInitialize();
radio.dumpRegisters(Serial);
radio.vGoRx();
Serial.println("Start RX...");
}
void loop()
{
char messageIn[128] = {""};
byte messageOut[] = {"Hello world"};
if(radio.bGetMessage(messageIn)!=0)
{
Serial.print("MessageIn:");
Serial.print(messageIn);
Serial.println();
}
}
The application started up after I sorted out the RFM69 chip select, interrupt and reset pin numbers.
20:03:56.574 -> 0x0: 0x0
20:03:56.608 -> 0x1: 0x4
20:03:56.608 -> 0x2: 0x0
20:03:56.608 -> 0x3: 0x34
20:03:56.643 -> 0x4: 0x0
20:03:56.643 -> 0x5: 0x2
20:03:56.643 -> 0x6: 0x3D
20:03:56.643 -> 0x7: 0xE4
20:03:56.677 -> 0x8: 0xC0
20:03:56.677 -> 0x9: 0x0
20:03:56.677 -> 0xA: 0x41
20:03:56.710 -> 0xB: 0x40
20:03:56.710 -> 0xC: 0x2
20:03:56.710 -> 0xD: 0x92
20:03:56.745 -> 0xE: 0xF5
20:03:56.745 -> 0xF: 0x20
20:03:56.745 -> 0x10: 0x24
20:03:56.779 -> 0x11: 0x9C
20:03:56.779 -> 0x12: 0x5
20:03:56.813 -> 0x13: 0xF
20:03:56.813 -> 0x14: 0x40
20:03:56.813 -> 0x15: 0xB0
20:03:56.846 -> 0x16: 0x7B
20:03:56.846 -> 0x17: 0x9B
20:03:56.846 -> 0x18: 0x88
20:03:56.880 -> 0x19: 0x2A
20:03:56.880 -> 0x1A: 0x2A
20:03:56.880 -> 0x1B: 0x78
20:03:56.880 -> 0x1C: 0x80
20:03:56.914 -> 0x1D: 0x6
20:03:56.914 -> 0x1E: 0x10
20:03:56.947 -> 0x1F: 0x0
20:03:56.947 -> 0x20: 0x0
20:03:56.947 -> 0x21: 0x0
20:03:56.981 -> 0x22: 0x0
20:03:56.981 -> 0x23: 0x2
20:03:56.981 -> 0x24: 0xFF
20:03:57.015 -> 0x25: 0x0
20:03:57.015 -> 0x26: 0xF7
20:03:57.049 -> 0x27: 0x80
20:03:57.049 -> 0x28: 0x0
20:03:57.049 -> 0x29: 0xFF
20:03:57.083 -> 0x2A: 0x0
20:03:57.083 -> 0x2B: 0x0
20:03:57.083 -> 0x2C: 0x0
20:03:57.118 -> 0x2D: 0x10
20:03:57.118 -> 0x2E: 0x90
20:03:57.152 -> 0x2F: 0xAA
20:03:57.152 -> 0x30: 0x2D
20:03:57.152 -> 0x31: 0xD4
20:03:57.152 -> 0x32: 0x0
20:03:57.186 -> 0x33: 0x0
20:03:57.186 -> 0x34: 0x0
20:03:57.186 -> 0x35: 0x0
20:03:57.219 -> 0x36: 0x0
20:03:57.219 -> 0x37: 0x90
20:03:57.219 -> 0x38: 0x40
20:03:57.253 -> 0x39: 0x0
20:03:57.253 -> 0x3A: 0x0
20:03:57.253 -> 0x3B: 0x0
20:03:57.288 -> 0x3C: 0x1
20:03:57.288 -> 0x3D: 0x0
20:03:57.322 -> Start RX...
I then manually set the RFM69HCW Radio Bonnet registers to match the Arduino device.
public sealed class StartupTask : IBackgroundTask
{
private const int ChipSelectLine = 1;
private const int ResetLine = 25;
private Rfm69HcwDevice rfm69Device = new Rfm69HcwDevice(ChipSelectLine, ResetLine);
const double RH_RF6M9HCW_FXOSC = 32000000.0;
const double RH_RFM69HCW_FSTEP = RH_RF6M9HCW_FXOSC / 524288.0;
const byte NetworkID = 100;
const byte NodeAddressFrom = 0x03;
const byte NodeAddressTo = 0x02;
public void Run(IBackgroundTaskInstance taskInstance)
{
//rfm69Device.RegisterDump();
// regOpMode standby
rfm69Device.RegisterWriteByte(0x01, 0b00000100);
// BitRate MSB/LSB
rfm69Device.RegisterWriteByte(0x03, 0x34);
rfm69Device.RegisterWriteByte(0x04, 0x00);
// Frequency deviation
rfm69Device.RegisterWriteByte(0x05, 0x02);
rfm69Device.RegisterWriteByte(0x06, 0x3d);
// Calculate the frequency accoring to the datasheett
byte[] bytes = BitConverter.GetBytes((uint)(915000000.0 / RH_RFM69HCW_FSTEP));
Debug.WriteLine("Byte Hex 0x{0:x2} 0x{1:x2} 0x{2:x2} 0x{3:x2}", bytes[0], bytes[1], bytes[2], bytes[3]);
rfm69Device.RegisterWriteByte(0x07, bytes[2]);
rfm69Device.RegisterWriteByte(0x08, bytes[1]);
rfm69Device.RegisterWriteByte(0x09, bytes[0]);
// RegRxBW
rfm69Device.RegisterWriteByte(0x19, 0x55);
// RegAfcBw
rfm69Device.RegisterWriteByte(0x1A, 0x8b);
// RegOokPeak
rfm69Device.RegisterWriteByte(0x1B, 0x40);
// Setup preamble length to 16 (default is 3)
rfm69Device.RegisterWriteByte(0x2C, 0x0);
rfm69Device.RegisterWriteByte(0x2D, 0x10);
// Set the Sync length and byte values SyncOn + 3 custom sync bytes
rfm69Device.RegisterWriteByte(0x2e, 0x90);
rfm69Device.RegisterWriteByte(0x2f, 0xAA);
rfm69Device.RegisterWriteByte(0x30, 0x2D);
rfm69Device.RegisterWriteByte(0x31, 0xD4);
// RegPacketConfig1 changed for Variable length after 9:00PM vs 10:00PM fail
rfm69Device.RegisterWriteByte(0x37, 0x90);
//rfm69Device.RegisterWriteByte(0x38, 0x14);
rfm69Device.RegisterDump();
while (true)
{
// Standby mode while loading message into FIFO
rfm69Device.RegisterWriteByte(0x01, 0b00000100);
byte[] messageBuffer = UTF8Encoding.UTF8.GetBytes(" hello world " + DateTime.Now.ToLongTimeString());
messageBuffer[0] = (byte)messageBuffer.Length;
rfm69Device.RegisterWrite(0x0, messageBuffer);
// Transmit mode once FIFO loaded
rfm69Device.RegisterWriteByte(0x01, 0b00001100);
// Wait until send done, no timeouts in PoC
Debug.WriteLine("Send-wait");
byte IrqFlags = rfm69Device.RegisterReadByte(0x28); // RegIrqFlags2
while ((IrqFlags & 0b00001000) == 0) // wait until TxDone cleared
{
Task.Delay(10).Wait();
IrqFlags = rfm69Device.RegisterReadByte(0x28); // RegIrqFlags
Debug.Write(".");
}
Debug.WriteLine("");
// Standby mode while sleeping
rfm69Device.RegisterWriteByte(0x01, 0b00000100);
Debug.WriteLine($"{DateTime.Now.ToLongTimeString()}Send-Done");
Task.Delay(5000).Wait();
}
}
}
My Arduino device then started receiving messages from my Raspberry PI 3 running Windows 10 IoT Core.
20:03:57.288 -> 0x3C: 0x1
20:03:57.288 -> 0x3D: 0x0
20:03:57.322 -> Start RX...
20:03:58.648 -> MessageIn:hello world 8:03:58 PM
20:04:03.920 -> MessageIn:hello world 8:04:03 PM
20:04:09.161 -> MessageIn:hello world 8:04:09 PM
20:04:14.421 -> MessageIn:hello world 8:04:14 PM
20:04:19.662 -> MessageIn:hello world 8:04:19 PM
20:04:24.895 -> MessageIn:hello world 8:04:24 PM
20:04:30.139 -> MessageIn:hello world 8:04:30 PM
20:04:35.392 -> MessageIn:hello world 8:04:35 PM
20:04:40.637 -> MessageIn:hello world 8:04:40 PM
20:04:45.890 -> MessageIn:hello world 8:04:45 PM
20:04:51.158 -> MessageIn:hello world 8:04:51 PM
Transmit is working! Though it’s starting to look like I might have to create my own lightweight Arduino RFM69HCW library “inspired” by the Arduino-LoRa library.
Pingback: RFM69 hat library Part7 | devMobile's blog