Log, scale, round..... on an ATTiny26 ??

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

Could use some help if anybody has good idea:

Sampling an audio signal with 8-bit ADC, and want to take the log, then scale/round it to an 8-bit result.

So,

Log(ADC-sample)/Log(255) = Scaled-Value/255

or,

Scaled-value = Log(ADC-sample)/Log(255)*255

Then rounded to closest integer.

So, as examples:

If ADC reads 256, I want to display 256
If ADC reads 128, I want to display 223
If ADC reads 40, I want to display 170
If ADC reads 10, I want to display 106
If ADC reads 1, I want to display 0

Also - I'm using the ATTiny26 in assembler, where there's no MUL instruction.

Have looked at a few piece-wise linear algo's but difficult to implement w/o MUL. Hate to use 256 bytes for a full lookup table as I'm short on code-space already.

Any thoughts would be greatly appreciated!

-mark

Mark
Elgin, IL (near Chicago)

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

You might consider calculating the exponential function (which might be easier to code). Then you have to step through the displayable values to "match" up with your ADC value. Might be slow, but might work well for you. don't worry about multiplication --there are many good mult routines floating around (see Atmel's site too).

see this--good clues:
http://www.embeddedrelated.com/u...

http://www.efunda.com/math/taylo...

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

Quote:
Hate to use 256 bytes for a full lookup table as I'm short on code-space already.

I don't see that implementing floating point routines will save you that much over the look-up table, floating point routines can take up a lot of space. But you could cut the look-up table in half. Do two tables, one that is a straight look-up table for ADC values 1 to 64. This gives you output values from 0 to 191. Then do a second 64 byte table that is a reverse look-up. These 64 entries represent output values from 192 to 255. The value of these entries is the ADC input value. You do a search through this table to find the closest match to the input value. The output value is then the index of the found value plus 192. Using a binary search you can find the value in 6 tries. It gives you the exact same accuracy as the full look-up table, but takes much less time (and possibly less space) than doing the floating point math.

Regards,
Steve A.

The Board helps those that help themselves.

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

Another 'trick' I've come across is the piecewise method whereby you divide the input into a number of ranges then manipulate the value.

For example:

if value is >0 and <50
return value
if value >50 and <100
return value * 2
if value > 100 and < 200
return value + 0.75 value
if value >200
return value.

Don't trust the numbers here - I'm just trying to illustrate the technique. The multiplies can all be done with shifts and adds. You'll have to sit down and nut this one out! Its quick and not so nasty.