|
|
View previous topic :: View next topic |
Author |
Message |
MassaM
Joined: 08 Jun 2019 Posts: 31
|
debouncing missing out on presses! |
Posted: Sat Jun 08, 2019 10:59 am |
|
|
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!
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!
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: 19549
|
|
Posted: Sat Jun 08, 2019 11:22 am |
|
|
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
|
|
Posted: Sat Jun 08, 2019 11:33 am |
|
|
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!
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: 19549
|
|
Posted: Sat Jun 08, 2019 12:59 pm |
|
|
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: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jun 08, 2019 1:44 pm |
|
|
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
|
|
Posted: Sat Jun 08, 2019 7:40 pm |
|
|
Quote: | I'll try to sort out a little example program. Won't be till tomorrow though.
|
Appreciate it!
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
|
|
Posted: Sat Jun 08, 2019 7:46 pm |
|
|
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! God bless and keep coding sir! _________________ while(!dead)
{
keepLearning();
} |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
|
MassaM
Joined: 08 Jun 2019 Posts: 31
|
|
Posted: Sat Jun 08, 2019 8:59 pm |
|
|
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! 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: 19549
|
|
Posted: Sun Jun 09, 2019 7:26 am |
|
|
Well done.
Looks quite tidy.
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: 19549
|
|
Posted: Sun Jun 09, 2019 8:38 am |
|
|
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
|
|
Posted: Sun Jun 09, 2019 9:28 am |
|
|
Ttelmah wrote: | Well done.
Looks quite tidy. |
Thank you!
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!
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
|
|
Posted: Sun Jun 09, 2019 9:37 am |
|
|
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!
Will definitely shift to the latest ones to benefit from the features as you mentioned of course.
Cheers! _________________ while(!dead)
{
keepLearning();
} |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Jun 09, 2019 9:44 am |
|
|
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: 19549
|
|
Posted: Sun Jun 09, 2019 10:04 am |
|
|
The issues here were with a very early V5 compiler, that was still really a
'beta' at best. |
|
|
|
|
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
|