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

debouncing missing out on presses!
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

debouncing missing out on presses!
PostPosted: Sat Jun 08, 2019 10:59 am     Reply with quote

Hi all,

I am from Arduino/AVR background and new to PIC and chose to start learning the CCS-C in comparison to others like Hightech-C and Mikro-C as I found it more CArduino-ish! Smile

Hope I am correct with this conclusion and in my choice!

So, to learn, I started programming a 5 channels relay controller board that I have already done with Arduino with complete success.

However, the debouncing does not work smoothly as it misses out many presses randomly, but it eventually works and toggles the LEDs.

All your helps are all appreciated in advance! Smile

Below is the full code.


Code:


/*
   Project:    Demo Controller Board - 5 Channels Relay with status LEDs and push buttons for a ON/OFF toggle
   Compiler:   CCS-C-PIC - PCWHD Version 5.076
   Author:     MassaM, June 2019
   Chip:       PIC16F877A@10Mhz
   Copyright:  No copy-rights nor copy-wrongs! :) Make it better and post it back on this thread, so we all learn please!
*/

#include <16f877a.h>
#fuses XT, NOWDT

#use delay(clock = 10000000) // 10MHz external crystal
#use rs232(stream=SERIAL, baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)  // settings for Serial/Terminal outputs

// switches
#define SW1    PIN_A0   // Switch 1 on port A pin 0
#define SW2    PIN_A1   // Switch 2 on port A pin 1
#define SW3    PIN_A2   // Switch 3 on port A pin 2
#define SW4    PIN_A3   // Switch 4 on port A pin 3
#define SW5    PIN_A4   // Switch 5 on port A pin 4

// leds
#define LED1   PIN_B0   // LED 1 on port B pin 0 - This output will control Relay 1
#define LED2   PIN_B1   // LED 2 on port B pin 1 - This output will control Relay 2
#define LED3   PIN_B2   // LED 3 on port B pin 2 - This output will control Relay 3
#define LED4   PIN_B3   // LED 4 on port B pin 3 - This output will control Relay 4
#define LED5   PIN_B4   // LED 5 on port B pin 4 - This output will control Relay 5

void main(void)
{

   set_tris_a(0b11111111); // all inputs
   set_tris_b(0b00000000); // all outputs
   
   setup_adc_ports(NO_ANALOGS);  //sets porta to all digital inputs

   printf("Ready!\r\n");   // Terminal/Serial - Prints ready as a test output

   int16 state; // Will be used to check the switch press state

   while(true)
   {     

      // switch 1
      if(!input_state(SW1))   // Check if switch was pressed meaning it is at state 0. By default it was set to state 1
      {
            do
            {
               state = input_state(SW1); // Check switch state
               delay_ms(10);
            }
            while(!state); // keep reading till a LOW
           
            delay_ms(100);  // Switchpress detected  - debouncing delay
            state = input_state(SW1);  // read again
     
            if (!state)
            {
               output_toggle(LED1);//if open turn off/on led
            }
      }
     
      // swtich 2
      if(!input_state(SW2))   // Check if switch was pressed meaning it is at state 0. By default it was set to state 1
      {
            do
            {
               state = input_state(SW2);
               delay_ms(10);
            }
            while(!state); // keep reading till a LOW
           
            delay_ms(100);  // Switchpress detected  - debouncing delay
            state = input_state(SW2);  // read again
     
            if (!state)
            {
               output_toggle(LED2);//if open turn off/on led
            }
      }
     
      // switch 3
      if(!input_state(SW3))   // Check if switch was pressed meaning it is at state 0. By default it was set to state 1
      {
            do
            {
               state = input_state(SW3);
               delay_ms(10);
            }
            while(!state); // keep reading till a LOW
           
            delay_ms(100);  // Switchpress detected  - debouncing delay
            state = input_state(SW3);  // read again
     
            if (!state)
            {
               output_toggle(LED3);//if open turn off/on led
            }
      }
     
      // switch 4
      if(!input_state(SW4))   // Check if switch was pressed meaning it is at state 0. By default it was set to state 1
      {
            do
            {
               state = input_state(SW4);
               delay_ms(10);
            }
            while(!state); // keep reading till a LOW
           
            delay_ms(100);  // Switchpress detected  - debouncing delay
            state = input_state(SW4);  // read again
     
            if (!state)
            {
               output_toggle(LED4);//if open turn off/on led
            }
      }
     
      // switch 5
      if(!input_state(SW5))   // Check if switch was pressed meaning it is at state 0. By default it was set to state 1
      {
            do
            {
               state = input_state(SW5);
               delay_ms(10);
            }
            while(!state); // keep reading till a LOW
           
            delay_ms(100);  // Switchpress detected  - debouncing delay
            state = input_state(SW5);  // read again
     
            if (!state)
            {
               output_toggle(LED5);//if open turn off/on led
            }
      }

   }//while
   
}// main



And the schematic linked below.

[IMG]https://www.4shared.com/img/uUhScm1mda/s25/16b37f7f348/SWITCH_LED_TOGGLE[/IMG]
_________________
while(!dead)
{
keepLearning();
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19381

View user's profile Send private message

PostPosted: Sat Jun 08, 2019 11:22 am     Reply with quote

The big issue is that it pauses checking other keys if a key is low.

This is where a 'timer' based approach wins.
If (for example), you have a 'tick' interrupt at 10mSec intervals,
then you can simply check that the inputs are low for two successive
interrupts. So each time in, you read all five buttons.
Then compare the value read with what was read last time.
If both are zero, trigger a flag to say 'seen'.
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

PostPosted: Sat Jun 08, 2019 11:33 am     Reply with quote

Ttelmah wrote:
The big issue is that it pauses checking other keys if a key is low.

This is where a 'timer' based approach wins.
If (for example), you have a 'tick' interrupt at 10mSec intervals,
then you can simply check that the inputs are low for two successive
interrupts. So each time in, you read all five buttons.
Then compare the value read with what was read last time.
If both are zero, trigger a flag to say 'seen'.


Hi Ttelmah,

Indeed, and I do agree and have done that in the Arduino.

This is my first basic switch polling demo to start off the CCS PIC-C learning process! Smile

What I'd wish to do is an advance timer0 based with interrupts and switch array with debouncing all at the same press time.

Any links to a demo please so I study it?

Appreciated.

MassaM
_________________
while(!dead)
{
keepLearning();
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19381

View user's profile Send private message

PostPosted: Sat Jun 08, 2019 12:59 pm     Reply with quote

I'll try to sort out a little example program. Won't be till tomorrow though.
As one comment though 10MHz == HS, not XT. Your chip may well not be
running correctly.
temtronic



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

View user's profile Send private message

PostPosted: Sat Jun 08, 2019 1:44 pm     Reply with quote

Have a look in the 'code library'. There's a nice 'button' function either Mr. T or PCMP wrote, I forget as I'm old(er) at 66....
I KNOW it works very well as I've used it in 3 or 4 projects.

Jay
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

PostPosted: Sat Jun 08, 2019 7:40 pm     Reply with quote

Quote:
I'll try to sort out a little example program. Won't be till tomorrow though.


Appreciate it! Very Happy

Quote:
As one comment though 10MHz == HS, not XT. Your chip may well not be
running correctly.


Good point. Will test other options and hope it helps.
_________________
while(!dead)
{
keepLearning();
}
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

PostPosted: Sat Jun 08, 2019 7:46 pm     Reply with quote

temtronic wrote:
Have a look in the 'code library'. There's a nice 'button' function either Mr. T or PCMP wrote,
Jay


I looked for "debouncing switch array", "debouncing", "switch timer interrupt" but nothing was found matching the required!

temtronic wrote:

I forget as I'm old(er) at 66....
I KNOW it works very well as I've used it in 3 or 4 projects.


Age is just a number! Cool God bless and keep coding sir!
_________________
while(!dead)
{
keepLearning();
}
temtronic



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

View user's profile Send private message

PostPosted: Sat Jun 08, 2019 8:22 pm     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=23837

took me a bit to find it....
Jay
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

PostPosted: Sat Jun 08, 2019 8:59 pm     Reply with quote

temtronic wrote:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837

took me a bit to find it....
Jay


Great. Will check it out. Thank you.

Meanwhile, I found this by "PCM programmer" with a big Thank you! Very Happy here:

https://www.ccsinfo.com/forum/viewtopic.php?t=53600

and coded a simple test with a timer interrupt version with two buttons.

I still am going to make it into an array of switches and leds timer/interrupts based polling as per the demo i managed to code.

Tested and working full code below.

Code:


#include <18F4520.h>
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

#define FOSC getenv("CLOCK")  // Get PIC oscillator frequency
#define TIMER0_PRELOAD (256 - (FOSC/4/256/100))

#define  BUTTON1   PIN_B0
#define  BUTTON2   PIN_B1

#define  LED1      PIN_D0
#define  LED2      PIN_D1

void timer0_init(void)
{
   setup_timer_0(T0_INTERNAL | T0_DIV_256 | T0_8_BIT);
   set_timer0(TIMER0_PRELOAD);
   clear_interrupt(INT_TIMER0);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
}

int8 switch1_is_down = FALSE,
     switch2_is_down = FALSE;

#int_timer0
void timer0_isr(void)
{
   int8 active_state1, previuos_state1,
        active_state2, previuos_state2;
   
   set_rtcc(TIMER0_PRELOAD); // Reload Timer0 for 10ms rate
   
   active_state1 = input(BUTTON1);  // Read the button
   active_state2 = input(BUTTON2);  // Read the button
   
   if((previuos_state1 == 1) && (active_state1 == 0))
   {
      switch1_is_down = TRUE;   
   }

   if((previuos_state2 == 1) && (active_state2 == 0))
   {
      switch2_is_down = TRUE;   
   }
   
   previuos_state1 = active_state1;  // Save current value for next time
   previuos_state2 = active_state2;  // Save current value for next time
   
}


void main()
{

   timer0_init();
   
   while(TRUE)
   {
   
   if(switch1_is_down == TRUE)
     {
         switch1_is_down = FALSE;  // Clear the switch is pushed flag
         output_toggle(LED1);     
     }
   
   if(switch2_is_down == TRUE)
     {
         switch2_is_down = FALSE;  // Clear the switch is pushed flag
         output_toggle(LED2);     
     }
   
   }
}


Hope it helps others and would appreciate any inputs and help.

MassaM
_________________
while(!dead)
{
keepLearning();
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19381

View user's profile Send private message

PostPosted: Sun Jun 09, 2019 7:26 am     Reply with quote

Well done.
Looks quite tidy. Smile
As a comment, your flags for switchx_is_down, might as well be int1's.
The processor has inbuilt instructions for testing and branching on a bit,
so using these may well be more efficient, and will save space.
One of the things that has to be learnt on the PIC, is that you only have
a very small amount of RAM, so saving is always worthwhile.
Ttelmah



Joined: 11 Mar 2010
Posts: 19381

View user's profile Send private message

PostPosted: Sun Jun 09, 2019 8:38 am     Reply with quote

As one more comment, why are you using such an old chip?.

The 16F877A, is 'not recommended for new designs'. It came out around
about 2000, and there are newer PIC's, that use less power, have more
peripherals, are faster, have more RAM, and are cheaper!...
It's amazing how many people still carry on using such old chips.

I don't know whether you have PCH or only PCM, but the PCH chips
(PIC18's), also have a much tidier actual architecture. The 16F877A was
a reasonable chip to use 15 years ago, but now is making things harder
for yourself than they need to be...
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

PostPosted: Sun Jun 09, 2019 9:28 am     Reply with quote

Ttelmah wrote:
Well done.
Looks quite tidy. Smile

Thank you! Smile

Ttelmah wrote:
As a comment, your flags for switchx_is_down, might as well be int1's.
The processor has inbuilt instructions for testing and branching on a bit,
so using these may well be more efficient, and will save space.
One of the things that has to be learnt on the PIC, is that you only have
a very small amount of RAM, so saving is always worthwhile.


All you mentioned are priceless, very well noted and will be put into action for future PIC adventures! Cool

With gentlemen such as yourself, and this community of course, learning PIC and CCS-C will be an easy task and I found it to be the right choice.

Bless all.

MassaM
_________________
while(!dead)
{
keepLearning();
}
MassaM



Joined: 08 Jun 2019
Posts: 31

View user's profile Send private message Visit poster's website

PostPosted: Sun Jun 09, 2019 9:37 am     Reply with quote

Ttelmah wrote:
As one more comment, why are you using such an old chip?.

The 16F877A, is 'not recommended for new designs'. It came out around
about 2000, and there are newer PIC's, that use less power, have more
peripherals, are faster, have more RAM, and are cheaper!...
It's amazing how many people still carry on using such old chips.

I don't know whether you have PCH or only PCM, but the PCH chips
(PIC18's), also have a much tidier actual architecture. The 16F877A was
a reasonable chip to use 15 years ago, but now is making things harder
for yourself than they need to be...


I agree. It's just the beginning for me and PIC, most tutorials use it, and added that I have couple of those laying in the boxes from those days! Smile

Will definitely shift to the latest ones to benefit from the features as you mentioned of course.

Cheers! Smile
_________________
while(!dead)
{
keepLearning();
}
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Sun Jun 09, 2019 9:44 am     Reply with quote

Just a caution about int1:

I've experienced something where with larger projects that have more variables and more int1's scattered around, they don't work properly for some reason.

There is some brief discussion about this in the beginning of this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=57881&postdays=0&postorder=asc&start=0

So if you suddenly start to have problems with int1 flags, then this may be it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19381

View user's profile Send private message

PostPosted: Sun Jun 09, 2019 10:04 am     Reply with quote

The issues here were with a very early V5 compiler, that was still really a
'beta' at best.
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 1, 2, 3  Next
Page 1 of 3

 
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