High current

  • I'm having trouble with high current consumption in an battery operated node. I suspect the NRF beeing the offending part. How can I be sure I have put the radio to sleep? I don't use the sleep() command because I use pinchange interupt instead of INT0 or INT1. I put the cpu to sleep with my own code. But how can I be sure that the radio has been put to sleep?
    In the code as it is now I use,


    But I'm not sure that the radio is put to sleep.

  • Mod

    @kk02067 you should be able to mimic the MySensors sleep function, see https://github.com/mysensors/MySensors/blob/7e6db413c7a9efe45e2fc927e0438fd55d5179d3/core/MySensorsCore.cpp#L518 . Looks like transportDisable() is the one to call. You should be able to copy the power up sequence as well.

    Do you think your code could be added to the MySensors library to allow wake up on pinchange? If that was possible, you wouldn't need to maintain a copy of some of the code, and others could also use that wake up feature.

  • @mfalkvidd
    I will look into using your suggestions when I have the time.

    Regarding using my code in the library I don't see it beeing an option. The reason is that I'm an amateur programmer and as such I dont know all the "rules" on how code should look. In swedish as you know we have the term "spagettikod" and thats kind of how my code looks. I'm from an assembler background and and there I'm used to "slap some thing together", poking in registers directly and such.

  • Mod

    @kk02067 maybe you can get in touch with one of the developers so he can review your code. Wake up on ping change is something many people have struggled with, so if you found a solution it would be nice to have it working in the library 🙂

  • Hardware Contributor

    it's not so easy to add pcint change to the lib in a clean way actually. Also doing this would increase lib size. It exists an external lib for this but not ready to use with mysensors yet afaik..
    Need some work.. and now it's so easier with more powerful mcus and it's cheap.

    So for the moment, it's easier, and saving mem, to do it by hand like you've done 😉 (i also use pcint like this).

    Regarding sleep code, that can work sure, by using the transport functions (i did that a while) but, @mfalkvidd is right, I think your asm sleep code is missing some important code part from the mysensors sleep functions.. When i did that i tried to mimic some parts of mysensors sleep code and so on.

  • @scalz

    The snippet of code in my previous post isn't the whole code. This is a bit more of the code (the loop section),

      while(!isTransportReady){   //kolla om allt ok för "sleep"
        _process();               //om inte så kör processen som styr biblioteket
      transportPowerDown();   //Stäng ner radion
    //  Serial.print("Gonatt :");
    //  Serial.println(sleepcounter);
      Serial.flush ();    //vänta på serial skall bli klar
      WDTCSR=0b00011000;  //Starta watchdog timer interupt på 1s
      SMCR=0b00000101;    //Välj powerdown mode
      if (pinchange){     //Om pinchange är anledningen till vakna så sov igen
        goto sleep;
    // Här har det gått en sekund skicka nya data om det behövs
      TCNT1=0;            //Nollställ cykelräknaren 
    //  Serial.print("Cykeltid: ");
    //  Serial.println(cycle*8);

    But it seems to consume to much power.

    The pinchange interupt fires fairly often but the mcu is mostly awake for about 120 cycles every second. So a drop of 0.2 Volts in battery in under 18 hours seems a bit high. This on a 3.3v pro mini at 8MHz.

  • Sorry for OT but I am a bit confused, doesn't support sleep wakeups on pin changes? I guess you mean something else then?

       * Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change.
       * See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin
       * is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3
       * @param interrupt Interrupt that should trigger the wakeup
       * @param mode RISING, FALLING, CHANGE
       * @param sleepingMS Number of milliseconds to sleep or 0 to sleep forever
       * @param smartSleep Set True if sending heartbeat and process incoming messages before going to sleep
       * @return Interrupt number if wake up was triggered by pin change, @ref MY_WAKE_UP_BY_TIMER if wake up was triggered by timer, @ref MY_SLEEP_NOT_POSSIBLE if sleep was not possible (e.g. ongoing FW update)
    int8_t sleep(const uint8_t interrupt, const uint8_t mode, const uint32_t sleepingMS = 0,const bool smartSleep = false);

  • Mod

    In theory it's supported, but in practice many people didn't get it to work using CHANGE

  • Hero Member

    @pansen The pinchange interrupt is a different feature in the atmega. It can be used on any pin and is not supported in MySensors. That is why you need to make sure yourself that everything goes to sleep as wanted.

  • @gohan @AWI I understand, so the main issue is that CHANGE does not work. I checked the datasheet and INT0 and INT1 can also do CHANGE so it's a bit weird:


    Of course you're limited to the INT0/1 pins then.

    But also:


    So PCINT is just not implemented in MySensors? Code is probably based on an old datahseet:


    Because that's just wrong...Looking at hwSleep for AVR it looks like it's just using attachInterrupt with the passed through mode. I'll test later because in fact I'm working on a project with a MPR121 touch controller that wakes up my Pro Mini on FALLING so I change it to CHANGE and see what happens...

    Anyhow, @kk02067 I'd use INT0/1 pins if you can...also, just measure the current consumption und unplug the nrf to see how much it changes. My mentioned MPR121 project consumes about 0.5-0.9mA in sleep and ~18mA in awake (MPR121+Pro Mini+nrf) just to give you some ballpark numbers. Consumption went to 5mA with nrf unplugged.

  • The pinchange interupt works fine.

    I found the offending things on my board. It was a combination of a couple of things. First it was the BME280 that was constantly active. Change to forced mode dropped the consumption from 0.4mA to 0.1 mA. I stopped using the internal pullup for my windspeedsensor which is based on a reedswitch. I noticed when the switch was open the consumption dropped to 0.04mA so I mounted a 1Mohm resistor instead of the internal pullup. Turning off the ADC dropped a about 10-20 uA. And lastly it seems that my nimh batterys where bad. They could not keep the charge. Changed to 2 x aaa and now it looks better.

    Current now on average 0.035 mA in sleepmode

    I will buy new nimh's to see if my solar panel circuit will work as expected. I hope to keep it running for about 5 years without changing the battery.
    Only time will tell now.

  • Mod

    I am planning to use supercaps, instead of rechargeable batteries, with solar panel. I'll see what it can do when I get the parts

  • Hero Member

    @pansen What i meant is that the MySensors API only specifies the (hw) INT0/INT1 RISING/ FALLING/ CHANGE. All of these work as expected.

Log in to reply

Suggested Topics