Can anyone walk me through a quick 'Idiots guide to Lookup Tables'?


I've been reading up on lookup tables, but most of the stuff I've read has been to advanced, or a brute force approach which I'm trying to avoid.

Here is my goal:

I have a tempmin and tempmax that I've mapped to a variable with PWM

voltage = map(temp, tempMin, tempMax, 0, 255);

What I am trying to do is display either a percentage or actual voltage based off the PWM. Which is easy right?

voltageDisplay = map(temp, resMin, resMax, 0, 11.8);
lcd.print(F("Voltage: "));
lcd.print(voltageDisplay, 0);

Except it's not linear. I probably need to get more data points, but I took 34 points in testing and came up with a quick chart. There are no test points below 1.5v so it's a straight line to 0, and on the upper end I widened the test points as there was very little voltage change for the larger PWM increases, but you can tell in the chart that there are flat spots.

Can someone explain in layman's terms how to accomplish my goal? I can probably muddle through but I doubt that it would be an efficient solution....

Eventually I would like to base my PWM voltage control off of the temperature and convert it to a linear output (i.e. 1c° increase = 1v increase) As right now my increase for 1c° would be close 5.5v on the bottom end and less than 0.5v on the top end. But hopefully if I can figure out lookup tables for my display voltage, I would be able to in turn use those as a control method based off of percentages. Or at least that's what the hamster wheel in my head is squeaking....

The first thing you need it to determine if the table is ordered, low value to high value, or high value to low value, for the entry you are going to look up. Or is the table order random?

Are the look-up values in the table unique? If you are going to do a look-up in a table with duplicated entries, a table is of no use to you.


I would assume that the values are low to high, unless I'm misunderstanding you. Which is quite possible, I'm new to programming...

0 PWM = 0v
255 PWM = 11.8v

I'm not sure I understand the unique values question? Are you asking if at a PWM of say 25, it would be possible to return a voltage of 5.5 and 6? If so, then no all of the values should be unique. Even a PWM increase of 1 should net me a voltage increase of a minimum of 0.001 at the highest scale (i.e. PWM 254 to 255).

You have mapped values, but I don't see where you have placed anything into a table. What does your 'table' look like?


Ah, that was my question :slight_smile:

How do I create a table, and how would I go about using said table to display a 0-255 PWM value (based off of the voltage variable above) to a 0-11.8 output.

would it be something like this? I've never written a lookup table, so this is just guess work and plagiarizing others work from the forums :slight_smile: any mistakes are wholly mine!

// look-up tables for mapping readings to measurements
int[] theArray = {
  11.8, 255,
  11.6, 240,
  11.5, 220, 
  11.3, 200, 
  11.2, 180, 
  11.0, 160, 
  10.8, 140, 
  10.6, 120, 
  10.1, 100,
  9.4, 80, 
  8.5, 60, 
  7.0, 40, 
  4.6, 20, 
  3.0, 10, 
  1.4, 5,
  0, 0

I see what you are asking for. Actually, the graph looks suspiciously like a logarithmic curve. So if you don't need calibrated accuracy, you might be able to just calculate it. But the chart shows voltage vs. PWM so I'm not sure it represents the input or output data more honestly. I think you did talk about it, but I'm not sure.

Anyway, it rings alarm bells in my brain about your sensor circuitry. Is it normal? A lot of sensors are linear or almost linear. Maybe the curve is a result of non-linear biasing, such as a resistor circuit? If so, you could change the circuit to make it linear and make your life easier.

The circuit is a buck convertor. The non-linear curve is probably my fault, I'm not an engineer, but I designed and built the circuit.

The voltage is tested on the output side of the circuit, 11.8 was my max output voltage at 100% duty cycle with an input voltage of 11.9.

It takes 12v in from a ATX PSU and based on the PWM duty cycle converts it to a linear voltage out. The voltage curve probably has something to do with the size of inductor and capacitor, plus the fact that the test was run at around 10 amps, the actual circuitry will see a max of 20 amps for one leg and 10 amps each for the other two, so I'll have to go through and retest once I have all the components ready. I was just trying to get a jump on the programming side so that I have an idea of what I'm doing once I have usable results to plot with.

Well, it may not be so much a fault as an inherent characteristic. If you look up logarithm on wiki, the first thing that leaps out at you is a graph that looks almost exactly like yours. :slight_smile:

I’ll make sure to do that!

I’ve uploaded a picture of my circuit, seems like you’re a bit more experienced than I am :slight_smile: I’ve already blown up a few components by not thinking about the transient voltage spikes… had to add that snubber in there to get it low enough to stop blowing up mosfets and drivers… oops :blush: .

But if that truly is a value that I can calculate… that would probably make my life way easier!

I’d still like to know about lookup tables, each time I think I’ve got my project on track something else pops up that I want to learn about!

You better have good shielding and RFI suppression around it, or you'll have the FCC (or equivalent) sniffer truck snooping around your neighborhood.

Why is that? That's a pretty common circuit is it not? Am I missing something completely? lol (and yes it would be the FCC :slight_smile: )

or you'll have the FCC (or equivalent) sniffer truck snooping around your neighborhood

Not enough money in the budget for that :wink:

Maybe you could use LINEST in EXCEL to come up with the equation of the curve and use it in your sketch.

LINEST? I'll have to look it up, I'm beating my head against logarithm's, but I'm just coming away bloody, nothing sinking in....

So, you are just measuring the voltage on the PWM output and comparing that to the number you are putting into analogOut?

I'm not an electronics person, but that is going to do freaky weird stuff if your voltage meter has any capacitance or inductance. Which it will do.

I'm measuring the voltage out of the Buck convertor. (I.E. I'm measuring voltage right at the load). The PWM voltage is what it is, 5v as defined by the Arduino, I can change that to 12v on my circuit by using a driver (which I did) to run the MOSFET to ensure full switching.

That circuit is actually a bit old, I've since updated to a logic level MOSFET to get the Vcc for the driver off of my 12v line as I was still worried about transient voltage spikes.

All I'm trying to do is set the PWM duty cycle based off of a temperature, which is easy, and display what the output voltage of the buck convertor is on a screen, which is kicking my butt.

I know that there is a way to calculate this, or use lookup tables. But I can't for the life of me figure it out yet. Eventually a light bulb will go off (probably after someone walks in the thread and flips the switch on...), but for now I'm stuck reading and attempting to understand.

I could cheat and use a volt meter and return that value to the arduino, but I don't really want to add another component, especially when this is well within the arduino's capabilities, I'm just not smart enough to figure it out yet.

alright, I give up. Logarithm's are beyond me right now. I just can't wrap my head around it, or I've failed to find an example that I can relate to.

Back to lookup tables. I'll shelve the logarithm idea for the moment and come back to it when I've had some more sleep.

How would I go about creating a lookup table for 0-255 and 0-11.8 volts, non linear, and then reference said lookup table for a display based on the value of the PWM output (0-255)? Anyone?

Sure, just put your data into an Excel spreadsheet, develop the numbers you want to look up, and put then into an array. Pretty simple.

Ironically I was just reading your posts here:


Where does the array go in the sketch?

Would that go into my declarations section, prior to setup?

So something like this?

/* Include needed libraries */

#include somelibraryhere

float Varray[32] = {
2, 1.5, 
5, 2.24, 
10, 3, 
20, 4.6, 
30, 5.9,  
40, 6.9, 
50, 7.75, 
60, 8.4, 
70, 8.9, 
80, 9.4,
100, 10,
120, 10.5,
140, 10.8,
175, 11.2,
200, 11.35,
225, 11.5,
255, 11.8,};

some code here


for (x= 0; x<18; x=x+2){
 if (Vread >=Varray[x] && Vread <=Varray[x+2])
   calcvolt = Varray[x+3] + ( (Varray[x+1] - Varray[x+3]) * ( (Vread - Varray[x]) / (Varray[x+2] - Varray[x]) ) )
// temp = base temp + (high temp- base temp) * (Vread - Vbase) / (Vhigh - Vbase)

Some things I’m fuzzy on.
-Where does x come from and how do I declare it?
-What is the Varray[x+3]? Not that specifically, but all of the [x+?]
-Is the formula: voltage = (((reading - PWMArrayBelow) * ( VoltageArrayAbove - VoltageArrayBelow)) / (PWMArrayAbove - PWMArrayBelow) + VoltageArrayBelow

I guess that’s why I’m confused as to the [x+?]
Obviously I would have to declare Vread, but could I just use my PWM declaration of voltage since that is what is printing the analogwrite?

voltage = map(temp, tempMin, tempMax, 0, 255);
analogWrite(Pin9, voltage);

Think what you want your look up table to do. You have an input value and an output value.

Your input value is the index of your array. Your output value is the contents of that array location.
So you need an array entry for every possible input value. If this is the PWM value then you need 256 elements in that array. Each element will have the value of the output voltage for that value of PWM.

If this number is a float this array will take up 1K of SRAM, half the space on an arduino so look to put it in program memory.