[SOLVED] Development branch: st=fails after node sleep
-
I decided to start with the development branch because of the improved support for the RFM69. I have one outside weather node running without problems for over a month now. My gateway is on 1.5 and my controller is Pimatic.
My next node will be a wall switch with extra's. I want to make it super versatile and configurable in the same way as the MySensors settings in the 2.0 branch (that will show in the code I have so far...). It consists of 2 boards: one withe the radio and buttons mounted on a standard (in DE and NL) pulse switch, and one with the relays and a power supply. If you only use the mcu board it will be powered by a CR2032.
That's my project in short, now the challenge:
Slowly building up the sketch I now come to the sleeping part for when the node is battery powered. I used the code from a LowPowerLab forum user (bottom post on page 2) because at first I was unable to get the PCInt function working. Later I found I used a outdated version of the lib (2.19 in stead of 2.42).
Without sleep the code loops through theupdateChan()function. Works perfectly. ChanA is a momentary button and ChanB toggles. All the changes are sent to the controller like I want them to. Now enter "sleep": when I usesleep(0, FALLING, 0), all I get after the node sleeps arest=fail:x. The node sleeps only after 5 seconds. In the time before sleeping it registers all changes well.Starting sensor (RRNNA-, 2.0.0-beta) Radio init successful. Reading config... Starting up... Start radio and sensors Send node info. send: 117-117-0-0 s=255,c=3,t=15,pt=0,l=2,sg=0,st=ok: send: 117-117-0-0 s=255,c=0,t=17,pt=0,l=10,sg=0,st=ok:2.0.0-beta send: 117-117-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0 read: 0-0-117 s=255,c=3,t=6,pt=0,l=1,sg=0:M send: 117-117-0-0 s=255,c=3,t=11,pt=0,l=19,sg=0,st=ok:switchNode(battery) send: 117-117-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:0.9 send: 117-117-0-0 s=0,c=0,t=3,pt=0,l=0,sg=0,st=ok: send: 117-117-0-0 s=1,c=0,t=3,pt=0,l=0,sg=0,st=ok: Init complete, id=117, parent=0, distance=1 Function 1 Pressed send: 117-117-0-0 s=0,c=1,t=16,pt=1,l=1,sg=0,st=ok:1 Function 1 Released send: 117-117-0-0 s=0,c=1,t=16,pt=1,l=1,sg=0,st=ok:0 Function 1 Pressed send: 117-117-0-0 s=0,c=1,t=16,pt=1,l=1,sg=0,st=ok:1 Function 1 Released send: 117-117-0-0 s=0,c=1,t=16,pt=1,l=1,sg=0,st=ok:0 Sleeping Function 1 Pressed send: 117-117-0-0 s=0,c=1,t=16,pt=1,l=1,sg=0,st=fail:1 Function 1 Released send: 117-117-0-0 s=0,c=1,t=16,pt=1,l=1,sg=0,st=fail:0 SleepingIf I use
sleep(ms)the code fails to register the first button press while sleeping. Not exactly what you want in a light switch.Do I do something wrong? I also tried the LowPower.h library but that will not compile because of double declarations of
enum period_tAnd finally: the code...
/*************************************************************************** ** ** Light switch v1.0 with additional relay/power supply daughter board ** ** Designed by D Hille. MySensors library by Henrik Ekblad. ** Interrupt and debounce by ** ***************************************************************************/ // Enable debug prints #define MY_DEBUG // Set serial baudrate #define MY_BAUD_RATE 57600 // Enable and select radio type attached #define MY_RADIO_RFM69 #define MY_NODE_ID 117 /**************************************************************************/ #define LED_FUNCTION 0 // LED functions: // 0.: no LED present // 1.: ACK (LED will flash briefly when ACk is received) // 2.: Notification (LED wil diplay a function of the controller) #define NODE_CHAN_A_FUNCTION 1 #define NODE_CHAN_B_FUNCTION 2 // Node functions: // 0.: channel off // 1.: button only momentary ("ON" while button pushed, "OFF" when released) // 2.: button only toggle (every button push toggles state) /**************************************************************************/ #include <SPI.h> #include <MySensor.h> #include <PinChangeInt.h> //#include "LowPower.h" #define buttApin 4 // Arduino Digital I/O pin number for buttons #define buttBpin 5 #define LEDpin 9 #define pulseMinimal 200 #define bounceTime 10 #define awakeTime 5000 #define sketchName "switchNode(battery)" #define sketchVer "0.9" #define ChanA 0 #define ChanB 1 #define ChanC 2 #define ChanD 3 int pinChanged = 255; bool loopRead; bool reqAck = false; bool stateLED = 0; unsigned long pulseTime = 0; static unsigned long lastInterruptTime = 0; int inputPin[4] = {0, 0, 0, 0}; int function[4] = {0, 0, 0, 0}; bool currLvl[4] = {1, 1, 1, 1}; bool lastLvl[4] = {1, 1, 1, 1}; bool debouncer[4] = {1, 1, 1, 1}; bool outState[4] = {0, 0, 0, 0}; unsigned long lastButtonPressed[4] = {0, 0, 0, 0}; bool setDebug = false; bool startUp = true; bool noRFchanB = false; MyMessage msgButton(0, V_TRIPPED); MyMessage msgToggle(0, V_STATUS); MyMessage msgLED(LEDpin, V_LIGHT); #if (NODE_CHAN_A_FUNCTION == 0) #error Channel A cannot be turned off. For single channel use turn off channel B. #endif void setup() { #ifdef MY_DEBUG //Differentiate between global debug including radio and local debug setDebug = true; //for the sketch alone. #endif if (setDebug){ Serial.println("\nReading config..."); } if (NODE_CHAN_B_FUNCTION == 0) { noRFchanB = true; } if (LED_FUNCTION == 1) { reqAck = true; } inputPin[ChanA] = buttApin; inputPin[ChanB] = buttBpin; function[ChanA] = NODE_CHAN_A_FUNCTION; function[ChanB] = NODE_CHAN_B_FUNCTION; if (setDebug) { Serial.println("\nStarting up..."); Serial.println("Start radio and sensors"); Serial.println("Send node info."); } pinMode(inputPin[ChanA],INPUT_PULLUP); pinMode(inputPin[ChanB],INPUT_PULLUP); pinMode(LEDpin, OUTPUT); attachPinChangeInterrupt(inputPin[ChanA], ChanA_ISR, FALLING); attachPinChangeInterrupt(inputPin[ChanB], ChanB_ISR, FALLING); } void presentation() { sendSketchInfo(sketchName, sketchVer); present(ChanA, S_BINARY); if (!noRFchanB) { present(ChanB, S_LIGHT); } if (LED_FUNCTION == 2) { present(LEDpin, S_LIGHT); } lastInterruptTime = millis(); } void loop() { updateChan(pinChanged); sleepNow(); } void sleepNow(void) { if (millis()-lastInterruptTime > awakeTime) { //delay (50); Serial.println ("Sleeping"); lastInterruptTime = millis(); //delay (100); sleep(0, RISING, 0); } } void receive(const MyMessage &message) { if (message.isAck()) { flashLED(); } if (message.type == V_LIGHT) { if (message.sensor == LEDpin) { stateLED = message.getBool(); changeNotification(); } } } void flashLED() { digitalWrite(LEDpin, HIGH); wait(50); digitalWrite(LEDpin, LOW); } void changeNotification() { } void ChanA_ISR() { pinChanged = ChanA; lastInterruptTime = millis(); } void ChanB_ISR() { pinChanged = ChanB; lastInterruptTime = millis(); } void updateChan(byte bttnNo) { currLvl[bttnNo] = digitalRead(inputPin[bttnNo]); unsigned long currTme = millis(); if (currLvl[bttnNo] != lastLvl[bttnNo]) { lastButtonPressed[bttnNo] = currTme; } if (currTme - lastButtonPressed[bttnNo] > bounceTime) { if (currLvl[bttnNo] != debouncer[bttnNo]) { debouncer[bttnNo] = currLvl[bttnNo]; if (function[bttnNo] == 1) { Serial.println("Function 1"); if (currLvl[bttnNo] == LOW) { Serial.println("Pressed"); send(msgButton.setSensor(bttnNo).set(true)); } else { Serial.println("Released"); send(msgButton.setSensor(bttnNo).set(false)); } } if (function[bttnNo] >= 2) { Serial.println("Function 2"); if (currLvl[bttnNo] == LOW) { Serial.println("Toggle"); outState[bttnNo] = !outState[bttnNo]; send(msgToggle.setSensor(bttnNo).set(outState[bttnNo]), reqAck); } } } } lastLvl[bttnNo] = currLvl[bttnNo]; } -
Glad it helped David. I just thought about it again, maybe sleep(0xff, 0x00, 0) does work too. I did not test it but I think it calls the same function anyway.
However the method of direct calling sleep(0xff, 0x00, 0xff, 0x00, 0) should save some clocks because one less jmp is required :)
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login