Should the node Present itself to the Gateway upon wake from sleep?



  • I have a node that wakes from an external signal (voltage monitor). When it wakes up, the Gateway sees all of the presentation material as though the node is being powered up for the first time. The sketch looks like this:

    / Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #define MY_NODE_ID 3
    #define MY_RF24_CE_PIN 8
    
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <prescaler.h>
    
    #define SKETCH_NAME "Sensor Node"
    #define SKETCH_MAJOR_VER "1"
    #define SKETCH_MINOR_VER "0"
    
    #define TEMPERATURE_SENSOR 1
    
    const byte EN = 17; //turns on the boost converter to get 3.3v
    const byte PER = 14; //peripherals (DS18B20, nRF24L01)
    const byte Wake_pin = 2;  //wake from sleep mode powerdown
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(TEMPERATURE_SENSOR, V_TEMP);
    
    void before(){
    
      pinMode(EN,OUTPUT);
      digitalWrite(EN,LOW);  //give us 3.3v
      
      pinMode(PER, OUTPUT);   //for turning on peripherals
      digitalWrite(PER,LOW);  //peripherals on - P Chan FET
      
      digitalWrite (Wake_pin, HIGH);  //will wake with falling edge
      
    }
    void setup()  
    {  
      
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
    
      // Register binary input sensor to sensor_node (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      present(TEMPERATURE_SENSOR, S_TEMP);  
     
    }
    
    // Loop will iterate on changes on the BUTTON_PINs
    void loop() 
    {
    
         send(msg.set(20));
    
    
        //we slow the CPU down so that it can run down to 1.8 volts safely.  The voltage
        //monitor will wake it up when the capacitor voltage drops from 3.3 volts
        //down to 2 volts
        setClockPrescaler(CLOCK_PRESCALER_4);  //bring the cpu to slow speed
        
        sleep(0,FALLING);  //interrupt on pin 2
        
        //the boost converter has been enabled so it is safe to bring the CPU
        //back up to full speed.
        setClockPrescaler(CLOCK_PRESCALER_1);  //bring the cpu back to full speed
    
    } 
    

    This is the output from the Gateway. I've shown a couple of full sleep >> wake cycles. I added a space between the end of one cycle and the beginning of the next. As you can see, the node sends the data, and then it goes through the whole initiation process. It doesn't do this when using the sleep function that is just based on the WDT. Is it supposed to do this?

    3;1;1;0;0;20
    0;255;3;0;9;TSP:MSG:READ 3-3-255 s=255,c=3,t=7,pt=0,l=0,sg=0:
    0;255;3;0;9;TSP:MSG:BC
    0;255;3;0;9;TSP:MSG:FPAR REQ (sender=3)
    0;255;3;0;9;TSP:CHKUPL:OK
    0;255;3;0;9;TSP:MSG:GWL OK
    0;255;3;0;9;TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=8,pt=1,l=1,sg=0,ft=0,st=ok:0
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=24,pt=1,l=1,sg=0:1
    0;255;3;0;9;TSP:MSG:PINGED (ID=3, hops=1)
    0;255;3;0;9;TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=25,pt=1,l=1,sg=0,ft=0,st=ok:1
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    0;255;3;0;9;TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=ok:0100
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=0,t=17,pt=0,l=5,sg=0:2.0.0
    3;255;0;0;17;2.0.0
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=6,pt=1,l=1,sg=0:0
    3;255;3;0;6;0
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=11,pt=0,l=11,sg=0:Sensor Node
    3;255;3;0;11;Sensor Node
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=12,pt=0,l=3,sg=0:1.0
    3;255;3;0;12;1.0
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=1,c=0,t=6,pt=0,l=0,sg=0:
    3;1;0;0;6;
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=26,pt=1,l=1,sg=0:2
    0;255;3;0;9;TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=27,pt=1,l=1,sg=0,ft=0,st=ok:1
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=1,c=1,t=0,pt=2,l=2,sg=0:20
    3;1;1;0;0;20
    
    
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=1,c=1,t=0,pt=2,l=2,sg=0:20
    3;1;1;0;0;20
    0;255;3;0;9;TSP:MSG:READ 3-3-255 s=255,c=3,t=7,pt=0,l=0,sg=0:
    0;255;3;0;9;TSP:MSG:BC
    0;255;3;0;9;TSP:MSG:FPAR REQ (sender=3)
    0;255;3;0;9;TSP:CHKUPL:OK
    0;255;3;0;9;TSP:MSG:GWL OK
    0;255;3;0;9;TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=8,pt=1,l=1,sg=0,ft=0,st=ok:0
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=24,pt=1,l=1,sg=0:1
    0;255;3;0;9;TSP:MSG:PINGED (ID=3, hops=1)
    0;255;3;0;9;!TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=25,pt=1,l=1,sg=0,ft=0,st=fail:1
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    0;255;3;0;9;TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=ok:0100
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=0,t=17,pt=0,l=5,sg=0:2.0.0
    3;255;0;0;17;2.0.0
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=6,pt=1,l=1,sg=0:0
    3;255;3;0;6;0
    0;255;3;0;9;TSP:SANCHK:OK
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=11,pt=0,l=11,sg=0:Sensor Node
    3;255;3;0;11;Sensor Node
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=12,pt=0,l=3,sg=0:1.0
    3;255;3;0;12;1.0
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=1,c=0,t=6,pt=0,l=0,sg=0:
    3;1;0;0;6;
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=255,c=3,t=26,pt=1,l=1,sg=0:2
    0;255;3;0;9;TSP:MSG:SEND 0-0-3-3 s=255,c=3,t=27,pt=1,l=1,sg=0,ft=0,st=ok:1
    0;255;3;0;9;TSP:MSG:READ 3-3-0 s=1,c=1,t=0,pt=2,l=2,sg=0:20
    3;1;1;0;0;20
    

    One other possibly relevant thing is that I modified the file MyHwATMega328.cpp in function:

    void hwPowerDown(period_t period)
    

    to include a few lines to manipulate the pins that enable and disable the boost converter on the board:

    sei();
    	DDRC &= ~(1<<3);  //disable boost converter
    	PORTC &= ~(1<<3);
    	// sleep until WDT or ext. interrupt
    	sleep_cpu();
        sleep_disable();
    	DDRC |= (1<<3);	//enable boost converter
    	PORTC |= (1<<3);
    	// restore previous WDT settings
    

  • Admin

    @jerseyguy1996 looks like a wdt reset. Please also post the node's debug log.


  • Hardware Contributor

    @jerseyguy1996
    so you're trying to make an ulpnode 😉 i have already made my own so I detected 🙂
    though, pir does not work well with ulpnode concept unfortunately (because variable voltage trigger pir) but it's great for telemetry etc and a nice exercise btw 🙂 so for pir multisensors i have to use an other low power board.

    It could be multiple source for your problem, not easy from here! I hope you will find

    • tekka is right it looks watchdog rst. or some brown out. not sure.
    • your assembly/board but I don't hope for you!
    • try to add small delay after changing prescaler to see if it helps but not sure.
      I change prescaler too, and mix things with tx transmit etc and no problem.. Small delays can help for serial debug output, maybe in your case
    • do you really need to put this in hwPowerDown ?? you should have enough time to put this just after sleep() and there is also the storage capa so..Then, after mysensors lib update, you won't have to add this again


  • @tekka I threw a wdt_reset() in there but still no joy. It also seems like most of the transmissions are failing when it comes out of sleep mode. Also there is a particular transmission that if it fails I've noticed the node gets stuck and won't go back to sleep. It's very perplexing.



  • @scalz Yes you are correct in that I am making a ULPNode :-). I need it for monitoring various parts of a salt water aquarium and I don't want to have to have power cords going everywhere. The node I made actually works great as far as being able to go to sleep, wake up with the interrupt from the voltage monitor, power on the radio and sensors, and then transmit out its data before going back to sleep. It just seems to be having trouble with the MySensors sleep functionality. I may just use the sleep(ms) function until I can figure it out.

    I had already tried most of your suggestions so I guess great minds think alike 😉

    Below is the link for my ULPNode. It has a connection for a DS18B20 temperature sensor and 3 float switches which are used for water levels. It also has an input for the raw battery voltage so that it can monitor its battery levels and notify me when it needs to be changed.

    What do you mean by "pir"? What does that stand for?

    Saleem's ULPNode Schematic

    Saleem's ULPNode Board

    Picture Bottom

    Picture Top


  • Mod

    @jerseyguy1996 said:

    It also seems like most of the transmissions are failing when it comes out of sleep mode.

    I've seen many nRF's that have a hard time communicating just after power up. Seems like internals are still settling or calibrating.
    If, in your setup, this leads to retry of transmissions, I doubt if powering off while sleeping will extend battery life.


  • Hardware Contributor

    @jerseyguy1996 by PIR, I mean motion detection sensor. They trigger on a very small change of vcc. So a variable vcc is not great which is the concept here! and as I wanted to limit the number of module, I did another multisensor board with all included still limiting power consumption.

    I'm sorry to say this, looking at your schematic, ulpnode sequence is not complete. It's not because you can have sort of sequence working that it works reliably. And another not good feedback..is that your node is not low power, far from ulpnode...

    Why:

    • I have not looked deep, but you may have some pin floating. It's not a good practice to not put pullup on mosfet, because you can miss a case and let the place to floating state. When you know exactly what you do and schematic is wired in a way, it's ok. So if you may have a floating state on your radio mosfet, it could be the problem. Try to add a pullup if it helps.
    • sequence not complete. Why nothing connected to the input of your supervisor, it's useless like this. To have a reliable sequence without having to rely on software (as ulpnode works), you have to connect the input of supervisor to your vcc.
    • about power consumption, I think you have not checked the power consumption yet and you could be disappointed! because you don't disconnect the resistor divider of the booster from gnd. So there is a big consumption there.
    • You're using an inverter supervisor on output. It's not low power too. you should use mosfet and connect it to your booster...and be careful with the booster en pin not floating during wiring everything.
    • for the mcp1640 I hope you choosed the MCP1640 or MCP1640T variant as others are less efficient for your case.
    • you could need a uCurrent. A simple multimeter is not enough. and a scope is very useful too sometimes.
    • etc..

    I already met Charles from Hallard.me (it's almost a neighboor). very cool guy. I told him I would wait to release my homemade working clone, for respect, it was first on this 😉



  • @scalz

    Thanks for the feedback! I think some of the issues that you highlight are correct but some are actually covered in my design. I'll try to address each one and I would love to hear any additional feedback and if my explanation addresses these issues.

    • I have not looked deep, but you may have some pin floating. It's not a good practice to not put pullup on mosfet, because you can miss a case and let the place to floating state. When you know exactly what you do and schematic is wired in a way, it's ok. So if you may have a floating state on your radio mosfet, it could be the problem. Try to add a pull-up if it helps.

    You are correct that this is an issue. This is actually my 3rd build of this board and I've been fixing little problems along the way. This will be addressed in the next iteration.

    • sequence not complete. Why nothing connected to the input of your supervisor, it's useless like this. To have a reliable sequence without having to rely on software (as ulpnode works), you have to connect the input of supervisor to your vcc.

    If you look closely at the schematic, VCC is connected to the input of the supervisor. It is connected at pin 2 of the device. The sleep/wake up functionality of the board is currently working fine.

    • about power consumption, I think you have not checked the power consumption yet and you could be disappointed! because you don't disconnect the resistor divider of the booster from gnd. So there is a big consumption there.

    In this case my total resistance across that divider is 1.5Mohms so the current even when VCC is at 3.3V is about 2.15 uA. Certainly high compared to the nanoAmp draw that we are attempting but for my use I can live with it.

    • You're using an inverter supervisor on output. It's not low power too. you should use mosfet and connect it to your booster...and be careful with the booster en pin not floating during wiring everything.

    Good call....I'll switch that one out on the next iteration for a mosfet

    • for the mcp1640 I hope you choosed the MCP1640 or MCP1640T variant as others are less efficient for your case.

    Yes I'm using this one: MCP1640T-I/CHY

    • you could need a uCurrent. A simple multimeter is not enough. and a scope is very useful too sometimes.

    I'm not trying to make it absolutely low power...I just want to not have to change the battery more than once a year. I rough estimated my current consumption by timing the discharge of the 470uF storage capacitor. My sleep to wake period is right at 30 seconds so the capacitor has to discharge from 3.3v down to 2.0v over that time. That gives me a peak current in sleep mode of about 26uA.....certainly not the nano amp level that Charles Hallarde was able to get but it is fine for my implementation. A typical AAA battery has about 1000 mAh of useful capacity so at 26uA continuous draw (ignoring the short on times) I should have a useful battery life of about 38500 hours or about 4.39 years........which is more than enough.

    What are your thoughts?



  • @Yveaux I was having this problem in my test script which was just the GettingStarted example script on the RF24 library. I solved it by simply re-transmitting if the first one failed. It never took more than 2 trys. I just don't know how to force the mysensors library to retry the transmission if the first attempt fails.


  • Hardware Contributor

    i have not so much time to make a complete answer sorry. but i agree if it fits your needs that's most important 🙂

    i thought first you wanted to make ultra low power node (ulpnode). but 26uA is not that bad sure.
    but as i said the pullup missing on mosfet can help you to not waste time with some radio issue during coding.

    so my thought is congrats for your board working 😉



  • @scalz Thanks for all of your advice! It's nice to get help from someone who has already successfully made a ulpnode.


 

325
Online

7.9k
Users

8.8k
Topics

93.8k
Posts