View previous topic :: View next topic |
Author |
Message |
zombiePIC
Joined: 08 Feb 2014 Posts: 23
|
Switch statement using push button increment to switch cases |
Posted: Sun Feb 16, 2014 3:32 pm |
|
|
Hi Guys
I am trying to set up a LED lighting system that can demo through different opperating modes. For example I want the LED to ramp up to full brightness then push a button and ramp down to low brightness then push the button again and return to full brightness and so on.
I think I am having trouble with the PWM set up.....
for case 1 I get full brightness no ramp up
for case 2 I get probally less than 5% brightness with no ramp down ..
PIC16F87
IDE version 5.016
PCB version 5.016
PCM version 5.016
PCH version 5.016
ICD-U64
CCS LOAD V4.051
Windows 8.1 64 bit
Can some body have a look at my code
Code: | #include <16F87.h>
#fuses INTRC,NOWDT
#use delay(clock=1000000)
#define Button_Press PIN_A0
int count=0;
void demo_sequence(int Demo_Number){
// variables used to set by PWM duty cycle
long led_duty =0;
int led_set=0;
//----------------------------------------------------------------------------
// PWM Setup
//----------------------------------------------------------------------------
setup_oscillator(OSC_1MHZ);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_4, 64, 1);
switch(Demo_Number){
case 0 : led_set=255;//Demo 0 while count zero, set LED to full brightness
if(led_duty<led_set){led_duty++;}
if(led_duty>led_set){led_duty--;}
set_pwm1_duty(led_duty);//ramp up to 255, full brightness
delay_ms(10);
break;
case 1 : led_set=51;//Demo 1 while count 1, set LED to 20%
if(led_duty<led_set){led_duty++;}
if(led_duty>led_set){led_duty--;}
set_pwm1_duty(led_duty);//ramp down to 20%
delay_ms(10);
count=0;//return to start
break;
}
}
void wait_for_one_press(){
while(input(Button_Press));
while(!input(Button_Press));
}
void main() {
while (TRUE){
wait_for_one_press();
count++;
demo_sequence(count);
}
} |
I have no scope to measure the PWM
Thanks |
|
|
stinky
Joined: 05 Mar 2012 Posts: 99 Location: Central Illinois
|
|
Posted: Sun Feb 16, 2014 4:51 pm |
|
|
Quote: | void wait_for_one_press(){
while(input(Button_Press));
while(!input(Button_Press));
} |
What happens if the button isn't being pressed? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Sun Feb 16, 2014 5:16 pm |
|
|
keyword is 'debounce'.
search the forum using it, read a few posts.
hth
jay |
|
|
zombiePIC
Joined: 08 Feb 2014 Posts: 23
|
|
Posted: Sun Feb 16, 2014 5:17 pm |
|
|
Quote: | What happens if the button isn't being pressed? |
I persume the code jumps to the case statement depending on the count value... looks like that anyway.. |
|
|
zombiePIC
Joined: 08 Feb 2014 Posts: 23
|
|
Posted: Sun Feb 16, 2014 5:26 pm |
|
|
Quote: | keyword is 'debounce'.
search the forum using it, read a few posts. |
Thanks
I will give that a try... but i think i will be back here.. |
|
|
zombiePIC
Joined: 08 Feb 2014 Posts: 23
|
|
Posted: Sun Feb 16, 2014 5:49 pm |
|
|
Hi
I modified my code to include the comment made in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=51914&highlight=debounce+increment
Code: | #include <16F87.h>
#fuses INTRC,NOWDT
#use delay(clock=1000000)
#define Button_Press PIN_A0
#define LOW 0
#define HIGH 1
int count=0;
void demo_sequence(int Demo_Number){
// variables used to set by PWM duty cycle
long led_duty =0;
int led_set=0;
//----------------------------------------------------------------------------
// PWM Setup
//----------------------------------------------------------------------------
setup_oscillator(OSC_1MHZ);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_4, 64, 1);
switch(Demo_Number){
case 0 :
break;}
case 1 :
break;}
}
}
void wait_for_one_press(){
while(TRUE)
{
if (input(Button_Press)==LOW)
{
delay_ms(10); //short delay
if (input(Button_Press)==LOW) //key is still low
count++;
}
}
}
void main() {
while (TRUE){
wait_for_one_press();
demo_sequence(count);
}
}
|
Added a while loop to the case statement...
No change. the LED stays at full brightness after PB is incremented.... Quote: | keyword is 'debounce'.
search the forum using it, read a few posts. |
Last edited by zombiePIC on Fri Feb 21, 2014 4:20 pm; edited 1 time in total |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Feb 16, 2014 5:54 pm |
|
|
Two additional comments:-
1) Case statements look too complex.
2) For loops (or while loops) in case statements may achieve what you're after.
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19542
|
|
Posted: Mon Feb 17, 2014 1:43 am |
|
|
Just re-typed the code to show a major problem.....
Code: |
case 0 :
while (count==0)
{
led_set=255;//Demo 0 while count zero, set LED to full brightness
if(led_duty<led_set)
led_duty++;
if(led_duty>led_set)
led_duty--;
set_pwm1_duty(led_duty);//ramp up to 255, full brightness
delay_ms(10);
break;
}
|
Now read up on what 'break' does.
A break exits the _innermost_ control loop (for, while, do, switch).
So this code executes _once_ (good thing since nothing will ever change count in this), then runs off the end of the case (since there is no 'break' for this).
The flow is fundamentally flawed. |
|
|
zombiePIC
Joined: 08 Feb 2014 Posts: 23
|
|
Posted: Mon Feb 17, 2014 11:30 am |
|
|
I am having no success here, i played around with the break; no joy.....I dont seem to understand what could be wrong now.. |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Mon Feb 17, 2014 11:36 am |
|
|
Hi,
Pssst...... Your 'Break' statement is inside your 'While' loop, so the loop runs once and exits. You want to move the 'Break' outside of the 'While' loop so
as to exit the 'Case 0' section instead......
You might find some relevant 'C' language programming help here: https://docs.google.com/file/d/0B_EYtdS7J5eKZ1RaeEt4a2hlQnM/edit?pli=1
John |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Mon Feb 17, 2014 11:44 am |
|
|
break your code up( no pun intended).
Start with a simpler program where each case statement sends a printf(....case number...) to PC or LCD module.This way you can easily debug and see what's going on since case '3' should send the number '3' to the PC.
hth
jay |
|
|
zombiePIC
Joined: 08 Feb 2014 Posts: 23
|
|
Posted: Mon Feb 17, 2014 11:50 am |
|
|
No luck modified the code to change break;
Code: | #include <16F87.h>
#fuses INTRC,NOWDT
#use delay(clock=1000000)
#define Button_Press PIN_A0
#define LOW 0
#define HIGH 1
int count=0;
void demo_sequence(int Demo_Number){
// variables used to set by PWM duty cycle
long led_duty =0;
int led_set=0;
//----------------------------------------------------------------------------
// PWM Setup
//----------------------------------------------------------------------------
setup_oscillator(OSC_1MHZ);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_4, 64, 1);
switch(Demo_Number){
case 0 :
while (count==0)
{
led_set=255;//Demo 0 while count zero, set LED to full brightness
if(led_duty<led_set)
led_duty++;
if(led_duty>led_set)
led_duty--;
set_pwm1_duty(led_duty);//ramp up to 255, full brightness
delay_ms(10);
}
break;
case 1 :
while (count==1)
{
led_set=55;//Demo 0 while count zero, set LED to full brightness
if(led_duty<led_set)
led_duty++;
if(led_duty>led_set)
led_duty--;
set_pwm1_duty(led_duty);//ramp up to 255, full brightness
delay_ms(10);
}
break;
}
}
void wait_for_one_press(){
while(input(Button_Press));
while(!input(Button_Press));
}
void main() {
while (TRUE){
demo_sequence(count);
wait_for_one_press();
}
}
|
When target board starts up the LED ramps from low to high. No change occurs when button is pressed several times.
Code: | void wait_for_one_press(){
while(input(Button_Press));
while(!input(Button_Press));
} |
this bit of code was taken from the Exercise book for the ccs 16f877a dev board |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Feb 17, 2014 11:51 am |
|
|
The switch case is not now your real problem.
You've fouled up another section as well.
So, you never actually get to the break as a problem!
How do you imagine that this latest posted version ever exits?
Code: | void wait_for_one_press(){
while(TRUE)
{
if (input(Button_Press)==LOW)
{
delay_ms(10); //short delay
if (input(Button_Press)==LOW) //key is still low
count++;
}
}
}
|
Mike |
|
|
zombiePIC
Joined: 08 Feb 2014 Posts: 23
|
|
Posted: Mon Feb 17, 2014 11:53 am |
|
|
Quote: | The switch case is not now your real problem.
You've fouled up another section as well.
So, you never actually get to the break as a problem!
How do you imagine that this latest posted version ever exits? |
i switched back over to this....
Code: | Code:
void wait_for_one_press(){
while(input(Button_Press));
while(!input(Button_Press));
}
|
|
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Mon Feb 17, 2014 12:08 pm |
|
|
All waiting for button press to go true then false does is go through there many times when the switch bounces (which most of them do). Switch bounces have driven many people screaming into the night - you either need to debounce it in software or hardware (something like an RC network can work well although it introduces a slight delay in sensing switch closure). Multiple closures in just a few ms (typical) causes most software to act goofy and the user does not realize that they have effectively pushed the button multiple times in just a few ms. Just for entertainment, you could create a little routine that used your "check for low, check for high" routine and increments a counter each time through then displays the result (count switch bounces) and see what it shows each time you press the switch. Would be interesting to see how many times it bounces.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
|