Author Topic: Controlling LED with a button  (Read 314 times)

0 Members and 3 Guests are viewing this topic.

Offline TadeuszhTopic starter

  • Newbie
  • Posts: 9
  • Country: pl
Controlling LED with a button
« on: April 23, 2024, 03:49:33 pm »
Hi there,
so I have a simple problem, I am trying to controll the LED with a button. I want it to flash when the button is set, and darken when it's on reset. I've used the TogglePin function, and it doesn't work. It changes the LED state and leaves it as it is. I've tried removing the else statement cauze I thought it might be enough for one if to be written - but when i did, it crashes. I mean it works but once it lights up, the communication between button and LED breaks and clicking the button doesn't change the LED's state. I have to mention that it is supposed to be controlled by ISR. Any advices what do I do?


void ToggleDiode()
{
       if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET)
       {
           HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_7);
       }
       else
       {
          HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_7);
       }
}

void handleButtonInterrupt(void)
{
   ToggleDiode();
}
 

Online xvr

  • Regular Contributor
  • *
  • Posts: 175
  • Country: ie
    • LinkedIn
Re: Controlling LED with a button
« Reply #1 on: April 23, 2024, 05:04:44 pm »
> I want it to flash when the button is set

So you need some activity (LED flashing) while button is pressed, i.e. not change they state. So you can't do it EXCLUSIVELY in button press interrupt.
You need something ongoing, that will be executed in cycles. Do you use FreeRTOS? If yes you can create Task to flashing LED.
 

Offline CountChocula

  • Supporter
  • ****
  • Posts: 200
  • Country: ca
  • I break things—sometimes on purpose.
Re: Controlling LED with a button
« Reply #2 on: April 23, 2024, 05:08:00 pm »
Assuming that I understand your port correctly, the problem is that you're just calling ToggleDiode() once when the a change in the button pin's status causes an interrupt. ToggleDiode() runs just once and then just flips the status of PA7, regardless of what PA5 reads at that point in time. If you want the LED to flash, you don't even need to use interrupts; you could just have something like this (written from memory, so may need some tweaking to actually make it work):

Code: [Select]
#define BUTTON_PIN_PORT GPIOA
#define BUTTON_PIN GPIO_PIN_0

#define LED_PIN_PORT GPIOC
#define LED_PIN GPIO_PIN_13

#define FLASH_INTERVAL 500

void ToggleDiode() {
  static uint32_t last_time = 0;

  if (HAL_GPIO_ReadPin(BUTTON_PIN_PORT, BUTTON_PIN) == GPIO_PIN_SET) {
    // Turn off the LED if the button is not pressed (assumes that the button pin is set to input with a pull-up resistor)
    HAL_GPIO_WritePin(LED_PIN_PORT, LED_PIN, GPIO_PIN_RESET);
  } else {
    // Determine whether it's time to flip the bit
    if (HAL_GetTick() - last_time > FLASH_INTERVAL) {
      HAL_GPIO_TogglePin(LED_PIN_PORT, LED_PIN);
      last_time = HAL_GetTick();
    }
  }
}

int main() {
  HAL_Init();
  SystemClock_Config();

  while (1) {
    ToggleDiode();
    // Do other things
    HAL_Delay(1);
  }
}


This will work without blocking the rest of your program.

HTH,


—CC
Lab is where your DMM is.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf