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

I can not get out from while function!!

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



Joined: 17 Jul 2019
Posts: 6

View user's profile Send private message

I can not get out from while function!!
PostPosted: Tue Jul 30, 2019 12:12 pm     Reply with quote

Hello everyone !!

First, i explain what my code should do:

At the beginning a LED(pin A0) should blink automatically time1 seconds high and time1 seconds low and when i press button (pin B0)
The second LED(pin A1) should blink automatically time2 seconds high and time2 seconds low, and when i press the other button(pin B1) the first LED should blink and so on, in a loop.

The problem is when i press the first button I must keep it pressed at least 2*time1 to change of LED, and 2*time2 for the seconds case.

I want this change to be immediate.

Code:

#include <16f628.h>
#fuses XT, NOWDT, NOMCLR
#use delay(clock=4000000)
#use standard_io(B)
#use standard_io(A)
#BYTE OPTION=0X81
#include <stdint.h>//for signed and unsigned variables

void __delay_ms(uint16_t time)
{
   while(time>0)
   {
   delay_ms(1);
   time = time-1;
   }
}

void juego1(uint16_t a)
{
   output_high(pin_A0);
   __delay_ms(a);
   output_low(pin_A0);
   __delay_ms(a);
}

void juego2(uint16_t b)

   output_high(pin_A1);   
   __delay_ms(b);
   output_low(pin_A1);
   __delay_ms(b);
}

void main()
{
   bit_clear(OPTION,7);//enable internals pull ups in all ports B
   uint16_t time1=1000,time2=1000;
   output_low(pin_A0);
   output_low(pin_A1);
   while(true)
  {     
   while(input(pin_B0))
   {
   if(!input(pin_B0)){break;}//---->> it doesnt work
   juego1(time1);
   }
   while(input(pin_B1))
   {
   if(!input(pin_B1)){break;}//---->> it doesnt work
   juego2(time2);
   }
 }
}


I will appreciate your help

peace!!
temtronic



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

View user's profile Send private message

PostPosted: Tue Jul 30, 2019 2:18 pm     Reply with quote

Mechanical pushbuttons have a LOT of 'contact bounce' ! Usually you can 'dampen' that with a simple cap across the switch contacts. I use a .68mfd cap, seeing how I still have 3700+ on a reel from a project from years ago.
You should search the 'code library' here for a 'button' program that either PCM P or Mr. T wrote.
I've used it several times so I know i works.
Also you've got the same time for both functions. At least for test purposes, they should be different so you can SEE that the hardware and logic are correct.


edit:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837&highlight=pic+basic+button

It's in the code library, compliments of PCM P.


Jay
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

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

Re: i can not get out from while function!!
PostPosted: Tue Jul 30, 2019 10:03 pm     Reply with quote

Luis123migueL wrote:

Code:

   while(true)
  {     
   while(input(pin_B0))
   {
   if(!input(pin_B0)){break;}//---->> it doesnt work
   juego1(time1);
   }
   while(input(pin_B1))
   {
   if(!input(pin_B1)){break;}//---->> it doesnt work
   juego2(time2);
   }
 }



The above section uses redundant code. For example
Code:

   while (input(on pin B0) is high)
   {
         if (input(on pin B0) is low) break out of this while loop

         play time1
   }

The while loop executes as long as the input on B0 is high. So, the second check for input on B0 going low is redundant. That if statement will not execute except if there is a fast bounce signal that slips through.

Hope you understand what I'm trying to tell you
_________________
Regards
Jerson Fernandes
Luis123migueL



Joined: 17 Jul 2019
Posts: 6

View user's profile Send private message

PostPosted: Tue Jul 30, 2019 11:41 pm     Reply with quote

hi temtronic thanks for your answer!!

I consider the problem is more than a debouncing problem. I think the problem is in the __delays__ms(), I mean, at the beginning when the while(pin_B0) is true(pin_B0==1), juego1 is executed, the first LED is ON for time1 seconds and the code stops in this line time1 seconds in consecuence if i press pin_B0(pin_B0==0) this event is not recognized for while(pin_B0) function because the code is still running inside the while function. For this reason I have to press and hold the button (pin_B0==0) until while(pin_B0) recognized this new value for next loop. For the new loop pin_B0==0, the second while function starts and juego2 is executed.

I want to press the button and execute second while function, not press and hold.

I hope you understand my idea, I don't speak english very well and use google translate to write. u.u

Peace!!
---------------------------------
Hi Jerson,

You have reason.

my code should be without if(!input(pin_B0)){break;} statement for both while functions.

Thanks A lot.

Peace!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jul 31, 2019 12:53 am     Reply with quote

The big problem is sequencing. Some comments in line:
Code:

void main()
{
   bit_clear(OPTION,7);//enable internals pull ups in all ports B
   uint16_t time1=1000,time2=1000;
   output_low(pin_A0);
   output_low(pin_A1);
   while(true)
   {     
       while(input(pin_B0)) //at this instant, will enter loop if B0 is high
       {
             //It would now exit if B0 is now low, but it'd
             //have to have gone low in the machine cycle between the
             //'while', and here. Otherwise the external 'while' will
             //not be true....
             if(!input(pin_B0))
               {break;}//---->> it doesnt work
            //It then sits for two seconds in this 'juego1' function.
            juego1(time1);
       }
       while(input(pin_B1))
       {
           if(!input(pin_B1))
               {break;}//---->> it doesnt work
           juego2(time2);
       }
   }
}

So the big problem is the 'break' will only be reached, if the pin goes
low on exactly the point between the 'while', and the 'if', and this
in a loop that takes 2 seconds to execute. Probability of hitting this
is close to zero....

What you need is to be putting the test that exits, inside the delays.
So (for example):

Code:

//Instead of delay_ms(1000)
    int8 count=100;
    while (count--)
    {
        delay_ms(10);
        if (!input(PIN_B0))
            break;
    }


This gives you a delay for 100*10mSec, which will exit if PIN_B0 goes low.
Luis123migueL



Joined: 17 Jul 2019
Posts: 6

View user's profile Send private message

PostPosted: Tue Aug 13, 2019 6:06 pm     Reply with quote

hi Ttelmah

I took your idea and did this code (below). It works as i wanted. I simulated and did it on breadboard. I will appreciate if you check my code.

Thanks a lot!!

Code:

#include <16f628.h>
#fuses XT, NOWDT, NOMCLR
#use delay(clock=4000000)
#use standard_io(B)
#use standard_io(A)
#BYTE OPTION=0X81
#include <stdint.h>//for signed and unsigned variables

void juego2(uint16_t aa, uint16_t bb)//LED A1 blinking
{
while(true)

                 
                  uint16_t a=aa, b=bb;
                  while(a>0)
                  {
                  output_high(pin_A1);
                  delay_ms(1);
                  if(input(pin_B1)==0){break;}
                  a=a-1;
                  if(a==0)
                  {
                  while(b>0)
                  {
                  output_low(pin_A1);
                  delay_ms(1);
                  if(input(pin_B1)==0){break;}
                  b=b-1;                 
                  }
                  }
                  }
                  if(input(pin_B1)==0){
                  output_low(pin_A1);
                  break;}
}
}

void juego1(uint16_t aa, uint16_t bb ,uint16_t cc, uint16_t dd)//LED A0 blinking
{
                  uint16_t a=aa, b=bb , c=cc , d=dd;
                  while(a>0)
                  {
                  output_high(pin_A0);
                  delay_ms(1);
                  if(input(pin_B0)==0){
                  output_low(pin_A0);
                  juego2(c,d);}
                  a=a-1;
                  if(a==0)
                  {
                  while(b>0)
                  {
                  output_low(pin_A0);
                  delay_ms(1);
                  if(input(pin_B0)==0){
                  output_low(pin_A0);
                  juego2(c,d);}
                  b=b-1;                 
                  }
                  }
                  }
}

void main()
{
   bit_clear(OPTION,7);//enable internals pull ups in all ports B   
   while(true)
   {
         uint16_t time1_on = 1000,time1_off = 1000,time2_on=1000,time2_off=1000;
         juego1(time1_on,time1_off,time2_on,time2_off);
   }
}


Peace!!
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