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 CCS Technical Support

problem with press button and interrupts

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



Joined: 04 May 2008
Posts: 260

View user's profile Send private message

problem with press button and interrupts
PostPosted: Thu Sep 18, 2014 3:10 pm     Reply with quote

Hi

I stay many time without programming, because work time... now I start like a "newer"

A simple program I need have a switch button to choose, some sequences on program.

but the 1º program stay in fact, when I press the switch (I have pulldown 1k) my interrupt count many times, and jump sequences.

Can one help to see the problem?

best regards

Code:

#include <16F628A.h>
#fuses NOWDT,INTRC_IO, NOCPD, NOPROTECT, MCLR, NOPUT, BROWNOUT
#use delay(clock=4000000)

int8 count = 0, aux = 0;

#define LED1 PIN_A1
#define LED2 PIN_A0
#define LED3 PIN_A7
#define LED4 PIN_A6

#int_ext
void int_rb0()
{
   count++;
   delay_ms(50);
}


void seq1()
{
//###### sequenciador 1
output_high(LED1); output_low(LED2);output_low(LED3); output_low(LED4); delay_ms(100);
output_low(LED1); output_high(LED2);output_low(LED3); output_low(LED4); delay_ms(100);
output_low(LED1); output_low(LED2);output_high(LED3); output_low(LED4); delay_ms(100);
output_low(LED1); output_low(LED2);output_low(LED3); output_high(LED4); delay_ms(100);

aux=1;
}
void seq2()
{
//###### sequeciador 2
output_high(LED1); output_low(LED2);output_low(LED3); output_low(LED4); delay_ms(200);
output_high(LED1); output_high(LED2);output_low(LED3); output_low(LED4); delay_ms(200);
output_high(LED1); output_high(LED2);output_high(LED3);output_low(LED4); delay_ms(200);
output_high(LED1); output_high(LED2);output_high(LED3);output_high(LED4); delay_ms(200);

output_low(LED1); output_high(LED2);output_high(LED3); output_high(LED4); delay_ms(200);
output_low(LED1); output_low(LED2);output_high(LED3); output_high(LED4); delay_ms(200);
output_low(LED1); output_low(LED2);output_low(LED3); output_high(LED4); delay_ms(200);
output_low(LED1); output_low(LED2);output_low(LED3); output_low(LED4); delay_ms(200);

aux=2;
}
void seq3()
{
//###### sequeciador 3
output_high(LED1); output_high(LED2);output_high(LED3); output_high(LED4); delay_ms(200);

aux=3;
}
void seq4()
{
//###### sequeciador 4
output_high(LED1); output_low(LED2);output_high(LED3); output_low(LED4);delay_ms(100);
output_low(LED1); output_high(LED2);output_low(LED3); output_high(LED4);delay_ms(100);
output_high(LED1); output_low(LED2);output_high(LED3); output_low(LED4);delay_ms(100);
output_low(LED1); output_high(LED2);output_low(LED3); output_high(LED4);delay_ms(100);

aux=4;
}



void main (void)
{
int8 temp = 0;
int16 aux = 0;


   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT);     
   setup_timer_2(T2_DIV_BY_1, 255, 1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(0);  //0 até 255


while(TRUE)
{
 
      if (count==0) seq1();
      if (count==1) seq2();
      if (count==2) seq3();
      if (count==3) seq4();
     
      if (count>3) count=0;

        set_pwm1_duty(aux);
     
      if (temp==0) aux=aux+20;
      if (temp==1) aux=aux-20;
     
      if (aux<=0) temp=0;
      if (aux>=1020) temp=1;
 

}
}

newguy



Joined: 24 Jun 2004
Posts: 1909

View user's profile Send private message

PostPosted: Thu Sep 18, 2014 3:53 pm     Reply with quote

Your problem is very likely caused by switch bounce. Put very simply, the contacts of the switch are making-breaking-making-breaking-making...(etc) very rapidly even though it feels, to you, like one press. Humans don't "see" the bounce because it happens so quickly but your processor can see it.

You either need a software debounce routine or you'll need to add a capacitor to your switch circuitry to implement an RC circuit that will filter/smooth the bounce. In my experience, bounce usually stops within 20-30ms at worst, so use this fact to choose your R and C values. A software debounce routine can be as simple or as complex as you wish but it generally involves a timer that's triggered by the button interrupt -> timer expires -> is switch still pressed? -> NOW do what you originally wanted to do.
Ttelmah



Joined: 11 Mar 2010
Posts: 19544

View user's profile Send private message

PostPosted: Fri Sep 19, 2014 12:35 am     Reply with quote

Easier in many ways, is to forget using interrupts directly from the buttons at all....

Instead have a system 'tick' (a timer interrupt at say 100Hz).

Then in this, read the buttons.
If a button is set, set a flag to say 'may have'.
Then the next time the interrupt calls, if the button is set, and the 'may have' flag is also set, record a button.
If the button is no longer set, clear the flag.

This way a button has to be set, for two successive calls, before it is recorded.
It is more reliable, and extendible for as many buttons as you want.
Also, the same timer, can then be used for other 'housekeeping' tasks.

I doubt if any of the 'old hands' here, actually uses an external level interrupt directly to handle buttons.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Sep 19, 2014 5:02 am     Reply with quote

I'm with Ttelmah on this one.
Using an edge trigger for buttons never even crosses my mind.

I'd also be wary of connecting a C directly across any kind of switch contact.
Long term, repeated discharge is likely to damage the contact.

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9244
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Sep 19, 2014 5:16 am     Reply with quote

here's a simple approach that works well without using the 'timer' method.

LT is the I/O PIN that the switch is connected to( and ground), pullup resistor(10K) as well).
The delay value of 20ms can be changed ,less is faster response.

Code:
//armed function - wait for keypress -
int armed()
{
   while (!input(LT) )   ;               //wait if low
   delay_ms(20);                     //debounce delay
   while (input(LT) )   ;               //wait if hi
   delay_ms(20);                     //debounce delay
   return (1);                     //set armed flag
}
as I said it is simple, easy to use, no timer involved....


jay
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