|
|
View previous topic :: View next topic |
Author |
Message |
tim_sid
Joined: 11 Apr 2014 Posts: 16
|
Weird behavior on 'less than' condition |
Posted: Thu Sep 24, 2015 11:07 am |
|
|
Hello all,
This question might sound weird but I am facing this. I have a simple piece of code running fine as long as i do not include the less than '<' condition. When I include less than condition i.e: (temp<1), pin_c6 starts toggling with unequal interval when temp is in range of 1-2 (according to code it must stay stable). If i remove less than condition the code work fine no unequal toggles. I am using ccs c 4.104 version.
Plz suggest what is going here.
Code: |
if((temp>2)||(temp<1))
{
while((temp>2)||(temp<1))
{
temp=_sample_adc();
output_low(pin_c6);
delay_ms(300);
output_high(pin_c6);
delay_ms(300);
}
output_high(pin_d3);
output_high(pin_d4); //Charger ICs turned off
output_high(pin_c6);
}
|
|
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Thu Sep 24, 2015 2:22 pm |
|
|
Hi,
How is 'temp' declared? Is it an integer? A float?
What exactly do you think the logical difference is between the outer 'If', and the inner 'While'?
What exactly do you expect the A/D will return in temp? Values of '1' or '2' are basically indistinguishable from 0 (zero). I think you need to re-think what's going on there! _________________ John
If it's worth doing, it's worth doing in real hardware! |
|
|
tim_sid
Joined: 11 Apr 2014 Posts: 16
|
|
Posted: Fri Sep 25, 2015 12:19 am |
|
|
'Temp' is float.
Once the Temp is out of range it is caught in the if condition and stays in while until it comes in range. sample_ADC is returning float value of voltage. All goes fine with exact limit i set in the code. just that unequal blinks start when i add less than condition. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19543
|
|
Posted: Fri Sep 25, 2015 1:05 am |
|
|
Aaargh.....
Honestly, floats used like this are a sure sign of somebody who has no experience of micro-controllers, and is not actually _thinking_. (sorry to be a bit rude, but it is true....).
You have an integer value coming from the ADC. Not a float. You are then spending a huge time and space converting this to a float (don't - instead use scaled integers - faster, smaller, and more accurate). Then even more time doing comparisons on these - even worse you compare them to integers.
Your comparisons, involve converting the int, to float, then performing a float subtraction. So just the two comparisons shown in each bracket, takes over 300uSec at 20MHz. Over 1500 instructions. Conversely with int32's, this is just 30 instructions. Duh. Then in fact your accuracy is _worse_ than using integer.
Use integer maths throughout. Have your values scaled to be (say) integer mV. Then the comparisons become integer comparisons >1000 etc..
You will find the code becomes enormously smaller. Massively quicker, and gives better results.
Assuming your sampling routine 'averages' some readings, then use binary divisions for these. So (for instance) 8 samples, 16 samples etc..
Your hiccup is almost certainly that things do not actually behave as you expect. First a float is very inaccurate for some value. So a value like '0.12', which seems so nice and simple, actually cannot be represented by a binary float, so gets stored as 0.1199999. Then the times can get horrendous (especially if you are performing division - /10 - float takes twice as long at * 0.1).
Float should _only_ be used when dealing with numbers in an indeterminate range. If (for instance) you have an auto-scaling DVM ADC, that can handling inputs over several decades of range, then a float may need to be used. The point about float is it stores the range details for you. Unless this is the case, so you are working with values over a fixed range, you should be using scaled integers. A scaled int32, is potentially hundreds of times more accurate than a 32bit float, and is dozens of times faster to work with.
Even on the PC, with a hardware maths co-processor, floats are _not_ used for things like financial calculations, because they introduce too much error.
I do use floats on PIC's, but only when they are necessary (logarithmic scaled sensors for example), and then only with great care (values tested for range before they get near the maths etc..).
Your approach is fundamentally flawed. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19543
|
|
Posted: Fri Sep 25, 2015 1:22 am |
|
|
It's worth perhaps pointing to this old example that I was told to explain as a student, why it'd not work...:
Code: |
float ctr;
for (ctr = 0; ctr != 0.3; ctr += 0.1)
{
//code
}
|
Shows well the 'dangers' of float and float comparisons..... |
|
|
tim_sid
Joined: 11 Apr 2014 Posts: 16
|
|
Posted: Wed Sep 30, 2015 9:52 am |
|
|
Sorry for such a late update for some other reasons.
@Ttelmah; I tried with scaled integers it didnt work but now the previous code is working. Yeah your point does make sense and noted, thanks. |
|
|
|
|
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
|