CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Switch debouncing
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
TaiChipY
Guest







PostPosted: Tue Mar 08, 2005 3:27 am     Reply with quote

THANK YOU MARK and "GUEST" and all others for replays on this topic!
I will try the code today!

TaiChipY
TaiChipY
Guest







PostPosted: Tue Mar 08, 2005 9:37 am     Reply with quote

Your code is very good !
I have extend this to suit my needs and it's working nice
accept one part...

I can not understand how you handle the interupts from some new defined button,or how you extend single click to some other sub parts(under single click)...

I have writen new functions for single click on pinA4, which are called single_A_click and single_B_click.

In single_A_click im testing if the value ( from button on B0 ) has been changed from 0 to 1. If this is true i remove the welcome screen ( which is displayed on first A4 click until the value B0 is true) if not the welcome screen is activated until first B0 press.
After removing the welcome screen i should be able to switch thru single_A_click,single_B_click,double_click.

So i write new function and put them into case to test this but nothing happens.... Please explain me how do you handle this situations.

TaiChipY
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Mar 08, 2005 9:42 am     Reply with quote

Can you post your code? It would be easier for me to look at what you have and make it work.
TaiChipY
Guest







PostPosted: Wed Mar 09, 2005 6:35 am     Reply with quote

Im realy sorry for the code stuff. Im keep forgeting this :---).
I can send you one part and i must explain the other part.

The whole project is about temperature sensoring and calibration.
This is base device which will control other two devices. If the heat is not in range start with warning and activate “to cold” or “ to hot state”. Calibrate…

What I want to do is to extend the posibilities of the whole base device, on the way that I can expand the buttons functions. One click, double click, one hold click+one double click, one hold + second hold and so on…. Before I can make this mix stuff and(I hope I will make this thru your code)I must do the basic part (described in last post ).


Your code (partly changed):
Code:
…..
short int SBstate=0;
short int counter;

enum switch_states
{
  single_A_click, single_B_click, double_click, welcome_click,confirmation_click
  //single_A_double_click
};

//--------------------------------------------------------
 I have tried to define the _B_ click here but I don’t get it how will he
 find the second _B_ state because single click is defined as one single click.
//--------------------------------------------------------
void switch_released(void)
{
if (Click_Timer)
    switch_states = double_click;
else if
    switch_state = one_A_click;   
else
    switch_state = one_B_click;
    Click_Timer = double_click_TIME;
}


void confirmation_click(void)
{

   If (cButtonPress())
   {
     SBstate=1;
     counter++;   // until 10 then reset to 0
  }
 
}

void event_welcome_click(void)
{
   do
   {
      if(SBstate == 0)
       lcd_putc("Welcome!");
   }while(TRUE);
}
//--------------------------------------
void event_single_A_click(void)
{
     printf(lcd_putc,"Time:   ","/","Opened","%D",counter,"times");
}

void event_single_B_click(void)
{
     lcd_putc("Temperature:");
}
//--------------------------------------

void event_double_click(void)
{
     lcd_putc("LOGO");
}

//--------------------------------------
void event_single_A_double_click (void)
{


}

//-------------------------------------
void Switch_Timers(void)
{

  if (Read_Switch_Timer == 0)
    Read_Switch_Timer--;
  else
    Read_Switch_Flag = TRUE;

  if(Click_Timer)
  {
    Click_Timer--;
    if(Click_Timer == 0)
    {
      switch (switch_state)
      {
       case single_A_click:
             event_single_A_click();
          break;
     case single_B_click:
             event_single_B_click();
          break;
     case double_click:
             event_double_click();
          break;
          default:
      event_welcome_click();   
     break;
      }
    }
  }
}
TaiChipY
Guest







PostPosted: Wed Mar 09, 2005 6:37 am     Reply with quote

Im realy sorry for the code stuff. Im keep forgeting this :---).
I can send you one part and i must explain the other part.

The whole project is about temperature sensoring and calibration.
This is base device which will control other two devices. If the heat is not in range start with warning and activate “to cold” or “ to hot state”. Calibrate…

What I want to do is to extend the posibilities of the whole base device, on the way that I can expand the buttons functions. One click, double click, one hold click+one double click, one hold + second hold and so on…. Before I can make this mix stuff and(I hope I will make this thru your code)I must do the basic part (described in last post ).


Your code (partly changed):
Code:
…..
short int SBstate=0;
short int counter;

enum switch_states
{
  single_A_click, single_B_click, double_click, welcome_click,confirmation_click
  //single_A_double_click
};

//--------------------------------------------------------
 I have tried to define the _B_ click here but I don’t get it how will he
 find the second _B_ state because single click is defined as one single click.
//--------------------------------------------------------
void switch_released(void)
{
if (Click_Timer)
    switch_states = double_click;
else if
    switch_state = one_A_click;   
else
    switch_state = one_B_click;
    Click_Timer = double_click_TIME;
}


void confirmation_click(void)
{

   If (cButtonPress())
   {
     SBstate=1;
     counter++;   // until 10 then reset to 0
  }
 
}

void event_welcome_click(void)
{
   do
   {
      if(SBstate == 0)
       lcd_putc("Welcome!");
   }while(TRUE);
}
//--------------------------------------
void event_single_A_click(void)
{
     printf(lcd_putc,"Time:   ","/","Opened","%D",counter,"times");
}

void event_single_B_click(void)
{
     lcd_putc("Temperature:");
}
//--------------------------------------

void event_double_click(void)
{
     lcd_putc("LOGO");
}

//--------------------------------------
void event_single_A_double_click (void)
{


}

//-------------------------------------
void Switch_Timers(void)
{

  if (Read_Switch_Timer == 0)
    Read_Switch_Timer--;
  else
    Read_Switch_Flag = TRUE;

  if(Click_Timer)
  {
    Click_Timer--;
    if(Click_Timer == 0)
    {
      switch (switch_state)
      {
       case single_A_click:
             event_single_A_click();
          break;
     case single_B_click:
             event_single_B_click();
          break;
     case double_click:
             event_double_click();
          break;
          default:
      event_welcome_click();   
     break;
      }
    }
  }
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Mar 09, 2005 2:55 pm     Reply with quote

Look at this and see if it helps
Code:

#include <18F452.h>
#use delay(clock=10000000)
#fuses HS, NOWDT, PUT, NOLVP

#include "PICDEMLCD.C"

#define CLICK_TIME 250       // Maximum time to consider a press/release a click
#define DBL_CLICK_TIME 500   // Time to wait for a dbl_click in ms
#define SWITCH_READ_TIME 30  // Interval to read the switches in ms

// Search for TO ADD MORE SWITCHES to find out where the code needs to be changed
#define NUM_SWITCHES 2  // Good for up to 8 switches without
                        // having to modify the variable types

// Different types of click events
enum SWITCH_STATES
{
  SWITCH_IDLE,
  SWITCH_DOWN,
  SWITCH_HELD,
  SINGLE_CLICK,
  DOUBLE_CLICK
};

// Our system timer
int8 Miliseconds;

// How often we read the switch inputs
int8 Read_Switch_Timer = 0;

// Signal to read the switches
int1 Read_Switch_Flag = FALSE;

// Timeout value or in this case the double click time
int16 Click_Timer[NUM_SWITCHES];

enum SWITCH_STATES Switch_State[NUM_SWITCHES];

// Timer 2 is our system tick
#int_timer2
void timer2_isr(void)
{
  if (Miliseconds < 0xFF)
    Miliseconds++;
}

// Handles what happens when we release a switch
void Switch_Released(int8 number)
{
  // Make sure this is a valid switch
  if (number < NUM_SWITCHES)
  {
    switch (Switch_State[number])
    {
      case SWITCH_DOWN:
        // Set the timer to the maximum time between a press and release to
        // consider this a single click
        Click_Timer[number] = CLICK_TIME;
        Switch_State[number] = SINGLE_CLICK;
        break;
      case SWITCH_HELD:
        // Just set the timer to a small number so that it will fire as soon
        // as we release the switch
        Click_Timer[number] = 1;
        // Don't change the state here, the timers will take care of it
        break;
      case SINGLE_CLICK:
        // Set the timer for the maximum time we will wait for a double click
        Click_Timer[number] = DBL_CLICK_TIME;
        Switch_State[number] = DOUBLE_CLICK;
        break;
      case DOUBLE_CLICK:
        // The user is just clicking away at the button.  We won't really do
        // until he stops or we could cancel the operation by setting the state
        // to idle and the timer to 0
        Click_Timer[number] = DBL_CLICK_TIME;
        Switch_State[number] = DOUBLE_CLICK;
        break;
      default:
        Click_Timer[number] = 0;
        Switch_State[number] = SWITCH_IDLE;
        break;
    }
  }
}

// Handles what happens when we press a switch
void Switch_Pressed(int8 number)
{
  // Make sure this is a valid switch
  if (number < NUM_SWITCHES)
  {
    // Set the state to down only if we haven't just processed a click
    if (Switch_State[number] == SWITCH_IDLE)
      Switch_State[number] = SWITCH_DOWN;
    Click_Timer[number] = DBL_CLICK_TIME;
  }
}

// Handles debouncing of the switches
void Switch_Read_Value(void)
{
  static int8 last_read = 0xFF;
  static int8 last_state = 0xFF;
  static int8 debounce_count;
  int8 result = 0xFF;
  int8 i;
  int8 changed;

  // TO ADD MORE SWITCHES you need to put them into result

  // Read the current result
  if (!input(PIN_A4))
    bit_clear(result,0);

  if (!input(PIN_B0))
    bit_clear(result,1);

  // See if it changed
  if (result != last_read)
  {
    // It did so debounce it
    debounce_count = 5;
    last_read = result;
  }
  // We are debouncing
  else if (debounce_count)
  {
    debounce_count--;
    // Done debouncing
    if (debounce_count == 0)
    {
      // See if the state of the switch has changed
      changed = (result ^ last_state);
      // Determine what type of event occurred
      for(i=0;i<8;i++)
      {
        if (bit_test(changed,i))
        {
          if (bit_test(result,i))
            Switch_Released(i);
          else
            Switch_Pressed(i);
        }
        // Save the current state
        last_state = result;
      }
    }
  }
}

// What we do if a switch was pressed longer than the click time
void Switch_Pressed_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Light an LED on RB3 of the picdem2 plus board
      output_high(PIN_B3);
      printf(lcd_putc,"\fSW1 Pressed");
      break;
   case 1:
      // Light an LED on RB2 of the picdem2 plus board
      output_high(PIN_B2);
      printf(lcd_putc,"\fSW2 Pressed");
     break;
   default:
     break;
  }
}

// What we do if a switch was pressed and held longer than the click time
void Switch_Release_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Turn off the LED on RB3 of the picdem2 plus board
      output_low(PIN_B3);
      printf(lcd_putc,"\fSW1 Released");
      break;
   case 1:
      // Turn off the LED on RB2 of the picdem2 plus board
      output_low(PIN_B2);
      printf(lcd_putc,"\fSW2 Released");
     break;
   default:
     break;
  }
}

// What we do on a single click
void Single_Click_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Light an LED on RB3 of the picdem2 plus board
      output_high(PIN_B3);
      if (Switch_State[1] == SWITCH_HELD)
        printf(lcd_putc,"\fSW1 Click\nWhile SW2 Held");
      else
        printf(lcd_putc,"\fSW1 Click");
      break;
   case 1:
      // Light an LED on RB2 of the picdem2 plus board
      output_high(PIN_B2);
      if (Switch_State[0] == SWITCH_HELD)
        printf(lcd_putc,"\fSW2 Click\nWhile SW1 Held");
      else
        printf(lcd_putc,"\fSW2 Click");
     break;
   default:
     break;
  }
}

void Double_Click_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Turn off the LED on RB3 of the picdem2 plus board
      output_low(PIN_B3);
      if (Switch_State[1] == SWITCH_HELD)
        printf(lcd_putc,"\fSW1 Dbl_Click\nWhile SW2 Held");
      else
        printf(lcd_putc,"\fSW1 Dbl_Click");
      break;
   case 1:
      // Turn off the LED on RB2 of the picdem2 plus board
      output_low(PIN_B2);
      if (Switch_State[0] == SWITCH_HELD)
        printf(lcd_putc,"\fSW2 Dbl_Click\nWhile SW1 Held");
      else
        printf(lcd_putc,"\fSW2 Dbl_Click");
     break;
   default:
     break;
  }
}

// Handles all our switch timers
void Switch_Timers(void)
{
  int8 i;

  if (Read_Switch_Timer == 0)
    Read_Switch_Timer--;
  else
    Read_Switch_Flag = TRUE;

  for(i=0;i<NUM_SWITCHES;i++)
  {
    if (Click_Timer[i])
    {
      Click_Timer[i]--;
      if (Click_Timer[i] == 0)
      {
        switch (Switch_State[i])
        {
          case SWITCH_DOWN:
            Switch_Pressed_Event(i);
            Switch_State[i] = SWITCH_HELD;
            break;
          case SWITCH_HELD:
            Switch_Release_Event(i);
            Switch_State[i] = SWITCH_IDLE;
            break;
          case SINGLE_CLICK:
            Single_Click_Event(i);
            Switch_State[i] = SWITCH_IDLE;
            break;
          case DOUBLE_CLICK:
            Double_Click_Event(i);
            Switch_State[i] = SWITCH_IDLE;
            break;
          default:
            Switch_State[i] = SWITCH_IDLE;
            break;
        }
      }
    }
  }
}

// Handles all our switch tasks
void Switch_Tasks(void)
{
  if (Read_Switch_Flag)
  {
    Switch_Read_Value();
    Read_Switch_Timer = SWITCH_READ_TIME;
    Read_Switch_Flag = FALSE;
  }
}

// System counter
void System_Tick(void)
{
  while (Miliseconds)
  {
    Switch_Timers();
    Miliseconds--;
  }
}


void main (void)
{
  int8 i;

  for(i=0;i<NUM_SWITCHES;i++)
    Click_Timer[i] = 0;

  // Setup timer2 to int every 1ms
  setup_timer_2(T2_DIV_BY_4,125,5);
  enable_interrupts(INT_TIMER2);
  enable_interrupts(GLOBAL);
  lcd_init();
  printf(lcd_putc,"PICDEM Switch\nEvent Test");
  // Start counting now
  Miliseconds = 0;

  while(1)
  {
    System_Tick();
    Switch_Tasks();
  }
}
TaiChipY
Guest







PostPosted: Fri Mar 11, 2005 5:17 am     Reply with quote

You know Mark, i can write THANK YOU again and again but i dont think that this would have such a value like if i would write:
"Men, your code is very good and i will give my best to understand the whole switch debouncing stuff ".... Very Happy

Now im going to take deeper look into the code and i let you know if i would have any "wrong understanded" stuff...


TaiChipY
TaiChipY



Joined: 11 Mar 2005
Posts: 21

View user's profile Send private message

PostPosted: Sat Mar 12, 2005 1:56 pm     Reply with quote

I have to ask becuse im spining in the circle with this one... Twisted Evil
I have add one additional switch to activate the mixed mode and to trigger
the reset.In your single_click_event part i have set the case 0 for info, case 1 for confirmation and case 2 for mixed mode.

This and all other parts are working with no problems.
First info press and i display welcome screen. After that i hit the confirmation button , con_count value is set into eeprom. So for so good. I go back to hit info button, to look into the stored con_count values and temperature but the single_click event is displaying the
welcome screen again. Now, before i post code please explain me this:

Is the single_click_event set to trigger just one state on one button ( with one case for each button) or can you define other states in one case? Becuse i have tryed with nested if's, and with switch_states to pull this out, but with no result...
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat Mar 12, 2005 4:49 pm     Reply with quote

It fires every time a single click occurs. If you want it to do something different, then you will have to add another state machine for that button.
TaiChipY



Joined: 11 Mar 2005
Posts: 21

View user's profile Send private message

PostPosted: Sun Mar 13, 2005 7:04 am     Reply with quote

If you want it to do something different, then you will have to add another state machine for that button.
***
Can this be implemented in the single_click_event or how do you think
that this could be solved, when you say "another state maschine" ?

Do i have to write all from the begining or is there some solution?
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sun Mar 13, 2005 9:47 am     Reply with quote

Here is an example where I added a state machine to switch 1. The state machine is reset by holding down switch 2 and clicking switch 1.
Code:

/*****************************************************************************/
/*                                                                           */
/*         Multi-Event Switch Action for Microchip Microcontrollers          */
/*                                                                           */
/* This program was designed to run on the PICDEM2 Plus demo board from      */
/* Microchip.                                                                */
/*                                                                           */
/* Usage:                                                                    */
/*         S3 - Is Switch 2                                                  */
/*         S2 - Is Switch 1                                                  */
/*                                                                           */
/* This code was designed for a clock speed of 10MHz                         */
/* The target device was a PIC18F452.                                        */
/*****************************************************************************/
#include <18F452.h>
// Note to check timer2 setup if you change this to make sure it ints every ms
#define clockspeed 4000000
#use delay(clock=clockspeed)
#fuses HS, NOWDT, PUT, NOLVP

#include "PICDEMLCD.C"

#define CLICK_TIME 250       // Maximum time to consider a press/release a click
#define DBL_CLICK_TIME 500   // Time to wait for a dbl_click in ms
#define SWITCH_READ_TIME 30  // Interval to read the switches in ms

// Search for TO ADD MORE SWITCHES to find out where the code needs to be changed
#define NUM_SWITCHES 2  // Good for up to 8 switches without
                        // having to modify the variable types

enum
{
  STATE1,
  STATE2,
  STATE3,
  STATE4
}S1_Click_State = STATE1;

// Different types of click events
enum SWITCH_STATES
{
  SWITCH_IDLE,
  SWITCH_DOWN,
  SWITCH_HELD,
  SINGLE_CLICK,
  DOUBLE_CLICK
};

// Our system timer
int8 Miliseconds;

// How often we read the switch inputs
int8 Read_Switch_Timer = 0;

// Signal to read the switches
int1 Read_Switch_Flag = FALSE;

// Timeout value or in this case the double click time
int16 Click_Timer[NUM_SWITCHES];

enum SWITCH_STATES Switch_State[NUM_SWITCHES];

// Timer 2 is our system tick
#int_timer2
void timer2_isr(void)
{
  if (Miliseconds < 0xFF)
    Miliseconds++;
}

// Handles what happens when we release a switch
void Switch_Released(int8 number)
{
  // Make sure this is a valid switch
  if (number < NUM_SWITCHES)
  {
    switch (Switch_State[number])
    {
      case SWITCH_DOWN:
        // Set the timer to the maximum time between a press and release to
        // consider this a single click
        Click_Timer[number] = CLICK_TIME;
        Switch_State[number] = SINGLE_CLICK;
        break;
      case SWITCH_HELD:
        // Just set the timer to a small number so that it will fire as soon
        // as we release the switch
        Click_Timer[number] = 1;
        // Don't change the state here, the timers will take care of it
        break;
      case SINGLE_CLICK:
        // Set the timer for the maximum time we will wait for a double click
        Click_Timer[number] = DBL_CLICK_TIME;
        Switch_State[number] = DOUBLE_CLICK;
        break;
      case DOUBLE_CLICK:
        // The user is just clicking away at the button.  We won't really do
        // until he stops or we could cancel the operation by setting the state
        // to idle and the timer to 0
        Click_Timer[number] = DBL_CLICK_TIME;
        Switch_State[number] = DOUBLE_CLICK;
        break;
      default:
        Click_Timer[number] = 0;
        Switch_State[number] = SWITCH_IDLE;
        break;
    }
  }
}

// Handles what happens when we press a switch
void Switch_Pressed(int8 number)
{
  // Make sure this is a valid switch
  if (number < NUM_SWITCHES)
  {
    // Set the state to down only if we haven't just processed a click
    if (Switch_State[number] == SWITCH_IDLE)
      Switch_State[number] = SWITCH_DOWN;
    Click_Timer[number] = DBL_CLICK_TIME;
  }
}

// Handles debouncing of the switches
void Switch_Read_Value(void)
{
  static int8 last_read = 0xFF;
  static int8 last_state = 0xFF;
  static int8 debounce_count;
  int8 result = 0xFF;
  int8 i;
  int8 changed;

  // TO ADD MORE SWITCHES you need to put them into result

  // Read the current result
  if (!input(PIN_A4))
    bit_clear(result,0);

  if (!input(PIN_B0))
    bit_clear(result,1);

  // See if it changed
  if (result != last_read)
  {
    // It did so debounce it
    debounce_count = 5;
    last_read = result;
  }
  // We are debouncing
  else if (debounce_count)
  {
    debounce_count--;
    // Done debouncing
    if (debounce_count == 0)
    {
      // See if the state of the switch has changed
      changed = (result ^ last_state);
      // Determine what type of event occurred
      for(i=0;i<8;i++)
      {
        if (bit_test(changed,i))
        {
          if (bit_test(result,i))
            Switch_Released(i);
          else
            Switch_Pressed(i);
        }
        // Save the current state
        last_state = result;
      }
    }
  }
}

// What we do if a switch was pressed longer than the click time
void Switch_Pressed_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Light an LED on RB3 of the picdem2 plus board
      output_high(PIN_B3);
      printf(lcd_putc,"\fSW1 Pressed");
      break;
   case 1:
      // Light an LED on RB2 of the picdem2 plus board
      output_high(PIN_B2);
      printf(lcd_putc,"\fSW2 Pressed");
     break;
   default:
     break;
  }
}

// What we do if a switch was pressed and held longer than the click time
// and then released
void Switch_Release_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Turn off the LED on RB3 of the picdem2 plus board
      output_low(PIN_B3);
      printf(lcd_putc,"\fSW1 Released");
      break;
   case 1:
      // Turn off the LED on RB2 of the picdem2 plus board
      output_low(PIN_B2);
      printf(lcd_putc,"\fSW2 Released");
     break;
   default:
     break;
  }
}

// What we do on a single click
void Single_Click_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Light an LED on RB3 of the picdem2 plus board
      output_high(PIN_B3);
      if (Switch_State[1] == SWITCH_HELD)
      {
        printf(lcd_putc,"\fSW1 Click\nWhile SW2 Held");
        // Reset Switch 1's state machine if we hold down S2 and click S1
        S1_Click_State = STATE1;
      }
      else
      {
        printf(lcd_putc,"\fSW1 Click");
        // Decide what state we are in
        switch (S1_Click_State)
        {
          case STATE1:
            S1_Click_State++;
            printf(lcd_putc,"\nState 1");
            break;
          case STATE2:
            S1_Click_State++;
            printf(lcd_putc,"\nState 2");
            break;
          case STATE3:
            S1_Click_State++;
            printf(lcd_putc,"\nState 3");
            break;
          case STATE4:
            S1_Click_State++;
            printf(lcd_putc,"\nState 4");
            break;
          default:
            printf(lcd_putc,"\nInvalid State");
            break;
        }
      }
      break;
   case 1:
      // Light an LED on RB2 of the picdem2 plus board
      output_high(PIN_B2);
      if (Switch_State[0] == SWITCH_HELD)
        printf(lcd_putc,"\fSW2 Click\nWhile SW1 Held");
      else
        printf(lcd_putc,"\fSW2 Click");
     break;
   default:
     break;
  }
}

// What we do for a dbl_click
void Double_Click_Event(int8 number)
{
  // TO ADD MORE SWITCHES you need to add the cases
  switch(number)
  {
    case 0:
      // Turn off the LED on RB3 of the picdem2 plus board
      output_low(PIN_B3);
      if (Switch_State[1] == SWITCH_HELD)
        printf(lcd_putc,"\fSW1 Dbl_Click\nWhile SW2 Held");
      else
        printf(lcd_putc,"\fSW1 Dbl_Click");
      break;
   case 1:
      // Turn off the LED on RB2 of the picdem2 plus board
      output_low(PIN_B2);
      if (Switch_State[0] == SWITCH_HELD)
        printf(lcd_putc,"\fSW2 Dbl_Click\nWhile SW1 Held");
      else
        printf(lcd_putc,"\fSW2 Dbl_Click");
     break;
   default:
     break;
  }
}

// Handles all our switch timers
void Switch_Timers(void)
{
  int8 i;

  if (Read_Switch_Timer == 0)
    Read_Switch_Timer--;
  else
    Read_Switch_Flag = TRUE;

  for(i=0;i<NUM_SWITCHES;i++)
  {
    if (Click_Timer[i])
    {
      Click_Timer[i]--;
      if (Click_Timer[i] == 0)
      {
        switch (Switch_State[i])
        {
          case SWITCH_DOWN:
            Switch_Pressed_Event(i);
            Switch_State[i] = SWITCH_HELD;
            break;
          case SWITCH_HELD:
            Switch_Release_Event(i);
            Switch_State[i] = SWITCH_IDLE;
            break;
          case SINGLE_CLICK:
            Single_Click_Event(i);
            Switch_State[i] = SWITCH_IDLE;
            break;
          case DOUBLE_CLICK:
            Double_Click_Event(i);
            Switch_State[i] = SWITCH_IDLE;
            break;
          default:
            Switch_State[i] = SWITCH_IDLE;
            break;
        }
      }
    }
  }
}

// Handles all our switch tasks
void Switch_Tasks(void)
{
  if (Read_Switch_Flag)
  {
    Switch_Read_Value();
    Read_Switch_Timer = SWITCH_READ_TIME;
    Read_Switch_Flag = FALSE;
  }
}

// System counter
void System_Tick(void)
{
  while (Miliseconds)
  {
    Switch_Timers();
    Miliseconds--;
  }
}

// Our main loop
void main (void)
{
  int8 i;

  // Initialize all of the timers and states
  for(i=0;i<NUM_SWITCHES;i++)
  {
    Click_Timer[i] = 0;
    Switch_State[i] = SWITCH_IDLE;
  }
  // Setup timer2 to int every 1ms
  // Note this is good for a clock between 80K - 20MHz
  // Although some frequencies that do not divide equally
  // by 80K will be slightly off.  You might want to verify this
  setup_timer_2(T2_DIV_BY_4,(clockspeed/80000),5);
  enable_interrupts(INT_TIMER2);
  enable_interrupts(GLOBAL);
  lcd_init();
  printf(lcd_putc,"PICDEM Switch\nEvent Test");
  // Start counting now
  Miliseconds = 0;

  while(1)
  {
    System_Tick();
    Switch_Tasks();
  }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group