cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_GPIO_EXTI_Callback() Only called half the time.

JustSomeGuy
Associate III

The code I wrote for the B-L072Z-LRWAN1 is supposed to count pulses on a falling-edge external interrupt pin. The pulse source is an Arduino which toggles its GPIO on and off every 5ms, for a 10ms pulse period. after 6 seconds, the B-L072Z-LRWAN1 transmits the accumulated pulses to a receiving B-L072Z-LRWAN1 device (using proprietary peer-to-peer communication [confirmed to work properly]), which after 6 seconds should receive a count of 600 pulses. The 6 second timer has been confirmed to trigger a callback every 6 seconds.

My issue is that only 300 pulses are being send, which implies that the interrupt is only being called or incrementing every other time. There is an IoT bridge which takes the pulse input from both the arduino and the receiving STM32 device, and displays the pulse count on an IoT platform. the graph shows that the pulse rate for the STM32 is exactly half of what is coming from the Arduino. After debugging, I confirmed that the sending device is sending the wrong number of 300 pulses. Can anyone tell me the reason for this? 

Here is a screenshot of the gpio configuration:

Screenshot 2024-10-30 113050.png

here is the cubeMX configuration function:

 

 

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, PA15_RESERVED_Pin|PA12_RESERVED_Pin|PA1_RESERVED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GREEN_LED_Pin|BLUE_LED_Pin|RED_LED_Pin|TCXO_PWR_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, PC1_RESERVED_Pin|PC0_RESERVED_Pin|PC2_RESERVED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : PA15_RESERVED_Pin PA12_RESERVED_Pin PA1_RESERVED_Pin */
  GPIO_InitStruct.Pin = PA15_RESERVED_Pin|PA12_RESERVED_Pin|PA1_RESERVED_Pin;
  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 GPIO pins : GREEN_LED_Pin BLUE_LED_Pin RED_LED_Pin TCXO_PWR_Pin */
  GPIO_InitStruct.Pin = GREEN_LED_Pin|BLUE_LED_Pin|RED_LED_Pin|TCXO_PWR_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PB9 PB8 PB15 PB11
                           PB12 PB10 */
  GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_15|GPIO_PIN_11
                          |GPIO_PIN_12|GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PA14 PA10 PA13 PA8
                           PA11 PA9 PA0 PA5 */
  GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_10|GPIO_PIN_13|GPIO_PIN_8
                          |GPIO_PIN_11|GPIO_PIN_9|GPIO_PIN_0|GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB4_RESERVED_Pin PB1_RESERVED_Pin TEST_RANGE_Pin PB0_RESERVED_Pin */
  GPIO_InitStruct.Pin = PB4_RESERVED_Pin|PB1_RESERVED_Pin|TEST_RANGE_Pin|PB0_RESERVED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PC13 PC14 PC15 */
  GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PC1_RESERVED_Pin PC0_RESERVED_Pin PC2_RESERVED_Pin */
  GPIO_InitStruct.Pin = PC1_RESERVED_Pin|PC0_RESERVED_Pin|PC2_RESERVED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PH0 PH1 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);

  /*Configure GPIO pin : PULSE_INPUT_Pin */
  GPIO_InitStruct.Pin = PULSE_INPUT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(PULSE_INPUT_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : ENTER_SETUP_Pin */
  GPIO_InitStruct.Pin = ENTER_SETUP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(ENTER_SETUP_GPIO_Port, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);

  HAL_NVIC_SetPriority(EXTI2_3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);

  HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

 

 

here is the interrupt callback function:

 

 

//this function is called when an external interrupt is triggered
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	/*if the interrupt is triggered from the pulse input pin, increment the pulse 
        counter*/
  if(GPIO_Pin == PULSE_INPUT_Pin)
	pulseCount++;
}

 

 

for good measure, here is the code for the arduino which sends the pulses to the STM32 (sorry in advance; arduino sucks, I know):

 

 

#define ledPin 13
#define pulse_1 4
#define pulse_2 5
#define PULSE_WIDTH 5000 //5 mS

uint32_t timestamp = 0;
bool state = LOW;

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPin, OUTPUT);
  pinMode(pulse_1, OUTPUT);
  pinMode(pulse_2, OUTPUT);
  digitalWrite(pulse_1, LOW);
  digitalWrite(pulse_2, LOW);
  digitalWrite(ledPin, LOW);
  timestamp = micros();
}

void loop() {
  if((micros() - timestamp) >= PULSE_WIDTH)
  {
    digitalWrite(pulse_1, state);
    digitalWrite(pulse_2, state);
    timestamp = micros();
    digitalWrite(ledPin, state);
    (state == HIGH) ? state = LOW : state = HIGH;
  }
}

 

 

And here is what is showing up on the IoT platform. Sometimes the controller sends the correct 600 pulses, and sometimes it sends 300. The units are not important, as this is only to show if the number of pulses sent match what is sent from the arduino or not. the dip at 11:00 is just from me disconnecting the receiving device for a few minutes.

Screenshot 2024-10-30 142615.png

2 REPLIES 2
PGump.1
Senior III

Hi,

Have you got an independent pulse count?

Kind regards
Pedro

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.
Sarra.S
ST Employee

Hello @JustSomeGuy,

This is looking like debounce effect, based on the provided GPIO initialization code, the pin is set to trigger on the falling edge, but if the external interrupt pin is not properly debounced, it might be missing some of the pulses! 

Make sure that the signal from the Arduino is clean and stable, if not, consider adding a debounce mechanism either in hardware (using capacitors) or in software (by adding a small delay in the ISR)

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.