Printable Version | Subscribe | Add to Favourites
<<  1    2    3  >>
New Topic New Poll New Reply
Author: Subject: Any Atmel AVR C programmers on here?
AdrianH

posted on 7/1/10 at 10:39 PM Reply With Quote
I have tried something simple to check out the maths bit, that is to see how the compiler is dealing with the division by 2.5.


So I used xacc = (500/2.5)-196 and the answer on the screen was 4

So it looks as though the compiler is dealing with the decimal divide correctly.

This was my thinking. If it trunkated the 2.5 to 2 the answer would have been 54

If it rounded 2.5 up to 3 then the anser would have been -29

I then checked with xacc = (600/2.5)-196 and the answer on the screen was 44. This just seeming to confirm the bit above.

I then used xacc = (303/2.5)-196 On a calculator the answer is -74.8 and the display is -74 s

xacc = (503/2.5)-196 indicates 5 on the display(should be 5.2)

So it is showing that the compiler uses what ever number type it thinks is correct, but then chops the decimal point for the integer required result. I think this is good as the error should be minimised.

Adrian
o it is indicating to me that





Why do I have to make the tools to finish the job? More time then money.

View User's Profile View All Posts By User U2U Member
Madinventions

posted on 7/1/10 at 10:57 PM Reply With Quote
I think that when the compiler sees '2.5' it knows it has to do the calculation with floating point math. If you put in a '2' it would use integer math.
The reason it is losing the decimal after conversion is that xacc is defined as an integer.
If speed isn't an issue and you're not trying to conserve memory, then floating point will be fine. Integer math will be considerably faster, but the conversion to readable format is a bit more involved as we've seen.

Try making xacc a float variable, and use ftoa() instead of itoa(). You should get decimal values on your display if that's what you want.

Ed.





Mojo build diary: http://www.madinventions.co.uk

Solo music project: Syrrenfor http://www.reverbnation.com/syrrenfor

View my band website:
http://www.shadowlight.org.uk

http://www.eastangliankitcars.co.uk/

View User's Profile Visit User's Homepage View All Posts By User U2U Member
AdrianH

posted on 8/1/10 at 12:02 AM Reply With Quote
Sorry for not getting back to you before.

Just playing around a bit more with code and following one of your previos posts on why I got the 26612 number.

and as you said it must be down to the type of ADC.

Using another variable as

int16_t acc =0;

then in the code

xacc= (acc-480)/2.5 it all works as expected.

Using the time to go through the posts and slowly learn by trying it all out step by step and trying to follow what is happening. Time for sleep I think and more tomorrow, I will look for ftoa in the complier liberies and see if in there and how it works etc.





Why do I have to make the tools to finish the job? More time then money.

View User's Profile View All Posts By User U2U Member
MikeRJ

posted on 8/1/10 at 01:17 PM Reply With Quote
quote:
Originally posted by AdrianH
I have tried something simple to check out the maths bit, that is to see how the compiler is dealing with the division by 2.5.


So I used xacc = (500/2.5)-196 and the answer on the screen was 4

So it looks as though the compiler is dealing with the decimal divide correctly.



Right, in this case both sides of the floating point calculation are constants, so the compiler is free to make this calculation itself and replace the calculation with the integer result i.e. the actual code it compiles will be:

xacc = 200-196;

This is very handy as it allows you to make the compiler do all sorts of floating point calculations and as long as the result is constant it should all be optimised out.

quote:
Originally posted by AdrianH

xacc= (acc-480)/2.5 it all works as expected.



Here you have a non-constant floating point division, so the compiler has no choice to but to implement this. Check your code size and execution speed, it's probably an order of magnitude slower than the first expression. There is a simple fix, scale everything to avoid floating point values e.g.

xacc= ((acc-480) * 2)/5;

If acc is an unsigned value you can force the use of a bitwise shift to replace the multiply (though multiplications on the ATmega are pretty fast) e.g.

xacc= ((acc-480)<<1)/5;

If this doesn't reduce you code size it's possible you have other floating point operations and the floating point library is still being included.


If you are interested in writing to SD cards with the ATmega there is a lot of information and code here.

[Edited on 8/1/10 by MikeRJ]

View User's Profile View All Posts By User U2U Member
AdrianH

posted on 8/1/10 at 07:44 PM Reply With Quote
Thanks for the input Mike.

I had a bit of time and stripped off of the superflous code out of this programme, I had it answering pings and had a web page etc.

So now all it will actually do is use the ADC and write the results to the screen

The programme was just over 3 K at 20%

With the change so not using 2.5 as above reduced to 9% at 1.5 K sh programme.

Speed has not really increased but this will be down to use of simple delays I have so I can read the LCD.

Cheers

Adrian





Why do I have to make the tools to finish the job? More time then money.

View User's Profile View All Posts By User U2U Member
<<  1    2    3  >>
New Topic New Poll New Reply


go to top






Website design and SEO by Studio Montage

All content © 2001-16 LocostBuilders. Reproduction prohibited
Opinions expressed in public posts are those of the author and do not necessarily represent
the views of other users or any member of the LocostBuilders team.
Running XMB 1.8 Partagium [© 2002 XMB Group] on Apache under CentOS Linux
Founded, built and operated by ChrisW.