Log in

View Full Version : Code: Toggle on Tap


Dave Scheck
11-02-2005, 18:07
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;