MiniPill LoRa - STM32 Low Power Node

Dear @leo_korbee and @dvalencia,

thanks a lot for the replies. Indeed I use a bluepill a (genericSTM32F103C8) board. I provide here a (minimal) code where you (if you like) could see where the problems occurs. Some comments:

  • The ABP works if LowPower.attachInterruptWakeup is removed in the code, i.e.
    if you comment line 60 (LowPower.attachInterruptWakeup) you see that sending via ABP works, the BluePill switched into LowPower mode and wakes up periodically.

  • Low Power wakeup works only if the lora.Send_data is removed in the code, i.e.
    if you comment line 89 (lora.Send_Data(...)) the BluePill sleeps and can be woken up by pressing a button.

Maybe this helps a bit as a starting point. But don’t take too much time; I thought about implementing a displaying method when starting the BluePill, i.e., using the setup() function, i.e. just need to reset the BluePill, then the code in the setup() is executed once.

#include <Arduino.h>
// Low Power for sleeping
#include <STM32LowPower.h>
// LORA
#include "LoRaWAN.h"
#include "STM32IntRef.h"
// configuration of ABP parameters/keys ...
#include "secconfig.h" 


// RFM95W connection on MiniPill LoRa
#define DIO0 PB10
#define NSS  PA4
RFM95 rfm(SPI, DIO0, NSS);

// define LoRaWAN layer
LoRaWAN lora = LoRaWAN(rfm);
// frame counter for lora
unsigned int Frame_Counter_Tx = 0x0000;

// LowPower
// Sleep this many microseconds.
#define SLEEP_INTERVAL 60000
// Declare it volatile since it's incremented inside an interrupt
volatile bool wakeupbool = false;
// wakeup: Pin used to trigger a wakeup
#ifndef USER_BTN
#define USER_BTN PA15
#endif
// wakeup: define pin for waking up
const int wakeuppin = USER_BTN;


// wakeup - LowPower
// this function is a callback function; it will be called when the wakeup is done
// try to avoid any delays or operations which takes time (see library example of lowpower)
void wakeuptask(){
  wakeupbool = true;
}


void setup() {
  // Serial monitor for debugging:
  Serial.begin(9600);
  Serial.println("test hello");
  
  //Initialize RFM module
  rfm.init();
  lora.setKeys(NwkSkey, AppSkey, DevAddr);
  Serial.println("Initialize RFM module done");
  delay(500);

  // LowPower: Configure low power at startup
  LowPower.begin();
  // LowPower: Set pin as INPUT_PULLUP to avoid spurious wakeup
  pinMode(wakeuppin, INPUT_PULLUP);
  delay(100);
  // LowPower: Attach a wakeup interrupt on pin, calling repetitionsIncrease when the device is woken up
  // cirtical code: use interrupt: lora.Send_Data will stuck
  LowPower.attachInterruptWakeup(wakeuppin, wakeuptask, RISING);
  Serial.println("LowPower init done");

  // use this delay for first packet send 8 seconds after reset
  delay(8000);
}


void loop() {
  Serial.println("In the loop");

  // define bytebuffer
  uint8_t Data_Length = 0x09;
  uint8_t Data[Data_Length];
  // fill Data with useful data later, e.g. with sensor data
  for (int i=0; i<Data_Length; i++){
    Data[i] = i;
  }

  if (wakeupbool){
    // here something should ONLY happen when wakeup is done
    // e.g. displaying a value
    Serial.println("I woke up");
    wakeupbool = false;
    
  }
  
  // LORA, send the data
  Serial.println("I will send");
  //lora.Send_Data(Data, Data_Length, Frame_Counter_Tx);
  Serial.println("I have sent");
  // LORA, increase framecounter by 1
  Frame_Counter_Tx++;

  // take SLEEP_INTERVAL time to sleep
  Serial.println("I sleep now");
  delay(100);
  LowPower.deepSleep(SLEEP_INTERVAL);
  //LowPower.sleep();
  Serial.println("I woke up AFTER sleep");
  delay(100);
}

I use PlatformIO as environment, the platform.ini file looks like:

[env:genericSTM32F103C8]
platform = ststm32
board = genericSTM32F103C8
framework = arduino
upload_protocol = serial
monitor_speed = 9600
lib_deps = 
	; Low Power
	stm32duino/STM32duino Low Power @ 1.0.3