Add RangeTest examples
This commit is contained in:
parent
3cbd159143
commit
add5e29208
|
|
@ -0,0 +1,193 @@
|
||||||
|
//*********************************************************************************************
|
||||||
|
// RangeTest_Gateway (to be used with an RFGateway or similar Moteino)
|
||||||
|
// Adapted from Gateway firmware sketch
|
||||||
|
// Acts as a listener for testing RF performance, in tandem with a RangeTest_Transmitter
|
||||||
|
//*********************************************************************************************
|
||||||
|
// Copyright Felix Rusu 2021, http://www.LowPowerLab.com/contact
|
||||||
|
//*********************************************************************************************
|
||||||
|
#include <RFM69.h> //https://www.github.com/lowpowerlab/rfm69
|
||||||
|
#include <RFM69_ATC.h> //https://www.github.com/lowpowerlab/rfm69
|
||||||
|
#include <U8g2lib.h> //https://github.com/olikraus/u8g2/wiki/u8g2reference fonts:https://github.com/olikraus/u8g2/wiki/fntlistall
|
||||||
|
#include <Wire.h> //i2c scanner: https://playground.arduino.cc/Main/I2cScanner
|
||||||
|
#include <PString.h> //easy string manipulator: http://arduiniana.org/libraries/pstring/
|
||||||
|
//*********************************************************************************************
|
||||||
|
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
|
||||||
|
//*********************************************************************************************
|
||||||
|
#define NODEID 1 //unique for each node on same network
|
||||||
|
#define NETWORKID 100 //the same on all nodes that talk to each other
|
||||||
|
#define FREQUENCY RF69_915MHZ //others: RF69_433MHZ, RF69_868MHZ, match to radio variant on your Moteino/board
|
||||||
|
#define ENCRYPTKEY "sampleEncryptKey"
|
||||||
|
#define IS_RFM69HW_HCW //assumes RFM69 HCW/HW, remove if you have RFM69 W/CW
|
||||||
|
#define ENABLE_ATC //comment out to disable AUTO TRANSMISSION CONTROL (ie. always transmit at max power)
|
||||||
|
//*********************************************************************************************
|
||||||
|
#define SERIAL_BAUD 500000 //this works with 0% error on all LowPowerLab boards, for SAMD it is irrelevant
|
||||||
|
#define LED LED_BUILTIN
|
||||||
|
#define BUZZER 6
|
||||||
|
//***********************************************************************************************************
|
||||||
|
#define OLED_BAUD 1600000 //fast i2c clock
|
||||||
|
#define OLED_ADDRESS 0x3C //i2c address on most small OLEDs
|
||||||
|
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
||||||
|
//***********************************************************************************************************
|
||||||
|
#define LED_HIGH digitalWrite(LED, HIGH)
|
||||||
|
#define LED_LOW digitalWrite(LED, LOW)
|
||||||
|
|
||||||
|
#ifdef ENABLE_ATC
|
||||||
|
RFM69_ATC radio;
|
||||||
|
#else
|
||||||
|
RFM69 radio;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SERIAL_BAUD
|
||||||
|
#define DEBUG(input) Serial.print(input)
|
||||||
|
#define DEBUGln(input) Serial.println(input)
|
||||||
|
#define DEBUGHex(input) Serial.print(input, HEX)
|
||||||
|
#define DEBUGFlush() Serial.flush()
|
||||||
|
#else
|
||||||
|
#define DEBUG(input)
|
||||||
|
#define DEBUGln(input)
|
||||||
|
#define DEBUGHex(input)
|
||||||
|
#define DEBUGFlush()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MSG_MAX_LEN 30 //don't need more for testing purposes
|
||||||
|
#define HISTORY_LEN 9 //hold this many past messages - to display on OLED at small font size
|
||||||
|
|
||||||
|
byte OLEDfound=false;
|
||||||
|
char buff[61];
|
||||||
|
PString Pbuff(buff, sizeof(buff)); //easy string manipulator
|
||||||
|
byte ackCount=0;
|
||||||
|
byte lastMessageIndex = HISTORY_LEN;
|
||||||
|
byte historyLength = 0;
|
||||||
|
uint16_t senderID;
|
||||||
|
int rxRSSI;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char msg[MSG_MAX_LEN];
|
||||||
|
int rssi;
|
||||||
|
uint16_t from;
|
||||||
|
byte pinged;
|
||||||
|
byte pingedOK;
|
||||||
|
} Message;
|
||||||
|
Message * messageHistory = new Message[HISTORY_LEN];
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(BUZZER, OUTPUT);
|
||||||
|
pinMode(LED, OUTPUT);
|
||||||
|
Serial.begin(SERIAL_BAUD);
|
||||||
|
radio.initialize(FREQUENCY,NODEID,NETWORKID);
|
||||||
|
#ifdef IS_RFM69HW_HCW
|
||||||
|
radio.setHighPower();
|
||||||
|
#endif
|
||||||
|
radio.encrypt(ENCRYPTKEY);
|
||||||
|
DEBUG(F("Listening at ")); DEBUG(radio.getFrequency()); DEBUGln(F(" Hz.."));
|
||||||
|
DEBUGln(buff);
|
||||||
|
|
||||||
|
Pbuff = F("Listening at ");
|
||||||
|
Pbuff.print(radio.getFrequency());
|
||||||
|
Pbuff.print(F("Hz..."));
|
||||||
|
DEBUGln(buff);
|
||||||
|
|
||||||
|
delay(1000); //Wire apparently needs 50ms
|
||||||
|
Wire.begin();
|
||||||
|
Wire.beginTransmission(OLED_ADDRESS);
|
||||||
|
byte error = Wire.endTransmission();
|
||||||
|
if (error == 0) {
|
||||||
|
DEBUG(F("OLED FOUND at 0x")); DEBUGln(OLED_ADDRESS);
|
||||||
|
u8g2.begin();
|
||||||
|
u8g2.setDisplayRotation(U8G2_R2); //if required (inside/custom mount?)
|
||||||
|
u8g2.setBusClock(OLED_BAUD);
|
||||||
|
OLEDfound = true;
|
||||||
|
} else {
|
||||||
|
DEBUGln(F("NO OLED found..."));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFlush();
|
||||||
|
u8g2.clearBuffer();
|
||||||
|
u8g2.setFont(u8g2_font_8x13B_tf);
|
||||||
|
u8g2.setCursor(0,10); u8g2.print("OLED PKT CAPTURE");
|
||||||
|
u8g2.sendBuffer();
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (radio.receiveDone()) {
|
||||||
|
LED_HIGH;
|
||||||
|
senderID = radio.SENDERID;
|
||||||
|
rxRSSI = radio.RSSI;
|
||||||
|
|
||||||
|
DEBUG('[');DEBUG(senderID);DEBUG(F("] "));
|
||||||
|
DEBUG((char*)radio.DATA);
|
||||||
|
DEBUG(F(" [RX_RSSI:"));DEBUG(rxRSSI);DEBUG(F("]"));
|
||||||
|
|
||||||
|
Pbuff = "";
|
||||||
|
Pbuff.print(radio.SENDERID);
|
||||||
|
Pbuff.print(' ');
|
||||||
|
Pbuff.print((char*)radio.DATA);
|
||||||
|
Pbuff.print(' ');
|
||||||
|
Pbuff.print(radio.RSSI);
|
||||||
|
|
||||||
|
if (radio.ACKRequested()) {
|
||||||
|
radio.sendACK();
|
||||||
|
|
||||||
|
if (++ackCount%3==0) {
|
||||||
|
DEBUG(F(" Pinging ["));
|
||||||
|
DEBUG(senderID);
|
||||||
|
DEBUG(F("]:"));
|
||||||
|
delay(3); //need this when sending right after reception .. ?
|
||||||
|
//if (radio.sendWithRetry(senderID, "ACK TEST", 8, 0)) { // 0 = only 1 attempt, no retries
|
||||||
|
if (radio.sendWithRetry(senderID, "ACK TEST", 8)) {
|
||||||
|
DEBUG(F("OK!"));
|
||||||
|
Pbuff.print(" OK");
|
||||||
|
} else {
|
||||||
|
DEBUG(F("nothing"));
|
||||||
|
Pbuff.print(" NOK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUGln();
|
||||||
|
saveToHistory(buff);
|
||||||
|
DEBUGln();
|
||||||
|
if (OLEDfound) draw();
|
||||||
|
DEBUGln();
|
||||||
|
LED_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
//LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw() {
|
||||||
|
u8g2.clearBuffer();
|
||||||
|
u8g2.setFont(u8g2_font_tom_thumb_4x6_tf);
|
||||||
|
|
||||||
|
byte offset=0;
|
||||||
|
for (byte i=lastMessageIndex+1; i<historyLength; i++) {
|
||||||
|
offset = 7 + (i-lastMessageIndex-1)*7;
|
||||||
|
u8g2.setCursor(0, offset); u8g2.print(messageHistory[i].msg);
|
||||||
|
//DEBUG(F("L1_i=")); DEBUG(i); DEBUG(F("_offset=")); DEBUGln(offset);
|
||||||
|
}
|
||||||
|
offset+=7;
|
||||||
|
for (byte i=0; i<=lastMessageIndex; i++) {
|
||||||
|
u8g2.setCursor(0, offset + i*7); u8g2.print(messageHistory[i].msg);
|
||||||
|
//DEBUG(F("L2_i=")); DEBUG(i); DEBUG(F("_offset=")); DEBUG(offset); DEBUG(F("_x=")); DEBUGln(offset + i*7);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8g2.sendBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveToHistory(char * msg) {
|
||||||
|
byte length = strlen(msg);
|
||||||
|
if (length == 0) return;
|
||||||
|
|
||||||
|
if (historyLength < HISTORY_LEN) historyLength++;
|
||||||
|
if (lastMessageIndex >= HISTORY_LEN-1) //reset pointed in circular buffer/array
|
||||||
|
lastMessageIndex = 0;
|
||||||
|
else
|
||||||
|
lastMessageIndex++;
|
||||||
|
|
||||||
|
strcpy(messageHistory[lastMessageIndex].msg, msg);
|
||||||
|
DEBUG(F("HIST ADDED ["));
|
||||||
|
DEBUG(lastMessageIndex);
|
||||||
|
DEBUG(F("]["));
|
||||||
|
DEBUG((char*)messageHistory[lastMessageIndex].msg);
|
||||||
|
DEBUG(F("]"));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,259 @@
|
||||||
|
//*********************************************************************************************
|
||||||
|
// RangeTest_Transmitter (to be used with a MotionMote or similar Moteino)
|
||||||
|
// Adapted from MotionMote firmware sketch
|
||||||
|
// Acts as a continuous transmitter for testing RF performance, in tandem with a RangeTest_Gateway
|
||||||
|
//*********************************************************************************************
|
||||||
|
// Copyright Felix Rusu 2021, http://www.LowPowerLab.com/contact
|
||||||
|
//*********************************************************************************************
|
||||||
|
#include <RFM69.h> //https://www.github.com/lowpowerlab/rfm69
|
||||||
|
#include <RFM69_ATC.h>//https://www.github.com/lowpowerlab/rfm69
|
||||||
|
#include <LowPower.h> //https://github.com/lowpowerlab/lowpower
|
||||||
|
#include <SPIFlash.h> //https://www.github.com/lowpowerlab/spiflash
|
||||||
|
//*********************************************************************************************
|
||||||
|
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE ************
|
||||||
|
//*********************************************************************************************
|
||||||
|
#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
|
||||||
|
#define FREQUENCY RF69_915MHZ //others: RF69_433MHZ, RF69_868MHZ, match to radio variant on your Moteino/board
|
||||||
|
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
|
||||||
|
#define IS_RFM69HW_HCW //assumes RFM69 HCW/HW, remove if you have RFM69 W/CW
|
||||||
|
#define ENABLE_ATC //comment out to disable AUTO TRANSMISSION CONTROL (ie. always transmit at max power)
|
||||||
|
#define ATC_RSSI -90 //noise floor is at -100dB, keep above by a margin of 10db
|
||||||
|
//*********************************************************************************************
|
||||||
|
//************ GPIO & MISC ********************************************************************
|
||||||
|
//*********************************************************************************************
|
||||||
|
#define ACK_TIME 30 // max # of ms to wait for an ack
|
||||||
|
#define ONBOARDLED 9 // MotionMote onboard LED on D9
|
||||||
|
#define PIR_POWER 7 //PIR is powered from D7
|
||||||
|
#define RFM_RST A0 //used to reset the radio module at power up to ensure a clean start
|
||||||
|
#define MOTION_PIN 3 // D3
|
||||||
|
#define MOTION_IRQ 1 // hardware interrupt 1 (D3) - where motion sensors OUTput is connected, this will generate an interrupt every time there is MOTION
|
||||||
|
#define LED_PWR 6 // separate MotionMote LED powered from D6
|
||||||
|
#define LED_GND 5 // separate MotionMote LED ground on D5
|
||||||
|
#define LED_HIGH digitalWrite(LED_PWR, HIGH)
|
||||||
|
#define LED_LOW digitalWrite(LED_PWR, LOW)
|
||||||
|
#define DUPLICATE_INTERVAL 10000 //avoid duplicates in 55second intervals (ie mailman sometimes spends 30+ seconds at mailbox)
|
||||||
|
#define BATT_INTERVAL 4000 // read and report battery voltage every this many ms (approx)
|
||||||
|
#define INTERNAL_AREF_V 1100 //=1.1v internal bandgap. can be adjusted to more or less to be more accurate
|
||||||
|
//*********************************************************************************************
|
||||||
|
#define DEBUG_EN //comment this out when deploying to an installed SM to save a few KB of sketch size
|
||||||
|
#ifdef DEBUG_EN
|
||||||
|
#define SERIAL_BAUD 500000
|
||||||
|
#define DEBUG(input) Serial.print(input)
|
||||||
|
#define DEBUGln(input) Serial.println(input)
|
||||||
|
#define DEBUGHEX(input, param) Serial.print(input, param)
|
||||||
|
#define DEBUGFlush() Serial.flush()
|
||||||
|
#else
|
||||||
|
#define DEBUG(input)
|
||||||
|
#define DEBUGln(input)
|
||||||
|
#define DEBUGHEX(input, param)
|
||||||
|
#define DEBUGFlush();
|
||||||
|
#endif
|
||||||
|
//*********************************************************************************************
|
||||||
|
#ifdef ENABLE_ATC
|
||||||
|
RFM69_ATC radio;
|
||||||
|
#else
|
||||||
|
RFM69 radio;
|
||||||
|
#endif
|
||||||
|
SPIFlash flash(SS_FLASHMEM, 0xEF30); //EF30 for 4mbit Windbond chip (W25X40CL)
|
||||||
|
|
||||||
|
volatile boolean motionDetected=false;
|
||||||
|
float batteryVolts = 5;
|
||||||
|
float temp = 0;
|
||||||
|
char BATstr[10]; //longest battery voltage reading message = 9chars
|
||||||
|
char TEMPstr[10];
|
||||||
|
char sendBuf[32];
|
||||||
|
void motionIRQ(void);
|
||||||
|
void checkBattery(void);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
#ifdef DEBUG_EN
|
||||||
|
Serial.begin(SERIAL_BAUD);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (flash.initialize()) {
|
||||||
|
DEBUGln(F("SPI Flash Init OK!"));
|
||||||
|
flash.sleep(); //safe to call because initialize() wakes it up
|
||||||
|
}
|
||||||
|
else DEBUGln(F("SPI Flash MEM FAIL!"));
|
||||||
|
|
||||||
|
pinMode(MOTION_PIN, INPUT);
|
||||||
|
pinMode(ONBOARDLED, OUTPUT);
|
||||||
|
pinMode(PIR_POWER, OUTPUT);
|
||||||
|
pinMode(RFM_RST, OUTPUT);
|
||||||
|
pinMode(LED_PWR, OUTPUT);
|
||||||
|
pinMode(LED_GND, OUTPUT);
|
||||||
|
digitalWrite(PIR_POWER, HIGH);
|
||||||
|
digitalWrite(RFM_RST, LOW);
|
||||||
|
attachInterrupt(MOTION_IRQ, motionIRQ, RISING);
|
||||||
|
digitalWrite(RFM_RST, HIGH); delay(100); digitalWrite(RFM_RST, LOW);
|
||||||
|
|
||||||
|
radio.initialize(FREQUENCY,NODEID,NETWORKID);
|
||||||
|
#ifdef IS_RFM69HW_HCW
|
||||||
|
radio.setHighPower();
|
||||||
|
#endif
|
||||||
|
radio.encrypt(ENCRYPTKEY);
|
||||||
|
|
||||||
|
//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);
|
||||||
|
DEBUGln("RFM69_ATC Enabled (Auto Transmission Control)\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEBUG("Transmitting at "); DEBUG(radio.getFrequency()); DEBUGln(" Hz..");
|
||||||
|
|
||||||
|
radio.sendWithRetry(GATEWAYID, "START", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void motionIRQ() {
|
||||||
|
motionDetected=true;
|
||||||
|
DEBUGln("IRQ");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t time=0, now=0, MLO=0, BLO=0;
|
||||||
|
byte motionRecentlyCycles=0;
|
||||||
|
byte ackCount=0;
|
||||||
|
byte packetCounter=0;
|
||||||
|
void loop() {
|
||||||
|
now = millis();
|
||||||
|
checkBattery();
|
||||||
|
//DEBUG("Slept: ");DEBUG(now-lastSleepTime);DEBUGln("ms");
|
||||||
|
|
||||||
|
if (motionDetected && (time-MLO > DUPLICATE_INTERVAL)) {
|
||||||
|
packetCounter++;
|
||||||
|
LED_HIGH; //digitalWrite(LED, HIGH);
|
||||||
|
MLO = BLO = time; //save timestamp of event
|
||||||
|
sprintf(sendBuf, "%d MOTION X:%d", packetCounter, radio.getPowerLevel());
|
||||||
|
DEBUG(sendBuf);
|
||||||
|
|
||||||
|
if (radio.sendWithRetry(GATEWAYID, sendBuf, strlen(sendBuf))) {
|
||||||
|
DEBUG("..OK! RSSI:");
|
||||||
|
DEBUG(radio.RSSI);
|
||||||
|
listen_a_little();
|
||||||
|
} else DEBUG("..NOK..");
|
||||||
|
|
||||||
|
radio.sleep();
|
||||||
|
LED_LOW;
|
||||||
|
} else if (time-BLO > BATT_INTERVAL) {
|
||||||
|
packetCounter++;
|
||||||
|
sprintf(sendBuf, "%d V:%s F:%s X:%d", packetCounter, BATstr, TEMPstr, radio.getPowerLevel());
|
||||||
|
BLO = time;
|
||||||
|
|
||||||
|
DEBUG(sendBuf);
|
||||||
|
if (radio.sendWithRetry(GATEWAYID, sendBuf, strlen(sendBuf))) {
|
||||||
|
DEBUG("..OK!");
|
||||||
|
listen_a_little();
|
||||||
|
} else DEBUG("..NOK..");
|
||||||
|
}
|
||||||
|
DEBUGln(); DEBUGFlush();
|
||||||
|
|
||||||
|
//while motion recently happened sleep for small slots of time to better approximate last motion event
|
||||||
|
//this helps with debouncing a "MOTION" event more accurately for sensors that fire the IRQ very rapidly (ie panasonic sensors)
|
||||||
|
if (motionDetected || motionRecentlyCycles>0) {
|
||||||
|
if (motionDetected) motionRecentlyCycles=8;
|
||||||
|
else motionRecentlyCycles--;
|
||||||
|
motionDetected=false; //do NOT move this after the SLEEP line below or motion will never be detected
|
||||||
|
time = time + 250 + millis()-now; //correct millis() resonator drift, may need to be tweaked to be accurate
|
||||||
|
radio.sleep();
|
||||||
|
LowPower.powerDown(SLEEP_250MS, ADC_OFF, BOD_OFF);
|
||||||
|
DEBUGln("WAKEUP250ms");
|
||||||
|
} else {
|
||||||
|
time = time + 4000 + millis()-now /*+ 480*/; //correct millis() resonator drift, may need to be tweaked to be accurate
|
||||||
|
radio.sleep();
|
||||||
|
LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF); //watchdog sleep uses extra ~4uA!
|
||||||
|
//sleep(4000);
|
||||||
|
DEBUGln("WAKEUP4s");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BLR=0;
|
||||||
|
void checkBattery()
|
||||||
|
{
|
||||||
|
if (time-BLR > 3) //only read battery every 30s or so
|
||||||
|
{
|
||||||
|
BLR = time;
|
||||||
|
long vavg = 0;
|
||||||
|
temp = 0;
|
||||||
|
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // Ref to Vcc. Measure internal 1.1V ref
|
||||||
|
for (int j = 0; j < 10; j++)
|
||||||
|
{ // Read a few times to get ADC to settle
|
||||||
|
ADCSRA |= _BV(ADSC); // Start conversion
|
||||||
|
temp += radio.readTemperature(-1); // Temperature. -1 = user cal factor, adjust for correct ambient
|
||||||
|
while (bit_is_set(ADCSRA,ADSC)); // measuring
|
||||||
|
if (j > 4) { // Skip the first 5 Vcc readings, take the next 5
|
||||||
|
vavg = vavg + (((INTERNAL_AREF_V * 1024L) / ADC) + 5L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
batteryVolts = (vavg/5.0)/1000.0;
|
||||||
|
temp /= 10;
|
||||||
|
dtostrf(temp, 2,0, TEMPstr);
|
||||||
|
dtostrf(batteryVolts, 3,1, BATstr); //update the BATStr which gets sent every BATT_CYCLES or along with the MOTION message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sleep(uint32_t sleepTime) {
|
||||||
|
DEBUGFlush();
|
||||||
|
if (sleepTime < 262) { //sleeps just the MCU, using WDT (radio is not touched)
|
||||||
|
LowPower.longPowerDown(sleepTime);
|
||||||
|
} else { //sleeps MCU using the radio timer - should not be used if radio needs to be in RX mode!
|
||||||
|
uint32_t freq = radio.getFrequency();
|
||||||
|
uint32_t remainingSleepTime = sleepTime;
|
||||||
|
|
||||||
|
while (remainingSleepTime) { //split into sleep(60s) calls if > 60s sleep
|
||||||
|
if (remainingSleepTime > 65500) {
|
||||||
|
sleepTime = 65500;
|
||||||
|
remainingSleepTime -= 65500;
|
||||||
|
} else {
|
||||||
|
sleepTime = remainingSleepTime;
|
||||||
|
remainingSleepTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sleepTime%262 && sleepTime > 262*2) {
|
||||||
|
DEBUG("Sleep "); DEBUGln(sleepTime-sleepTime%262-262); DEBUGFlush();
|
||||||
|
listenModeSleep(sleepTime-sleepTime%262-262);
|
||||||
|
DEBUG("Sleep "); DEBUGln(sleepTime%262 + 262); DEBUGFlush();
|
||||||
|
listenModeSleep(sleepTime%262 + 262);
|
||||||
|
} else {
|
||||||
|
DEBUG("Sleep "); DEBUGln(sleepTime); DEBUGFlush();
|
||||||
|
listenModeSleep(sleepTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
//WAKEUP happens here (must reinit!)
|
||||||
|
radio.RFM69::initialize(FREQUENCY,NODEID,NETWORKID); //call base init!
|
||||||
|
#ifdef ENCRYPTKEY
|
||||||
|
radio.encrypt(ENCRYPTKEY);
|
||||||
|
#endif
|
||||||
|
radio.setFrequency(freq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void listenModeSleep(uint16_t millisInterval) {
|
||||||
|
radio.listenModeSleep(millisInterval);
|
||||||
|
LowPower.powerDown( SLEEP_FOREVER, ADC_OFF, BOD_OFF );
|
||||||
|
LowPower.powerDown( SLEEP_FOREVER, ADC_OFF, BOD_OFF );
|
||||||
|
LowPower.powerDown( SLEEP_FOREVER, ADC_OFF, BOD_OFF );
|
||||||
|
radio.endListenModeSleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void listen_a_little() {
|
||||||
|
radio.receiveDone(); //radio RX!
|
||||||
|
LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF);
|
||||||
|
|
||||||
|
if (radio.receiveDone()) {
|
||||||
|
DEBUG(" [");DEBUG(radio.SENDERID);DEBUG("] ");
|
||||||
|
DEBUG((char*)radio.DATA);
|
||||||
|
DEBUG("[RX_RSSI:");DEBUG(radio.RSSI);DEBUG("]");
|
||||||
|
|
||||||
|
if (radio.ACKRequested()) {
|
||||||
|
radio.sendACK();
|
||||||
|
DEBUG("[ACK sent]");
|
||||||
|
}
|
||||||
|
time += 10;
|
||||||
|
} else time += 60;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue