Hi all,
A quick sence check please, before I have to build a new node.
One of my battery powered PIR sensors in the home, suddenly stopped communicating, node has been in existence for well over 18 months, working flawlessly, no hangups or anything.
I received a email from my domoticz system, when there had been no coms for a period of time from the node.
I looked at the reported battery voltage, and thought, ok, time for a recharge (LIPO battery), in fact it's first recharge.
after charging, nothing, did not show up again in domoticz, so plugged into the pro-mini, to see the serial output, of which there wasn't any, as the debug wasn't enabled. Reflashed code, with debug enabled, and node cannot find any parent? whilst I am going this, I am sat on my sofa, 10 feet from the gateway, and another node which is a repeater. I fiddle with the tx power, to make sure it's now not too high, for its current (temporary location) I try it in it's normal location as well, equally no joy.
Here is the log, well a bit of it
60194 TSF:TRI:TSB
Motion 0
60246 !MCO:SND:NODE NOT REG
RAWbatcount :987
batV :4.10
batP :88
60665 !MCO:SND:NODE NOT REG
60667 !MCO:SND:NODE NOT REG
Sleep 3000
60672 MCO:SLP:MS=3000,SMS=0,I1=255,M1=255,I2=255,M2=255
60678 !MCO:SLP:TNR
Sleep infinit
63680 MCO:SLP:MS=3600000,SMS=0,I1=1,M1=1,I2=255,M2=255
63686 !MCO:SLP:TNR
66232 TSM:FAIL:RE-INIT
66234 TSM:INIT
66236 TSM:INIT:TSP OK
66240 TSM:INIT:STATID=21
66242 TSF:SID:OK,ID=21
66244 TSM:FPAR
67246 ?TSF:MSG:SEND,21-21-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
69255 !TSM:FPAR:NO REPLY
69257 TSM:FPAR
70260 ?TSF:MSG:SEND,21-21-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
72269 !TSM:FPAR:NO REPLY
72271 TSM:FPAR
73273 ?TSF:MSG:SEND,21-21-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
73689 MCO:SLP:MS=3589999
73691 TSF:TDI:TSL
73693 MCO:SLP:WUP=1
73695 TSF:TRI:TSB
Motion 0
73748 !MCO:SND:NODE NOT REG
RAWbatcount :987
batV :4.10
batP :88
74166 !MCO:SND:NODE NOT REG
74168 !MCO:SND:NODE NOT REG
Sleep 3000
74172 MCO:SLP:MS=3000,SMS=0,I1=255,M1=255,I2=255,M2=255
74178 !MCO:SLP:TNR
75282 !TSM:FPAR:NO REPLY
75284 TSM:FPAR
76288 ?TSF:MSG:SEND,21-21-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
Sleep infinit
77180 MCO:SLP:MS=3600000,SMS=0,I1=1,M1=1,I2=255,M2=255
77187 !MCO:SLP:TNR
78297 !TSM:FPAR:FAIL
78299 TSM:FAIL:CNT=4
78301 TSM:FAIL:DIS
78303 TSF:TDI:TSL
87189 MCO:SLP:MS=3590000
87191 TSF:TDI:TSL
here is the battery voltage graph before failure

and a switch log, showing the working connection, when the voltage had dropped / dropping.

given that the voltage has dropped very quickly in recent time , see years chart below.

Do people think there has been a catastrophic failure on the radio module (RFM69HW)?
Here is the sketch, in reflashing this node to enable the debug, the version migrated from 2.2.0 to 2.3.2
I have also tried clearing the eeprom, and have restarted domoticz.
// Enable debug prints
//#define MY_DEBUG
//#define MY_DEBUG_VERBOSE
//#define MY_DEBUG_VERBOSE_RFM69
//#define MY_DEBUG_VERBOSE_SIGNING
//#define MY_SIGNING_SOFT
//#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
//#define MY_SIGNING_REQUEST_SIGNATURES
#define MY_SPLASH_SCREEN_DISABLED
//#define MY_DISABLE_RAM_ROUTING_TABLE_FEATURE
#define MY_TRANSPORT_WAIT_READY_MS 20000
// Enable and select radio type attached
//#define MY_REPEATER_FEATURE
#define MY_RADIO_RFM69
#define MY_RFM69_FREQUENCY RFM69_433MHZ // Set your frequency here
//#define MY_RFM69_MAX_POWER_LEVEL_DBM (13) // max. TX power 10dBm = 10mW
#define MY_RFM69_TX_POWER_DBM (13)
#define MY_IS_RFM69HW // Omit if your RFM is not "H"
//#define MY_RF69_IRQ_PIN 2
//#define MY_RFM69_CS_PIN 9 // NSS. Use MY_RF69_SPI_CS for older versions (before 2.2.0)
//#define MY_RFM69_ENABLE_ENCRYPTION
//#define MY_RFM69_NETWORKID 100 // Default is 100 in lib. Uncomment it and set your preferred network id if needed
#define MY_NODE_ID 21
//#include <MyConfig.h>
//#include <Filter.h>
#include <MySensors.h>
//#include <TimeLib.h>
//#include <Bounce2.h>
//#include <avr/wdt.h>
#include <Vcc.h>
#define VCC_MIN 3.0
#define VCC_MAX 4.25
Vcc vcc;
int rawbatteryLevel = 0;
int prevbatterylevel=0;
int scaledbatterylevel = 0;
uint8_t batP = 100;
float batV = 3.250;
int oldBatteryPcnt = 0;
const float BatVccMin = 3000; // Minimum expected Battery Vcc level, in Volts.
const float BatVccMax = 4250; // Maximum expected BatteryVcc level, in Volts.
const int MaxBattCount = 1023;
const float BatVccCorrection = 4.15 / 4.18; // Measured Battery Vcc by multimeter divided by reported Vcc
#define CHILD_ID_PRESENCE 4
#define CHILD_ID_RX_RSSI 5
#define CHILD_ID_BATVCC 6
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
const int PresenceDetect = 3;
const long interval = 20000;
unsigned long previousMillis,previousrelayMillis,previouprescence= 0;
unsigned long debouncetime =0;
bool myprescenceDetected = 0;
bool Relaystate = 0;
bool uplinkAvailable = true;
bool requestState;
bool firstStart = true;
unsigned long MYsleepTime = 3600000;//SLEEP_SEC*1000 * SLEEP_MINS * 60 ; //period_t is an enum type defined in the LowPower library (LowPower.h)
int sleepcnt =0;
volatile long currenttime = 0;
volatile long temptime = 0;
//long lightLevel = 0;
// Initialize message
MyMessage msgPrescenceDetect(CHILD_ID_PRESENCE, V_TRIPPED);
MyMessage msgRxRSSI(CHILD_ID_RX_RSSI, V_LEVEL);
MyMessage msgVcc(CHILD_ID_BATVCC, V_VOLTAGE);
void setup() { // put your setup code here, to run once:
pinMode(PresenceDetect, INPUT); // interruptPin
pinMode(2, INPUT_PULLUP); // interruptPin2
EIFR = (1<<INTF0) | (1<<INTF1);// prevent initial trigger, clear interrupt
wait(100);
EIFR = (1<<INTF0) | (1<<INTF1);
// attachInterrupt(digitalPinToInterrupt(PresenceDetect), prescenceDetected, RISING);
wdt_disable(); // Might be redundant as the bootloader should have done this already
analogReference(INTERNAL);
}//end setup
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo("Motion Sensor", "1.0.1");
// Register all sensors to gw (they will be created as child devices)
// present(CHILD_ID_LIGHTLEVEL, S_LIGHT_LEVEL,"LIGHT_LEVEL",true);
// wait(250);
present(CHILD_ID_RX_RSSI, S_SOUND, "Motion RX RSSI",true);
wait(1000);
present(CHILD_ID_PRESENCE, S_MOTION, "Prescence", true);
wait(250);
present(CHILD_ID_BATVCC, S_MULTIMETER, "Motion Battery V");
}//end presentation
void loop() { // put your main code here, to run repeatedly:
// Read digital motion value
wait(50);// wait a bit, then read in level, avoid spurious noise as PIR holds high state for 27sec
bool Motion = digitalRead(PresenceDetect) == HIGH;
Serial.print("Motion ");
Serial.println(Motion);
send(msgPrescenceDetect.set(Motion?"1":"0")); // Send tripped value to gw
// get the battery Voltage
if(Motion == 0){
wait(5);
rawbatteryLevel = analogRead(BATTERY_SENSE_PIN);//
if(prevbatterylevel != rawbatteryLevel){
wait(5);
long tempV=0;
for(int i=1;i<=50;i++){
wait(5);
rawbatteryLevel = analogRead(BATTERY_SENSE_PIN);//
tempV=tempV + rawbatteryLevel;
}
rawbatteryLevel = tempV/50;
prevbatterylevel = rawbatteryLevel;
float scaledbatterylevel = map(rawbatteryLevel,0,MaxBattCount,0,BatVccMax );// changed it to milivolts
float batV = scaledbatterylevel /(1000); // Battery voltage
uint8_t batP = (((scaledbatterylevel - BatVccMin)*100)/(BatVccMax-BatVccMin)); //((input - min) * 100) / (max - min)
#ifdef MY_DEBUG
Serial.print("RAWbatcount :");
Serial.println(rawbatteryLevel);
Serial.print("batV :");
Serial.println(batV);
Serial.print("batP :");
Serial.println(batP);
#endif
wait(100);
float volts = vcc.Read_Volts();
send(msgVcc.set(batV,2),false);
if (oldBatteryPcnt != batP) {
sendBatteryLevel(batP);
oldBatteryPcnt = batP;
}
RX_SEND();
}
}
Serial.println("Sleep 3000");
sleep(3000);
Serial.println("Sleep infinit");
// EIFR = 1;// clear interrupts
// EIFR = 2;
EIFR = (1<<INTF0) | (1<<INTF1);// clear interrupts
sleep(digitalPinToInterrupt(PresenceDetect), CHANGE, MYsleepTime);
}// end loop
void receive(const MyMessage &message) {
// We only expect one type of message from controller. But we better check anyway.
if (message.isAck()) {
#ifdef MY_DEBUG
Serial.println("+Ack FMGW");
#endif
}
#ifdef MY_DEBUG
Serial.print("*InMsgty :");
Serial.print(message.type);
Serial.print(" MsgComd:");
Serial.print(message.getCommand());
Serial.print(" childID:");
Serial.print(message.sensor);
Serial.print(" Switch:");
Serial.println(message.getFloat());
#endif
if (message.type == V_STATUS || S_HEATER || V_LIGHT || V_HVAC_SETPOINT_HEAT || V_TEMP || S_HVAC) {
if (message.getCommand() == 2){// THIS PROCESSES THE CONTROLLERS EXPECTED STATE OF THE OUTPUT
// put code here to be executed when the message is from a request
#ifdef MY_DEBUG
Serial.print("REQ_Msg :");
Serial.print(message.type);
Serial.print(" MsgCmd:");
Serial.print(message.getCommand());
Serial.print(" childID:");
Serial.print(message.sensor);
Serial.print(" Switch:");
Serial.println(message.getBool());
#endif
switch (message.sensor) {// the child ID
case 1:
break;
case 6:
break;
} // end switch
}// end msg=2
if (message.getCommand() == 1){// THIS PROCESSES DIRECTED COMMANDS
#ifdef MY_DEBUG
Serial.print("*InMsgty :");
Serial.print(message.type);
Serial.print(" MsgComd:");
Serial.print(message.getCommand());
Serial.print(" childID:");
Serial.print(message.sensor);
Serial.print(" Switch:");
Serial.println(message.getBool());
#endif
switch (message.sensor) {// the child ID
case 1:
break;
case 3:
break;
case 6:
break;
} // end switch
}// end if msg = 1
}// end msg type function
}// end void loop
void prescenceDetected() { // action when interrupt button doesnt really do anyhing as edge triggered
currenttime = millis();
if ((currenttime - debouncetime) > 2000) {
myprescenceDetected = 1;
}
debouncetime = currenttime;
}
void RX_SEND()
{
send(msgRxRSSI.set(transportGetSignalReport(SR_RX_RSSI)));
}
void sendBatteryReport() {
float p = vcc.Read_Perc(VCC_MIN, VCC_MAX, true);
int batP = static_cast<int>(p);
#ifdef MY_DEBUG
Serial.print("Battery is: "); Serial.println(batP);
#endif
sendBatteryLevel(batP);
}
/*
// This is called when a new time value was received
void receiveTime(unsigned long controllerTime) {
// Ok, set incoming time
#ifdef MY_DEBUG
Serial.print("Time value received: ");
#endif
if (controllerTime > 1525129200){
setTime(controllerTime);
#ifdef MY_DEBUG
Serial.print("Time value valid: ");
Serial.println(controllerTime);
#endif
// RTC.set(controllerTime); // this sets the RTC to the time from controller - which we do want periodically
timeReceived = true;
#ifdef MY_DEBUG
Serial.print(hour());
Serial.print(" ");
Serial.print(minute());
Serial.print(" ");
Serial.print(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
#endif
}
}
*/
Any suggestions gratefully received.
Regards
Nigel