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

Keyboard, keypad debouncing and more

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Hawk
Guest







Keyboard, keypad debouncing and more
PostPosted: Sun Jan 11, 2009 7:53 am     Reply with quote

Hello.

I've removed some parts from Mark's source code so it can fit my needs.
There is just single click check and hold down part.
I want to learn on this example but some help is welcome.

My end goal is to do keyboard (3x4, 4x4 debouncing on this way:
A B C a b c 1, A B C a b c 1, A B C a b c 1 and so on.

One button should be able to switch between this 7 possibilities and if you hold this button for 3 seconds, last char should be remembered.
The same as on mobile phones keypad.
--------------------------------------------------
Before i implement the keyboard i want to understand how to make this with the buttons on the picdem board , so i started with Mark's code.


1.) How to switch this possibilities thru some IF loop ?
2.) The clockspeed is 4 MHZ not 10 ( as in example ) so timer should be reconfigured.

Thank you.

Quote:
case 0:
if (Switch_State[1] == SWITCH_HELD) // hold for 3 secounds
printf(lcd_putc,"\fSW1 Click\nWhile SW2 Held");
else
if ( )
{
printf(lcd_putc,"\fSW1 Click");
//-------------------------------
printf("A\n\r");
//-------------------------------
}
break;



Code:

// Note to check timer2 setup if you change this to make sure it ints every ms
#define clockspeed 4000000
#use delay(clock=clockspeed)

#define CLICK_TIME        200       // Maximum time to consider a press/release a click
#define SWITCH_READ_TIME 30         // Interval to read the switches in ms
#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,                  // last char confirmation
  SINGLE_CLICK,
};

int8 Miliseconds;                  // Our system timer
int8 Read_Switch_Timer = 0;            // How often we read the switch inputs
int1 Read_Switch_Flag = FALSE;         // Signal to read the switches
int16 Click_Timer[NUM_SWITCHES];      // Timeout value or in this case the double click time

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)
{
  if (number < NUM_SWITCHES)      // Make sure this is a valid switch
  {
    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
        break;
      default:
        Click_Timer[number] = 0;
        Switch_State[number] = SWITCH_IDLE;
        break;
    }
  }
}
//---------------------------------
void Switch_Pressed(int8 number)   // Handles what happens when we press a switch   
{
  if (number < NUM_SWITCHES)      // Make sure this is a valid switch
  {
    if (Switch_State[number] == SWITCH_IDLE)  // Set the state to down only if we haven't just processed a click
        Switch_State[number] = SWITCH_DOWN;
  }
}
void Switch_Read_Value(void)      // Handles debouncing of the switches
{
  static int8 last_read = 0xFF;
  static int8 last_state = 0xFF;
  static int8 debounce_count;
  int8 result = 0xFF;
  int8 i;
  int8 changed;

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

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

  if (result != last_read)              // See if it changed
  {
    // It did so debounce it
    debounce_count = 5;
    last_read = result;
  }
  else if (debounce_count)             // We are debouncing
  {
    debounce_count--;
    if (debounce_count == 0)           // Done debouncing
    {
      changed = (result ^ last_state);   // See if the state of the switch has changed
      for(i=0;i<8;i++)                // Determine what type of event occurred
      {
        if (bit_test(changed,i))
        {
          if (bit_test(result,i))
            Switch_Released(i);
          else
            Switch_Pressed(i);
        }
            last_state = result;       // Save the current state   
      }
    }
  }
}
//***************************************************************
void Single_Click_Event(int8 number) // ***** ONE CLICK *****
{
  switch(number)                // TO ADD MORE SWITCHES you need to add the cases
  {
    case 0:
       if (Switch_State[1] == SWITCH_HELD)      // hold for 3 secounds
        printf(lcd_putc,"\fSW1 Click\nWhile SW2 Held");
      else
        if (  )
      { 
      printf(lcd_putc,"\fSW1 Click");
      //-------------------------------
      printf("A\n\r");
      //-------------------------------
      }
      break;
   case 1:
      if (Switch_State[0] == SWITCH_HELD)
        printf(lcd_putc,"\fSW2 Click\nWhile SW1 Held");
      else
        printf(lcd_putc,"\fSW2 Click");
      printf("D\n\r");
      break;
   default:
     break;
  }
}
void Switch_Timers(void)         // ***** Handles all our switch timers *****
{
  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_State[i] = SWITCH_HELD;
            break;
          case SWITCH_HELD:
            Switch_State[i] = SWITCH_IDLE;
            break;
          case SINGLE_CLICK:
            Single_Click_Event(i);
            Switch_State[i] = SWITCH_IDLE;
            break;
          default:
            Switch_State[i] = SWITCH_IDLE;
            break;
        }
      }
    }
  }
}
void Switch_Tasks(void)         //***** Handles all our switch tasks *****
{
  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--;
  }
}


PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 12, 2009 12:07 am     Reply with quote

Mark's code does not work with a 3x4 keypad. It's intended for individual
switches, where each switch is connected to a separate PIC pin.
You will need a different driver for a 3x4 keypad.


Here is a data sheet for Grayhill 3x4 keypads. They have switches
wired in a matrix and have a 7-pin header on the back:
http://embrace.grayhill.com/embrace/IMAGES/PDF/c-06-09.pdf
Hawk
Guest







PostPosted: Mon Jan 12, 2009 12:50 pm     Reply with quote

Hi PCM Programmer,
and thank you for reply.

Yes i am aware that Mark's code is for individual switches only, but i was thinking that maybe it would be interesting to implement this kind of logic into keypad.

How would you make this what i described in first post ?
A B C a b c 1, A B C a b c 1, A B C a b c 1 and so on.

I now i have to use timers but i am not quite sure how will all this affect performance of the program, speed etc.

Anyway, where would you start ?
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Mon Jan 12, 2009 5:06 pm     Reply with quote

Call me clueless, but what does "A B C a b c 1, A B C a b c 1, A B C a b c " mean?
dyeatman



Joined: 06 Sep 2003
Posts: 1923
Location: Norman, OK

View user's profile Send private message

PostPosted: Mon Jan 12, 2009 5:09 pm     Reply with quote

He wants it to cycle through the selections each time you push the button. First short push it displays A. the second short push it displays B etc. If you push and hold the button for three seconds it accepts that as the selection of the user.
Hawk
Guest







PostPosted: Sun Feb 01, 2009 6:05 am     Reply with quote

What is better way to connect the keypad, regarding to functionality described in previous posts ?

This
ht://i44.tinypic*com/1szblz.jpg

or
ht://i40.tinypic*com/rbxyrp.jpg

I will try to use modified ccs keypad example and mark's state machine idea, to get what i need. Suggestions, examples ?

Thanx!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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