how to perform calculations with an atmega?

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi,

 

right now i can receive and show a voltage on a lcd.

but i have to do some calculations with the input before showing them on the lcd now.

 

attached is a curve

x-axis is the input and the y-axis represents the data i want to show on the lcd

i added a line of best fit and the formula for that line is to the power of 4

 

"y = 0.00000000001661249863*pow(x,4)- 0.00000012009735767385*pow(x,3)+ 0.00033807921726585*pow(x,2)- 0.482076867931636*x+339.419792445089; "

 

now i am using the formula to calculate my output for the lcd.

 

-is it to complex for an atmega (324pa or others) to do the calculation? the result is getting inaccurate when x is getting higher!

 

-should i do linear approximation between my the points to get y?

 

or is there any other way how to solve this with an atmega?

 

-sl00k

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, 2.5 Gigavolts! That's impressive. And/or measured with a 32-bit ADC.

 

Perhaps you ought to tell us...

 

1) What your input range really is.

2) What you output range is.

3) What precision you require.

4) What accuracy you require.

5) How long your calculation can take.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

Last Edited: Thu. Sep 21, 2017 - 04:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sl00k wrote:
-is it to complex for an atmega (324pa or others) to do the calculation? the result is getting inaccurate when x is getting higher!

An AVR8 is...an 8-bit processor.

 

That said, many/most calculators, historically, are based on 4-bit and 8-bit microprocessors.

 

You haven't said which language and toolchain you are using.  Some/many AVR8 toochains only have "single", not "double" float precision.

 

You haven't said what accuracy you need/desire.  For general microcontroller work, the blue circles on the graph don't look that bad.

 

Apparently, you have about half a dozen data points.  When you run them through your calculations in the spreadsheet, what is the real difference, say in percent error?  What is the source of the input reading?  If e.g. AVR8 10-bit ADC result, best-case is only 0.1%.  Typical depends on your skill in designing the analog subsystem.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Thu. Sep 21, 2017 - 04:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Typical depends on your skill in designing the analog subsystem.

and to get anywhere near that theoretical 0.1% best case would require quite a lot of skill ... 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unless I've made a mistake the OP is going to need to be using a maths package with 36 bits of precision.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

Unless I've made a mistake the OP is going to need to be using a maths package with 36 bits of precision.

 

Scrub that. That's 36 bits after the decimal point.

 

 

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
Wow, 2.5 Gigavolts!

Or just in/with a locale where a comma is use as the decimal mark.. Among others, that would be more or less all of continental Europe (including the Nordic Countries).

 

Decimal separator around the world

 

Blue: point, Light/Bright Green: comma, Red: other, Grey: Data unavailable. Canada is "mixed": point when using the English language, comma when using the French.

 


 

Or, if you like...

 

Brian Fairchild wrote:
Wow, 2.5 Gigavolts!

 

Hey, your thousands marker is not making any sense there! ;-)

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Thu. Sep 21, 2017 - 04:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the code is written in c and i use the native toolchain from atmel studio 7

the input is from a Distance Measuring Sensor Unit which is connected to a 12bit adc, connected over i2c to the atmega

 

the x-axis is in mV

 

input range is from x = 2640mV to 590mV

output range is from y= 20cm to 150cm

5% precision is already good enough for now (whats the difference to accuracy?)

the calculation can take up to 500ms

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sl00k wrote:
5% precision is already good enough for now (whats the difference to accuracy?)
theusch wrote:
Apparently, you have about half a dozen data points. When you run them through your calculations in the spreadsheet, what is the real difference, say in percent error?

At a quick glance, Id say you are already almost done.

 

I'm a little rusty, and would need to do some noodling with pencil or spreadsheet.  Perhaps the "problem" terms are the first couple, with the high exponent values.  One could factor out some powers of ten to reduce the enormous dynamic range, and then apply after the multiplication.

 

E.g. isn't

sl00k wrote:
0.00000000001661249863*pow(x,4)

 

equivalent to

16.6125 times 10e-12 times (x / 10e-3) to the fourth power times 10e12

 

[I might have missed a power or two doing it in my head] Then the 10e-12 and 10e+12 turn into 1, right?  Now you have a lot less dynamic range.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

sl00k wrote:

...12bit adc...5% precision is already good enough for now...

 

Take your 12-bit value from the ADC, divide it by 16 (shift right 4 bits) to get a 8 bit result and use that as a lookup into a 256 entry table holding 8-bit values in the range 20 to 150. Job done.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

5% precision is already good enough for now

 

There is nothing wrong with your approach, but it is perhaps better suited to working on a PC rather than an 8-bit micro.

 

An alternative approach, given the rather few data points, and the 5% range, would be to split the curve up into several segments, and do a simple linear approximation over the smaller, segmental, ranges.

 

Worst case, make every pair of data points a short segment, giving you 10 - 15 segments or so.

 

A lookup table holds the linear approx. variables for that segment.

 

JC 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

Take your 12-bit value from the ADC, divide it by 16 (shift right 4 bits) to get a 8 bit result and use that as a lookup into a 256 entry table holding 8-bit values in the range 20 to 150. Job done.

 

Done this way, if my spreadsheet is correct, the maximum error is -2.5%.

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
Done this way, if my spreadsheet is correct, the maximum error is -2.5%.

When looking at the chart that OP posted, there are only a couple outliers.  The one higher on the chart has an asterisk, as the X value didn't seem to line up with the other test points.  The only other outlier is already within ~5%.  Thus, I said OP is "done" already.  If I had to guess, the outliers had to do with measurement error and not formula error.  But hey -- we are not allowed to see the raw data.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i can make more datapoints, thats not a problem.

and more accurate, the ones i have now where done in a rush, just to see if it is possible that way.

 

thanks for the input. i can test 3 different ways now ... well, after the weekend :/

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

0.00000012009735767385

Just to note that most AVR C compilers only have 32 bit floats which offer about 7.5 significant decimal digits so a number like that will be interpreted as:

 

0.0000001200974

 

or similar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:

5% precision is already good enough for now

 

There is nothing wrong with your approach, but it is perhaps better suited to working on a PC rather than an 8-bit micro.

 

An alternative approach, given the rather few data points, and the 5% range, would be to split the curve up into several segments, and do a simple linear approximation over the smaller, segmental, ranges.

 

Worst case, make every pair of data points a short segment, giving you 10 - 15 segments or so.

 

A lookup table holds the linear approx. variables for that segment.

 

JC 

Used this method with a 32 entry table to get well under 1% precision on a thermocouple application.  Pretty simple.  Wrote a little C program to calculate the table entries from the thermocouple equation.  After you generate the table entries you can then have the same program calculate the maximum error by calculating the error half way between each pair of table entries.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Given OP's output range, 5% accuracy could be done with a 42-entry table.

2% could be done with a 102-entry table.

Use binary search.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Re-arrange your polynomial to Horner style -> Better conditioning, and no more insanely small constants, and no more pow() needed.
 

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Piecewise linear interpolation is probably the approach I would use... buy hey... I am old school.

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

y = ax^4 + bx^3 + cx^2 + dx + e

y = (((ax + b)x + c)x + d)x + e

 

and much more computationally efficient.

Letting the smoke out since 1978

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And many architectures have multiply-accumulate instructions at no extra cost compared to simple multiply, so this becomes even better.

 

But for a simple 8 bit MCU, I would go for the lookup table with linear interpolation.