Here is the transmitter code (run on a separate moteino):
// Sample RFM69 sender/node sketch, with ACK and optional encryption
// Sends periodic messages of increasing length to gateway (id=1)
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#define NODEID 2 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
#define GATEWAYID 1
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
#define SERIAL_BAUD 115200
int TRANSMITPERIOD = 150; //transmit a packet to gateway so often (in ms)
char payload[] = "123 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buff[20];
byte sendSize=0;
boolean requestACK = false;
SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for 4mbit Windbond chip (W25X40CL)
RFM69 radio;
void setup() {
Serial.begin(SERIAL_BAUD);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //uncomment only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
//radio.setFrequency(919000000); //set frequency to some custom frequency
char buff[50];
sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
if (flash.initialize())
{
Serial.print("SPI Flash Init OK ... UniqueID (MAC): ");
flash.readUniqueId();
for (byte i=0;i<8;i++)
{
Serial.print(flash.UNIQUEID[i], HEX);
Serial.print(' ');
}
Serial.println();
}
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
}
long lastPeriod = 0;
void loop() {
//process any serial input
if (Serial.available() > 0)
{
char input = Serial.read();
if (input >= 48 && input <= 57) //[0,9]
{
TRANSMITPERIOD = 100 * (input-48);
if (TRANSMITPERIOD == 0) TRANSMITPERIOD = 1000;
Serial.print("\nChanging delay to ");
Serial.print(TRANSMITPERIOD);
Serial.println("ms\n");
}
if (input == 'r') //d=dump register values
radio.readAllRegs();
//if (input == 'E') //E=enable encryption
// radio.encrypt(KEY);
//if (input == 'e') //e=disable encryption
// radio.encrypt(null);
if (input == 'd') //d=dump flash area
{
Serial.println("Flash content:");
uint16_t counter = 0;
Serial.print("0-256: ");
while(counter<=256){
Serial.print(flash.readByte(counter++), HEX);
Serial.print('.');
}
while(flash.busy());
Serial.println();
}
if (input == 'e')
{
Serial.print("Erasing Flash chip ... ");
flash.chipErase();
while(flash.busy());
Serial.println("DONE");
}
if (input == 'i')
{
Serial.print("DeviceID: ");
word jedecid = flash.readDeviceId();
Serial.println(jedecid, HEX);
}
}
//check for any received packets
if (radio.receiveDone())
{
Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
for (byte i = 0; i < radio.DATALEN; i++)
Serial.print((char)radio.DATA[i]);
Serial.print(" [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]");
if (radio.ACKRequested())
{
radio.sendACK();
Serial.print(" - ACK sent");
}
Blink(LED,3);
Serial.println();
}
int currPeriod = millis()/TRANSMITPERIOD;
if (currPeriod != lastPeriod)
{
lastPeriod=currPeriod;
//send FLASH id
if(sendSize==0)
{
sprintf(buff, "FLASH_MEM_ID:0x%X", flash.readDeviceId());
byte buffLen=strlen(buff);
if (radio.sendWithRetry(GATEWAYID, buff, buffLen))
Serial.print(" ok!");
else Serial.print(" nothing...");
//sendSize = (sendSize + 1) % 31;
}
else
{
Serial.print("Sending[");
Serial.print(sendSize);
Serial.print("]: ");
for(byte i = 0; i < sendSize; i++)
Serial.print((char)payload[i]);
if (radio.sendWithRetry(GATEWAYID, payload, sendSize))
Serial.print(" ok!");
else Serial.print(" nothing...");
}
sendSize = (sendSize + 1) % 31;
Serial.println();
Blink(LED,3);
}
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
One odd thing I did notice is that when I set the modulus of how many receives to do before printing a result to a higher number, I expected it would more quickly pick up the transmitter and record its maximum, since it wouldn't be slowed down by doing all the serial printouts, but it actually seemed to be the opposite of that. So, maybe there needs to be some settle time explicitly added in between adjustments to the radio.
I cleaned up the code a little, and it runs even better now. :)
Also, I ran the test with the transmitter (node Moteino) running at 1200bps, and the receiver (gateway Moteino) has its bitrate set at 300kbps. It functions the same, so it is further evidence that it is reading the RSSI and not just the RSSI on packets that it decodes. In fact, with the bitrates set so differently, it shouldn't be decoding any valid packets at all.
Here's Version2 of the transmitter (node Moteino) code:
// Sample RFM69 sender/node sketch, with ACK and optional encryption
// Sends periodic messages of increasing length to gateway (id=1)
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <RFM69registers.h>
#define NODEID 2 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
#define GATEWAYID 1
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
#define SERIAL_BAUD 115200
int TRANSMITPERIOD = 150; //transmit a packet to gateway so often (in ms)
char payload[] = "123 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buff[20];
byte sendSize=0;
boolean requestACK = false;
SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for 4mbit Windbond chip (W25X40CL)
RFM69 radio;
void setup() {
Serial.begin(SERIAL_BAUD);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //uncomment only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
//radio.setFrequency(919000000); //set frequency to some custom frequency
radio.writeReg(REG_BITRATEMSB, RF_BITRATEMSB_1200); //set MSB bitrate to 1200
radio.writeReg(REG_BITRATELSB, RF_BITRATELSB_1200); //set LSB bitrate to 1200
Serial.println(F("Bitrate set to 1200"));
char buff[50];
sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
if (flash.initialize())
{
Serial.print("SPI Flash Init OK ... UniqueID (MAC): ");
flash.readUniqueId();
for (byte i=0;i<8;i++)
{
Serial.print(flash.UNIQUEID[i], HEX);
Serial.print(' ');
}
Serial.println();
}
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
}
long lastPeriod = 0;
void loop() {
//process any serial input
if (Serial.available() > 0)
{
char input = Serial.read();
if (input >= 48 && input <= 57) //[0,9]
{
TRANSMITPERIOD = 100 * (input-48);
if (TRANSMITPERIOD == 0) TRANSMITPERIOD = 1000;
Serial.print("\nChanging delay to ");
Serial.print(TRANSMITPERIOD);
Serial.println("ms\n");
}
if (input == 'r') //d=dump register values
radio.readAllRegs();
//if (input == 'E') //E=enable encryption
// radio.encrypt(KEY);
//if (input == 'e') //e=disable encryption
// radio.encrypt(null);
if (input == 'd') //d=dump flash area
{
Serial.println("Flash content:");
uint16_t counter = 0;
Serial.print("0-256: ");
while(counter<=256){
Serial.print(flash.readByte(counter++), HEX);
Serial.print('.');
}
while(flash.busy());
Serial.println();
}
if (input == 'e')
{
Serial.print("Erasing Flash chip ... ");
flash.chipErase();
while(flash.busy());
Serial.println("DONE");
}
if (input == 'i')
{
Serial.print("DeviceID: ");
word jedecid = flash.readDeviceId();
Serial.println(jedecid, HEX);
}
}
//check for any received packets
if (radio.receiveDone())
{
Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
for (byte i = 0; i < radio.DATALEN; i++)
Serial.print((char)radio.DATA[i]);
Serial.print(" [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]");
if (radio.ACKRequested())
{
radio.sendACK();
Serial.print(" - ACK sent");
}
Blink(LED,3);
Serial.println();
}
int currPeriod = millis()/TRANSMITPERIOD;
if (currPeriod != lastPeriod)
{
lastPeriod=currPeriod;
//send FLASH id
if(sendSize==0)
{
sprintf(buff, "FLASH_MEM_ID:0x%X", flash.readDeviceId());
byte buffLen=strlen(buff);
if (radio.sendWithRetry(GATEWAYID, buff, buffLen))
Serial.print(" ok!");
else Serial.print(" nothing...");
//sendSize = (sendSize + 1) % 31;
}
else
{
Serial.print("Sending[");
Serial.print(sendSize);
Serial.print("]: ");
for(byte i = 0; i < sendSize; i++)
Serial.print((char)payload[i]);
if (radio.sendWithRetry(GATEWAYID, payload, sendSize))
Serial.print(" ok!");
else Serial.print(" nothing...");
}
sendSize = (sendSize + 1) % 31;
Serial.println();
Blink(LED,3);
}
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
Below is an example snippet of the output:
24271. RSSI=-107, maxRSSI=-79
24272. RSSI=-101, maxRSSI=-79
24273. RSSI=-110, maxRSSI=-79
24274. RSSI=-95, maxRSSI=-79
24275. RSSI=-105, maxRSSI=-79
24276. RSSI=-104, maxRSSI=-79
24277. RSSI=-106, maxRSSI=-79
24278. RSSI=-102, maxRSSI=-79
24279. RSSI=-105, maxRSSI=-79
24280. RSSI=-105, maxRSSI=-79
24281. RSSI=-114, maxRSSI=-79
24282. RSSI=-101, maxRSSI=-79
24283. RSSI=-106, maxRSSI=-79
24284. RSSI=-100, maxRSSI=-79
24285. RSSI=-100, maxRSSI=-79
24286. RSSI=-34, maxRSSI=-34
24287. RSSI=-33, maxRSSI=-33
24288. RSSI=-31, maxRSSI=-31
24289. RSSI=-31, maxRSSI=-31
24290. RSSI=-31, maxRSSI=-31
24291. RSSI=-30, maxRSSI=-30
24292. RSSI=-31, maxRSSI=-30
24293. RSSI=-30, maxRSSI=-30
24294. RSSI=-30, maxRSSI=-30
24295. RSSI=-30, maxRSSI=-30
24296. RSSI=-31, maxRSSI=-30
24297. RSSI=-31, maxRSSI=-30
24298. RSSI=-31, maxRSSI=-30
24299. RSSI=-31, maxRSSI=-30
24300. RSSI=-31, maxRSSI=-30
24301. RSSI=-31, maxRSSI=-30
24302. RSSI=-31, maxRSSI=-30
24303. RSSI=-31, maxRSSI=-30
24304. RSSI=-31, maxRSSI=-30
24305. RSSI=-30, maxRSSI=-30
24306. RSSI=-30, maxRSSI=-30
24307. RSSI=-31, maxRSSI=-30
24308. RSSI=-31, maxRSSI=-30
24309. RSSI=-31, maxRSSI=-30
24310. RSSI=-31, maxRSSI=-30
Time index 24286 marks the instant at which I turned on the transmitter Moteino node. You can see the RSSI immediately increase from a prior maximum of -79dB to an RSSI of -34dB, and very quickly from there to -30dB. Also, before the transmitter is turned on, the RSSI numbers are fluctuating over a wider range, as you would expect, and once the transmitter is turned on, the RSSI numbers become much more tightly clustered, again as you would perhaps expect.
I implemented a simple version of what was discussed. RSSIvalue isn't read until after the RSSI flag goes HIGH. However, I think what will surprise you guys is that after doing so the RSSI value afterward (but before the next Rx cycle is started) doesn't settle onto a single value but rather continues to jump around.
Here's the Version 3.0 code:
//Version 3.0
// Sample RFM69 receiver/gateway sketch, with ACK and optional encryption
// Passes through any wireless received messages to the serial port & responds to ACKs
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <RFM69registers.h>
#define NODEID 1 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define SERIAL_BAUD 250000
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
RFM69 radio;
SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for 4mbit Windbond chip (W25X40CL)
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
void setup() {
Serial.begin(SERIAL_BAUD);
delay(10);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
radio.promiscuous(promiscuousMode);
radio.writeReg(REG_BITRATEMSB, RF_BITRATEMSB_300000); //set MSB bitrate to 300Kbps
radio.writeReg(REG_BITRATELSB, RF_BITRATELSB_300000); //set LSB bitrate to 300Kbps
Serial.println(F("Bitrate set to 300Kbps."));
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
if (flash.initialize())
{
Serial.print("SPI Flash Init OK. Unique MAC = [");
flash.readUniqueId();
for (byte i=0;i<8;i++)
{
Serial.print(flash.UNIQUEID[i], HEX);
if (i!=8) Serial.print(':');
}
Serial.println(']');
//alternative way to read it:
//byte* MAC = flash.readUniqueId();
//for (byte i=0;i<8;i++)
//{
// Serial.print(MAC[i], HEX);
// Serial.print(' ');
//}
}
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY); //set standby-mode
radio.writeReg(REG_RSSITHRESH, 0xFF); //set RSSI threshhold as low as possible
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER); //set Rx-mode
}
long loopCount=0;
int theRSSI;
int maxRSSI= (-125);
uint8_t regIrqFlags1;
void loop() {
loopCount++;
while (!(radio.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_RSSI)) { //busy-wait until RSSI flag goes HIGH
}
for (int i=0;i<10; i++) {
regIrqFlags1 = radio.readReg(REG_IRQFLAGS1);
theRSSI = -(radio.readReg(REG_RSSIVALUE))/2;
if ((theRSSI > maxRSSI)) {
maxRSSI = theRSSI;
}
Serial.print(loopCount);Serial.print(F("."));Serial.print(i);
Serial.print(F(": regIrqFlags1="));Serial.print((regIrqFlags1),BIN);
Serial.print(F(", RSSI=")); Serial.println(theRSSI);
}
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY); //set standby-mode
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER); //set Rx-mode
}
and here is some sample output:
302.0: regIrqFlags1=10011000, RSSI=-79
302.1: regIrqFlags1=11011000, RSSI=-99
302.2: regIrqFlags1=11011000, RSSI=-103
302.3: regIrqFlags1=11011000, RSSI=-98
302.4: regIrqFlags1=11011000, RSSI=-99
302.5: regIrqFlags1=11011000, RSSI=-103
302.6: regIrqFlags1=11011000, RSSI=-101
302.7: regIrqFlags1=11011000, RSSI=-104
302.8: regIrqFlags1=11011000, RSSI=-96
302.9: regIrqFlags1=11011000, RSSI=-104
303.0: regIrqFlags1=10011000, RSSI=-76
303.1: regIrqFlags1=11011000, RSSI=-98
303.2: regIrqFlags1=11011000, RSSI=-127
303.3: regIrqFlags1=11011000, RSSI=-105
303.4: regIrqFlags1=11011000, RSSI=-94
303.5: regIrqFlags1=11011000, RSSI=-96
303.6: regIrqFlags1=11011000, RSSI=-97
303.7: regIrqFlags1=11011000, RSSI=-101
303.8: regIrqFlags1=11011000, RSSI=-100
303.9: regIrqFlags1=11011000, RSSI=-106
304.0: regIrqFlags1=10011000, RSSI=-78
304.1: regIrqFlags1=11011000, RSSI=-95
304.2: regIrqFlags1=11011000, RSSI=-101
304.3: regIrqFlags1=11011000, RSSI=-99
304.4: regIrqFlags1=11011000, RSSI=-99
304.5: regIrqFlags1=11011000, RSSI=-98
304.6: regIrqFlags1=11011000, RSSI=-107
304.7: regIrqFlags1=11011000, RSSI=-98
304.8: regIrqFlags1=11011000, RSSI=-104
304.9: regIrqFlags1=11011000, RSSI=-101
305.0: regIrqFlags1=10011000, RSSI=-81
305.1: regIrqFlags1=11011000, RSSI=-96
305.2: regIrqFlags1=11011000, RSSI=-103
305.3: regIrqFlags1=11011000, RSSI=-99
305.4: regIrqFlags1=11011000, RSSI=-99
305.5: regIrqFlags1=11011000, RSSI=-103
305.6: regIrqFlags1=11011000, RSSI=-99
305.7: regIrqFlags1=11011000, RSSI=-102
305.8: regIrqFlags1=11011000, RSSI=-105
305.9: regIrqFlags1=11011000, RSSI=-98
Is that what you expected?
If I switch to the default baudrate provided by Felix's code on both the node and the gateway, and after I power-up the node, then I get the results I would expect, except that reported RSSI seems to lag even after the PayloadReady bit in IrqFlags2 is first reported to have gone HIGH. On the other hand, once the RSSI value catches up, it stays at that number on subsequent reads within the same Rx-cycle.
Here is an excerpt of the output which illustrates:
2177.0: regIrqFlags1=10011000, RSSI=-81, regIrqFlags2=0
2177.1: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
2177.2: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
2177.3: regIrqFlags1=11011000, RSSI=-98, regIrqFlags2=1000110
2177.4: regIrqFlags1=11011001, RSSI=-43, regIrqFlags2=1000110
2177.5: regIrqFlags1=11011001, RSSI=-43, regIrqFlags2=1000110
2177.6: regIrqFlags1=11011001, RSSI=-43, regIrqFlags2=1000110
2177.7: regIrqFlags1=11011001, RSSI=-43, regIrqFlags2=1000110
2177.8: regIrqFlags1=11011001, RSSI=-43, regIrqFlags2=1000110
2177.9: regIrqFlags1=11011001, RSSI=-43, regIrqFlags2=1000110
2178.0: regIrqFlags1=10011000, RSSI=-83, regIrqFlags2=0
2178.1: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
2178.2: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
2178.3: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
2178.4: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
2178.5: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
2178.6: regIrqFlags1=11011000, RSSI=-98, regIrqFlags2=0
2178.7: regIrqFlags1=11011000, RSSI=-92, regIrqFlags2=0
2178.8: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
2178.9: regIrqFlags1=11011000, RSSI=-108, regIrqFlags2=0
2179.0: regIrqFlags1=10011000, RSSI=-81, regIrqFlags2=0
2179.1: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
2179.2: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
2179.3: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
2179.4: regIrqFlags1=11011000, RSSI=-126, regIrqFlags2=0
2179.5: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
2179.6: regIrqFlags1=11011000, RSSI=-96, regIrqFlags2=0
2179.7: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
2179.8: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
2179.9: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
2180.0: regIrqFlags1=10011000, RSSI=-79, regIrqFlags2=0
2180.1: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
2180.2: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=1000110
2180.3: regIrqFlags1=11011001, RSSI=-44, regIrqFlags2=1000110
2180.4: regIrqFlags1=11011001, RSSI=-44, regIrqFlags2=1000110
2180.5: regIrqFlags1=11011001, RSSI=-44, regIrqFlags2=1000110
2180.6: regIrqFlags1=11011001, RSSI=-44, regIrqFlags2=1000110
2180.7: regIrqFlags1=11011001, RSSI=-44, regIrqFlags2=1000110
2180.8: regIrqFlags1=11011001, RSSI=-44, regIrqFlags2=1000110
2180.9: regIrqFlags1=11011001, RSSI=-44, regIrqFlags2=1000110
2181.0: regIrqFlags1=10011000, RSSI=-81, regIrqFlags2=0
2181.1: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
2181.2: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
2181.3: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
2181.4: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
2181.5: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
2181.6: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
2181.7: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
2181.8: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
2181.9: regIrqFlags1=11011000, RSSI=-97, regIrqFlags2=1000110
2182.0: regIrqFlags1=10011000, RSSI=-80, regIrqFlags2=0
@emjay I'll make an attempt on shorting the antenna and post the results.
Oops. It turns out the "lag" was actually just an artificat of the order in which I was reading the irqFlags. I corrected it so that irqFlags2 is now read first, and now it matches what you would expect (though maybe there's some lag in the FIFO flags getting cleared, but that's not really consequential):
Reading the registers in this corrected order:
regIrqFlags2 = radio.readReg(REG_IRQFLAGS2);
regIrqFlags1 = radio.readReg(REG_IRQFLAGS1);
theRSSI = -(radio.readReg(REG_RSSIVALUE))/2;
yields results like this:
441.0: regIrqFlags1=11011000, RSSI=-87, regIrqFlags2=0
441.1: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
441.2: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
441.3: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
441.4: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
441.5: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
441.6: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
441.7: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
441.8: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
441.9: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
442.0: regIrqFlags1=11011000, RSSI=-83, regIrqFlags2=1100000
442.1: regIrqFlags1=11011000, RSSI=-100, regIrqFlags2=0
442.2: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
442.3: regIrqFlags1=11011000, RSSI=-98, regIrqFlags2=0
442.4: regIrqFlags1=11011000, RSSI=-96, regIrqFlags2=0
442.5: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
442.6: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
442.7: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
442.8: regIrqFlags1=11011000, RSSI=-96, regIrqFlags2=0
442.9: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
443.0: regIrqFlags1=11011000, RSSI=-52, regIrqFlags2=0
443.1: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.2: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.3: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.4: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.5: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.6: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.7: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.8: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
443.9: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
444.0: regIrqFlags1=11011000, RSSI=-90, regIrqFlags2=1100000
444.1: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
444.2: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
444.3: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
444.4: regIrqFlags1=11011000, RSSI=-98, regIrqFlags2=0
444.5: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
444.6: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
444.7: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
444.8: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
444.9: regIrqFlags1=11011001, RSSI=-32, regIrqFlags2=1100110
445.0: regIrqFlags1=11011000, RSSI=-86, regIrqFlags2=1100000
Anyhow, the main point is that the early evidence seems to indicate that the RSSI value doesn't latch unless payloadReady is HIGH.
I unsoldered Felix's wire antenna and then soldered on a 47 ohm resistor to short antenna to ground (see attached photo). After doing so, here are the results from using the latest version of the sketch:
2.0: regIrqFlags1=11011000, RSSI=-86, regIrqFlags2=0
2.1: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
2.2: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
2.3: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
2.4: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
2.5: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
2.6: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
2.7: regIrqFlags1=11011000, RSSI=-108, regIrqFlags2=0
2.8: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
2.9: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
3.0: regIrqFlags1=11011000, RSSI=-89, regIrqFlags2=0
3.1: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
3.2: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
3.3: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
3.4: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
3.5: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
3.6: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
3.7: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
3.8: regIrqFlags1=11011000, RSSI=-110, regIrqFlags2=0
3.9: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
4.0: regIrqFlags1=11011000, RSSI=-86, regIrqFlags2=0
4.1: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
4.2: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
4.3: regIrqFlags1=11011000, RSSI=-109, regIrqFlags2=0
4.4: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
4.5: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
4.6: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
4.7: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
4.8: regIrqFlags1=11011001, RSSI=-104, regIrqFlags2=1000000
4.9: regIrqFlags1=11011000, RSSI=-112, regIrqFlags2=0
5.0: regIrqFlags1=11011000, RSSI=-88, regIrqFlags2=0
5.1: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
5.2: regIrqFlags1=11011000, RSSI=-113, regIrqFlags2=0
5.3: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
5.4: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
5.5: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
5.6: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
5.7: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
5.8: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
5.9: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
6.0: regIrqFlags1=11011000, RSSI=-88, regIrqFlags2=0
6.1: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
6.2: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
6.3: regIrqFlags1=11011000, RSSI=-115, regIrqFlags2=0
6.4: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
6.5: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
6.6: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
6.7: regIrqFlags1=11011000, RSSI=-108, regIrqFlags2=0
6.8: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
6.9: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
7.0: regIrqFlags1=11011000, RSSI=-94, regIrqFlags2=0
7.1: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
7.2: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
7.3: regIrqFlags1=11011000, RSSI=-102, regIrqFlags2=0
7.4: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
7.5: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
7.6: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
7.7: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
7.8: regIrqFlags1=11011000, RSSI=-107, regIrqFlags2=0
7.9: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
8.0: regIrqFlags1=11011000, RSSI=-86, regIrqFlags2=0
8.1: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
8.2: regIrqFlags1=11011000, RSSI=-114, regIrqFlags2=0
8.3: regIrqFlags1=11011000, RSSI=-99, regIrqFlags2=0
8.4: regIrqFlags1=11011000, RSSI=-104, regIrqFlags2=0
8.5: regIrqFlags1=11011000, RSSI=-98, regIrqFlags2=0
8.6: regIrqFlags1=11011000, RSSI=-106, regIrqFlags2=0
8.7: regIrqFlags1=11011000, RSSI=-103, regIrqFlags2=0
8.8: regIrqFlags1=11011000, RSSI=-105, regIrqFlags2=0
8.9: regIrqFlags1=11011000, RSSI=-101, regIrqFlags2=0
What do you think it all means?
Here's the sketch:
//Version 3.1
// Sample RFM69 receiver/gateway sketch, with ACK and optional encryption
// Passes through any wireless received messages to the serial port & responds to ACKs
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <RFM69registers.h>
#define NODEID 1 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define SERIAL_BAUD 250000
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
RFM69 radio;
SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for 4mbit Windbond chip (W25X40CL)
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
void setup() {
Serial.begin(SERIAL_BAUD);
delay(10);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
radio.promiscuous(promiscuousMode);
//radio.writeReg(REG_BITRATEMSB, RF_BITRATEMSB_300000); //set MSB bitrate to 300Kbps
//radio.writeReg(REG_BITRATELSB, RF_BITRATELSB_300000); //set LSB bitrate to 300Kbps
//Serial.println(F("Bitrate set to 300Kbps."));
Serial.println(F("Default bitrate."));
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
if (flash.initialize())
{
Serial.print("SPI Flash Init OK. Unique MAC = [");
flash.readUniqueId();
for (byte i=0;i<8;i++)
{
Serial.print(flash.UNIQUEID[i], HEX);
if (i!=8) Serial.print(':');
}
Serial.println(']');
//alternative way to read it:
//byte* MAC = flash.readUniqueId();
//for (byte i=0;i<8;i++)
//{
// Serial.print(MAC[i], HEX);
// Serial.print(' ');
//}
}
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY); //set standby-mode
radio.writeReg(REG_RSSITHRESH, 0xFF); //set RSSI threshhold as low as possible
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER); //set Rx-mode
}
long loopCount=0;
int theRSSI;
int maxRSSI= (-125);
uint8_t regIrqFlags1, regIrqFlags2;
void loop() {
loopCount++;
while (!(radio.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_RSSI)) { //busy-wait until RSSI flag goes HIGH
}
for (int i=0;i<10; i++) {
regIrqFlags2 = radio.readReg(REG_IRQFLAGS2);
regIrqFlags1 = radio.readReg(REG_IRQFLAGS1);
theRSSI = -(radio.readReg(REG_RSSIVALUE))/2;
if ((theRSSI > maxRSSI)) {
maxRSSI = theRSSI;
}
Serial.print(loopCount);Serial.print(F("."));Serial.print(i);
Serial.print(F(": regIrqFlags1="));Serial.print((regIrqFlags1),BIN);
Serial.print(F(", RSSI=")); Serial.print(theRSSI);
Serial.print(F(", regIrqFlags2="));Serial.println((regIrqFlags2),BIN);
}
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY); //set standby-mode
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER); //set Rx-mode
}
I can see how using an SMD resistor would have been ideal. Unfortunately, I don't have any on-hand. If anyone else does, feel free to repeat the test using that together with the same sketch, and then post.
For the moment, I removed flagsIrq2 from consideration and ran the latest version (version 4.0) of the sketch on the Moteino whose antenna is nominally shorted. BTW, it now uses RxRestart in the main loop.
I also turned on the transmitter and found that even with the antenna "shorted," it was still receiving some packets:
1.0: regIrqFlags1=10011000, RSSI=-82
1.1: regIrqFlags1=11011000, RSSI=-101
1.2: regIrqFlags1=11011000, RSSI=-102
1.3: regIrqFlags1=11011000, RSSI=-109
1.4: regIrqFlags1=11011000, RSSI=-104
1.5: regIrqFlags1=11011000, RSSI=-107
1.6: regIrqFlags1=11011000, RSSI=-111
1.7: regIrqFlags1=11011000, RSSI=-101
1.8: regIrqFlags1=11011000, RSSI=-109
1.9: regIrqFlags1=11011000, RSSI=-105
2.0: regIrqFlags1=10011000, RSSI=-81
2.1: regIrqFlags1=11011000, RSSI=-103
2.2: regIrqFlags1=11011001, RSSI=-56
2.3: regIrqFlags1=11011001, RSSI=-58
2.4: regIrqFlags1=11011001, RSSI=-58
2.5: regIrqFlags1=11011001, RSSI=-58
2.6: regIrqFlags1=11011001, RSSI=-58
2.7: regIrqFlags1=11011001, RSSI=-58
2.8: regIrqFlags1=11011001, RSSI=-58
2.9: regIrqFlags1=11011001, RSSI=-58
3.0: regIrqFlags1=10011000, RSSI=-77
3.1: regIrqFlags1=11011000, RSSI=-102
3.2: regIrqFlags1=11011000, RSSI=-104
3.3: regIrqFlags1=11011000, RSSI=-107
3.4: regIrqFlags1=11011000, RSSI=-107
3.5: regIrqFlags1=11011000, RSSI=-107
3.6: regIrqFlags1=11011000, RSSI=-100
3.7: regIrqFlags1=11011000, RSSI=-110
3.8: regIrqFlags1=11011000, RSSI=-102
3.9: regIrqFlags1=11011000, RSSI=-105
4.0: regIrqFlags1=10011000, RSSI=-81
4.1: regIrqFlags1=11011000, RSSI=-105
4.2: regIrqFlags1=11011000, RSSI=-99
4.3: regIrqFlags1=11011000, RSSI=-103
4.4: regIrqFlags1=11011000, RSSI=-104
4.5: regIrqFlags1=11011000, RSSI=-100
4.6: regIrqFlags1=11011000, RSSI=-102
4.7: regIrqFlags1=11011000, RSSI=-107
4.8: regIrqFlags1=11011000, RSSI=-101
4.9: regIrqFlags1=11011001, RSSI=-58
5.0: regIrqFlags1=10011000, RSSI=-76
5.1: regIrqFlags1=11011000, RSSI=-105
5.2: regIrqFlags1=11011000, RSSI=-101
5.3: regIrqFlags1=11011000, RSSI=-104
5.4: regIrqFlags1=11011000, RSSI=-103
5.5: regIrqFlags1=11011000, RSSI=-109
5.6: regIrqFlags1=11011000, RSSI=-105
5.7: regIrqFlags1=11011000, RSSI=-104
5.8: regIrqFlags1=11011000, RSSI=-108
5.9: regIrqFlags1=11011000, RSSI=-102
6.0: regIrqFlags1=10011000, RSSI=-81
6.1: regIrqFlags1=11011000, RSSI=-107
6.2: regIrqFlags1=11011000, RSSI=-107
6.3: regIrqFlags1=11011000, RSSI=-106
6.4: regIrqFlags1=11011000, RSSI=-108
6.5: regIrqFlags1=11011000, RSSI=-102
6.6: regIrqFlags1=11011000, RSSI=-103
6.7: regIrqFlags1=11011000, RSSI=-103
6.8: regIrqFlags1=11011000, RSSI=-103
6.9: regIrqFlags1=11011000, RSSI=-110
7.0: regIrqFlags1=10011000, RSSI=-82
7.1: regIrqFlags1=11011000, RSSI=-106
7.2: regIrqFlags1=11011000, RSSI=-105
7.3: regIrqFlags1=11011000, RSSI=-102
7.4: regIrqFlags1=11011000, RSSI=-101
7.5: regIrqFlags1=11011001, RSSI=-54
7.6: regIrqFlags1=11011001, RSSI=-57
7.7: regIrqFlags1=11011001, RSSI=-57
7.8: regIrqFlags1=11011001, RSSI=-57
7.9: regIrqFlags1=11011001, RSSI=-57
8.0: regIrqFlags1=10011000, RSSI=-77
8.1: regIrqFlags1=11011000, RSSI=-103
8.2: regIrqFlags1=11011000, RSSI=-105
8.3: regIrqFlags1=11011000, RSSI=-107
8.4: regIrqFlags1=11011000, RSSI=-109
8.5: regIrqFlags1=11011000, RSSI=-109
8.6: regIrqFlags1=11011000, RSSI=-103
8.7: regIrqFlags1=11011000, RSSI=-101
8.8: regIrqFlags1=11011000, RSSI=-107
8.9: regIrqFlags1=11011000, RSSI=-111
9.0: regIrqFlags1=10011000, RSSI=-82
9.1: regIrqFlags1=11011000, RSSI=-107
9.2: regIrqFlags1=11011000, RSSI=-105
9.3: regIrqFlags1=11011000, RSSI=-106
9.4: regIrqFlags1=11011000, RSSI=-102
9.5: regIrqFlags1=11011000, RSSI=-105
9.6: regIrqFlags1=11011000, RSSI=-107
9.7: regIrqFlags1=11011000, RSSI=-103
9.8: regIrqFlags1=11011000, RSSI=-105
9.9: regIrqFlags1=11011000, RSSI=-107
10.0: regIrqFlags1=10011000, RSSI=-82
Here's the current sketch which produced the above results:
//Version 4.0
// Sample RFM69 receiver/gateway sketch, with ACK and optional encryption
// Passes through any wireless received messages to the serial port & responds to ACKs
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <RFM69registers.h>
#define NODEID 1 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define SERIAL_BAUD 250000
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define FLASH_SS 23 // and FLASH SS on D23
#else
#define LED 9 // Moteinos have LEDs on D9
#define FLASH_SS 8 // and FLASH SS on D8
#endif
RFM69 radio;
SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for 4mbit Windbond chip (W25X40CL)
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
uint8_t oldRegPacketConfig1,newRegPacketConfig1;
uint8_t oldPacketConfig2, newPacketConfig2;
void setup() {
Serial.begin(SERIAL_BAUD);
delay(10);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
radio.promiscuous(promiscuousMode);
//radio.writeReg(REG_BITRATEMSB, RF_BITRATEMSB_300000); //set MSB bitrate to 300Kbps
//radio.writeReg(REG_BITRATELSB, RF_BITRATELSB_300000); //set LSB bitrate to 300Kbps
//Serial.println(F("Bitrate set to 300Kbps."));
Serial.println(F("Default bitrate."));
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
if (flash.initialize())
{
Serial.print("SPI Flash Init OK. Unique MAC = [");
flash.readUniqueId();
for (byte i=0;i<8;i++)
{
Serial.print(flash.UNIQUEID[i], HEX);
if (i!=8) Serial.print(':');
}
Serial.println(']');
//alternative way to read it:
//byte* MAC = flash.readUniqueId();
//for (byte i=0;i<8;i++)
//{
// Serial.print(MAC[i], HEX);
// Serial.print(' ');
//}
}
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
//oldRegPacketConfig1 = radio.readReg(REG_PACKETCONFIG1);
//newRegPacketConfig1 = oldRegPacketConfig1 & ((RF_PACKET1_CRC_ON)^0xFF); //clear CRC_ON bit
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY); //set standby-mode
radio.writeReg(REG_RSSITHRESH, 0xFF); //set RSSI threshhold as low as possible
//radio.writeReg(REG_PACKETCONFIG1,newRegPacketConfig1); //disable CRC checking
radio.writeReg(REG_OPMODE, (radio.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER); //set Rx-mode
}
long loopCount=0;
int theRSSI;
int maxRSSI= (-125);
uint8_t regIrqFlags1, regIrqFlags2;
void loop() {
loopCount++;
while (!(radio.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_RSSI)) { //busy-wait until RSSI flag goes HIGH
}
for (int i=0;i<10; i++) {
//regIrqFlags2 = radio.readReg(REG_IRQFLAGS2);
regIrqFlags1 = radio.readReg(REG_IRQFLAGS1);
theRSSI = -(radio.readReg(REG_RSSIVALUE))/2;
//if ((theRSSI > maxRSSI)) {
//maxRSSI = theRSSI;
//}
Serial.print(loopCount);Serial.print(F("."));Serial.print(i);
Serial.print(F(": regIrqFlags1="));Serial.print((regIrqFlags1),BIN);
Serial.print(F(", RSSI=")); Serial.println(theRSSI);
//Serial.print(F(", regIrqFlags2="));Serial.println((regIrqFlags2),BIN);
}
oldPacketConfig2 = radio.readReg(REG_PACKETCONFIG2);
newPacketConfig2 = (oldPacketConfig2 | RF_PACKET2_RXRESTART); //set RxRestart bit
radio.writeReg(REG_PACKETCONFIG2,newPacketConfig2); //transition to Rx-WAIT mode
}
So, here are my conclusions:
1. Obviously, some external RF is getting into the system, even with a "shorted" antenna. So, that may explain, either fully or in-part, the varying RSSI.
2. If you want to measure RSSI, wait until the RxReady flag goes HIGH. The RSSI measured after the RSSI flag goes HIGH but before the RxReady flag goes HIGH seems less accurate.
What are your conclusions?
My conclusions are:
1) If you are receiving genuine packets you should wait for the PayloadReady interrupt and read the RSSI immediately before emptying the FIFO because PayloadReady freezes the RSSI register. Once you empty the FIFO, or take out of RX mode, the RSSI register will start to change again.
2) My experiments with unlimited packet length seem to imply a strangeness with the RSSI levels reported. If a packet starts to be received it appears the correct value is sometimes not put into the RSSI register. When using variable length mode a PayloadReady is generated, and the correct value is put in the RSSI register at that point. This may have implications for using unlimited packet length mode and reading the RSSI assiciated with it.
3) Waiting for an RSSI interrupt, reading the RSSI register and restarting the receiver appears to be the most reliable.
Here's the code I'm using to sample at 1ms resolution. I'm not convinced it really is 1ms, if you restart by switching to STANDBY and then to RX mode (which waits for MODEREADY) the cycle time will drop to 2.5ms with no delays. I'm beginning to suspect this is the fastest possible, there certainly appears to be a limit on the maximum rate at which the RSSI register updates and it is in the same order of 2.5ms.
void rssiLoop(void)
{
int8_t rssi[20];
uint8_t flags1[20];
uint8_t flags2[20];
uint16_t loopCount = 0;
uint8_t x;
uint16_t cnt1= 0;
uint16_t cnt2= 0;
rfm69WrSpi(REG_RSSITHRESH, 0xFF); // permanently trigger
setRfm69Mode(RX_MODE); // set to RX mode
while(1)
{
loopCount++;
for(x=0; x<20; x++)
{
nLEDON_PORT |= (1 << nLEDON_BIT); // used with 'scope to measure cycle time
// wait for RSSI interrupt
while((rfm69RdSpi(REG_IRQFLAGS1) & IRQFLAGS1_RSSI)==0);
nLEDON_PORT &= ~(1 << nLEDON_BIT); // used with 'scope to measure cycle time
// sample RSSI and flags
rssi[x] = -(rfm69RdSpi(REG_RSSIVALUE)/2);
flags1[x] = rfm69RdSpi(REG_IRQFLAGS1);
flags2[x] = rfm69RdSpi(REG_IRQFLAGS2);
// restart receiver
rfm69WrSpi(REG_PACKETCONFIG2, (PACKETCONFIG2_RESTARTRX));
// slows sampling down to ~1ms
_delay_us(800);
}
// dump out if we see some activity
if((rssi[5] > -60) && (rssi[10] > -60))
{
SYS_DEBUG((PSTR("cnt1 = %d, cnt2 = %d\r\n"),cnt1,cnt2));
for(x=0; x<20; x++)
{
SYS_DEBUG((PSTR("%d.%d: irqFlags1=0x%X, irqFlags2=0x%X, RSSI=%d\r\n"),loopCount,x,flags1[x],flags2[x],rssi[x]));
}
}
}
}
Here's an example of the output, this is sampling a packet which takes just over 10ms to transmit:
2949.0: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-107
2949.1: irqFlags1=0x98, irqFlags2=0x0, RSSI=-35
2949.2: irqFlags1=0x98, irqFlags2=0x0, RSSI=-34
2949.3: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-34
2949.4: irqFlags1=0x98, irqFlags2=0x0, RSSI=-35
2949.5: irqFlags1=0x98, irqFlags2=0x0, RSSI=-33
2949.6: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-33
2949.7: irqFlags1=0x98, irqFlags2=0x0, RSSI=-34
2949.8: irqFlags1=0x98, irqFlags2=0x0, RSSI=-34
2949.9: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-34
2949.10: irqFlags1=0x98, irqFlags2=0x0, RSSI=-35
2949.11: irqFlags1=0x98, irqFlags2=0x0, RSSI=-32
2949.12: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-32
2949.13: irqFlags1=0x98, irqFlags2=0x0, RSSI=-107
2949.14: irqFlags1=0x98, irqFlags2=0x0, RSSI=-107
2949.15: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-107
2949.16: irqFlags1=0x98, irqFlags2=0x0, RSSI=-104
2949.17: irqFlags1=0x98, irqFlags2=0x0, RSSI=-104
2949.18: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-104
2949.19: irqFlags1=0x98, irqFlags2=0x0, RSSI=-107
Edit: Curiously the cycle time changes to 3ms if instead of waiting for RSSI in the loop we wait for RXREADY. This fits with your observation that waiting for RXREADY is more reliable. I think 3ms is probably the fastest you can sample different values, any faster and there's repetition.
Mark.
BTW, I was finding issuing a restart introduced a delay, but not immediately. The 'scope was showing a delay in the LED toggling inserted into a stream of fast reads. So I wondered what would happen instead of restarting I waited for a PayloadReady and cleared the FIFO, this apparently is also a reset condition. So I tried the code below, and this appears to update the RSSI register with a 100us cycle time (at least when I look at noise the values update on practically every sample) and there are no extra delays introduced by restarting:
void rssiLoop(void)
{
int8_t rssi[20];
uint8_t flags1[20];
uint8_t flags2[20];
uint16_t loopCount = 0;
uint8_t x;
uint16_t cnt1= 0;
uint16_t cnt2= 0;
rfm69WrSpi(REG_RSSITHRESH, 0xFF); // permanently trigger
setRfm69Mode(RX_MODE); // set to RX mode
while(1)
{
loopCount++;
for(x=0; x<20; x++)
{
nLEDON_PORT |= (1 << nLEDON_BIT); // used with 'scope to measure cycle time
// wait for RSSI interrupt
while((rfm69RdSpi(REG_IRQFLAGS1) & IRQFLAGS1_RSSI)==0);
nLEDON_PORT &= ~(1 << nLEDON_BIT); // used with 'scope to measure cycle time
// sample RSSI and flags
rssi[x] = -(rfm69RdSpi(REG_RSSIVALUE)/2);
flags1[x] = rfm69RdSpi(REG_IRQFLAGS1);
flags2[x] = rfm69RdSpi(REG_IRQFLAGS2);
if(flags2[x] & IRQFLAGS2_PAYLOADREADY)
{
while(rfm69RdSpi(REG_IRQFLAGS2) & IRQFLAGS2_FIFONOTEMPTY)
{
rfm69RdSpi(REG_FIFO);
}
}
}
// dump out if we see some activity
if((rssi[6] > -120) && (rssi[9] > 120))
{
SYS_DEBUG((PSTR("cnt1 = %d, cnt2 = %d\r\n"),cnt1,cnt2));
for(x=0; x<20; x++)
{
SYS_DEBUG((PSTR("%d.%d: irqFlags1=0x%X, irqFlags2=0x%X, RSSI=%d\r\n"),loopCount,x,flags1[x],flags2[x],rssi[x]));
}
}
}
}
Here's an example of that, the register is updating quickly on 100us cycle:
33.0: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-111
33.1: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-111
33.2: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-107
33.3: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-110
33.4: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-110
33.5: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-112
33.6: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-112
33.7: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-112
33.8: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-107
33.9: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-107
33.10: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-106
33.11: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-106
33.12: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-108
33.13: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-109
33.14: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-109
33.15: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-110
33.16: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-111
33.17: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-105
33.18: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-107
33.19: irqFlags1=0xD8, irqFlags2=0x0, RSSI=-107
@WhiteHare,
Just to check - AGC and AFC are disabled for these tests?
Good question, and I think I need help/guidance in order to answer it. I'm not sure how to check whether or not they are disabled, because I don't see an explicit enabled/disabled bit for either one. So, I did just now capture what seemed to be the most relevant registers just prior to taking each RSSI reading, and the results were:
1.0. RSSI=-80, regAFCFEI=B10000, regLNA=B10000
1.1. RSSI=-99, regAFCFEI=B10000, regLNA=B10000
1.2. RSSI=-103, regAFCFEI=B10000, regLNA=B10000
1.3. RSSI=-107, regAFCFEI=B10000, regLNA=B10000
1.4. RSSI=-108, regAFCFEI=B10000, regLNA=B10000
1.5. RSSI=-103, regAFCFEI=B10000, regLNA=B10000
1.6. RSSI=-106, regAFCFEI=B10000, regLNA=B10000
1.7. RSSI=-105, regAFCFEI=B10000, regLNA=B10000
1.8. RSSI=-101, regAFCFEI=B10000, regLNA=B10000
1.9. RSSI=-106, regAFCFEI=B10000, regLNA=B10000
2.0. RSSI=-79, regAFCFEI=B10000, regLNA=B10000
2.1. RSSI=-98, regAFCFEI=B10000, regLNA=B10000
2.2. RSSI=-107, regAFCFEI=B10000, regLNA=B10000
2.3. RSSI=-104, regAFCFEI=B10000, regLNA=B10000
2.4. RSSI=-106, regAFCFEI=B10000, regLNA=B10000
2.5. RSSI=-101, regAFCFEI=B10000, regLNA=B10000
2.6. RSSI=-107, regAFCFEI=B10000, regLNA=B10000
2.7. RSSI=-104, regAFCFEI=B10000, regLNA=B10000
2.8. RSSI=-105, regAFCFEI=B10000, regLNA=B10000
2.9. RSSI=-104, regAFCFEI=B10000, regLNA=B10000
3.0. RSSI=-80, regAFCFEI=B10000, regLNA=B10000
3.1. RSSI=-95, regAFCFEI=B10000, regLNA=B10000
3.2. RSSI=-105, regAFCFEI=B10000, regLNA=B10000
3.3. RSSI=-110, regAFCFEI=B10000, regLNA=B10000
3.4. RSSI=-108, regAFCFEI=B10000, regLNA=B10000
3.5. RSSI=-105, regAFCFEI=B10000, regLNA=B10000
3.6. RSSI=-103, regAFCFEI=B10000, regLNA=B10000
3.7. RSSI=-107, regAFCFEI=B10000, regLNA=B10000
3.8. RSSI=-102, regAFCFEI=B10000, regLNA=B10000
3.9. RSSI=-101, regAFCFEI=B10000, regLNA=B10000
4.0. RSSI=-79, regAFCFEI=B10000, regLNA=B10000
4.1. RSSI=-99, regAFCFEI=B10000, regLNA=B10000
4.2. RSSI=-109, regAFCFEI=B10000, regLNA=B10000
4.3. RSSI=-105, regAFCFEI=B10000, regLNA=B10000
4.4. RSSI=-108, regAFCFEI=B10000, regLNA=B10000
4.5. RSSI=-109, regAFCFEI=B10000, regLNA=B10000
4.6. RSSI=-102, regAFCFEI=B10000, regLNA=B10000
4.7. RSSI=-108, regAFCFEI=B10000, regLNA=B10000
4.8. RSSI=-107, regAFCFEI=B10000, regLNA=B10000
4.9. RSSI=-111, regAFCFEI=B10000, regLNA=B10000
5.0. RSSI=-64, regAFCFEI=B10000, regLNA=B10000
5.1. RSSI=-101, regAFCFEI=B10000, regLNA=B10000
5.2. RSSI=-104, regAFCFEI=B10000, regLNA=B10000
5.3. RSSI=-110, regAFCFEI=B10000, regLNA=B10000
5.4. RSSI=-105, regAFCFEI=B10000, regLNA=B10000
5.5. RSSI=-109, regAFCFEI=B10000, regLNA=B10000
5.6. RSSI=-107, regAFCFEI=B10000, regLNA=B10000
5.7. RSSI=-105, regAFCFEI=B10000, regLNA=B10000
5.8. RSSI=-102, regAFCFEI=B10000, regLNA=B10000
5.9. RSSI=-104, regAFCFEI=B10000, regLNA=B10000
BTW, the above results came from running on the Moteino with the shorted antenna (discussed previously and shown in a photo I posted earlier above).
So, from the look of it, AFC is "finished" whereas FEI is "on-going" according to the datasheet. So, in this context, does that mean that AFC is effectively "disabled"? Does it matter that FEI is "on-going"?
Regarding AGC, it looks as though "gain set by the internal AGC loop," according to the datasheet, so I guess that means AGC is "enabled"? The only way I see to "disable" AGC is maybe to manually pick some specific LnaGainSelect. Is that right? In all the cases, the LNA gain is set to B010, which the datasheet says maps to "G2 = highest gain – 6 dB".
So, setting LNA manually to G1 yields the following results:
1.0. RSSI=-102, regAFCFEI=B10000, regLNA=B1001
1.1. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
1.2. RSSI=-112, regAFCFEI=B10000, regLNA=B1001
1.3. RSSI=-105, regAFCFEI=B10000, regLNA=B1001
1.4. RSSI=-108, regAFCFEI=B10000, regLNA=B1001
1.5. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
1.6. RSSI=-110, regAFCFEI=B10000, regLNA=B1001
1.7. RSSI=-109, regAFCFEI=B10000, regLNA=B1001
1.8. RSSI=-111, regAFCFEI=B10000, regLNA=B1001
1.9. RSSI=-114, regAFCFEI=B10000, regLNA=B1001
2.0. RSSI=-98, regAFCFEI=B10000, regLNA=B1001
2.1. RSSI=-109, regAFCFEI=B10000, regLNA=B1001
2.2. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
2.3. RSSI=-127, regAFCFEI=B10000, regLNA=B1001
2.4. RSSI=-110, regAFCFEI=B10000, regLNA=B1001
2.5. RSSI=-115, regAFCFEI=B10000, regLNA=B1001
2.6. RSSI=-109, regAFCFEI=B10000, regLNA=B1001
2.7. RSSI=-107, regAFCFEI=B10000, regLNA=B1001
2.8. RSSI=-116, regAFCFEI=B10000, regLNA=B1001
2.9. RSSI=-112, regAFCFEI=B10000, regLNA=B1001
3.0. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
3.1. RSSI=-114, regAFCFEI=B10000, regLNA=B1001
3.2. RSSI=-110, regAFCFEI=B10000, regLNA=B1001
3.3. RSSI=-104, regAFCFEI=B10000, regLNA=B1001
3.4. RSSI=-110, regAFCFEI=B10000, regLNA=B1001
3.5. RSSI=-108, regAFCFEI=B10000, regLNA=B1001
3.6. RSSI=-112, regAFCFEI=B10000, regLNA=B1001
3.7. RSSI=-104, regAFCFEI=B10000, regLNA=B1001
3.8. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
3.9. RSSI=-108, regAFCFEI=B10000, regLNA=B1001
4.0. RSSI=-105, regAFCFEI=B10000, regLNA=B1001
4.1. RSSI=-114, regAFCFEI=B10000, regLNA=B1001
4.2. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
4.3. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
4.4. RSSI=-107, regAFCFEI=B10000, regLNA=B1001
4.5. RSSI=-111, regAFCFEI=B10000, regLNA=B1001
4.6. RSSI=-110, regAFCFEI=B10000, regLNA=B1001
4.7. RSSI=-110, regAFCFEI=B10000, regLNA=B1001
4.8. RSSI=-109, regAFCFEI=B10000, regLNA=B1001
4.9. RSSI=-109, regAFCFEI=B10000, regLNA=B1001
5.0. RSSI=-102, regAFCFEI=B10000, regLNA=B1001
5.1. RSSI=-112, regAFCFEI=B10000, regLNA=B1001
5.2. RSSI=-111, regAFCFEI=B10000, regLNA=B1001
5.3. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
5.4. RSSI=-107, regAFCFEI=B10000, regLNA=B1001
5.5. RSSI=-109, regAFCFEI=B10000, regLNA=B1001
5.6. RSSI=-110, regAFCFEI=B10000, regLNA=B1001
5.7. RSSI=-107, regAFCFEI=B10000, regLNA=B1001
5.8. RSSI=-106, regAFCFEI=B10000, regLNA=B1001
5.9. RSSI=-104, regAFCFEI=B10000, regLNA=B1001
Setting LNA manually to G2 (which is what the AGC was selecting) yields:
1.0. RSSI=-103, regAFCFEI=B10000, regLNA=B10010
1.1. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
1.2. RSSI=-107, regAFCFEI=B10000, regLNA=B10010
1.3. RSSI=-108, regAFCFEI=B10000, regLNA=B10010
1.4. RSSI=-102, regAFCFEI=B10000, regLNA=B10010
1.5. RSSI=-106, regAFCFEI=B10000, regLNA=B10010
1.6. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
1.7. RSSI=-106, regAFCFEI=B10000, regLNA=B10010
1.8. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
1.9. RSSI=-103, regAFCFEI=B10000, regLNA=B10010
2.0. RSSI=-100, regAFCFEI=B10000, regLNA=B10010
2.1. RSSI=-104, regAFCFEI=B10000, regLNA=B10010
2.2. RSSI=-106, regAFCFEI=B10000, regLNA=B10010
2.3. RSSI=-102, regAFCFEI=B10000, regLNA=B10010
2.4. RSSI=-104, regAFCFEI=B10000, regLNA=B10010
2.5. RSSI=-101, regAFCFEI=B10000, regLNA=B10010
2.6. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
2.7. RSSI=-109, regAFCFEI=B10000, regLNA=B10010
2.8. RSSI=-102, regAFCFEI=B10000, regLNA=B10010
2.9. RSSI=-101, regAFCFEI=B10000, regLNA=B10010
3.0. RSSI=-102, regAFCFEI=B10000, regLNA=B10010
3.1. RSSI=-102, regAFCFEI=B10000, regLNA=B10010
3.2. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
3.3. RSSI=-104, regAFCFEI=B10000, regLNA=B10010
3.4. RSSI=-107, regAFCFEI=B10000, regLNA=B10010
3.5. RSSI=-103, regAFCFEI=B10000, regLNA=B10010
3.6. RSSI=-107, regAFCFEI=B10000, regLNA=B10010
3.7. RSSI=-104, regAFCFEI=B10000, regLNA=B10010
3.8. RSSI=-106, regAFCFEI=B10000, regLNA=B10010
3.9. RSSI=-103, regAFCFEI=B10000, regLNA=B10010
4.0. RSSI=-107, regAFCFEI=B10000, regLNA=B10010
4.1. RSSI=-106, regAFCFEI=B10000, regLNA=B10010
4.2. RSSI=-104, regAFCFEI=B10000, regLNA=B10010
4.3. RSSI=-113, regAFCFEI=B10000, regLNA=B10010
4.4. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
4.5. RSSI=-104, regAFCFEI=B10000, regLNA=B10010
4.6. RSSI=-107, regAFCFEI=B10000, regLNA=B10010
4.7. RSSI=-103, regAFCFEI=B10000, regLNA=B10010
4.8. RSSI=-107, regAFCFEI=B10000, regLNA=B10010
4.9. RSSI=-108, regAFCFEI=B10000, regLNA=B10010
5.0. RSSI=-102, regAFCFEI=B10000, regLNA=B10010
5.1. RSSI=-101, regAFCFEI=B10000, regLNA=B10010
5.2. RSSI=-101, regAFCFEI=B10000, regLNA=B10010
5.3. RSSI=-104, regAFCFEI=B10000, regLNA=B10010
5.4. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
5.5. RSSI=-102, regAFCFEI=B10000, regLNA=B10010
5.6. RSSI=-105, regAFCFEI=B10000, regLNA=B10010
5.7. RSSI=-101, regAFCFEI=B10000, regLNA=B10010
5.8. RSSI=-100, regAFCFEI=B10000, regLNA=B10010
5.9. RSSI=-109, regAFCFEI=B10000, regLNA=B10010
Setting LNA manually to G6 (which is what the AGC was selecting) yields:
1.0. RSSI=-66, regAFCFEI=B10000, regLNA=B110110
1.1. RSSI=-70, regAFCFEI=B10000, regLNA=B110110
1.2. RSSI=-65, regAFCFEI=B10000, regLNA=B110110
1.3. RSSI=-63, regAFCFEI=B10000, regLNA=B110110
1.4. RSSI=-65, regAFCFEI=B10000, regLNA=B110110
1.5. RSSI=-65, regAFCFEI=B10000, regLNA=B110110
1.6. RSSI=-71, regAFCFEI=B10000, regLNA=B110110
1.7. RSSI=-67, regAFCFEI=B10000, regLNA=B110110
1.8. RSSI=-68, regAFCFEI=B10000, regLNA=B110110
1.9. RSSI=-64, regAFCFEI=B10000, regLNA=B110110
2.0. RSSI=-62, regAFCFEI=B10000, regLNA=B110110
2.1. RSSI=-63, regAFCFEI=B10000, regLNA=B110110
2.2. RSSI=-63, regAFCFEI=B10000, regLNA=B110110
2.3. RSSI=-67, regAFCFEI=B10000, regLNA=B110110
2.4. RSSI=-70, regAFCFEI=B10000, regLNA=B110110
2.5. RSSI=-68, regAFCFEI=B10000, regLNA=B110110
2.6. RSSI=-63, regAFCFEI=B10000, regLNA=B110110
2.7. RSSI=-72, regAFCFEI=B10000, regLNA=B110110
2.8. RSSI=-70, regAFCFEI=B10000, regLNA=B110110
2.9. RSSI=-67, regAFCFEI=B10000, regLNA=B110110
3.0. RSSI=-62, regAFCFEI=B10000, regLNA=B110110
3.1. RSSI=-72, regAFCFEI=B10000, regLNA=B110110
3.2. RSSI=-65, regAFCFEI=B10000, regLNA=B110110
3.3. RSSI=-69, regAFCFEI=B10000, regLNA=B110110
3.4. RSSI=-66, regAFCFEI=B10000, regLNA=B110110
3.5. RSSI=-65, regAFCFEI=B10000, regLNA=B110110
3.6. RSSI=-70, regAFCFEI=B10000, regLNA=B110110
3.7. RSSI=-62, regAFCFEI=B10000, regLNA=B110110
3.8. RSSI=-65, regAFCFEI=B10000, regLNA=B110110
3.9. RSSI=-63, regAFCFEI=B10000, regLNA=B110110
4.0. RSSI=-63, regAFCFEI=B10000, regLNA=B110110
4.1. RSSI=-60, regAFCFEI=B10000, regLNA=B110110
4.2. RSSI=-69, regAFCFEI=B10000, regLNA=B110110
4.3. RSSI=-68, regAFCFEI=B10000, regLNA=B110110
4.4. RSSI=-72, regAFCFEI=B10000, regLNA=B110110
4.5. RSSI=-68, regAFCFEI=B10000, regLNA=B110110
4.6. RSSI=-69, regAFCFEI=B10000, regLNA=B110110
4.7. RSSI=-75, regAFCFEI=B10000, regLNA=B110110
4.8. RSSI=-65, regAFCFEI=B10000, regLNA=B110110
4.9. RSSI=-74, regAFCFEI=B10000, regLNA=B110110
5.0. RSSI=-66, regAFCFEI=B10000, regLNA=B110110
5.1. RSSI=-66, regAFCFEI=B10000, regLNA=B110110
5.2. RSSI=-71, regAFCFEI=B10000, regLNA=B110110
5.3. RSSI=-64, regAFCFEI=B10000, regLNA=B110110
5.4. RSSI=-68, regAFCFEI=B10000, regLNA=B110110
5.5. RSSI=-67, regAFCFEI=B10000, regLNA=B110110
5.6. RSSI=-66, regAFCFEI=B10000, regLNA=B110110
5.7. RSSI=-66, regAFCFEI=B10000, regLNA=B110110
5.8. RSSI=-68, regAFCFEI=B10000, regLNA=B110110
5.9. RSSI=-69, regAFCFEI=B10000, regLNA=B110110
So, given the difference between manually setting LNA to G2 versus letting AGC set the LNA to G2, the manual setting seems less anomalous.
Theoretically, with a shorted antenna, all the RSSI values should be -127, at least ideally. Isn't that right? Looking at the above results, the only time I get even one measurement with RSSI=-127 is when LNA is set to G1.
Bottom line: when just measuring ambient RSSI, is it best to manually set LNA to G1?
On the other hand, suppose you determine empirically that when receiving packets from a particular RFM69 Moteino, the AGC is generally using a gain of G2. In that case, maybe setting LNA manually to G2 would be the more relevant choice, because then you'd be measuring the background RSSI at the LNA level that's most relevant to receiving packets from that particular RFM69 Moteino. Isn't that right?
I'm just feeling my way through the dark here, so any and all comments/suggestions/help/guidance would be more than welcome.
Not to overcomplicate the discussion, but does DC cancellation figure into this at all? Quoting the datasheet: "DC cancellation is required in zero-IF architecture transceivers to remove any DC offset generated through self-reception." What kind of "self-reception" is it referring to? i.e. Is that "self-reception" the result of the transceiver's own transmission, or is it "self-reception" of the noise created by the RFM69 in normal operation?
The datasheet also says, "It is advised to adjust the DCC setting while monitoring the receiver sensitivity." How does one even do that? I've searched this forum and haven't found any meaningful postings about DCC.
This post confirms a finding that Perky posted just recently:
If I setup to do an RxRestart after every measurement of RSSI, and if I record the time interval between RSSI measurements, an interesting pattern emerges:
---------------------------------------------------------------------
Radio Configuration:
====================
Receiver-Mode(RX)
Packet Mode, FSK modulation scheme
[ActualBitrate] 4799.760bps = nominal bitrate of 4800bps
[RxBw] 10416Hz
[RxBwExp] B101 (Bits 0-2 of regRXBW) = 5
[theRxBwMant] B10 (Bits 3-4 of regRXBW) -> [RxBwMant] 24
---------------------------------------------------------------------
0.0. RSSI=-116
1.0. RSSI=-116, elapsed=108uSec
2.0. RSSI=-116, elapsed=104uSec
3.0. RSSI=-116, elapsed=116uSec
4.0. RSSI=-116, elapsed=104uSec
5.0. RSSI=-116, elapsed=108uSec
6.0. RSSI=-115, elapsed=1752uSec
7.0. RSSI=-115, elapsed=112uSec
8.0. RSSI=-115, elapsed=108uSec
9.0. RSSI=-115, elapsed=108uSec
10.0. RSSI=-115, elapsed=104uSec
11.0. RSSI=-115, elapsed=108uSec
12.0. RSSI=-116, elapsed=1760uSec
13.0. RSSI=-116, elapsed=104uSec
14.0. RSSI=-116, elapsed=108uSec
15.0. RSSI=-116, elapsed=108uSec
16.0. RSSI=-116, elapsed=104uSec
17.0. RSSI=-116, elapsed=108uSec
18.0. RSSI=-115, elapsed=1760uSec
19.0. RSSI=-115, elapsed=104uSec
20.0. RSSI=-115, elapsed=108uSec
21.0. RSSI=-115, elapsed=104uSec
22.0. RSSI=-115, elapsed=108uSec
23.0. RSSI=-115, elapsed=108uSec
24.0. RSSI=-113, elapsed=1756uSec
25.0. RSSI=-113, elapsed=108uSec
26.0. RSSI=-113, elapsed=108uSec
27.0. RSSI=-113, elapsed=112uSec
28.0. RSSI=-113, elapsed=108uSec
29.0. RSSI=-113, elapsed=104uSec
30.0. RSSI=-116, elapsed=1752uSec
31.0. RSSI=-116, elapsed=116uSec
32.0. RSSI=-116, elapsed=104uSec
33.0. RSSI=-116, elapsed=108uSec
34.0. RSSI=-116, elapsed=108uSec
35.0. RSSI=-116, elapsed=104uSec
36.0. RSSI=-119, elapsed=1736uSec
37.0. RSSI=-119, elapsed=104uSec
38.0. RSSI=-119, elapsed=108uSec
39.0. RSSI=-119, elapsed=104uSec
40.0. RSSI=-119, elapsed=108uSec
41.0. RSSI=-119, elapsed=108uSec
42.0. RSSI=-115, elapsed=1756uSec
43.0. RSSI=-115, elapsed=108uSec
44.0. RSSI=-115, elapsed=108uSec
45.0. RSSI=-115, elapsed=104uSec
46.0. RSSI=-115, elapsed=108uSec
47.0. RSSI=-115, elapsed=108uSec
48.0. RSSI=-114, elapsed=1756uSec
49.0. RSSI=-114, elapsed=108uSec
50.0. RSSI=-114, elapsed=108uSec
51.0. RSSI=-114, elapsed=104uSec
52.0. RSSI=-114, elapsed=112uSec
53.0. RSSI=-114, elapsed=108uSec
54.0. RSSI=-119, elapsed=1752uSec
55.0. RSSI=-119, elapsed=108uSec
56.0. RSSI=-119, elapsed=112uSec
57.0. RSSI=-119, elapsed=108uSec
58.0. RSSI=-119, elapsed=104uSec
59.0. RSSI=-119, elapsed=108uSec
60.0. RSSI=-117, elapsed=1732uSec
61.0. RSSI=-117, elapsed=108uSec
62.0. RSSI=-117, elapsed=108uSec
63.0. RSSI=-117, elapsed=104uSec
64.0. RSSI=-117, elapsed=108uSec
65.0. RSSI=-117, elapsed=108uSec
66.0. RSSI=-114, elapsed=1756uSec
67.0. RSSI=-114, elapsed=108uSec
68.0. RSSI=-114, elapsed=108uSec
69.0. RSSI=-114, elapsed=104uSec
70.0. RSSI=-114, elapsed=108uSec
71.0. RSSI=-114, elapsed=108uSec
72.0. RSSI=-115, elapsed=1756uSec
73.0. RSSI=-115, elapsed=108uSec
74.0. RSSI=-115, elapsed=108uSec
75.0. RSSI=-115, elapsed=104uSec
76.0. RSSI=-115, elapsed=108uSec
77.0. RSSI=-115, elapsed=112uSec
78.0. RSSI=-116, elapsed=1752uSec
79.0. RSSI=-116, elapsed=108uSec
80.0. RSSI=-116, elapsed=112uSec
81.0. RSSI=-116, elapsed=108uSec
82.0. RSSI=-116, elapsed=104uSec
83.0. RSSI=-116, elapsed=108uSec
84.0. RSSI=-115, elapsed=1760uSec
85.0. RSSI=-115, elapsed=104uSec
86.0. RSSI=-115, elapsed=108uSec
87.0. RSSI=-115, elapsed=108uSec
88.0. RSSI=-115, elapsed=104uSec
89.0. RSSI=-115, elapsed=108uSec
90.0. RSSI=-115, elapsed=1732uSec
91.0. RSSI=-115, elapsed=108uSec
92.0. RSSI=-115, elapsed=108uSec
93.0. RSSI=-115, elapsed=104uSec
94.0. RSSI=-115, elapsed=108uSec
95.0. RSSI=-115, elapsed=104uSec
96.0. RSSI=-116, elapsed=1760uSec
97.0. RSSI=-116, elapsed=108uSec
98.0. RSSI=-116, elapsed=104uSec
99.0. RSSI=-116, elapsed=108uSec
Very often when the RSSI does change, it coincides with a much longer time to take the RSSI measurement (an order of magnitude longer).
That is to say: at lower bitrates such as these, the period between fresh RSSI measurements is noticeably longer.
Thanks for the encouragement. :)
So as to continue, I just now hooked up a factory fresh Moteino with the regular RFM69HW and wire antenna using Felix's FTDI connector. So, this is a little different, because Antenna is not shorted to ground, it has a wire antenna, and its voltage regulator is still intact. On the plus side, though, is that the hardware hasn't been monkeyed with, and so I don't expect anything will come loose anytime soon. Also, all of what follows should be easily reproducible by anyone reading this.
Here's the TL;DR summary: with this setup there is a disparity between the results that come from just reading the D2 pin versus attaching an interrupt to the D2 pin.
Using:
while (!(digitalRead(D2))) {} // Wait for RSSI to go HIGH
the RSSI flag doesn't appear to go high until about 6968uSeconds after putting the RFM69HW into Rx Mode:
---------------------------------------------------------------------
RSSI=-116, rssiFlagRising=6968uSec
RSSI=-118, rssiFlagRising=6968uSec
RSSI=-117, rssiFlagRising=6968uSec
RSSI=-115, rssiFlagRising=6968uSec
---------------------------------------------------------------------
However, if I attach an interrupt instead to D2 and attempt to get the atmega328p to enter powerdown sleep, what I get instead is:
---------------------------------------------------------------------
RSSI=-118, rssiFlagRising=12uSec
RSSI=-118, rssiFlagRising=16uSec
RSSI=-118, rssiFlagRising=16uSec
RSSI=-118, rssiFlagRising=12uSec
---------------------------------------------------------------------
RSSI=-115, rssiFlagRising=12uSec
RSSI=-115, rssiFlagRising=16uSec
RSSI=-115, rssiFlagRising=16uSec
RSSI=-115, rssiFlagRising=16uSec
---------------------------------------------------------------------
RSSI=-116, rssiFlagRising=16uSec
RSSI=-116, rssiFlagRising=16uSec
RSSI=-116, rssiFlagRising=12uSec
RSSI=-116, rssiFlagRising=16uSec
---------------------------------------------------------------------
RSSI=-117, rssiFlagRising=16uSec
RSSI=-117, rssiFlagRising=16uSec
RSSI=-117, rssiFlagRising=12uSec
RSSI=-117, rssiFlagRising=16uSec
---------------------------------------------------------------------
Obviously, that is a dramatic difference.
The code I'm using to attach the interrupt, powerdown, and wake up, is Nick Gammon's "Sketch J" ( http://www.gammon.com.au/power), which I simply repackaged as "sleepNow()":
#include <avr/sleep.h>
void wake ()
{
// cancel sleep as a precaution
sleep_disable();
// precautionary while we do other stuff
detachInterrupt (0);
} // end of wake
void sleepNow ()
{
// disable ADC
ADCSRA = 0;
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
// Do not interrupt before we go to sleep, or the
// ISR will detach interrupts and we won't wake.
noInterrupts ();
// will be called when pin D2 goes HIGH
attachInterrupt (0, wake, RISING);
EIFR = bit (INTF0); // clear flag for interrupt 0
// turn off brown-out enable in software
// BODS must be set to one and BODSE must be set to zero within four clock cycles
MCUCR = bit (BODS) | bit (BODSE);
// The BODS bit is automatically cleared after three clock cycles
MCUCR = bit (BODS);
// We are guaranteed that the sleep_cpu call will be done
// as the processor executes the next instruction after
// interrupts are turned on.
interrupts (); // one cycle
sleep_cpu (); // one cycle
} // end of sleepNow()
The only difference between the first and second sets of results is that I replaced:
while (!(digitalRead(D2))) {} // Wait for RSSI to go HIGH
with
If anyone has a better way to handle the interrupt scenario, please post a link and I'll try it instead. Normally Gammon's code works just fine for me, but just not now when DIO0 is mapped to RSSI. What's clear is that the atmega328p never even fully gets into deep powerdown sleep, because if it did, it would take about 2.1ms (at 8Mhz) just to wake up.
I think I found something which may inform what's going on. If I disconnect DIO0 from D2 but run the code above anyway (the version that is using the interrupt attachment), the result is:
---------------------------------------------------------------------
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=24uSec
RSSI=-127, rssiFlagRising=24uSec
---------------------------------------------------------------------
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=32uSec
---------------------------------------------------------------------
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=24uSec
RSSI=-127, rssiFlagRising=24uSec
RSSI=-127, rssiFlagRising=32uSec
---------------------------------------------------------------------
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=32uSec
RSSI=-127, rssiFlagRising=32uSec
---------------------------------------------------------------------
It makes sense that RSSI=-127, because PllLock hasn't yet gone high. So, the pregnant questions are:
1. Why wasn't RSSI=-127 when DIO0 was wired to D2? After all, it triggered at nearly the same time. My hypothesis is there must have been noise travelling from D2 into DIO0, and then into the radio.
2. Why does the interrupt trigger at all? Nothing is coming from DIO0 to trigger D2. Because there is no pulldown or pullup resistor, D2 is just a floating pin, so it must be triggering off whatever noise happens to be on D2. And whatever that noise is, it seems to hit the RISING threshhold fairly consistently at about 24-32uSec after putting the RFM69 into Rx Mode.
So, if I disconnect more wires from the radio one by one, and rerun the code, perhaps I'll narrow it down to the wire or wires which are causing D2 to trigger at the 24-32uSec mark, and that, then, would be a likely suspect for the noise.
[Edit: OK, so I next severed the wire that was connecting DIO3 to D3 (where D3 was using the default 00 mapping to FifoFull. Wow, the results sure did surprise me:
---------------------------------------------------------------------
RSSI=-117, rssiFlagRising=24uSec
RSSI=-119, rssiFlagRising=32uSec
RSSI=-120, rssiFlagRising=32uSec
RSSI=-122, rssiFlagRising=32uSec
---------------------------------------------------------------------
RSSI=-121, rssiFlagRising=32uSec
RSSI=-119, rssiFlagRising=32uSec
RSSI=-116, rssiFlagRising=32uSec
RSSI=-115, rssiFlagRising=32uSec
---------------------------------------------------------------------
RSSI=-116, rssiFlagRising=32uSec
RSSI=-119, rssiFlagRising=32uSec
RSSI=-118, rssiFlagRising=24uSec
RSSI=-119, rssiFlagRising=32uSec
---------------------------------------------------------------------
RSSI=-119, rssiFlagRising=32uSec
RSSI=-118, rssiFlagRising=32uSec
RSSI=-115, rssiFlagRising=32uSec
RSSI=-124, rssiFlagRising=32uSec
---------------------------------------------------------------------
RSSI=-114, rssiFlagRising=24uSec
RSSI=-118, rssiFlagRising=32uSec
RSSI=-117, rssiFlagRising=32uSec
RSSI=-121, rssiFlagRising=24uSec
---------------------------------------------------------------------
RSSI=-118, rssiFlagRising=24uSec
RSSI=-116, rssiFlagRising=24uSec
RSSI=-121, rssiFlagRising=32uSec
RSSI=-120, rssiFlagRising=32uSec
---------------------------------------------------------------------
Now RSSI is showing noise again! WTF? How does that make any sense? FifoFull should have been false, so presumably DIO3 was acting like a ground to D3, which was configured as an input, and therefore high impedance, at least to DC (but maybe not high impedance to high frequency noise?). Is that a possible explanation?]