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

Reduce noise of button

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



Joined: 30 Sep 2012
Posts: 24

View user's profile Send private message

Reduce noise of button
PostPosted: Wed Oct 10, 2012 2:45 am     Reply with quote

Hello, I'm doing my project with button, I'm using int_rb(r4-r7) so I want to know how to reduce noise and how to detect hold key action . Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Wed Oct 10, 2012 4:19 am     Reply with quote

Don't use the RB interrupts.

This has been covered before. They are not really suitable for this type of application.
1) Buttons are noisy.
2) The interrupts detect changes only, so are not suitable for detecting hold.
3) Because of the above it is very difficult indeed to reliably detect the required states: make, break, repeat

The normal good way of doing this, is to use a timer interrupt.
This is how the keyboard is handled in things like the PC keyboard.

Seriously, use the right tool for the job. Trying to do this with INT_RB, is making the task almost impossible, and vastly more work.

It's a bit like trying to use a hammer to drive a screw.

Best Wishes
falcon1877



Joined: 30 Sep 2012
Posts: 24

View user's profile Send private message

PostPosted: Wed Oct 10, 2012 4:42 am     Reply with quote

OK, I understand what you are saying and .....if I use timer, what is the best way to check for hold key action ? Can you give a sample code Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Wed Oct 10, 2012 5:07 am     Reply with quote

Difficult to be generic, without knowing your hardware details, with solutions changing if this is a key matrix, but something like (this for
four buttons on the upper four bits of portB - assuming interrupt every 1/100th second):
Code:

int8 kchr;

#INT_TIMERx //Choose to suit your hardware
void tick(void) {
   static int8 kseen[4];
   static int8 klast=0;
   int8 know, bit;

   know=input_b(); //read port
   swap(know); //move MSnibble to low nibble
   know=(~know)&15; //mask low four bits, and invert bits - assuming
   //low = key made

   for (bit=0;bit<4;bit++) {
      /* I check each bit in the input in turn */
      if (bit_test(know,bit)) {
         /* here this bit is set, and I have to check if it has allready been seen. */
         if (bit_test(klast,bit)) {
            /* Here the bit has allready been seen, and I respond if the counter
               reaches zero (4/100th sec first response, 30/100th sec repeat). */
            if (--kseen[bit]==0) {
               bit_set(kchr,bit);
               /* This sets the 'repeat' interval */
               kseen[bit]=30;
            }
         }
         else {
            /* here it is a 'first' response */
            bit_set(klast,bit);
            /* set to respond on the next loop - increasing this will slow
               keyboard debounce */
            kseen[bit]=4;
         }
      }
      else {
         /* here this key is not pressed */
         bit_clear(klast,bit);
      }
   }
}


kchr, will have the bit set corresponding to any key that is pressed. In your 'main' code, do what you want when this happens, and then clear the bit. If the key is held after 30/100th second, it'll be seen again. Key has to be 'down' for 4/100th second before it'll be seen.
The counter in kseen control how long the debounce is, and how fast the repeat.

Best Wishes
falcon1877



Joined: 30 Sep 2012
Posts: 24

View user's profile Send private message

PostPosted: Wed Oct 10, 2012 6:08 am     Reply with quote

@Ttelmah : thanks for your help, I will test it immediately.
falcon1877



Joined: 30 Sep 2012
Posts: 24

View user's profile Send private message

PostPosted: Wed Oct 10, 2012 8:26 pm     Reply with quote

@Ttelmah: Many thanks for you. Now my program works correctly. But I have a question. When do we need to use interrupt rb instead of timer ?? Can you give me some example Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19359

View user's profile Send private message

PostPosted: Thu Oct 11, 2012 3:09 am     Reply with quote

Classic use of INT_RB, would be something like an optical quadrature encoder. Here you have a signal source, that is warranted to give no bounce, two signals from the encoder, where you need to detect every edge (rising and falling on each signal), and respond fast (if you have -say- a 400line encoder on a shaft turning at 1000RPM, you have 26000 edges per second......).

Best Wishes
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