While loop glitch
Moderator: Benj
-
- Posts: 162
- Joined: Thu Jul 01, 2010 1:57 am
- Has thanked: 23 times
- Been thanked: 16 times
- Contact:
While loop glitch
I have written a program to sound a buzzer (duration and pitch). The while loop controls the duration. The loop count is calculated. But when it is run in simulation, the variable evaluates to zero, and bypasses the loop. Can't figure it out. The program is attached.
Thanks in advance.
Thanks in advance.
- Attachments
-
- Buzzer_V3.fcfx
- (14.69 KiB) Downloaded 324 times
-
- Posts: 444
- Joined: Tue Apr 15, 2014 4:19 pm
- Location: Kajaani, Finland
- Has thanked: 345 times
- Been thanked: 227 times
Re: While loop glitch
Have you seen this btw?
But seems that your code fails to evaluate the floor thing there? It could be that its atmel specific code part:
But seems that your code fails to evaluate the floor thing there? It could be that its atmel specific code part:
Atmel.com site wrote:The floor() function returns the largest integral value less than or equal to __x, expressed as a floating-point number
Ill just keep the good work up!
-
- Matrix Staff
- Posts: 9521
- Joined: Sat May 05, 2007 2:27 pm
- Location: Northamptonshire, UK
- Has thanked: 2585 times
- Been thanked: 3815 times
Re: While loop glitch
I don't know if i'm missing something here?
If you look at the calculation: You will see you have
I agree with that, but then you have
Since .Period_MicroSeconds is 2272 and not .00272 then loops = 100/2272 = 0.004 hence loop count = 0
The nearest I can get is
Simulation result is 50 and not 44, not sure why?
So issue appears to be within the calculations?
Martin
If you look at the calculation: You will see you have
Code: Select all
.Period_MicroSeconds = 1000000 / .Frequency_Hz = 1000000/440 = 2272
Code: Select all
Num_PeriodsF = floor (.Duration_MilliSec / .Period_MicroSeconds) = 100/.000272
The nearest I can get is
Code: Select all
.Num_PeriodsF = .Duration_MilliSec / (.Period_MicroSeconds / 1000)
So issue appears to be within the calculations?
Martin
Martin
-
- Posts: 162
- Joined: Thu Jul 01, 2010 1:57 am
- Has thanked: 23 times
- Been thanked: 16 times
- Contact:
Re: While loop glitch
Thanks. It simulates OK, but does not run on an UNO when I use .Num_Periods in the do_while loop. However if I change the loop counter to "44" it works on the UNO. I thought that since the .Num_Periods is an integer, that the number 44.01 would be cast to an integer, 44. Apparently not. I wonder how I can change 44.01 to an integer 44?
-
- Posts: 162
- Joined: Thu Jul 01, 2010 1:57 am
- Has thanked: 23 times
- Been thanked: 16 times
- Contact:
Re: While loop glitch
The following where .Num_PeriodsF is a float, does not work also.
".Num_PeriodsF = 1000 * .Duration_MilliSec / .Period_MicroSeconds // Periods = 1000*100 /.002272 = 44.01
.Num_Periods = float2int (.Num_PeriodsF) "
Dang.
".Num_PeriodsF = 1000 * .Duration_MilliSec / .Period_MicroSeconds // Periods = 1000*100 /.002272 = 44.01
.Num_Periods = float2int (.Num_PeriodsF) "
Dang.
-
- Posts: 162
- Joined: Thu Jul 01, 2010 1:57 am
- Has thanked: 23 times
- Been thanked: 16 times
- Contact:
Re: While loop glitch
Nor does this work on the UNO: where variables ending in F are floats.
.Period_MicroSecondsF = 1000000 / .Frequency_Hz // Example Period = 1000000/440 = 2272.72... microseconds
.Num_PeriodsF = 1000 * .Duration_MilliSec / .Period_MicroSecondsF // Periods = 1000*100 /.002272 = 44.01
.Period_MicroSeconds = float2int (.Period_MicroSecondsF)
.Num_Periods = float2int (.Num_PeriodsF)
.Period_MicroSecondsF = 1000000 / .Frequency_Hz // Example Period = 1000000/440 = 2272.72... microseconds
.Num_PeriodsF = 1000 * .Duration_MilliSec / .Period_MicroSecondsF // Periods = 1000*100 /.002272 = 44.01
.Period_MicroSeconds = float2int (.Period_MicroSecondsF)
.Num_Periods = float2int (.Num_PeriodsF)
- LeighM
- Matrix Staff
- Posts: 2178
- Joined: Tue Jan 17, 2012 10:07 am
- Has thanked: 481 times
- Been thanked: 699 times
Re: While loop glitch
Hi,
Your variables that are not floats are INT, so are limited to -32768 to 32767
So any temporary calculations will be limited to 16 bit integer on the UNO
Also ".Duration_MilliSec / .Period_MicroSeconds" can only give an integer result.
You will need to break down the steps of the calculations and consider the precision at each step,
and also change the ints to long ints where needed.
Your variables that are not floats are INT, so are limited to -32768 to 32767
So any temporary calculations will be limited to 16 bit integer on the UNO
Also ".Duration_MilliSec / .Period_MicroSeconds" can only give an integer result.
You will need to break down the steps of the calculations and consider the precision at each step,
and also change the ints to long ints where needed.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: While loop glitch
Also in addition to Leigh's post,
the 1000000 is an integer value, to cast the number as a float add the real portion of the number.
Code: Select all
1000000 / .Frequency_Hz
Code: Select all
1000000.0 / .Frequency_Hz
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 162
- Joined: Thu Jul 01, 2010 1:57 am
- Has thanked: 23 times
- Been thanked: 16 times
- Contact:
Re: While loop glitch
Thanks to all. The adding ".0" helped. But there is are still issues in designing an generic program where tone frequency and tone duration are passed to a subroutine.