• AVR Freaks

Hot!Possible Lookup Table

Author
Tuurbo46
Super Member
  • Total Posts : 225
  • Reward points : 0
  • Joined: 2004/09/12 05:05:45
  • Location: UK
  • Status: offline
2019/07/08 06:08:03 (permalink)
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:

* ADC read range (0V - 5V) == (0 - 1023)

* 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?

Look forward to your input.

Thanks,

Tuurbo46



#1

11 Replies Related Threads

    Jan Audio
    Starting Member
    • Total Posts : 53
    • Reward points : 0
    • Joined: 2018/09/24 08:12:24
    • Location: 0
    • Status: offline
    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
    #2
    NKurzman
    A Guy on the Net
    • Total Posts : 17485
    • 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.
    #3
    1and0
    Access is Denied
    • Total Posts : 9287
    • 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". ;)
     
    #4
    Tuurbo46
    Super Member
    • Total Posts : 225
    • 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
    #5
    Jan Audio
    Starting Member
    • Total Posts : 53
    • Reward points : 0
    • Joined: 2018/09/24 08:12:24
    • Location: 0
    • Status: offline
    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.
    #6
    pcbbc
    Super Member
    • Total Posts : 1090
    • 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
    #7
    davekw7x
    Entropy++
    • Total Posts : 1766
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Left Coast, USA
    • 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):

    x is ADC reading, y is battery voltage in millivolts
    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[183] = {
         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...
    #8
    mbrowning
    Just a Member
    • Total Posts : 1418
    • 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.

    Oh well - there's always next year
    #9
    pcbbc
    Super Member
    • Total Posts : 1090
    • 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.
    #10
    PStechPaul
    Super Member
    • Total Posts : 2290
    • 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%

     
    #11
    1and0
    Access is Denied
    • Total Posts : 9287
    • 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
    #12
    Jump to:
    © 2019 APG vNext Commercial Version 4.5