View Full Version : Crazy Loops
whytheheckme
04-02-2007, 00:36
Hey!
I'm trying to create a simple program that spins my bot for 20 seconds and sees how many tenths of degrees my gyro picks up. I've been programming for a long time, and I can't figure this one out. I'm using easyC because the rest of our team started coding with that, and I guess I'm stuck with it for this year....
Any way, here is some sudo code. Can't copy paste (It's not on this machine, but this is basically what it does)
Operator control
{
int gyro;
int timer = 0;
setgyrotype(4,125)
initgyro(4)
startgyro(4)
starttimer(1)
set_pwm(1,63)
set_pwm(2,63)
set_pwm(3,63)
set_pwm(4,63)
while(timer<20000)
{
gyro = getgyro(4)
timer = GetTimer(1)
PrintToScreen(gyro)
PrintToScreen(timer)
}
set_pwm(1,127)
set_pwm(2,127)
set_pwm(3,127)
set_pwm(4,127)
PrintToScreen("done")
}
Yeah, Yeah... Syntax. Semicolons are overrated. So are proper parameters. It's SUDO CODE....
Anyway... Heres where it breaks down.
It never leaves the while loop. The PrintToScreen SHOWS that the variable counts up to 20000, but continues to go around the loop after that. HOW DOES IT RUN THE LOOP WHEN THE CONDITION ISN'T MET???
Ive also tried an if statement inside the loop that checks the time and makes a variable 'done' 1, and I can show that at 20000, it becomes 1, but it still runs the while loop.
So what gives?
I just updated easyC to 3.0.1.1
I haven't tried this in the old version. Of course the same task in MPLab worked, and took half the time then clicking and dragging If statements....
Jacob
well this might be wrong but isnt the operator control function called from one big while loop in main?
you might want to put all of that in a function then in opcon do a
int i = 0;
while(1)
{
if i ==0
function();
i++;
}
dpick1055
04-02-2007, 00:49
While I have never worked in Easy C my best guess would be that it needs some sort of end while statement. While it doesn't seem likely cause C doesn't have a end while command I know it is in other languages so it's worth a shot. :D Good luck getting that working.
mluckham
04-02-2007, 00:52
GetTimer returns an unsigned long. Your timer variable is an int.
Does that make a difference?
whytheheckme
04-02-2007, 00:55
Whats weird, is that using the Wait block works. Just replacing the while loop with this block works. This is inconvenient though, because if you want to do anything with this time, you can't.
Perhaps it is the enclosing loop... I'll try this.
Thanks,
Jacob
Eric Finn
04-02-2007, 00:58
Do while 1, and have an if statement in your while loop, something like
if(!(timer < 20000))
{
break;
}
to break out of the loop
whytheheckme
04-02-2007, 00:59
Mmmmm.... About the unsigned long...
It was correct in my real code... I remember changing that. Sorry my sudo wasn't updated.
Whats weird is that it wasn't the timer. I used the timer to change another variable from a 0 to a 1, which was a change you could see with a print statement. The while loop simply said while(done ==0) { yadda yadda }
and you would see done change from 0 to 1 without leaving the loop....
It's just bizzare.
Jacob
whytheheckme
04-02-2007, 01:00
Do while 1, and have an if statement in your while loop, something like
if(!(timer < 20000))
{
break;
}
to break out of the loop
Yeah...... I forgot about break. Thanks for the idea!!!
Jacob
mluckham
04-02-2007, 01:06
If your 'done' variable was changing by itself, then perhaps the gyro call is assigning a variable of the wrong type ... if that variable is immediately adjacent in memory to the 'done' variable, the overflow would affect it.
This normally wouldn't be possible with a compiler like EasyC, which doesn't use pointers (well, it doesn't let US use pointers).
Please post the exact code - C code preferrably.
Mike
BTW - PSEUDO-CODE, not SUDO (but probably you know that)
TimCraig
04-02-2007, 01:11
Sorry my sudo wasn't updated.
Just so you know, it's pseudo code. :rolleyes:
whytheheckme
04-02-2007, 01:13
If your 'done' variable was changing by itself, then perhaps the gyro call is assigning a variable of the wrong type ... if that variable is immediately adjacent in memory to the 'done' variable, the overflow would affect it.
Yeah... This would make sense. Althought printing out the value of done yielded 1.
BTW - PSEUDO-CODE, not SUDO (but probably you know that)
lol yeah... Sudo is sudo for pseudo... hence sudo (my aim at a joke... perhaps a few hours of sleep would be more humorous to my team members...) OK that was pretty lame. I'll go back to using pseudo.
mluckham
04-02-2007, 01:28
Looking only a pseodo-code can lead one to erroneous results.
I once worked on a project where every module was coded, and had to have COMPLETE pseudo-code in the file header as well. Endless hours were spent making sure the two lined up.
Of course the programmers only looked at the code, knowing the pseudo-code would sometimes be wrong.
Recently I had a variable that mysteriously changed values, in a loop like yours. This was using MPLAB. Turned out there were two variables with exactly the same name, one in local scope and one in global scope. The compiler never hinted of the conflict (well, that's my story and I'm sticking to it!). Of course the global one was being updated (by an external .C routine) and the local one was read by the printf ... since it was on the stack and there were interrupts in the system, it always contained garbage.
The operator control routine in EasyC is run and run and run. If you exit, it will just call it again for you. To stop that behavior add something like the following to the end after the print done.
while (1) ;
paulcd2000
04-02-2007, 11:17
i dunno much about easyC, but in MPlab, while loops are never a good thing. They have a tendency to cause the motors not to get data. If that's not the case in EasyC, then ignore me. Otherwise, use if statements
i dunno much about easyC, but in MPlab, while loops are never a good thing. They have a tendency to cause the motors not to get data. If that's not the case in EasyC, then ignore me. Otherwise, use if statements
Thats not the case in EasyC - EasyC documentation indicates Getdata and Putdata is done in the background automatically for you.
Tom Line
04-02-2007, 14:51
I know it's suedo code and all, but if you have that int timer=0 inside routine, won't it re-initialize itself every time?
So yeah, it'll get to 20k and kick out of your while loop, but the next time it comes back through the routine it will re-initialize itself to zero and start all over again.
b_mallerd
05-02-2007, 00:51
I've never managed to implement a while loop yet for robot coding.
My recommendation would be to just use if statements and print it out as you go...
e.g
if(timer < 20000)
{
printf("Timer is: %d, Gyro is %d",timer,gyro);
}
...err or however you would do that in easyC
Timer will update itself so it would just print every time the controller loops.
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.