|
|
View previous topic :: View next topic |
Author |
Message |
Luis123migueL
Joined: 17 Jul 2019 Posts: 6
|
I can not get out from while function!! |
Posted: Tue Jul 30, 2019 12:12 pm |
|
|
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: 9241 Location: Greensville,Ontario
|
|
Posted: Tue Jul 30, 2019 2:18 pm |
|
|
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
|
Re: i can not get out from while function!! |
Posted: Tue Jul 30, 2019 10:03 pm |
|
|
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
|
|
Posted: Tue Jul 30, 2019 11:41 pm |
|
|
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: 19537
|
|
Posted: Wed Jul 31, 2019 12:53 am |
|
|
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
|
|
Posted: Tue Aug 13, 2019 6:06 pm |
|
|
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!! |
|
|
|
|
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
|