'Raspberry Pi 4 Code for while loop stuck on get char function
I am trying to use the Raspberry Pi 4 GPIO to make an alternate blinking scheme between 4 LEDs. The code is written in C. The red and the green LEDs are are connected in a tristate fashion, with the GPIO12 pin placed in between the two LEDs to control their respective blinking, and the same goes for a blue and orange LED which is controlled by GPIO22. When I run the program, it goes through the loop once and alternates the blinking of each LED as expected. My issue is that the last LED stays lit as if the while loop is waiting for a key press to happen. When I press any key that is not 'q', the loop will start again, but this is not what I want. Ultimately, I'm trying to make the LEDs blink in succession forever until a 'q' key is pressed. Any idea of what could be going wrong with my code
while(!done)
{
//Red LED ON, Green Blue & Orange LED OFF
io->gpio.GPFSEL1.field.FSEL2 = GPFSEL_OUTPUT;
io->gpio.GPFSEL2.field.FSEL2 = GPFSEL_INPUT;
GPIO_CLR(&(io->gpio), 12);
usleep(500 * 1000);
//Green LED ON, Red Blue & Orange LED OFF
GPIO_SET(&(io->gpio), 12);
usleep(500 * 1000);
//Blue LED ON, Red Green & Orange LED OFF
io->gpio.GPFSEL1.field.FSEL2 = GPFSEL_INPUT;
io->gpio.GPFSEL2.field.FSEL2 = GPFSEL_OUTPUT;
GPIO_CLR(&(io->gpio), 22);
usleep(500 * 1000);
//Orange LED ON, Red Green & Orange LED OFF
GPIO_SET(&(io->gpio), 22);
usleep(500 * 1000);
if(get_pressed_key() == 'q')
{
done = true;
}
}
The get_pressed_key function looks like this further up in my program, which utilizes <termios.h>.
int get_pressed_key(void)
{
struct termios original_attributes;
struct termios modified_attributes;
int ch;
tcgetattr( STDIN_FILENO, &original_attributes );
modified_attributes = original_attributes;
modified_attributes.c_lflag &= ~(ICANON | ECHO);
modified_attributes.c_cc[VMIN] = 1;
modified_attributes.c_cc[VTIME] = 0;
tcsetattr( STDIN_FILENO, TCSANOW, &modified_attributes );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &original_attributes );
return ch;
}
Solution 1:[1]
I think that the easiest way to do that, it's using the signals.
For example you can implement the Ctrl-C handler, namely SIGINT.
Your code should become something like this:
void handler(int sig)
{
fprintf(stdout, "Ctrl-C detected (%d). Exit.", sig);
exit(EXIT_SUCCESS);
}
int main()
{
signal(SIGINT, handler);
while (1) {
// Your code here
}
exit(EXIT_SUCCESS);
}
From the signal handler you can decide to redirect the program to an exit function which cleans the environment, instead of exit directly, or you can do something else, depending what you need.
On the other hand, if you really need to use getchar(), I think that you have to run the cycle in a child process using fork(); then in the parent one waiting for an user input and if it corresponds to 'q', you have to kill() the child.
This approach leads to a more complexity, also because you should implement signals in this case too (see the DOC to have a better understanding about how signals and kill() work).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
