Electronics > Electronics

Linearization circuit?

(1/2) > >>

xamirx:
I just recently bought a Sharp gp2y analogue Range finder for a robot project of mine. It works like a charm on its own but I'm having trouble figuring out a way for my microprocessor to handle its non-linear output. Is there possibly a circuit that converts non-linear signals into linear ones? Or would software be the only route? If so how would I approximate the non - linear transfer function? Please help! :(

JonHylands:
Go to this page:

http://www.hvwtech.com/products_resources.asp?CatID=0&SubCatID=0&SubSubCatID=0&ProductID=88

They show you how to do it...

- Jon

Admin:
Hmmmmm very good question. A hardware method would be much much better than doing it in software in terms of processing speed . . . but Im not sure how to do it either.

A quick google search brought up this interesting patent with a linearization circuit schematic
http://www.google.com/patents?id=2YcrAAAAEBAJ&dq=4241303

Let us know what you find.

The software method:
If you require precision and have a super fast processor, do the method Jon mentioned. It requires doing exponentials so its rather slow in software for some processors . . .

The software method I typically use:
If you dont require precision, just high speed, then do a linear approximation of the curve - your robot wont really care if its off 20%. You could also break the curve up into two or three segments, each with their own linearization equation to reduce error. Or do a lookup table, similar to what you would do to calculate trig functions on a microcontroller.

For a robot, I can only see you needing precision if you are doing mapping of some type . . .

JonHylands:
I used the formula in that doc to generate a lookup table:

//////////////////////////////////////////////////////////////////////
//
//      rangeTable is a 128-entry table that converts the 8-bit A/D value
//      to the corresponding range in cm.

byte const rangeTable [128] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 80, 76, 72, 68, 65, 62, 59, 57, 54, 52, 50, 48, 47,
   45, 44, 42, 41, 40, 38, 37, 36, 35, 34, 33, 33, 32, 31, 30, 30,
   29, 28, 28, 27, 26, 26, 25, 25, 24, 24, 23, 23, 23, 22, 22, 21,
   21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 17,
   16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14,
   13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 11,
   11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10};

//////////////////////////////////////////////////////////////////////
//
//      rangeFinderGetChannel
//
//      Return a converted range from the given A/D channel.
//      The conversion is done via a lookup table.

byte rangeFinderGetChannel (byte channel)
{
   byte voltage;

   set_adc_channel (channel);
   delay_us (10);
   voltage = read_adc ();
   if (voltage > 127)
      return (10);
   return (rangeTable [voltage]);
}

- Jon

Brandon121233:
use a graphing calculator with some values you previously measured (preferrably as many as possible) then in put those values into an X,Y chart graph it and find the best fit regression line, get the y=...  for the best fit line then use that with the code. It takes longer, but is more efficient that having to look up data points in an array.

Navigation

[0] Message Index

[#] Next page

Go to full version