Recently there have been a lot of questions about how to make something toggle when a button is tapped (i.e. the button is pressed and it previously wasn’t). The something being toggled is most likely going to be the state of a relay for pneumatics, but it can also be a variable or PWM output.
Below is a function that we use to abstract the functionality of toggling on the tap of a button.
The intended audience is
- Programmers that are new to the concept of state toggling
- Programmers that have many instances of state toggling
Feel free to use/modify this code in any way desired.
/***************************
* FUNCTION NAME: toggle_on_tap
* PURPOSE: Toggle a parameter when a button is tapped
* ARGUMENTS: unsigned char cur_button - The current button state
* unsigned char prev_button - The button state for the previous loop
* unsigned char prev_state - The parameter state for the previous loop
* unsigned char state1 - A state that the parameter can have
* unsigned char state2 - The other state that the parameter can have
* RETURNS: unsigned char new_state - The new state of the parameter
******************************/
unsigned char toggle_on_tap( unsigned char cur_button,
unsigned char prev_button,
unsigned char prev_state,
unsigned char state1,
unsigned char state2)
{
unsigned char new_state = prev_state;
if ((cur_button == 1) && (prev_button == 0))
{
if (prev_state == state1)
{
new_state = state2;
}
else
{
new_state = state1;
}
}
// printf("Cur %d PrevB %d PrevS %d NewS %d\r",cur_button,prev_button,prev_state,new_state);
return new_state;
}
Here’s an example of how it could be used.
- P1 trigger cycles relay 1 between STATE_A and STATE_B
- P1 top cycles relay 2 between STATE_C and STATE_D
#define STATE_A 1
#define STATE_B 0
#define STATE_C 0
#define STATE_D 1
...
static unsigned char p1_sw_trig_prev = 0;
static unsigned char p1_sw_top_prev = 0;
static unsigned char relay1_state_prev = STATE_A;
static unsigned char relay2_state_prev = STATE_C;
unsigned char new_state;
// Get the new state based on the current button state
// and the previous button and relay states
new_state = toggle_on_tap(p1_sw_trig,
p1_sw_trig_prev,
relay1_state_prev,
STATE_A,
STATE_B);
// Set the output to the new state
relay1_fwd = new_state;
// This may or may not be needed based on the application
// relay1_rev = relay1_state_prev;
//Store the current trigger state as the previous triggger state
p1_sw_trig_prev = p1_sw_trig;
//Store the new relay state as the previous relay state
relay1_state_prev = new_state;
// Get the new state based on the current button state
// and the previous button and relay states
new_state = toggle_on_tap(p1_sw_top,
p1_sw_top_prev,
relay2_state_prev,
STATE_C,
STATE_D);
// Set the output to the new state
relay2_fwd = new_state;
// This may or may not be needed based on the application
// relay2_rev = relay1_state_prev;
//Store the current trigger state as the previous triggger state
p1_sw_top_prev = p1_sw_top;
//Store the new relay state as the previous relay state
relay2_state_prev = new_state;