Sleep mode LowPower.h


(Russlan) #1

Has somebody experience with sleepmode, escpecialy with <LowPower.h> library?
I tried this sleepmode but it kind of doesnt work. I test it with serial print. It should print “sleepmode start” if it starts and print “sleepmode end” when it ends. But, when its time for the sleepmode to start, its kinda instant print as well “sleepmode start” as “sleepmode end”
without any delay. First i thought it could be an error cause of 30/8 =3.75 cycles, but i tried it with 32/8=4 cycles and it still insta prints as well “sleepmode start” as “sleepmode end”. Am i missing something? I marked the sleep mode part in the code with “!!!”

I use Dragoni Lora, OTAA. Everythings works just fine. Ty for your help

Here is my code

#include <lmic.h>        //LMIC
#include <hal/hal.h>     //LMIC 
#include <SPI.h>         //LMIC 
#include <SimpleDHT.h>   //DHT11 
#include <LowPower.h>





#ifdef COMPILE_REGRESSION_TEST    
# define FILLMEIN 0
#else
# warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!"
# define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN)
#endif



static const u1_t PROGMEM APPEUI[8]={  };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}


static const u1_t PROGMEM DEVEUI[8]={  0};
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}



static const u1_t PROGMEM APPKEY[16] = {  };
void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}


static osjob_t sendjob;


const unsigned TX_INTERVAL = 32;



//   RFM95  Arduino                   
const lmic_pinmap lmic_pins = {  
    .nss = 10, //Chip Select pin:D10
    .rxtx = LMIC_UNUSED_PIN, //Antenna selection pin: not used in our case.
    .rst = 9, //Reset pin used to reset the RFM95: D9
    .dio = {2, 6, 7}, //
};



int pinDHT11 = A0; 
SimpleDHT11 dht11(pinDHT11); 




void onEvent (ev_t ev) {
    Serial.print(os_getTime());
    Serial.print(": ");
    switch(ev) {
        case EV_SCAN_TIMEOUT:
            Serial.println(F("EV_SCAN_TIMEOUT"));
            break;
        case EV_BEACON_FOUND:
            Serial.println(F("EV_BEACON_FOUND"));
            break;
        case EV_BEACON_MISSED:
            Serial.println(F("EV_BEACON_MISSED"));
            break;
        case EV_BEACON_TRACKED:
            Serial.println(F("EV_BEACON_TRACKED"));
            break;
        case EV_JOINING:
            Serial.println(F("EV_JOINING"));
            break;
        case EV_JOINED:
            Serial.println(F("EV_JOINED"));
            {
              u4_t netid = 0;
              devaddr_t devaddr = 0;
              u1_t nwkKey[16];
              u1_t artKey[16];
              LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
              Serial.print("netid: ");
              Serial.println(netid, DEC);
              Serial.print("devaddr: ");
              Serial.println(devaddr, HEX);
              Serial.print("artKey: ");
              for (int i=0; i<sizeof(artKey); ++i) {
                Serial.print(artKey[i], HEX);
              }
              Serial.println("");
              Serial.print("nwkKey: ");
              for (int i=0; i<sizeof(nwkKey); ++i) {
                Serial.print(nwkKey[i], HEX);
              }
              Serial.println("");
            }
            // Disable link check validation (automatically enabled
            // during join, but because slow data rates change max TX
	    // size, we don't use it in this example.
            LMIC_setLinkCheckMode(0);
            break;
        /*
        || This event is defined but not used in the code. No
        || point in wasting codespace on it.
        ||
        || case EV_RFU1:
        ||     Serial.println(F("EV_RFU1"));
        ||     break;
        */
        case EV_JOIN_FAILED:
            Serial.println(F("EV_JOIN_FAILED"));
            break;
        case EV_REJOIN_FAILED:
            Serial.println(F("EV_REJOIN_FAILED"));
            break;
        case EV_TXCOMPLETE:
            Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
            if (LMIC.txrxFlags & TXRX_ACK)
              Serial.println(F("Received ack"));
            if (LMIC.dataLen) {
              Serial.print(F("Received "));
              Serial.print(LMIC.dataLen);
              Serial.println(F(" bytes of payload"));
            }
            // Schedule next transmission
// !!!!!!!!!!!!!!!!!!!!!!   sleep mode part
            //os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
            Serial.print("sleepmode start ");
for (int i=0; i<int(TX_INTERVAL/8); i++) {
        // Use library from https://github.com/rocketscream/Low-Power
        LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
      }
      Serial.print("Sleepmdoe end");
      do_send(&sendjob);
// !!!!!!!!!!!!!!!!!!!!!!  end of sleep mode part
            
            break;
        case EV_LOST_TSYNC:
            Serial.println(F("EV_LOST_TSYNC"));
            break;
        case EV_RESET:
            Serial.println(F("EV_RESET"));
            break;
        case EV_RXCOMPLETE:
            // data received in ping slot
            Serial.println(F("EV_RXCOMPLETE"));
            break;
        case EV_LINK_DEAD:
            Serial.println(F("EV_LINK_DEAD"));
            break;
        case EV_LINK_ALIVE:
            Serial.println(F("EV_LINK_ALIVE"));
            break;
        /*
        || This event is defined but not used in the code. No
        || point in wasting codespace on it.
        ||
        || case EV_SCAN_FOUND:
        ||    Serial.println(F("EV_SCAN_FOUND"));
        ||    break;
        */
        case EV_TXSTART:
            Serial.println(F("EV_TXSTART"));
            break;
        default:
            Serial.print(F("Unknown event: "));
            Serial.println((unsigned) ev);
            break;
    }
}



void do_send(osjob_t* j){


byte ID=1;




  Serial.println("=================================");
  Serial.println("Sample DHT11...");
  
  
  byte temperature = 0;
  byte humidity = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
    return;
  }
  
  Serial.print("Sample OK: ");
  Serial.print((int)temperature); Serial.print(" *C, "); 
  Serial.print((int)humidity); Serial.println(" H");
  
  // DHT11 sampling rate is 1HZ.
  delay(1500);
  


static int8_t mydata[6] ;
      mydata[0] = highByte(ID);
      mydata[1] = lowByte(ID);
      mydata[2] = highByte(temperature);
      mydata[3] = lowByte(temperature);
      mydata[4] = highByte(humidity);
      mydata[5] = lowByte(humidity);
      

  
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
       
        LMIC_setTxData2(1, mydata, sizeof(mydata), 0);  
        Serial.println(F("Packet queued"));
    }
    





}

void setup() {
    Serial.begin(9600); 
    Serial.println(F("Starting"));

    #ifdef VCC_ENABLE
 
    pinMode(VCC_ENABLE, OUTPUT);
    digitalWrite(VCC_ENABLE, HIGH);
    delay(1000);
    #endif

    // LMIC init
    os_init();
    // Reset the MAC state. Session and pending data transfers will be discarded.
    LMIC_reset();
     LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
   
    do_send(&sendjob);
   
}

void loop() {
    os_runloop_once();
}

(Grazy) #2

Please have a look to Lmic plus rfm95w staying awake for long periods

There is a code exemple how to sleep and a good explanation of problem with time.


(Russlan) #3

ty, it helped a lot


(Rudistrasser) #4

Hi,

it works for me. Take a look at https://github.com/strasserr/beelight/blob/master/draginoSense/dragino-otaa.cpp

     case EV_TXCOMPLETE:
        Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
        if (LMIC.txrxFlags & TXRX_ACK)
          Serial.println(F("Received ack"));
        if (LMIC.dataLen) {
          Serial.print(F("Received "));
          Serial.print(LMIC.dataLen);
          Serial.println(F(" bytes of payload"));
        }

        // Schedule next transmission
        //os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
        for (int i=0; i<int(TX_INTERVAL/8); i++) {
        	// Use library from https://github.com/rocketscream/Low-Power
        	LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
        }
        do_send(&sendjob);

        break;

/Rudi


(Rudistrasser) #5

Your print statements might get lost since the device goes to powerdown. Try to add delay(100) …


(Martin Sloup) #6

Use Serial.flush() instead of delay :slight_smile: