[Solved]RFM69 Sleep Mode - high current when sleeping



  • Re: RFM69 sleep mode

    Hello

    I'm back with my high current in sleep mode. After changing my multimeter, challenging my arduino configuration, doing lot of test loosing my hairs, i finally found that it is my rfm69w that consume 2mA in sleep mode.

    I use

    #define   MY_RADIO_RFM69
    #define MY_RFM69_NEW_DRIVER
    

    to configure RFM69

    I sleep wit the sleep functon

    int8_t cause = sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), FALLING, 600000);
    

    I measure the current directly in the 3.3V of the rfm69. In the meantime, the arduino mini is less than 50uA.

    What could I do debug such a situation ?

    Thank you for your help


  • Mod

    @barrydou are you sure your arduino is sleeping, and stays asleep? It could just as well go to sleep and wake again, go to sleep, wake etc.
    To be sure you could add some prints around the sleep statement.



  • Maybe you can also post your sketch, so that we have a complete view...



  • Hello

    Thank you for your time. Here is my complete sketch.

    If arduino goes to sleep and wakeup and so on, I think that I'll see lot of messages sended.
    I suspect my RFM69 to have some quality problems. But i'm not sure. I'll try to change it. as soon as i will receive new one from china.

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define   MY_RADIO_RFM69
    #define MY_RFM69_NEW_DRIVER
    
    #include <MySensors.h>
    
    #define DIGITAL_INPUT_SENSOR 3                  // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1                              // Id of the sensor child
    
    MyMessage volumeMsg(CHILD_ID, V_VOLUME);
    MyMessage lastCounterMsg(CHILD_ID, V_VAR1);
    
    volatile uint32_t pulseCount = 0;
    bool pcReceived = false;
    unsigned long loopNumber = 0;
    
    //=========================
    // BATTERY MEASURER
    // VOLTAGE DIVIDER SETUP
    // 1M, 470K divider across battery and using internal ADC ref of 1.1V
    // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
    // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
    // 3.44/1023 = Volts per bit = 0.003363075
    #define VBAT_PER_BITS 0.003363075
    #define VMIN 2.0                                  //  Vmin (radio Min Volt)=1.9V (564v)
    #define VMAX 3.2                                  //  Vmax = (2xAA bat)=3.0V (892v)
    int batLoop = 0;                                  // Loop to help calc average
    int batArray[4];                                  // Array to store value for average calc.
    int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
    //=========================
    
    
    void setup() {
      // initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
      pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
    
      pulseCount = 0;
      // Fetch last known pulse count value from gw
      request(CHILD_ID, V_VAR1);
    
      //Battery
      analogReference(INTERNAL);
    
      //On attend le resultat avant de passer dans la boucle
      wait(1000);
    
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Gas Meter", "2.0");
    
      // Register this device as Water flow sensor
      present(CHILD_ID, S_GAS);
    }
    
    //=========================
    // BATTERY MEASURER
    void MeasureBattery() //The battery calculations
    {
      delay(500);
      // Battery monitoring reading
      int sensorValue = analogRead(BATTERY_SENSE_PIN);
      delay(500);
    
      // Calculate the battery in %
      float Vbat  = sensorValue * VBAT_PER_BITS;
      int batteryPcnt = static_cast<int>(((Vbat - VMIN) / (VMAX - VMIN)) * 100.);
    #ifdef MY_DEBUG
      Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.print(" %"); Serial.print("Battery Voltage: "); Serial.print(Vbat); Serial.println(" Volts");
    #endif
    
      if (batteryPcnt > 100) {
        batteryPcnt = 100;
      }
      if (batteryPcnt < 0) {
        batteryPcnt = 0;
      }
    
      // Add it to array so we get an average of 3 (3x20min)
      batArray[batLoop] = batteryPcnt;
    
      if (batLoop > 2) {
        batteryPcnt = (batArray[0] + batArray[1] + batArray[2] + batArray[3]);
        batteryPcnt = batteryPcnt / 4;
    #ifdef MY_DEBUG
        Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
    #endif
        sendBatteryLevel(batteryPcnt);
        batLoop = 0;
      }
      else
      {
        batLoop++;
      }
    }
    
    void loop() {
      if (!pcReceived) {
        //Last Pulsecount not yet received from controller, request it again
        request(CHILD_ID, V_VAR1);
        wait(1000);
        return;
      }
    
      if (loopNumber % 12 == 0) {
        Serial.println("Measuring Battery");
        //=========================
        // BATTERY MEASURER
        MeasureBattery();
        //=========================
      }
    
    #ifdef MY_DEBUG
      Serial.println("I'm sleeping");
    #endif
      int8_t cause = sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), FALLING, 600000);
    #ifdef MY_DEBUG
      Serial.print("WakeUp , cause:");
      Serial.print(cause);
      Serial.print("(pin interrupt :");
      Serial.print(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR));
      Serial.println(";-1=timer)");
    #endif
    
      if (cause == digitalPinToInterrupt(DIGITAL_INPUT_SENSOR)) {
        pulseCount++;
        // softwaredebounce, on ignore toute entree pendant 100ms
        wait(100);
      }
    
    
    #ifdef MY_DEBUG
      Serial.print("Pulsecount=");
      Serial.println(pulseCount);
      Serial.println("Sending pulse Count");
    #endif
      double volume = 0;
      volume = ((double)pulseCount / ((double)1000));
      send(volumeMsg.set(volume, 4));
      send(lastCounterMsg.set(pulseCount));
    
      loopNumber++;
    
    }
    
    void receive(const MyMessage &message)
    {
      if (message.type == V_VAR1) {
        uint32_t gwPulseCount = message.getULong();
        if (!pcReceived) {
          pulseCount = gwPulseCount;
    #ifdef MY_DEBUG
          Serial.print("Received last pulse count from gw:");
          Serial.println(pulseCount);
    #endif
          pcReceived = true;
        }
      }
    }
    


  • @barrydou I don't see directly a problem in your sketch. (Besides, I should use wait everywhere and not delay, with a wait, mysensors can still receive messages).

    What is driving your digital input?
    It could be that the arduino is detecting something and doesn't sleep well.

    You could do an extra test by using following sketch : https://andreasrohner.at/posts/Electronics/How-to-modify-an-Arduino-Pro-Mini-clone-for-low-power-consumption/
    With this sketch we are sure that the arduino is sleeping.

    So let's recapitulate, you are saying that with your sketch running:

    • you measure the current consumption of only the arduino mini as less than 50 ยตA
    • you measure the current consumption of the RFM69W directly in the 3.3V as 2 mA : this is measured between the 3.3V power output and the 3.3V power input of the RFM69W?
      measure current.png
      (the PCB on the image is a RFM69HW, so your pin layout can be different!)

    If the 2mA are measured like in the image, than, if you have a scope, you can see if the inputs like NSS, MOSI, MISO and SCK are changed. It shouldn't during the sleep of the arduino.

    You have verified with a loop all your solder points?

    Maybe you could also post some photo's of your setup...



  • @evb it's for doing a gasmeter, counting with a reed sensor.
    But for my tests, the read sensor is not connected. So nothing wakeup the interrupt.
    I just send every 10 minutes the counter, as a keepalive. (Domoticz don't put the sensors as "red" )

    First, I was doing test with newbie pcb, and I had strange values.
    So I remove everything, and I do test with breadboard and dupont cable.

    I just have the arduino pro mini, and the rfm69 solder on a nrf2rfm69 board and a 0.1uF capacitor.
    I have 2AA alkaline battery, connected to the VCC/GND pin of arduino and to 3.3V/GND of NRF2RFM adapter.
    I measure the current on the cable between battery + and 3,3V of NRF2RFM69 (like in your photo)

    I have no scope, so I can't check NSS/MOSI/... and so on. But the transmissions are OK, and everything is working well, except current when sleeping.

    I had no time today to do more test today. I will double check everything as soon as possible, try your sketch



  • Sorry for not giving news.

    So I've done lot of tests, triple check everything and still found "nothing"
    I test with deepSleep sketch from lowpowerlab, and still have high current.

    I finally receive new rfm69 and change it. And it's ok now !!!
    I have 25uA when sleeping !!!

    Don't know why, but with new one, it's ok ๐Ÿ™‚

    Thank you again for your help and your ideas


Log in to reply
 

Suggested Topics

  • 87
  • 7
  • 5
  • 6
  • 3
  • 7

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts