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

Switch statement using push button increment to switch cases
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
zombiePIC



Joined: 08 Feb 2014
Posts: 23

View user's profile Send private message

Switch statement using push button increment to switch cases
PostPosted: Sun Feb 16, 2014 3:32 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 16, 2014 4:51 pm     Reply with quote

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: 9177
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Feb 16, 2014 5:16 pm     Reply with quote

keyword is 'debounce'.
search the forum using it, read a few posts.

hth
jay
zombiePIC



Joined: 08 Feb 2014
Posts: 23

View user's profile Send private message

PostPosted: Sun Feb 16, 2014 5:17 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 16, 2014 5:26 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 16, 2014 5:49 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 16, 2014 5:54 pm     Reply with quote

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: 19382

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 1:43 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 11:30 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 11:36 am     Reply with quote

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: 9177
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 11:44 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 11:50 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 11:51 am     Reply with 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?

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

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 11:53 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 17, 2014 12:08 pm     Reply with quote

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
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  Next
Page 1 of 2

 
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