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