Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 19:04 17 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Loop problem.....

Author Message
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9081
Posted: 03:40am 31 Aug 2017
Copy link to clipboard 
Print this post

Hi there.

Why won't this work:

[Code]
Dim As Float x
x=0.5
Do
'Servo 1,x
Print x
Pause 100
X=X+0.1
If X=2.5 Then Exit Do
Loop
Print "Done."
[/Code]

I want it to exit the loop when X=2.5, but it does not - X just keeps getting bigger.

As you can see, I am playing with servo motors.
I am just trying to slow-up the servo arm movement so the changes are more gradual rather then sudden. I have tried with and without the DIM statement, but X gets away up to 6.5 or more and just keeps going, and I have to CTRL-C stop it. I would have expected that once X was 2.5, the loop would end and 'Done.' would get printed to the console.

I've commented out the servo command, cos the servo did NOT like figures higher then 2.5.....
Smoke makes things work. When the smoke gets out, it stops!
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1994
Posted: 03:53am 31 Aug 2017
Copy link to clipboard 
Print this post

I suspect rounding errors on anything like this - would it be possible to change it to work with integers and just divide down at the point of use?

maybe x gets to 2.500001 (or similar) and this causes your test to fail, so if you went up in wholes and tested for 25 it would avoid any maths errors.

That's what i would try first

my 2pEdited by CaptainBoing 2017-09-01
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1139
Posted: 04:44am 31 Aug 2017
Copy link to clipboard 
Print this post

I think, CaptainBoing is correct!
If X=>2.5 Then Exit Do

will do the job.


Even better:

Dim As Float x
x=0.5
Do
'Servo 1,x
Print x
Pause 100
X=X+0.1
Loop While X<=2.5
Print "Done."


Regards
Michael
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3677
Posted: 05:02am 31 Aug 2017
Copy link to clipboard 
Print this post

Yes, it's that.

This is due to the way floating point works on all computers that use it (i.e. nearly all of them).

It's been covered before on here (and is on the net of course) if you want to read up more.

John
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8604
Posted: 05:42am 31 Aug 2017
Copy link to clipboard 
Print this post

  Quote  Even better:


Not good enough - still making an assumption

try:

ABS(X-2.5)<0.000001 'any small number that works
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1139
Posted: 06:23am 31 Aug 2017
Copy link to clipboard 
Print this post

anyway, I think this shows that integers are the first choice for exit conditions.

Michael
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9081
Posted: 03:21am 01 Sep 2017
Copy link to clipboard 
Print this post

Awesome, thanks for the pointers.

Bloody floating point numbers come around to wreck my life again once more.....

This test code is working fine for slow movement of the servo arm:

[Code]
TEST2:
Dim As Float X
Do
Print "Start."
X=0.5
Servo 1,x
Pause 1000 'Allow servo to move
Do
Servo 1,x
Print X
Pause 1000
X=X+0.05
If X>=2.5 Then Exit Do
Loop
Print "Done."
Pause 2000
Loop
[/Code]

This does nothing useful at the moment - I am just playing with an idea.
Smoke makes things work. When the smoke gets out, it stops!
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 05:17am 01 Sep 2017
Copy link to clipboard 
Print this post

I had a play with some servos before.
The way i did it was to setup a timer tick that called a subroutine that did the same as your do while but then only one iteration for each timer tick.
You can then remove the pause, this is good if you need a response foreground process, especially when you have a touchscreen or buttons.
Moving the servos will then not interfere with other parts of the program as it runs in the background.
I tried to find the code i used but as it was only a test i did not save it.

Microblocks. Build with logic.
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024