Open Eli-S-Bridge opened 10 months ago
Which frequency of chip? I wonder if you run into https://github.com/iwanders/plainRFM69/pull/13 I never got word back from testing of that, but an overflow in the frequency could affect the results. Can you try that branch?
I'm using 434mHz modules, so a 32bit overflow is probably not the issue.
By the way, thanks for responding.... I pulled out all the RFM69 registers from a plainRFM69 script and from radiohead (see below). There might be a clue among the differing registers. For instance, I was surprised to see the carrier frequency bytes (RegFrf...) were different. I'm not sure I have time to parse all of these registers out, but I suspect the difference in performance is explained in there somewhere.
PlainRFM69 | Radiohead | register description
reg no: value reg no: value. reg no, name, defaults, description
0x0: 0x0 | 0x0: 0x0 | 0x00 RegFifo 0x00 FIFO read/write access
0x1: 0x10 | 0x1: 0x4 | 0x01 RegOpMode 0x04 Operating modes of the transceiver
0x2: 0x0 | 0x2: 0x1 | 0x02 RegDataModul 0x00 Data operation mode and Modulation settings
0x3: 0x1A | 0x3: 0x0 | 0x03 RegBitrateMsb 0x1A Bit Rate setting, Most Significant Bits
0x4: 0xB | 0x4: 0x80 | 0x04 RegBitrateLsb 0x0B Bit Rate setting, Least Significant Bits
0x5: 0x0 | 0x5: 0x10 | 0x05 RegFdevMsb 0x00 Frequency Deviation setting, Most Significant Bits
0x6: 0x52 | 0x6: 0x0 | 0x06 RegFdevLsb 0x52 Frequency Deviation setting, Least Significant Bits
0x7: 0x6C | 0x7: 0x6C | 0x07 RegFrfMsb 0xE4 RF Carrier Frequency, Most Significant Bits
0x8: 0x90 | 0x8: 0x80 | 0x08 RegFrfMid 0xC0 RF Carrier Frequency, Intermediate Bits
0x9: 0x2 | 0x9: 0x0 | 0x09 RegFrfLsb 0x00 RF Carrier Frequency, Least Significant Bits
0xA: 0x41 | 0xA: 0x41 | 0x0A RegOsc1 0x41 RC Oscillators Settings
0xB: 0x40 | 0xB: 0x40 | 0x0B RegAfcCtrl 0x00 AFC control in low modulation index situations
0xC: 0x2 | 0xC: 0x2 | 0x0C Reserved0C 0x02 -
0xD: 0x92 | 0xD: 0x92 | 0x0D RegListen1 0x92 Listen Mode settings
0xE: 0xF5 | 0xE: 0xF5 | 0x0E RegListen2 0xF5 Listen Mode Idle duration
0xF: 0x20 | 0xF: 0x20 | 0x0F RegListen3 0x20 Listen Mode Rx duration
0x10: 0x24 | 0x10: 0x24 | 0x10 RegVersion 0x24
0x11: 0x9F | 0x11: 0x7F | 0x11 RegPaLevel 0x9F PA selection and Output Power control
0x12: 0x9 | 0x12: 0x9 | 0x12 RegPaRamp 0x09 Control of the PA ramp time in FSK mode
0x13: 0x1A | 0x13: 0x1A | 0x13 RegOcp 0x1A Over Current Protection control
0x14: 0x40 | 0x14: 0x40 | 0x14 Reserved14 0x40 -
0x15: 0xB0 | 0x15: 0xB0 | 0x15 Reserved15 0xB0 -
0x16: 0x7B | 0x16: 0x7B | 0x16 Reserved16 0x7B -
0x17: 0x9B | 0x17: 0x9B | 0x17 Reserved17 0x9B -
0x18: 0x88 | 0x18: 0x8 | 0x18 RegLna 0x08 0x88 LNA settings
0x19: 0x55 | 0x19: 0xE0 | 0x19 RegRxBw 0x86 0x55 Channel Filter BW Control
0x1A: 0x8B | 0x1A: 0xE0 | 0x1A RegAfcBw 0x8A 0x8B Channel Filter BW control during the AFC routine
0x1B: 0x40 | 0x1B: 0x40 | 0x1B RegOokPeak 0x40 OOK demodulator selection and control in peak mode
0x1C: 0x80 | 0x1C: 0x80 | 0x1C RegOokAvg 0x80 Average threshold control of the OOK demodulator
0x1D: 0x6 | 0x1D: 0x6 | 0x1D RegOokFix 0x06 Fixed threshold control of the OOK demodulator
0x1E: 0x10 | 0x1E: 0x10 | 0x1E RegAfcFei 0x10 AFC and FEI control and status
0x1F: 0x0 | 0x1F: 0x0 | 0x1F RegAfcMsb 0x00 MSB of the frequency correction of the AFC
0x20: 0x0 | 0x20: 0x0 | 0x20 RegAfcLsb 0x00 LSB of the frequency correction of the AFC
0x21: 0x0 | 0x21: 0x0 | 0x21 RegFeiMsb 0x00 MSB of the calculated frequency error
0x22: 0x0 | 0x22: 0x0 | 0x22 RegFeiLsb 0x00 LSB of the calculated frequency error
0x23: 0x0 | 0x23: 0x2 | 0x23 RegRssiConfig 0x02 RSSI-related settings
0x24: 0xBE | 0x24: 0xFF | 0x24 RegRssiValue 0xFF RSSI value in dBm
0x25: 0x0 | 0x25: 0x0 | 0x25 RegDioMapping1 0x00 Mapping of pins DIO0 to DIO3
0x26: 0x5 | 0x26: 0x5 | 0x26 RegDioMapping2 0x05 0x07 Mapping of pins DIO4 and DIO5, ClkOut frequency
0x27: 0xD8 | 0x27: 0x80 | 0x27 RegIrqFlags1 0x80 Status register: PLL Lock state, Timeout, RSSI > Threshold...
0x28: 0x0 | 0x28: 0x0 | 0x28 RegIrqFlags2 0x00 Status register: FIFO handling flags...
0x29: 0xE4 | 0x29: 0xFF | 0x29 RegRssiThresh 0xFF 0xE4 RSSI Threshold control
0x2A: 0x0 | 0x2A: 0x0 | 0x2A RegRxTimeout1 0x00 Timeout duration between Rx request and RSSI detection
0x2B: 0x0 | 0x2B: 0x0 | 0x2B RegRxTimeout2 0x00 Timeout duration between RSSI detection and PayloadReady
0x2C: 0x0 | 0x2C: 0x0 | 0x2C RegPreambleMsb 0x00 Preamble length, MSB
0x2D: 0x3 | 0x2D: 0x4 | 0x2D RegPreambleLsb 0x03 Preamble length, LSB
0x2E: 0x98 | 0x2E: 0x88 | 0x2E RegSyncConfig 0x98 Sync Word Recognition control
0x2F: 0x1 | 0x2F: 0x2D | 0x2F-0x36 RegSyncValue1-8 0x00 0x01 Sync Word bytes, 1 through 8
0x30: 0x1 | 0x30: 0xD4 |
0x31: 0x1 | 0x31: 0x0 |
0x32: 0x1 | 0x32: 0x0 |
0x33: 0x0 | 0x33: 0x0 |
0x34: 0x0 | 0x34: 0x0 |
0x35: 0x0 | 0x35: 0x0 |
0x36: 0x0 | 0x36: 0x0 |
0x37: 0x50 | 0x37: 0xD0 | 0x37 RegPacketConfig1 0x10 Packet mode settings
0x38: 0x4 | 0x38: 0x40 | 0x38 RegPayloadLength 0x40 Payload length setting
0x39: 0x0 | 0x39: 0x0 | 0x39 RegNodeAdrs 0x00 Node address
0x3A: 0x0 | 0x3A: 0x0 | 0x3A RegBroadcastAdrs 0x00 Broadcast address
0x3B: 0x85 | 0x3B: 0x0 | 0x3B RegAutoModes 0x00 Auto modes settings
0x3C: 0x1 | 0x3C: 0x8F | 0x3C RegFifoThresh 0x0F 0x8F Fifo threshold, Tx start condition
0x3D: 0x0 | 0x3D: 0x2 | 0x3D RegPacketConfig2 0x02 Packet mode settings
Edit; put the table in triple backticks for monospace and added some spaces for alignment.
Thanks for providing comparison!
I'm not sure I have time to parse all of these registers out
I think the difference (ignoring some register that I think don't matter) boils down to:
RegFrf
plainRFM: 0x6c9002 -> 0x6c9002 * 61 = 433999994 Hz
radiohead: 0x6c8000 -> 0x6c8000 * 61 = 433750016 Hz
RegFdev:
plainRFM: 0x0052 -> 0x0052 * 61 = 5002 Hz
radiohead: 0x1000 -> 0x1000 * 61 = 249856 Hz
RegPacketConfig1
plainRFM: 0x50=0b01010000 -> fixed length, whitening, crc
radiohead: 0xD0=0b11010000 -> variable length, whitening, crc
RegSyncConfig
plainRFM: 0x98=0b10011000 -> SyncSize:3 + 1 = 4,SyncOn
radiohead: 0x88=0b10001000 -> SyncSize:1 + 1 = 2,SyncOn
RegSyncValue{0..8}
PlainRFM: [0x1, 0x1, 0x1, 0x1] = [0b00000001, 0b00000001, 0b00000001, 0b00000001]
RadioHead: [0x2D, 0xD4] = [0b00101101, 0b11010100]
RegDataModul:
PlainRFM: no shaping
Radiohead: 01, Gaussian filter BT=1.0
RegBitrate{Msb,Lsb}:
plainRFM: 0x1a0b = 6667 -> 32e6(FXO_SC) / 6667 = 4799.7600119994 bit/s
radiohead: 0x0080 = 128 -> 32e6(FXO_SC) / 128 = 250000.0 bit/s
RegPaLevel:
plainRFM: 0x9F = 0b10011111 -> Pa0: on, pa1: off, pa2: off
raiodhead: 0x7F = 0b01111111 -> Pa0: off, pa1: on, pa2: on
RegRssiThresh:
plainRFM: 0xe4 -> -114 dbm
radiohead: 0xff -> -128 dbm
RegRxBw:
plainRFM: 0x55
radiohead: 0xe0
RegAfcBw:
plainRFM: 0x8b
radiohead: 0x1a
RegPreamble :
plainrfm: Preamblesize: 3 bytes
radiohead: Preamblesize: 4 bytes
RegPayloadLength:
plainrfm: fixed 4 bytes
radiohead: variable
RegPacketConfig2:
plainrfm: nothing
radiohead: restart Rx after receipt.
RegFifoThresh:
plainRFM: fifolevel, with 1
radiohead; fifo not empty, with 0b1111
For instance, I was surprised to see the carrier frequency bytes (RegFrf...) were different.
The difference isn't that large, just multiply the register with 61 to get the frequency in Hz; 433999994 for plainRFM, 433750016 for radiohead. You could use setFrequency with 433750016
to get the exact same as radiohead.
One thing that does stand out to me is the SyncValues; RegSyncValue
in the above, for plainRFM this is set to 0x01
, but this data is not whitened (page 52 of the datasheet), so those may actually be bad values... I know that's set by this section but it may be worth changing to what radiohead uses.
Another; RegPaLevel
, see above comparison, switch that to be the same as Radioheads, I'm not sure if all chips support the power amplifier options used here.
In this comparison, the baudrates are vastly different, with 4.8kb/s vs 250kb/s, that means transmissions take a pretty significant different duration, if there's any (periodic) interference in the environment plainRFM would be much more affected by that, you could try running setRecommended()
followed by baud300000()
, that sets it up for 300kb/s, which may set things up more similar to radiohead. Maybe even try this first, depending on the environment this may make a world of difference.
When I developed this library years ago I only really tested with three radios and short ranges. That project (not on github) used the following in the initialization;
this->rfm->setRecommended(); // set recommended paramters in RFM69.
this->rfm->setPacketType(true, true); // set the used packet type.
this->rfm->setBufferSize(this->buffer_size); // set the internal buffer size.
this->rfm->setPacketLength(64); // set the packet length.
this->rfm->setFrequency(this->frequency); // set the frequency.
this->rfm->setNodeAddress(this->kernel->getPlatformAddress());
this->rfm->setBroadcastAddress(PLATFORM_ADDRESS_BROADCAST);
this->rfm->baud153600();
this->rfm->setPreambleSize(10);
// tell the RFM to represent whether we are in automode on DIO 2.
this->rfm->setDioMapping1(RFM69_PACKET_DIO_2_AUTOMODE);
// set pinmode to input.
pinMode(this->dio2_pin, INPUT);
// Tell the SPI library we're going to use the SPI bus from an interrupt.
SPI.usingInterrupt(this->dio2_pin);
// hook our interrupt function to any edge.
attachInterrupt(this->dio2_pin, interrupt_RFM, CHANGE);
// start receiving.
this->rfm->receive();
I only needed like 3 meters of range and for that it seemed to work well. But it's like 10 years ago, so I probably forgot countless weeks of frustration trying to get it to work reliably ;)
Hope this gives you some pointers on what you could try and what the differences are. Remember that plainRFM
subclasses from bareRFM69
, so you can call any of those methods to directly modify registers.
Thank you for all of this informaiton.
I tried just changing just the baud rate as you recommended ("baud(300000)"), but that resulted in no messages being recieved.
So I moved writeRegister() to make it a public function, and just set registers to match the settings in Radiohead as follows.
rfm.writeRegister(1, 4);
rfm.writeRegister(2, 1);
rfm.writeRegister(3, 0);
rfm.writeRegister(4, 0x80);
rfm.writeRegister(5, 0x10);
rfm.writeRegister(6, 0);
rfm.writeRegister(8, 0x80);
rfm.writeRegister(9, 0);
rfm.writeRegister(0x11, 0x7F);
rfm.writeRegister(0x18, 0x08);
rfm.writeRegister(0x19, 0xE0);
rfm.writeRegister(0x1A, 0xE0);
rfm.writeRegister(0x23, 0x0);
rfm.writeRegister(0x24, 0xBE);
rfm.writeRegister(0x27, 0xD8);
rfm.writeRegister(0x29, 0xFF);
rfm.writeRegister(0x2D, 0x04);
rfm.writeRegister(0x2E, 0x88);
rfm.writeRegister(0x2F, 0x2D);
rfm.writeRegister(0x37, 0x00);
rfm.writeRegister(0x38, 0x04);
With those settings reception is good but I get random messages (see below). It's not missing any packets (despite the "packetloss" messages), so I guess I am in a pretty noisy environment. I have CRC checking turned off and there are no sync words so I think using those features would get rid of some of the mess. Unfortunately, this is all the work I can do today. I'll post more progress soon.
Packet (4): 146 Packetloss detected! Packet (4): 147 Packet (4): 447749699 Packetloss detected! Packet (4): 148 Packetloss detected! Packet (4): 3718659856 Packetloss detected! Packet (4): 3619914529 Packetloss detected! Packet (4): 3266891158 Packetloss detected! Packet (4): 149 Packetloss detected! Packet (4): 1447554770 Packetloss detected! Packet (4): 466365913 Packetloss detected! Packet (4): 150 Packetloss detected! Packet (4): 151 Packet (4): 152 Packet (4): 3053510378 Packetloss detected! Packet (4): 153 Packetloss detected! Packet (4): 4110991270 Packetloss detected! Packet (4): 244994896 Packetloss detected! Packet (4): 154 Packetloss detected! Packet (4): 155 Packet (4): 2811694902 Packetloss detected! Packet (4): 1815969940 Packetloss detected! Packet (4): 1398638066 Packetloss detected! Packet (4): 903718780
I have CRC checking turned off and there are no sync words so I think using those features would get rid of some of the mess
Without both of these, you have nothing that will prevent noise from being decoded as data. Especiall with RegRssiThresh
at -128 dBm
, that is a very low detection threshold, so if you have any 443 MHz background noise, it'll likely be able to decode data from it. But as you can see, that data is just wrong. Adding crc and sync words will likely allow you to reduce the spurious receptions significantly, perhaps even completely.
I'm still surprised that you didn't get reliable reception with lower baud rates, I recall testing lower baudrates and getting reasonably reliable reception through multiple concrete walls, but that environment likely had very little background noise.
Got stuck today trying to write my own writeRegister routine (so I can use plainRFM69 unaltered). Seems simple but I could not get this to work:
void writeRFM69Register(uint8_t RFM_Reg, uint8_t RFM_Val) { //write a byte to a radio register.
pinMode(SLAVE_SELECT_PIN, OUTPUT);
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); // gain control of SPI bus
digitalWrite(SLAVE_SELECT_PIN, LOW);
SPI.transfer(0x80 | (RFM_Reg & 0x7F));
SPI.transfer(RFM_Val);
digitalWrite(SLAVE_SELECT_PIN, HIGH);
SPI.endTransaction(); // release the SPI bus
}
So I gave up and used the function in bareRFM69.cpp. Is there a reason for it to be a private function?
I changed the RSSI threshold and got perfect transmission and reception within a range of register values from 0x50 to 0x78. Next I will implement CRC and syncwords.
Hmm, sure looks like that should work... no real reason it's a private function, just never needed to be public before. I haven't used this chip in years, so my memory on all of these things is a bit hazy.
I changed the RSSI threshold and got perfect transmission and reception within a range of register values from 0x50 to 0x78
Nice, glad you're getting it working.
Just one more appeal for help, I think. I found that the automode and interupt systems would not work for me (I'm working toward something that will use interrupts and SPI elsewhere). So what I need is to just poll an interrupt pin (DIO0) to see if a message has come in, and if so, read it. I've got that working, and I now have a much simplified radio interface that just uses functions to read and write to the radio registers, to reset the radio, and to fill and read the FIFO. I've taken these functions out of plainRFM69 and I have my own versions in the main sketch. It all works so long as I still create an instance of plainRFM69 with:
plainRFM69 rfm = plainRFM69(SLAVE_SELECT_PIN);
BUT...If I don't create the instance, then the code compiles and runs but there's no communication with the radio -- all register reads come back as 0xFF. So I'm trying to find the magic button that gets pushed when creating an instance. Any ideas?
In case you are wondering why I don't just keep the instance...I'm coding for a device that will have lots of non-programmer as users, and I'm trying to keep the overhead low. The fewer libraries to download and update the better.
Thanks again for all of your help. Here's the sketch in case it is useful to others:
/*
* Modified from code by Ivor Wanders
* MIT License, see the LICENSE.md file in the root folder.
*/
#include <SPI.h>
#include <Arduino.h>
#include <plainRFM69.h>
// slave select pin.
#define SLAVE_SELECT_PIN 8
// connected to the reset pin of the RFM69.
#define RESET_PIN 7
#define LED_RFID 43 // (PA27) Pin to control the LED indicator.
#define RADIO_INT 9 //
// define serial com parameters
#define Serial SerialUSB // SerialUSB
//create instance of plainRFM69 = why is this necessary???
plainRFM69 rfm = plainRFM69(SLAVE_SELECT_PIN);
uint32_t counter = 0; // to count the messages.
bool gotMessage = 0;
void setup(){
pinMode(RADIO_INT, INPUT);
Serial.begin(9600);
SPI.begin();
blinkLED(LED_RFID, 3, 200);
delay(3000);
Serial.println("POWER ON!!");
radioReset(RESET_PIN); // send the RFM69 a hard-reset.
//settings rendered by rfm.setRecommended(), with modifications
radioWriteRegister(0x18, 0x08); //Set regLNA to turn on LnaZin and have gain set by the internal AGC loop
radioWriteRegister(0x2D, 0x04); //4 LSB for preamble bytes. default = 3; MSB defaults to 0
radioWriteRegister(0x2E, B10011000); //Sync on; FifoFillCondition = 0; 3 sync bytes, no tolerance
radioWriteRegister(0x2F, 0x2D); // Sync value: Set to arbitrary value - same across network
radioWriteRegister(0x29, 0x64); //setRSSIThreshold (trial & error)
radioWriteRegister(0x6F, 0x30); //setContinuousDagc 0 0
radioWriteRegister(0x02, 0x01); //set DataModul to one to turn on guassan filter
radioWriteRegister(0x3C, 0x7F & 15 ); //FIFO threshold; first bit zero -> TX when fifo over threshold. other bits = threshold (need to experiment)
radioWriteRegister(0x19, 0xE0); //Channel filtering?? DccFreq = B010; RxBwMant = B10, RxBwExp = B101
radioWriteRegister(0x1A, 0xE0); //Channel filtering?? DccFreqAfc = B111, RxBwMantAfc = B01, RxBwExpAfc = B000
radioWriteRegister(0x13, 0x1A); //setPALevel...
radioWriteRegister(0x11, 0x7F); //setPALevel: power almost at max
radioWriteRegister(0x07, 0x6C); //Frequency MSB for 434,000,000 Mhz
radioWriteRegister(0x08, 0x80); //Frequency MidSB for 434,000,000 Mhz
radioWriteRegister(0x09, 0x00); //Frequency LSB for 434,000,000 Mhz
//Settings from radioHeand and trial & error.
radioWriteRegister(1, 4);
radioWriteRegister(3, 0);
radioWriteRegister(4, 0x80);
radioWriteRegister(5, 0x10);
radioWriteRegister(6, 0);
radioWriteRegister(0x23, 0x0);
radioWriteRegister(0x24, 0xBE);
radioWriteRegister(0x25, 0x40); //RFM69_DIO_MAPPING
radioWriteRegister(0x27, 0xD8);
radioWriteRegister(0x30, 0x1);
radioWriteRegister(0x31, 0x1);
radioWriteRegister(0x32, 0x1);
radioWriteRegister(0x2F, 0x3D);
radioWriteRegister(0x37, 0xD0); //packet config, Variable length, whitening on, CRC on
radioWriteRegister(0x38, 0x20); //RFM69_PAYLOAD_LENGTH
//Final settings
radioWriteRegister(0x3D, 0); //no interpacket delay, no auto RX restart, no AES (encryption)
radioWriteRegister(0x3C, 0x01); //minimum package threshold
radioWriteRegister(0x3B, B00000000); //Automode setting - turn it off
radioWriteRegister(0x5A, 0x55); // RFM69_TEST_PA1: Normal mode and Rx mode
radioWriteRegister(0x5C, 0x70); //RFM69_TEST_PA2: Normal mode and Rx mode
radioWriteRegister(0x01, B00010000); //set to receiver mode
radioDumpRegisters(); // view all registers
delay(5);
}
void loop(){
char choose = 'R'; //Change to something other than "R' before loading to transmitter
if (choose == 'R'){
Serial.println("Going Receiver!");
receiver();
// this function never returns and contains an infinite loop.
} else {
Serial.println("Going sender!");
sender();
// idem.
}
}
void sender(){
uint32_t counter = 0; // the counter which we are going to send.
uint8_t tx_buffer[13]; //buffer is 1 more than message. First byte is length
//Send 12 numbers but change the 11th one each time...
tx_buffer[12] = 1; tx_buffer[1] = 2; tx_buffer[2] = 3; tx_buffer[3] = 4;
tx_buffer[4] = 5; tx_buffer[5] = 6; tx_buffer[6] = 7; tx_buffer[7] = 8;
tx_buffer[8] = 9; tx_buffer[9] = 0; tx_buffer[10] = 1; tx_buffer[11] = 2;
while(true){
delay(2000);
tx_buffer[11] = counter;
tx_buffer[0] = 12;
Serial.print("Send:");Serial.println(counter);
radioWriteRegister(0x01, B00000100); //First Set mode register to receive mode
//(0b010<<5) + (0b110<<2) + (0b11) = B01011011
radioWriteRegister(0x3B, B01011011); //set to automode - start transmitting when FIFO level is above the thresshold
radioWriteFIFO(tx_buffer, 12);
radioWriteRegister(0x01, B00000100); // Back to recieve mode.
counter++; // increase the counter.
blinkLED(LED_RFID, 3, 200);
}
}
void receiver(){
uint8_t rx_buffer[66] = {0};
uint32_t* rx_counter = (uint32_t*) &rx_buffer;
while(true){
delay(1000);
uint8_t rd = digitalRead(RADIO_INT);
Serial.println(rd);
if(rd) {
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); // gain control of SPI bus
digitalWrite(SLAVE_SELECT_PIN, LOW);
//this->chipSelect(true); // assert chip select
//SPI.transfer((RFM69_FIFO % RFM69_READ_REG_MASK));
SPI.transfer((0 % 0x7));
uint8_t len = SPI.transfer(0);
//len = len > (max_length-1) ? (max_length-1) : len; //Contain max value of len
for (uint8_t i=0; i < len; i++){
rx_buffer[i] = SPI.transfer(0);
}
digitalWrite(SLAVE_SELECT_PIN, HIGH);
SPI.endTransaction(); // release the SPI bus
Serial.print("Received Packet ("); Serial.print(len); Serial.println("): ");
for (byte i=0; i<len; i++) {
Serial.print(rx_buffer[i]); Serial.print(" ");
}
Serial.println();
gotMessage = 0;
}
}
}
void blinkLED(uint8_t ledPin, uint8_t repeats, uint16_t duration) { //Flash an LED or toggle a pin
pinMode(ledPin, OUTPUT); // make pin an output
for (int i = 0; i < repeats; i++) { // loop to flash LED x number of times
digitalWrite(ledPin, LOW); // turn the LED on (LOW turns it on)
delay(duration); // pause again
digitalWrite(ledPin, HIGH); // turn the LED off (HIGH turns it off)
delay(duration); // pause for a while
} // end loop
} // End function
void radioReset(uint8_t pin){ // function to send the RFM69 a hardware reset.
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
delayMicroseconds(150); // pull high for >100 uSec
pinMode(pin, INPUT); // release
delay(10); // wait 10 milliseconds before SPI is possible.
}
void radioWriteRegister(uint8_t reg, uint8_t data){
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); // gain control of SPI bus
digitalWrite(SLAVE_SELECT_PIN, LOW);
//this->chipSelect(true); // assert chip select
//SPI.transfer(RFM69_WRITE_REG_MASK | (reg & RFM69_READ_REG_MASK));
SPI.transfer(0x80 | (reg & 0x7F)); // send write instruction (high byte = 1)
SPI.transfer(data);
digitalWrite(SLAVE_SELECT_PIN, HIGH);
//this->chipSelect(false);// deassert chip select
SPI.endTransaction(); // release the SPI bus
}
uint8_t radioReadRegister(uint8_t reg){
uint8_t foo;
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); // gain control of SPI bus
digitalWrite(SLAVE_SELECT_PIN, LOW);
//SPI.transfer((reg % RFM69_READ_REG_MASK));
SPI.transfer(reg % 0x7F); //use modulo of 0x7F to ensure read instruction (high byte of address = 0)
foo = SPI.transfer(0);
digitalWrite(SLAVE_SELECT_PIN, HIGH);// deassert chip select
SPI.endTransaction(); // release the SPI bus
return foo;
}
void radioWriteFIFO(uint8_t *buf, uint8_t len){
for(byte i = 0; i < len; i++) {
Serial.print(buf[i]); Serial.print(" ");
}
Serial.println();
//uint8_t* r = reinterpret_cast<uint8_t*>(buffer);
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); // gain control of SPI bus
digitalWrite(SLAVE_SELECT_PIN, LOW); // assert chip select
//SPI.transfer(RFM69_WRITE_REG_MASK | (RFM69_FIFO & RFM69_READ_REG_MASK));
SPI.transfer(0x80); //high bit = 1 to indicate write instruction - reg address is 0x00 for FIFO
for (uint8_t i=0; i < len ; i++){
// Serial.print("Writing to FIFO: "); Serial.println(r[i]);
SPI.transfer(buf[i]);
}
digitalWrite(SLAVE_SELECT_PIN, HIGH); // deassert chip select
SPI.endTransaction(); // release the SPI bus
}
void radioDumpRegisters() { //View all radio registers
uint8_t val;
for (int i = 0; i <= 0x3d; i++) {
Serial.print("0x");
Serial.print(i, HEX);
Serial.print(": 0x");
val = radioReadRegister(i);
Serial.println(val, HEX);
}
int j = 0x58;
Serial.print("0x");
Serial.print(j, HEX);
Serial.print(": 0x");
Serial.println(radioReadRegister(j), HEX);
j = 0x5A;
Serial.print("0x");
Serial.print(j, HEX);
Serial.print(": 0x");
Serial.println(radioReadRegister(j), HEX);
j = 0x5C;
Serial.print("0x");
Serial.print(j, HEX);
Serial.print(": 0x");
Serial.println(radioReadRegister(j), HEX);
j = 0x6F;
Serial.print("0x");
Serial.print(j, HEX);
Serial.print(": 0x");
Serial.println(radioReadRegister(j), HEX);
j = 0x71;
Serial.print("0x");
Serial.print(j, HEX);
Serial.print(": 0x");
Serial.println(radioReadRegister(j), HEX);
}
edit; added cpp
to the triple backticks for syntax highlighing.
Cool, I'm glad you're getting it all working!
So I'm trying to find the magic button that gets pushed when creating an instance. Any ideas?
Absolutely, thanks for sharing your code. I think the missing bit is the pinMode
call, by default pins are in high impedance mode (INPUT
), in your sketch it is not set to OUTPUT
mode.
The plainRFM69
constructor delegates here to the bareRFM69 constructor, which performs that pinMode(this->cs_pin, OUTPUT);
call. If you add pinMode(SLAVE_SELECT_PIN, OUTPUT);
to your setup, I have no doubt you can eliminate the instance of plainRFM69
.
I'm running example scripts with an RFM69HWC. The code works but I am getting only intermittant reception with communication between two radios running on modified M0 arduinos. When I use the radiohead library reception is perfect (so the hardware is OK). But I would prefer to use plainRFM69 so I can have control over interrupts. I just can't figure out what I need to do to get the transmission to work properly. I've got a high power version of the radio, and I've tried several variations on rfm.setTxPower(14, true), but there's no effect on reception. I will note that touching one of the antennas improves reception, which imples hardware issues. But again, everything works with the example scripts in radiohead. I'm just wondering if there's some incompatibility with RFM69HWC that I'm unaware of.