Compare commits

...

10 Commits

Author SHA1 Message Date
Felix Rusu 47f686d8ed bump to 1.6.0 (forgot the zero!) 2025-10-17 18:13:40 -04:00
Felix Rusu a072d5e5be bump to v1.6 2025-10-17 17:38:15 -04:00
Felix Rusu 4edcee47d8
Update README.md
License explanation
2025-10-17 16:19:36 -04:00
Felix Rusu ec42b5e51b Update RFM69.cpp 2025-10-17 14:23:05 -04:00
Felix Rusu bfcd7a4762 Default 433mhz to legal 433.92mhz
Solves #202
2025-10-17 14:07:34 -04:00
Felix Rusu 705b0ab394 Update TxPowerTest_Transmitter.ino 2025-02-12 21:20:54 -05:00
Felix Rusu e29316c40e revert to working getPowerLevel() 2025-02-12 21:20:36 -05:00
Felix Rusu e038dcfaa8
Merge pull request #195 from brainelectronics/feature/additional-functions
Add new getter functions to RFM69 and RFM69 ATC
2025-02-11 16:12:18 -05:00
Jonas Scharpf 8b5ad8ec6a Add TestSetup.ino sketch to showcase the usage of all available getter functions 2025-01-03 15:18:17 +01:00
Jonas Scharpf 2021234261 Add new getter functions to RFM69 and RFM69 ATC
- getVersion() to read RFM version
- getAddress() to return configured node ID
- getNetwork() to return configured network ID
- getFrequencyDeviation() to read frequency deviation
- getBitRate() to read the modulation bitrate in bits/second
- getSpyMode() to return spy mode setting
- isSyncOn()
- getSyncSize()
- isCrcOn() to check if CRC is activated
- isAesOn() to check if encryption is enabled
- isHighPower() to check if module is configured as HCW or not
- dBm_to_mW() to convert dBm to mW
- getOutputPower() to get the configured output power instead of returning the last set value
- getTargetRssi() to get the configured RSSI value, only for RFM69_ATC
- `_networkID` made public to get it via getNetwork() function
2025-01-03 15:12:16 +01:00
10 changed files with 305 additions and 32 deletions

View File

@ -0,0 +1,159 @@
// Sample RFM69 sketch, with optional encryption, Automatic Transmission Control
// This will only init the radio module and print the values of all getter functions
// No data is transmitted or received. The device will only blink the onboard LED.
// **********************************************************************************
// Copyright Felix Rusu 2025, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU General
// Public License as published by the Free Software
// Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://www.github.com/lowpowerlab/rfm69
//*********************************************************************************************
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE ************
//*********************************************************************************************
// Address IDs are 10bit, meaning usable ID range is 1..1023
// Address 0 is special (broadcast), messages to address 0 are received by all *listening* nodes (ie. active RX mode)
// Gateway ID should be kept at ID=1 for simplicity, although this is not a hard constraint
//*********************************************************************************************
#define NODEID 1 // keep UNIQUE for each node on same network
#define NETWORKID 100 // keep IDENTICAL on all nodes that talk to each other
//*********************************************************************************************
// Frequency should be set to match the radio module hardware tuned frequency,
// otherwise if say a "433mhz" module is set to work at 915, it will work but very badly.
// Moteinos and RF modules from LowPowerLab are marked with a colored dot to help identify their tuned frequency band,
// see this link for details: https://lowpowerlab.com/guide/moteino/transceivers/
// The below examples are predefined "center" frequencies for the radio's tuned "ISM frequency band".
// You can always set the frequency anywhere in the "frequency band", ex. the 915mhz ISM band is 902..928mhz.
//*********************************************************************************************
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
//#define FREQUENCY_EXACT 916000000 // you may define an exact frequency/channel in Hz
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW_HCW //uncomment only for RFM69HW/HCW! Leave out if you have RFM69W/CW!
//*********************************************************************************************
//Auto Transmission Control - dials down transmit power to save battery
//Usually you do not need to always transmit at max output power
//By reducing TX power even a little you save a significant amount of battery power
//This setting enables this gateway to work with remote nodes that have ATC enabled to
//dial their power down to only the required level (ATC_RSSI)
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -80
//*********************************************************************************************
#define SERIAL_BAUD 115200
#define DEBUG(input) Serial.print(input)
#define DEBUGln(input) Serial.println(input)
#define BLINK_INTERVAL 1000 //< [ms] LED heartbeat blink interval
uint32_t last_blink = 0;
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
void setup() {
Serial.begin(SERIAL_BAUD);
pinMode(LED_BUILTIN, OUTPUT);
DEBUGln("START SETUP TEST!");
if (!radio.initialize(FREQUENCY,NODEID,NETWORKID))
DEBUGln("radio.init() FAIL");
else
DEBUGln("radio.init() SUCCESS");
#ifdef IS_RFM69HW_HCW
radio.setHighPower(); // must include this only for RFM69HW/HCW!
#endif
#ifdef ENCRYPTKEY
radio.encrypt(ENCRYPTKEY);
#endif
#ifdef FREQUENCY_EXACT
radio.setFrequency(FREQUENCY_EXACT); // set frequency to some custom frequency
#endif
// Auto Transmission Control - dials down transmit power to save battery (-100 is the noise floor, -90 is still pretty good)
// For indoor nodes that are pretty static and at pretty stable temperatures (like a MotionMote) -90dBm is quite safe
// For more variable nodes that can expect to move or experience larger temp drifts a lower margin like -70 to -80 would probably be better
// Always test your ATC mote in the edge cases in your own environment to ensure ATC will perform as you expect
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
test_config();
radio.readAllRegs();
}
void loop() {
uint32_t now = millis();
if (now > (last_blink + BLINK_INTERVAL)) {
last_blink = now;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
}
void test_config() {
/*
RFM version: 36
Node address: 2
Node network: 100
Frequency: 433MHz
Frequency deviation: 49987Hz
Bit rate: 55555bits/sec
Spy mode active: no
HCW module: yes
TX Power 20dBM, 100.00mW
Temperature: 24 Celsius
Sync active: yes
Sync size: 1
CRC on: yes
AES on: no
Target RSSI:-80
*/
DEBUG("RFM version: "); DEBUGln(radio.getVersion());
DEBUG("Node address: "); DEBUGln(radio.getAddress());
DEBUG("Node network: "); DEBUGln(radio.getNetwork());
DEBUG("Frequency: "); DEBUG(radio.getFrequency()/1000000L); DEBUGln("MHz");
DEBUG("Frequency deviation: "); DEBUG(radio.getFrequencyDeviation()); DEBUGln("Hz");
DEBUG("Bit rate: "); DEBUG(radio.getBitRate()); DEBUGln("bits/sec");
DEBUG("Spy mode active: "); DEBUGln(radio.getSpyMode()==1 ? "yes":"no");
DEBUG("HCW module: "); DEBUGln(radio.isHighPower()==1 ? "yes":"no");
uint8_t tx_power = radio.getPowerLevel();
DEBUG("TX Power "); DEBUG(tx_power); DEBUG("dBM, "); DEBUG(radio.dBm_to_mW(tx_power)); DEBUGln("mW");
DEBUG("Temperature: "); DEBUG(radio.readTemperature()); DEBUGln(" Celsius");
DEBUG("Sync active: "); DEBUGln(radio.isSyncOn()==1 ? "yes":"no");
DEBUG("Sync size: "); DEBUGln(radio.getSyncSize());
DEBUG("CRC on: "); DEBUGln(radio.isCrcOn()==1 ? "yes":"no");
DEBUG("AES on: "); DEBUGln(radio.isAesOn()==1 ? "yes":"no");
#ifdef ENABLE_ATC
DEBUG("Target RSSI by ATC: "); DEBUGln(radio.getTargetRssi());
#endif
}

View File

@ -10,6 +10,7 @@
// ********************************************************************************** // **********************************************************************************
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69 #include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> #include <RFM69_ATC.h>
#include <RFM69registers.h>
#define NODEID 123 //must be unique for each node on same network (range up to 254, 255 is used for broadcast) #define NODEID 123 //must be unique for each node on same network (range up to 254, 255 is used for broadcast)
#define NETWORKID 100 //the same on all nodes that talk to each other (range up to 255) #define NETWORKID 100 //the same on all nodes that talk to each other (range up to 255)
@ -17,7 +18,7 @@
//Match frequency to the hardware version of the radio on your Moteino (uncomment one): //Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ //#define FREQUENCY RF69_433MHZ
#define FREQUENCY RF69_915MHZ #define FREQUENCY RF69_915MHZ
#define FREQUENCY_EXACT 915500000 #define FREQUENCY_EXACT 910000000
#define IS_RFM69HW_HCW //uncomment only for RFM69HCW! Leave out if you have RFM69CW! #define IS_RFM69HW_HCW //uncomment only for RFM69HCW! Leave out if you have RFM69CW!
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL #define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -90 #define ATC_RSSI -90
@ -27,6 +28,19 @@
#define DEBUGln(input) Serial.println(input) #define DEBUGln(input) Serial.println(input)
#define DEBUGHEX(input, param) Serial.print(input, param) #define DEBUGHEX(input, param) Serial.print(input, param)
//assert button (to trigger transmission)
#ifdef RFGATEWAY
#define ASSERT_BTN 44
#else
#define ASSERT_BTN A0
#endif
#define TX_MODE_PACKET 1
#define TX_MODE_PACKET_BURST 2
#define TX_MODE_CONSTANT 3
#define TX_PACKET_PAYLOAD "PACKET WITH SOME DATA"
#define TX_MODE TX_MODE_CONSTANT
#ifdef ENABLE_ATC #ifdef ENABLE_ATC
RFM69_ATC radio/*(10,11) FOR M0 radio add-on board*/; //#if defined (__AVR_ATmega32U4__) RFM69_ATC radio(8,7); RFM69_ATC radio/*(10,11) FOR M0 radio add-on board*/; //#if defined (__AVR_ATmega32U4__) RFM69_ATC radio(8,7);
#else #else
@ -35,12 +49,17 @@
int MODE; int MODE;
void printHelp() {
DEBUGln("Use:\nt to toggle transmission on/off");
DEBUGln("+/- to adjust power in _powerLevel steps");
DEBUGln("<,> to adjust power in dBm");
DEBUGln("? to print this command reference\n");
}
void setup() { void setup() {
Serial.begin(SERIAL_BAUD); Serial.begin(SERIAL_BAUD);
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
pinMode(ASSERT_BTN, INPUT_PULLUP);
pinMode(0, OUTPUT); digitalWrite(0, LOW);
pinMode(A0, INPUT_PULLUP);
DEBUGln("START RFM69_NODE_TX_TEST!"); DEBUGln("START RFM69_NODE_TX_TEST!");
@ -49,6 +68,9 @@ void setup() {
else else
DEBUGln("radio.init() SUCCESS"); DEBUGln("radio.init() SUCCESS");
radio.writeReg(REG_FDEVMSB, RF_FDEVMSB_50000);
radio.writeReg(REG_FDEVLSB, RF_FDEVLSB_50000);
#ifdef IS_RFM69HW_HCW #ifdef IS_RFM69HW_HCW
radio.setHighPower(); //only for RFM69HW/HCW! radio.setHighPower(); //only for RFM69HW/HCW!
#endif #endif
@ -61,12 +83,12 @@ void setup() {
radio.enableAutoPower(ATC_RSSI); radio.enableAutoPower(ATC_RSSI);
#endif #endif
delay(5000);
char buff[50]; char buff[50];
sprintf(buff, "\nTransmitting at %lu Mhz...", radio.getFrequency()/1000000L); sprintf(buff, "\nTransmitting at %lu Hz...", radio.getFrequency());
DEBUGln(buff); DEBUGln(buff);
DEBUGln("Use:\n+,- to adjust power in _powerLevel steps"); printHelp();
DEBUGln("<,> to adjust power in dBm");
#ifdef ENABLE_ATC #ifdef ENABLE_ATC
DEBUGln("RFM69_ATC Enabled (Auto Transmission Control)\n"); DEBUGln("RFM69_ATC Enabled (Auto Transmission Control)\n");
@ -111,15 +133,26 @@ void loop() {
if (MODE == RF69_MODE_TX) { if (MODE == RF69_MODE_TX) {
MODE = RF69_MODE_SLEEP; MODE = RF69_MODE_SLEEP;
DEBUG("RADIO_MODE = 0/SLEEP; _powerLevel=");DEBUGln(radio.getPowerLevel()); DEBUG("RADIO_MODE = 0/SLEEP; _powerLevel=");DEBUGln(radio.getPowerLevel());
} } else {
else {
MODE = RF69_MODE_TX; MODE = RF69_MODE_TX;
DEBUG("RADIO_MODE = 4/TX; _powerLevel=");DEBUGln(radio.getPowerLevel()); DEBUG("RADIO_MODE = 4/TX; _powerLevel=");DEBUGln(radio.getPowerLevel());
} }
} }
if (input=='?') printHelp();
} }
delay(200); delay(100);
if (MODE == RF69_MODE_TX) radio.setMode(MODE); if (MODE == RF69_MODE_TX) radio.setMode(MODE);
else if (digitalRead(A0)==LOW) radio.setMode(RF69_MODE_TX); else if (digitalRead(ASSERT_BTN)==LOW) {
if (TX_MODE == TX_MODE_PACKET) {
DEBUGln("Sending 1 PACKET to node 88");
radio.send(88, TX_PACKET_PAYLOAD, strlen(TX_PACKET_PAYLOAD));
} else if (TX_MODE == TX_MODE_PACKET_BURST) {
DEBUGln("Sending RETRY PACKET to node 88");
radio.sendWithRetry(88, TX_PACKET_PAYLOAD, strlen(TX_PACKET_PAYLOAD));
} else if (TX_MODE == TX_MODE_CONSTANT) {
DEBUGln("Modulating constant carrier");
radio.setMode(TX_MODE);
}
}
else radio.setMode(RF69_MODE_SLEEP); else radio.setMode(RF69_MODE_SLEEP);
} }

View File

@ -13,7 +13,11 @@ RFM69 library for RFM69W, RFM69HW, RFM69CW, RFM69HCW (semtech SX1231, SX1231H)
The latest examples, new features and bug fixes are found in the [original repository](https://github.com/LowPowerLab/RFM69) of this library. The latest examples, new features and bug fixes are found in the [original repository](https://github.com/LowPowerLab/RFM69) of this library.
## License ## License
GPL 3.0, please see the [License.txt](https://github.com/LowPowerLab/RFM69/blob/master/License.txt) file for details. Be sure to include the same license with any fork or redistribution of this library. The default license is GPL 3.0, please see the [License.txt](https://github.com/LowPowerLab/RFM69/blob/master/License.txt) file for details. Be sure to include the same license with any fork or redistribution of this library.
<br/>
You are free to use the library for personal or commercial purposes but you must adhere to its copyleft requirements. This means that any modified or derivative work you distribute must also be licensed under GPL, and you must provide the source code to recipients.
<br/>
**For any other custom licensing arrangements where these terms are not acceptable, you must contact the [author directly]([url](https://github.com/LowPowerLab)) or use the [contact form through LowPowerLab.com](lowpowerlab.com/contact).**
## Features ## Features
- easy to use API with a few simple functions for basic usage - easy to use API with a few simple functions for basic usage

View File

@ -68,12 +68,12 @@ bool RFM69::initialize(uint8_t freqBand, uint16_t nodeID, uint8_t networkID) {
/* 0x02 */ { REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 }, // no shaping /* 0x02 */ { REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 }, // no shaping
/* 0x03 */ { REG_BITRATEMSB, RF_BITRATEMSB_55555}, // default: 4.8 KBPS /* 0x03 */ { REG_BITRATEMSB, RF_BITRATEMSB_55555}, // default: 4.8 KBPS
/* 0x04 */ { REG_BITRATELSB, RF_BITRATELSB_55555}, /* 0x04 */ { REG_BITRATELSB, RF_BITRATELSB_55555},
/* 0x05 */ { REG_FDEVMSB, RF_FDEVMSB_50000}, // default: 5KHz, (FDEV + BitRate / 2 <= 500KHz) /* 0x05 */ { REG_FDEVMSB, RF_FDEVMSB_50000}, // default: 5KHz, (FDEV+(BitRate/2)<=500KHz)
/* 0x06 */ { REG_FDEVLSB, RF_FDEVLSB_50000}, /* 0x06 */ { REG_FDEVLSB, RF_FDEVLSB_50000},
/* 0x07 */ { REG_FRFMSB, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFMSB_315 : (freqBand==RF69_433MHZ ? RF_FRFMSB_433 : (freqBand==RF69_868MHZ ? RF_FRFMSB_868 : RF_FRFMSB_915))) }, /* 0x07 */ { REG_FRFMSB, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFMSB_315 : (freqBand==RF69_433MHZ ? RF_FRFMSB_433_92 : (freqBand==RF69_868MHZ ? RF_FRFMSB_868 : RF_FRFMSB_915))) },
/* 0x08 */ { REG_FRFMID, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFMID_315 : (freqBand==RF69_433MHZ ? RF_FRFMID_433 : (freqBand==RF69_868MHZ ? RF_FRFMID_868 : RF_FRFMID_915))) }, /* 0x08 */ { REG_FRFMID, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFMID_315 : (freqBand==RF69_433MHZ ? RF_FRFMID_433_92 : (freqBand==RF69_868MHZ ? RF_FRFMID_868 : RF_FRFMID_915))) },
/* 0x09 */ { REG_FRFLSB, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFLSB_315 : (freqBand==RF69_433MHZ ? RF_FRFLSB_433 : (freqBand==RF69_868MHZ ? RF_FRFLSB_868 : RF_FRFLSB_915))) }, /* 0x09 */ { REG_FRFLSB, (uint8_t) (freqBand==RF69_315MHZ ? RF_FRFLSB_315 : (freqBand==RF69_433MHZ ? RF_FRFLSB_433_92 : (freqBand==RF69_868MHZ ? RF_FRFLSB_868 : RF_FRFLSB_915))) },
// looks like PA1 and PA2 are not implemented on RFM69W/CW, hence the max output power is 13dBm // looks like PA1 and PA2 are not implemented on RFM69W/CW, hence the max output power is 13dBm
// +17dBm and +20dBm are possible on RFM69HW // +17dBm and +20dBm are possible on RFM69HW
@ -140,14 +140,18 @@ bool RFM69::initialize(uint8_t freqBand, uint16_t nodeID, uint8_t networkID) {
attachInterrupt(_interruptNum, RFM69::isr0, RISING); attachInterrupt(_interruptNum, RFM69::isr0, RISING);
_address = nodeID; _address = nodeID;
_networkID = networkID;
#if defined(RF69_LISTENMODE_ENABLE) #if defined(RF69_LISTENMODE_ENABLE)
selfPointer = this; selfPointer = this;
_freqBand = freqBand; _freqBand = freqBand;
_networkID = networkID;
#endif #endif
return true; return true;
} }
uint8_t RFM69::getVersion() {
return readReg(REG_VERSION);
}
// return the frequency (in Hz) // return the frequency (in Hz)
uint32_t RFM69::getFrequency() { uint32_t RFM69::getFrequency() {
return RF69_FSTEP * (((uint32_t) readReg(REG_FRFMSB) << 16) + ((uint16_t) readReg(REG_FRFMID) << 8) + readReg(REG_FRFLSB)); return RF69_FSTEP * (((uint32_t) readReg(REG_FRFMSB) << 16) + ((uint16_t) readReg(REG_FRFMID) << 8) + readReg(REG_FRFLSB));
@ -169,6 +173,15 @@ void RFM69::setFrequency(uint32_t freqHz) {
setMode(oldMode); setMode(oldMode);
} }
// return the frequency deviation (in Hz)
uint32_t RFM69::getFrequencyDeviation() {
return RF69_FSTEP * ((readReg(REG_FDEVMSB) << 8) | readReg(REG_FDEVLSB));
}
uint32_t RFM69::getBitRate() {
return RF69_FXOSC / ((readReg(REG_BITRATEMSB) << 8) | readReg(REG_BITRATELSB));
}
void RFM69::setMode(uint8_t newMode) { void RFM69::setMode(uint8_t newMode) {
if (newMode == _mode) if (newMode == _mode)
return; return;
@ -210,14 +223,23 @@ void RFM69::sleep() {
// set this node's address // set this node's address
void RFM69::setAddress(uint16_t addr) { void RFM69::setAddress(uint16_t addr) {
_address = addr; _address = addr;
writeReg(REG_NODEADRS, _address); //unused in packet mode writeReg(REG_NODEADRS, _address); // unused in packet mode
}
uint16_t RFM69::getAddress() {
return _address;
} }
// set this node's network id // set this node's network id
void RFM69::setNetwork(uint8_t networkID) { void RFM69::setNetwork(uint8_t networkID) {
_networkID = networkID;
writeReg(REG_SYNCVALUE2, networkID); writeReg(REG_SYNCVALUE2, networkID);
} }
uint8_t RFM69::getNetwork() {
return _networkID;
}
// set user's ISR callback // set user's ISR callback
void RFM69::setIsrCallback(void (*callback)()) { void RFM69::setIsrCallback(void (*callback)()) {
_isrCallback = callback; _isrCallback = callback;
@ -263,6 +285,11 @@ void RFM69::setPowerLevel(uint8_t powerLevel) {
writeReg(REG_PALEVEL, PA_SETTING | powerLevel); writeReg(REG_PALEVEL, PA_SETTING | powerLevel);
} }
uint8_t RFM69::getOutputPower() {
// _RegisterBits(_REG_PA_LEVEL, offset=0, bits=5)
return readReg(REG_PALEVEL) & 0x1F;
}
// return stored _powerLevel // return stored _powerLevel
uint8_t RFM69::getPowerLevel() { return _powerLevel; } uint8_t RFM69::getPowerLevel() { return _powerLevel; }
@ -287,6 +314,10 @@ int8_t RFM69::setPowerDBm(int8_t dBm) {
return dBm; return dBm;
} }
double RFM69::dBm_to_mW(uint8_t dBm) {
return pow(10, (dBm / 10.0));
}
bool RFM69::canSend() { bool RFM69::canSend() {
if (_mode == RF69_MODE_RX && PAYLOADLEN == 0 && readRSSI() < CSMA_LIMIT) { // if signal stronger than -100dBm is detected assume channel activity if (_mode == RF69_MODE_RX && PAYLOADLEN == 0 && readRSSI() < CSMA_LIMIT) { // if signal stronger than -100dBm is detected assume channel activity
setMode(RF69_MODE_STANDBY); setMode(RF69_MODE_STANDBY);
@ -568,6 +599,26 @@ void RFM69::spyMode(bool onOff) {
//writeReg(REG_PACKETCONFIG1, (readReg(REG_PACKETCONFIG1) & 0xF9) | (onOff ? RF_PACKET1_ADRSFILTERING_OFF : RF_PACKET1_ADRSFILTERING_NODEBROADCAST)); //writeReg(REG_PACKETCONFIG1, (readReg(REG_PACKETCONFIG1) & 0xF9) | (onOff ? RF_PACKET1_ADRSFILTERING_OFF : RF_PACKET1_ADRSFILTERING_NODEBROADCAST));
} }
bool RFM69::getSpyMode() {
return _spyMode;
}
bool RFM69::isSyncOn() {
return readReg(REG_SYNCCONFIG) >> 7;
}
uint8_t RFM69::getSyncSize() {
return (readReg(REG_SYNCCONFIG) & 0b00111000) >> 3;
}
bool RFM69::isCrcOn() {
return (readReg(REG_PACKETCONFIG1) & 0b00010000) >> 4;
}
bool RFM69::isAesOn() {
return readReg(REG_PACKETCONFIG2) & 0b00000001;
}
// for RFM69 HW/HCW only: you must call setHighPower(true) after initialize() or else transmission won't work // for RFM69 HW/HCW only: you must call setHighPower(true) after initialize() or else transmission won't work
void RFM69::setHighPower(bool _isRFM69HW_HCW) { void RFM69::setHighPower(bool _isRFM69HW_HCW) {
_isRFM69HW = _isRFM69HW_HCW; _isRFM69HW = _isRFM69HW_HCW;
@ -575,6 +626,10 @@ void RFM69::setHighPower(bool _isRFM69HW_HCW) {
setPowerLevel(_powerLevel); setPowerLevel(_powerLevel);
} }
bool RFM69::isHighPower() {
return _isRFM69HW;
}
// internal function - for HW/HCW only: // internal function - for HW/HCW only:
// enables HiPower for 18-20dBm output // enables HiPower for 18-20dBm output
// should only be used with PA1+PA2 // should only be used with PA1+PA2
@ -1271,4 +1326,4 @@ void RFM69::listenModeSendBurst(uint8_t targetNode, const void* buffer, uint8_t
setMode(RF69_MODE_STANDBY); setMode(RF69_MODE_STANDBY);
reinitRadio(); reinitRadio();
} }
#endif #endif

33
RFM69.h
View File

@ -66,7 +66,7 @@
#elif defined(__APPLE__) // OSX #elif defined(__APPLE__) // OSX
#define RF69_PLATFORM RF69_PLATFORM_UNIX #define RF69_PLATFORM RF69_PLATFORM_UNIX
#else #else
#error Platform not defined! #error Platform not defined!
#endif #endif
#endif #endif
@ -87,7 +87,7 @@
// Arduino Mega, Mega ADK, Mega Pro // Arduino Mega, Mega ADK, Mega Pro
// 2->0, 3->1, 21->2, 20->3, 19->4, 18->5 // 2->0, 3->1, 21->2, 20->3, 19->4, 18->5
#define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : ((p) >= 18 && (p) <= 21 ? 23 - (p) : NOT_AN_INTERRUPT))) #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : ((p) >= 18 && (p) <= 21 ? 23 - (p) : NOT_AN_INTERRUPT)))
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
// Arduino 1284 and 1284P - See Maniacbug and Optiboot // Arduino 1284 and 1284P - See Maniacbug and Optiboot
// 10->0, 11->1, 2->2 // 10->0, 11->1, 2->2
#define digitalPinToInterrupt(p) ((p) == 10 ? 0 : ((p) == 11 ? 1 : ((p) == 2 ? 2 : NOT_AN_INTERRUPT))) #define digitalPinToInterrupt(p) ((p) == 10 ? 0 : ((p) == 11 ? 1 : ((p) == 2 ? 2 : NOT_AN_INTERRUPT)))
@ -163,6 +163,7 @@
#define RF69_BROADCAST_ADDR 0 #define RF69_BROADCAST_ADDR 0
#define RF69_CSMA_LIMIT_MS 1000 #define RF69_CSMA_LIMIT_MS 1000
#define RF69_TX_LIMIT_MS 1000 #define RF69_TX_LIMIT_MS 1000
#define RF69_FXOSC 32000000L
#define RF69_FSTEP 61.03515625 // == FXOSC / 2^19 = 32MHz / 2^19 (p13 in datasheet) #define RF69_FSTEP 61.03515625 // == FXOSC / 2^19 = 32MHz / 2^19 (p13 in datasheet)
// TWS: define CTLbyte bits // TWS: define CTLbyte bits
@ -201,7 +202,10 @@ class RFM69 {
RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW_HCW=false, SPIClass *spi=nullptr); RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW_HCW=false, SPIClass *spi=nullptr);
bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1); bool initialize(uint8_t freqBand, uint16_t ID, uint8_t networkID=1);
uint8_t getVersion();
uint16_t getAddress();
void setAddress(uint16_t addr); void setAddress(uint16_t addr);
uint8_t getNetwork();
void setNetwork(uint8_t networkID); void setNetwork(uint8_t networkID);
void setIsrCallback(void (*callback)()); void setIsrCallback(void (*callback)());
virtual bool canSend(); virtual bool canSend();
@ -213,17 +217,26 @@ class RFM69 {
virtual void sendACK(const void* buffer = "", uint8_t bufferSize=0); virtual void sendACK(const void* buffer = "", uint8_t bufferSize=0);
uint32_t getFrequency(); uint32_t getFrequency();
void setFrequency(uint32_t freqHz); void setFrequency(uint32_t freqHz);
uint32_t getFrequencyDeviation();
uint32_t getBitRate();
void encrypt(const char* key); void encrypt(const char* key);
void setCS(uint8_t newSPISlaveSelect); void setCS(uint8_t newSPISlaveSelect);
bool setIrq(uint8_t newIRQPin); bool setIrq(uint8_t newIRQPin);
int16_t readRSSI(bool forceTrigger=false); // *current* signal strength indicator; e.g. < -90dBm says the frequency channel is free + ready to transmit int16_t readRSSI(bool forceTrigger=false); // *current* signal strength indicator; e.g. < -90dBm says the frequency channel is free + ready to transmit
bool getSpyMode();
void spyMode(bool onOff=true); void spyMode(bool onOff=true);
//void promiscuous(bool onOff=true); //replaced with spyMode() bool isSyncOn();
uint8_t getSyncSize();
bool isCrcOn();
bool isAesOn();
//void promiscuous(bool onOff=true); // replaced with spyMode()
virtual void setHighPower(bool _isRFM69HW_HCW=true); // has to be called after initialize() for RFM69 HW/HCW virtual void setHighPower(bool _isRFM69HW_HCW=true); // has to be called after initialize() for RFM69 HW/HCW
bool isHighPower();
virtual uint8_t getPowerLevel(); // get powerLevel
virtual void setPowerLevel(uint8_t level); // reduce/increase transmit power level virtual void setPowerLevel(uint8_t level); // reduce/increase transmit power level
virtual int8_t setPowerDBm(int8_t dBm); // reduce/increase transmit power level, in dBm virtual int8_t setPowerDBm(int8_t dBm); // reduce/increase transmit power level, in dBm
double dBm_to_mW(uint8_t dBm); // convert dBm to mW
virtual uint8_t getPowerLevel(); // get powerLevel uint8_t getOutputPower();
void sleep(); void sleep();
uint8_t readTemperature(uint8_t calFactor=0); // get CMOS temperature (8bit) uint8_t readTemperature(uint8_t calFactor=0); // get CMOS temperature (8bit)
void rcCalibration(); // calibrate the internal RC oscillator for use in wide temperature variations - see datasheet section [4.3.5. RC Timer Accuracy] void rcCalibration(); // calibrate the internal RC oscillator for use in wide temperature variations - see datasheet section [4.3.5. RC Timer Accuracy]
@ -258,6 +271,7 @@ class RFM69 {
uint8_t _interruptPin; uint8_t _interruptPin;
uint8_t _interruptNum; uint8_t _interruptNum;
uint16_t _address; uint16_t _address;
uint8_t _networkID;
bool _spyMode; bool _spyMode;
uint8_t _powerLevel; uint8_t _powerLevel;
bool _isRFM69HW; bool _isRFM69HW;
@ -280,17 +294,17 @@ class RFM69 {
#if defined(RF69_LISTENMODE_ENABLE) #if defined(RF69_LISTENMODE_ENABLE)
static RFM69* selfPointer; static RFM69* selfPointer;
//============================================================================= //=============================================================================
// ListenMode specific declarations // ListenMode specific declarations
//============================================================================= //=============================================================================
public: public:
// When we receive a packet in listen mode, this is the time left in the sender's burst. // When we receive a packet in listen mode, this is the time left in the sender's burst.
// You need to wait at least this long before trying to reply. // You need to wait at least this long before trying to reply.
static volatile uint16_t RF69_LISTEN_BURST_REMAINING_MS; static volatile uint16_t RF69_LISTEN_BURST_REMAINING_MS;
void listenModeStart(void); void listenModeStart(void);
void listenModeEnd(void); void listenModeEnd(void);
void listenModeHighSpeed(bool highSpeed) { _isHighSpeed = highSpeed; } void listenModeHighSpeed(bool highSpeed) { _isHighSpeed = highSpeed; }
// rx and idle duration in microseconds // rx and idle duration in microseconds
bool listenModeSetDurations(uint32_t& rxDuration, uint32_t& idleDuration); bool listenModeSetDurations(uint32_t& rxDuration, uint32_t& idleDuration);
@ -319,7 +333,6 @@ class RFM69 {
// Save these so we can reinitialize the radio after sending a burst // Save these so we can reinitialize the radio after sending a burst
// or exiting listen mode. // or exiting listen mode.
uint8_t _freqBand; uint8_t _freqBand;
uint8_t _networkID;
uint8_t _rxListenCoef; uint8_t _rxListenCoef;
uint8_t _rxListenResolution; uint8_t _rxListenResolution;
uint8_t _idleListenCoef; uint8_t _idleListenCoef;
@ -328,4 +341,4 @@ class RFM69 {
#endif #endif
}; };
#endif #endif

View File

@ -174,6 +174,10 @@ void RFM69_ATC::enableAutoPower(int16_t targetRSSI){ // TomWS1: New method t
_targetRSSI = targetRSSI; // no logic here, just set the value (if non-zero, then enabled), caller's responsibility to use a reasonable value _targetRSSI = targetRSSI; // no logic here, just set the value (if non-zero, then enabled), caller's responsibility to use a reasonable value
} }
int16_t RFM69_ATC::getTargetRssi() {
return _targetRSSI;
}
//============================================================================= //=============================================================================
// getAckRSSI() - returns the RSSI value ack'd by the far end. // getAckRSSI() - returns the RSSI value ack'd by the far end.
//============================================================================= //=============================================================================

View File

@ -44,6 +44,7 @@ class RFM69_ATC: public RFM69 {
void sendACK(const void* buffer = "", uint8_t bufferSize=0); void sendACK(const void* buffer = "", uint8_t bufferSize=0);
bool sendWithRetry(uint16_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=RFM69_ACK_TIMEOUT); bool sendWithRetry(uint16_t toAddress, const void* buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=RFM69_ACK_TIMEOUT);
void enableAutoPower(int16_t targetRSSI=-90); // TWS: New method to enable/disable auto Power control void enableAutoPower(int16_t targetRSSI=-90); // TWS: New method to enable/disable auto Power control
int16_t getTargetRssi();
int16_t getAckRSSI(void); // TWS: New method to retrieve the ack'd RSSI (if any) int16_t getAckRSSI(void); // TWS: New method to retrieve the ack'd RSSI (if any)
int16_t _targetRSSI; // if non-zero then this is the desired end point RSSI for our transmission int16_t _targetRSSI; // if non-zero then this is the desired end point RSSI for our transmission

View File

@ -305,6 +305,10 @@
#define RF_FRFMSB_433 0x6C #define RF_FRFMSB_433 0x6C
#define RF_FRFMID_433 0x40 #define RF_FRFMID_433 0x40
#define RF_FRFLSB_433 0x00 #define RF_FRFLSB_433 0x00
//center frequency: 433.92 - see https://github.com/LowPowerLab/RFM69/issues/202
#define RF_FRFMSB_433_92 0x6C
#define RF_FRFMID_433_92 0x7A
#define RF_FRFLSB_433_92 0xE1
#define RF_FRFMSB_434 0x6C #define RF_FRFMSB_434 0x6C
#define RF_FRFMID_434 0x80 #define RF_FRFMID_434 0x80
#define RF_FRFLSB_434 0x00 #define RF_FRFLSB_434 0x00

View File

@ -1,6 +1,6 @@
{ {
"name": "RFM69", "name": "RFM69",
"version": "1.5.2", "version": "1.6.0",
"keywords": "rf, radio, wireless, spi", "keywords": "rf, radio, wireless, spi",
"description": "RFM69 library for RFM69W, RFM69HW, RFM69CW, RFM69HCW (semtech SX1231, SX1231H)", "description": "RFM69 library for RFM69W, RFM69HW, RFM69CW, RFM69HCW (semtech SX1231, SX1231H)",
"repository": "repository":

View File

@ -1,5 +1,5 @@
name=RFM69_LowPowerLab name=RFM69_LowPowerLab
version=1.5.2 version=1.6.0
author=LowPowerLab <lowpowerlab.com> author=LowPowerLab <lowpowerlab.com>
maintainer=Felix Rusu <felix@lowpowerlab.com> maintainer=Felix Rusu <felix@lowpowerlab.com>
sentence=Simple Arduino library for RFM69/SX1231h based radio module transceivers sentence=Simple Arduino library for RFM69/SX1231h based radio module transceivers