cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32 + LoRaWAN] LoRaWAN doesn't start when button is pressed (PA0)

Mariiian09
Associate II

Hi everyone,

I'm working with an STM32 microcontroller and the LoRaWAN stack provided by ST. My goal is to initialize LoRaWAN only when a button connected to pin PA0 is pressed.

I verified with a multimeter that PA0 is at 0V when idle and goes to 3.3V when the button is pressed, so the hardware seems fine.

In the code, I'm calling MX_LoRaWAN_Init() only if I detect PA0 is HIGH and a debounce time has passed. However, LoRaWAN never starts, even if I hold the button for several seconds.

Below is the full main.c file, including the logic for PA0 detection and conditional LoRaWAN startup:

 
/* USER CODE BEGIN Header */

/**

 ******************************************************************************

 * @file : main.c

 * @brief : Main program body

 ******************************************************************************

 * @attention

 *

 * Copyright (c) 2025 STMicroelectronics.

 * All rights reserved.

 *

 * This software is licensed under terms that can be found in the LICENSE file

 * in the root directory of this software component.

 * If no LICENSE file comes with this software, it is provided AS-IS.

 *

 ******************************************************************************

 */

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

#include "main.h"

#include "app_lorawan.h"

#include "LmHandler.h"

/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */



/* USER CODE END Includes */



/* Private typedef -----------------------------------------------------------*/

/* USER CODE BEGIN PTD */



/* USER CODE END PTD */



/* Private define ------------------------------------------------------------*/

/* USER CODE BEGIN PD */

#define PA0_HIGH_DETECTED 1

#define PA0_LOW_DETECTED 0

/* USER CODE END PD */



/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PM */



/* USER CODE END PM */



/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

uint8_t pa0_state = PA0_LOW_DETECTED;

uint8_t lorawan_started = 0;

/* USER CODE END PV */



/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

/* USER CODE BEGIN PFP */

void Check_PA0_State(void);

void Start_LoRaWAN_When_Ready(void);

/* USER CODE END PFP */



/* Private user code ---------------------------------------------------------*/

/* USER CODE BEGIN 0 */



/* USER CODE END 0 */



/**

 * @brief The application entry point.

 * @retval int

 */

int main(void)

{

/* USER CODE BEGIN 1 */



/* USER CODE END 1 */



/* MCU Configuration--------------------------------------------------------*/



/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 HAL_Init();



/* USER CODE BEGIN Init */



/* USER CODE END Init */



/* Configure the system clock */

 SystemClock_Config();



/* USER CODE BEGIN SysInit */



/* USER CODE END SysInit */



/* Initialize all configured peripherals */

 MX_GPIO_Init();



/* USER CODE BEGIN 2 */



/* USER CODE END 2 */



/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

 {

 

 Check_PA0_State();

 

 Start_LoRaWAN_When_Ready();

 

if(lorawan_started == 1)

 {

 MX_LoRaWAN_Process();

 }

else

 {

 HAL_Delay(100);

 }

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

 }

/* USER CODE END 3 */

}



/**

 * @brief System Clock Configuration

 * @retval None

 */

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};



/* Enable HSE Oscillator and Activate PLL with HSE as source */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

 RCC_OscInitStruct.HSEState = RCC_HSE_OFF;

 RCC_OscInitStruct.HSIState = RCC_HSI_ON;

 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;

 RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

 Error_Handler();

 }



/* Initializes the CPU, AHB and APB buses clocks */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;



if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

 {

 Error_Handler();

 }

}



/**

 * @brief GPIO Initialization Function

 * @PAram None

 * @retval None

 */

static void MX_GPIO_Init(void)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};



/* GPIO Ports Clock Enable */

 __HAL_RCC_GPIOA_CLK_ENABLE();

 __HAL_RCC_GPIOH_CLK_ENABLE();



/* Configure GPIO pin Output Level */

 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10|GPIO_PIN_8, GPIO_PIN_RESET);



/* Configure GPIO pins : PA10 PA8 */

 GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_8;

 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);



/*Configure PA0 as input pin */

 GPIO_InitStruct.Pin = GPIO_PIN_0;

 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

 GPIO_InitStruct.Pull = GPIO_NOPULL; 

 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}



/* USER CODE BEGIN 4 */

/**

 * @brief Check the state of PA0 pin

 * @retval None

 */

void Check_PA0_State(void)

{

 pa0_state = (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) ?

 PA0_HIGH_DETECTED : PA0_LOW_DETECTED;

}





/**

 * @brief Start LoRaWAN stack when PA0 is HIGH

 * @retval None

 */

void Start_LoRaWAN_When_Ready(void)

{

static uint32_t last_debounce_time = 0;

const uint32_t debounce_delay = 50; // ms





if(lorawan_started == 1)

return;





if((pa0_state == PA0_HIGH_DETECTED) &&

 ((HAL_GetTick() - last_debounce_time) > debounce_delay))

 {

MX_LoRaWAN_Init();

 lorawan_started = 1;



 }

else if(pa0_state == PA0_LOW_DETECTED)

 {

 last_debounce_time = HAL_GetTick();

 }

}

/* USER CODE END 4 */



/**

 * @brief This function is executed in case of error occurrence.

 * @retval None

 */

void Error_Handler(void)

{

 __disable_irq();

while (1)

 {

 }

}

Do you have any idea why it doesn’t enter the initialization code?
Could something be wrong in my GPIO config or timing logic?

Any suggestions would be greatly appreciated. Thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
Mariiian09
Associate II
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

The issue was resolved by changing the pin from PA0 to PA5.

View solution in original post

8 REPLIES 8

Please give details of the hardware you're using; see How to write your question to maximize your chances to find a solution.

 


@Mariiian09 wrote:

I verified with a multimeter that PA0 is at 0V when idle and goes to 3.3V when the button is pressed, so the hardware seems fine.


So have you verified that your software is actually seeing the button press?

Have you stepped the code in the debugger to see what's happening?

 

PS:

In your previous thread, you had issues with the order of GPIO & LoRa initialisation:

https://community.st.com/t5/stm32cubeide-mcus/how-do-you-add-a-ioc-file-to-an-existing-project-that-does-not/m-p/788965/highlight/true#M35416

You will need to at least have configured the GPIO for your button in order to be able to detect the button press...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
padawan
Senior II

Hi 

The Pin PA0 has no pull down enabled so the pin is floating

Do you have a pulldown resistor at the input pin? and a littel c (100nF)?

As Andrew has written:. make sure that your button is regoniced by the program..

Put a led  at your Device ( PA10?) and set or toggle it by your code.

 

hth Padawan 

 

Thank you for your feedback.

I'm using the STM32 B-L072Z-LRWAN1 board. I connected a button to PA0, with one leg going to 3.3V and the other connected to PA0 and a 10kΩ pulldown resistor to GND. I verified with a multimeter that PA0 goes high when the button is pressed.

To confirm that the input works, I connected an LED to PA5, and it turns ON when PA0 goes high — so the button input is being detected correctly.

However, LoRaWAN still doesn't start — I don't see any join request or uplink messages.

Then probably unrelated to button, unless PA0 dependency elsewhere

Debug MX_LoRaWAN_Init(); alone, without involving the button. Instrument it and the code it calls to understand a what point it stops working or fails.

Instrument Error_Handler() and HardFault_Handler() so you know when it ends up there.

Is SysTick counting properly?

If you STOP in the debugger, where in the code is it stuck?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Mariiian09 wrote:

I'm using the STM32 B-L072Z-LRWAN1 board.


So, as @Tesla DeLorean said,  try without the button - using the ST example unmodified.

Once you have that working, then try adding your button ...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Thank you both for the suggestions.

I understand the idea of starting with the unmodified ST example, but in my case, I do need the button from the beginning.

My goal is to use the button to trigger several end devices to start sending LoRaWAN messages at the same time. So pressing the button should act as a kind of synchronized "start signal" for the devices.

Also, when I run the project without involving the button, everything works fine — LoRaWAN initializes and messages are sent successfully. The issue only appears when I move the LoRaWAN initialization inside the if (PA0 is high) condition.

So, as @Tesla DeLorean said, instrument you code to see what's happening.

Is the MX_LoRaWAN_Init() ever called?

Is the button debouncing actually working?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Mariiian09
Associate II
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

The issue was resolved by changing the pin from PA0 to PA5.