• Forums
• Posts
Latest Posts
Active Posts
Recently Visited
Search Results
• Page Extras
• Forum Themes
• AVR Freaks

### Hot!Possible Lookup Table Author
Tuurbo46 Super Member • Total Posts : 233
• Reward points : 0
• Joined: 2004/09/12 05:05:45
• Location: UK
• Status: offline 0

# Possible Lookup Table

Hi,

I am struggling to read an ADC value, offset this value then convert into a battery voltage.

Below are my value:

* The ADC read range i am interesting in is (1.5V - 2.4V) == (309 - 491)

* I would like to convert 309 ADC value into battery minimum voltage 10V, and 491 ADC value into battery max voltage 14.4V.  Also i would like to display all the battery voltages between 309 and 491.

At this point i do not know a conversion factor to convert ADC value into battery voltage.  Would this be an ideal application for a look up table?

Thanks,

Tuurbo46

Jan Audio Senior Member • Total Posts : 154
• Reward points : 0
• Joined: 2018/09/24 08:12:24
• Location: 0
• Status: online Re: Possible Lookup Table 2019/07/08 06:19:26 (permalink)
+1 (1)
Yes why not, how else, if it fits your chip.
Make sure in your code you dont read outside the table by accident.
post edited by Jan Audio - 2019/07/08 06:21:23
NKurzman A Guy on the Net • Total Posts : 18773
• Reward points : 0
• Joined: 2008/01/16 19:33:48
• Location: 0
• Status: online Re: Possible Lookup Table 2019/07/08 06:26:17 (permalink)
+1 (1)
You can always use a lookup table.
But that will take us 1-2K of Core for 10 bits for a full table.
Another option is algebra. Y=mX+b
The point point or slope slope formula should get you m and b.
And work in millivolts so you can avoid floating point.
1and0 Access is Denied • Total Posts : 10902
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline Re: Possible Lookup Table 2019/07/08 06:50:34 (permalink)
+1 (1)
Google "finding the equation of a line given two points". ;)

Tuurbo46 Super Member • Total Posts : 233
• Reward points : 0
• Joined: 2004/09/12 05:05:45
• Location: UK
• Status: offline Re: Possible Lookup Table 2019/07/08 07:32:16 (permalink)
0
Hi,

Using y = mx + c i have come up with the below. The end points are not correct though.

* I would like to convert 309 ADC value into battery minimum voltage 10V, and 491 ADC value into battery max voltage 14.4V. Also i would like to display all the battery voltages between 309 and 491.

* y = 309 * 0.03 = 9.27V

* y = 491 * 0.03 = 14.73V

Is this the correct method of conversion?  I will update to mV if this is correct.

Thanks,

Tuurbo46
Jan Audio Senior Member • Total Posts : 154
• Reward points : 0
• Joined: 2018/09/24 08:12:24
• Location: 0
• Status: online Re: Possible Lookup Table 2019/07/08 07:36:20 (permalink)
0
A lookuptable has instant text.
If you dont care about speed go ahead and make things difficult.
pcbbc Super Member • Total Posts : 1698
• Reward points : 0
• Joined: 2014/03/27 07:04:41
• Location: 0
• Status: offline Re: Possible Lookup Table 2019/07/08 07:59:04 (permalink)
0
voltage = 10 + (adc_value - 309) x 4.4 / 182
davekw7x Entropy++ • Total Posts : 1877
• Reward points : 0
• Joined: 2012/01/16 12:01:07
• Location: Second star on the right, straight on till morning
• Status: offline Re: Possible Lookup Table 2019/07/08 09:22:57 (permalink)
+1 (1)
Tuurbo46

convert ADC value into battery voltage

The idea is to avoid floating point calculations and floating point print functions at run time.

You can do calculations off-line in floating point arithmetic and put rounded integer values in a lookup table.  Will be fast.  Table of 183 16-bit ints takes 366 bytes.
Or you can use integer arithmetic in your code.  Results will be less accurate.  I kind of doubt that you will save much program memory, but you can check it out

Maybe this can get you started (From a little program I whipped up to get comparative results):

Line equation is y = m*x + b
Where m = slope, b = y-intercept
Given
(x0,y0) = (309,10000)
(x1,y1) = (491,14400)
Then
Floating point  : m = 24.1758, b = 2529.67
Rounded integer : m = 24,      b = 2530

Rounded Float      Int Arithmetic
Use Table     Calculate at Run Time
(309,10000)        (309, 9946)
(310,10024)        (310, 9970)
(311,10048)        (311, 9994)
(312,10073)        (312,10018)
(313,10097)        (313,10042)
(314,10121)        (314,10066)
(315,10145)        (315,10090)
(316,10169)        (316,10114)
(317,10193)        (317,10138)
(318,10218)        (318,10162)
(319,10242)        (319,10186)
(320,10266)        (320,10210)
(321,10290)        (321,10234)
(322,10314)        (322,10258)
(323,10338)        (323,10282)
(324,10363)        (324,10306)
(325,10387)        (325,10330)
(326,10411)        (326,10354)
(327,10435)        (327,10378)
(328,10459)        (328,10402)
(329,10484)        (329,10426)
(330,10508)        (330,10450)
(331,10532)        (331,10474)
(332,10556)        (332,10498)
(333,10580)        (333,10522)
(334,10604)        (334,10546)
(335,10629)        (335,10570)
(336,10653)        (336,10594)
(337,10677)        (337,10618)
(338,10701)        (338,10642)
(339,10725)        (339,10666)
(340,10749)        (340,10690)
(341,10774)        (341,10714)
(342,10798)        (342,10738)
(343,10822)        (343,10762)
(344,10846)        (344,10786)
(345,10870)        (345,10810)
(346,10895)        (346,10834)
(347,10919)        (347,10858)
(348,10943)        (348,10882)
(349,10967)        (349,10906)
(350,10991)        (350,10930)
(351,11015)        (351,10954)
(352,11040)        (352,10978)
(353,11064)        (353,11002)
(354,11088)        (354,11026)
(355,11112)        (355,11050)
(356,11136)        (356,11074)
(357,11160)        (357,11098)
(358,11185)        (358,11122)
(359,11209)        (359,11146)
(360,11233)        (360,11170)
(361,11257)        (361,11194)
(362,11281)        (362,11218)
(363,11305)        (363,11242)
(364,11330)        (364,11266)
(365,11354)        (365,11290)
(366,11378)        (366,11314)
(367,11402)        (367,11338)
(368,11426)        (368,11362)
(369,11451)        (369,11386)
(370,11475)        (370,11410)
(371,11499)        (371,11434)
(372,11523)        (372,11458)
(373,11547)        (373,11482)
(374,11571)        (374,11506)
(375,11596)        (375,11530)
(376,11620)        (376,11554)
(377,11644)        (377,11578)
(378,11668)        (378,11602)
(379,11692)        (379,11626)
(380,11716)        (380,11650)
(381,11741)        (381,11674)
(382,11765)        (382,11698)
(383,11789)        (383,11722)
(384,11813)        (384,11746)
(385,11837)        (385,11770)
(386,11862)        (386,11794)
(387,11886)        (387,11818)
(388,11910)        (388,11842)
(389,11934)        (389,11866)
(390,11958)        (390,11890)
(391,11982)        (391,11914)
(392,12007)        (392,11938)
(393,12031)        (393,11962)
(394,12055)        (394,11986)
(395,12079)        (395,12010)
(396,12103)        (396,12034)
(397,12127)        (397,12058)
(398,12152)        (398,12082)
(399,12176)        (399,12106)
(400,12200)        (400,12130)
(401,12224)        (401,12154)
(402,12248)        (402,12178)
(403,12273)        (403,12202)
(404,12297)        (404,12226)
(405,12321)        (405,12250)
(406,12345)        (406,12274)
(407,12369)        (407,12298)
(408,12393)        (408,12322)
(409,12418)        (409,12346)
(410,12442)        (410,12370)
(411,12466)        (411,12394)
(412,12490)        (412,12418)
(413,12514)        (413,12442)
(414,12538)        (414,12466)
(415,12563)        (415,12490)
(416,12587)        (416,12514)
(417,12611)        (417,12538)
(418,12635)        (418,12562)
(419,12659)        (419,12586)
(420,12684)        (420,12610)
(421,12708)        (421,12634)
(422,12732)        (422,12658)
(423,12756)        (423,12682)
(424,12780)        (424,12706)
(425,12804)        (425,12730)
(426,12829)        (426,12754)
(427,12853)        (427,12778)
(428,12877)        (428,12802)
(429,12901)        (429,12826)
(430,12925)        (430,12850)
(431,12949)        (431,12874)
(432,12974)        (432,12898)
(433,12998)        (433,12922)
(434,13022)        (434,12946)
(435,13046)        (435,12970)
(436,13070)        (436,12994)
(437,13095)        (437,13018)
(438,13119)        (438,13042)
(439,13143)        (439,13066)
(440,13167)        (440,13090)
(441,13191)        (441,13114)
(442,13215)        (442,13138)
(443,13240)        (443,13162)
(444,13264)        (444,13186)
(445,13288)        (445,13210)
(446,13312)        (446,13234)
(447,13336)        (447,13258)
(448,13360)        (448,13282)
(449,13385)        (449,13306)
(450,13409)        (450,13330)
(451,13433)        (451,13354)
(452,13457)        (452,13378)
(453,13481)        (453,13402)
(454,13505)        (454,13426)
(455,13530)        (455,13450)
(456,13554)        (456,13474)
(457,13578)        (457,13498)
(458,13602)        (458,13522)
(459,13626)        (459,13546)
(460,13651)        (460,13570)
(461,13675)        (461,13594)
(462,13699)        (462,13618)
(463,13723)        (463,13642)
(464,13747)        (464,13666)
(465,13771)        (465,13690)
(466,13796)        (466,13714)
(467,13820)        (467,13738)
(468,13844)        (468,13762)
(469,13868)        (469,13786)
(470,13892)        (470,13810)
(471,13916)        (471,13834)
(472,13941)        (472,13858)
(473,13965)        (473,13882)
(474,13989)        (474,13906)
(475,14013)        (475,13930)
(476,14037)        (476,13954)
(477,14062)        (477,13978)
(478,14086)        (478,14002)
(479,14110)        (479,14026)
(480,14134)        (480,14050)
(481,14158)        (481,14074)
(482,14182)        (482,14098)
(483,14207)        (483,14122)
(484,14231)        (484,14146)
(485,14255)        (485,14170)
(486,14279)        (486,14194)
(487,14303)        (487,14218)
(488,14327)        (488,14242)
(489,14352)        (489,14266)
(490,14376)        (490,14290)
(491,14400)        (491,14314)

If you want to use a table, put the y-values from the first set on each row into a table.
Like this:
`//// For 309 <= adc_reading <= 491// Volage in millivolts = vtable[adc_reading-309]//uint16_t vtable = {      10000, 10024, 10048, 10073, 10097, 10121, 10145, 10169,      // 168 more values from the previous calculations     14255, 14279, 14303, 14327, 14352, 14376, 14400 };`

In either case there is an additional step to print the value in volts (does not require floating point arithmetic or floating point print function---I'll let you figure it out).

If you want to do floating point calculations and floating point print functions at run time, I expect it to cost several K bytes and take a fair amount of run time.  Depends on which device you are using and what compiler optimization settings are available to you.

Regards,

Dave
post edited by davekw7x - 2019/07/08 09:35:55

Sometimes I just can't help myself...
mbrowning USNA79 • Total Posts : 1768
• Reward points : 0
• Joined: 2005/03/16 14:32:56
• Location: Melbourne, FL
• Status: online Re: Possible Lookup Table 2019/07/08 10:14:11 (permalink)
0
I'm curious why the intercept isn't zero. I would think you would be using a simple resistive voltage divider, but then "b" (of y=mx+b) would be zero.

I guess I can understand if you used an opamp to keep the resistor values high for minimal battery drain, but why add an offset (intercept) to the equation? Especially since the offset does not significantly increase the resolution of the ADC measurements.
pcbbc Super Member • Total Posts : 1698
• Reward points : 0
• Joined: 2014/03/27 07:04:41
• Location: 0
• Status: offline Re: Possible Lookup Table 2019/07/08 10:56:18 (permalink)
+1 (1)
mbrowning
I'm curious why the intercept isn't zero. I would think you would be using a simple resistive voltage divider, but then "b" (of y=mx+b) would be zero. I guess I can understand if you used an opamp to keep the resistor values high for minimal battery drain, but why add an offset (intercept) to the equation? Especially since the offset does not significantly increase the resolution of the ADC measurements.

I noticed this also, but didn’t ask.

I suspect measurement error/ineptitude on the part of the OP.
If you don’t know how to calculate the slope of a graph, or why when you do calculate it “the end points are not correct”, then I suspect you wouldn’t notice a non-zero intercept either.
PStechPaul Super Member • Total Posts : 2720
• Reward points : 0
• Joined: 2006/06/27 16:11:32
• Location: Cockeysville, MD, USA
• Status: offline Re: Possible Lookup Table 2019/07/09 00:47:51 (permalink)
+2 (2)
A much closer integer calculation would be m=24 and b=2600

309 => 10016 +0.016%
400 => 12200  0.000%
491 => 14384 -0.011% 1and0 Access is Denied • Total Posts : 10902
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline Re: Possible Lookup Table 2019/07/09 07:40:58 (permalink)
+3 (3)
... and multiply by 24 can be efficiently done as a sum of two shifts of 4 and 3 bits.

... or a shift of 3 bits and sum it twice.

Edit:
PStechPaul
A much closer integer calculation would be m=24 and b=2600

309 => 10016 +0.016%
400 => 12200  0.000%
491 => 14384 -0.011%

That should be -0.11% to +0.16%, or an error up to ±16 mV.  You would need a good pcb layout to have noise below that. ;)
post edited by 1and0 - 2019/07/09 10:28:56 Jump to:
© 2020 APG vNext Commercial Version 4.5