Lookup Table and Code Setup

Hello, I'm working on an assignment that deals with a lookup table. I've been supplied limited information about Arduino coding and had to do research on my own. I've search several websites and was hoping to find an example similar to mine but to no previal. I'm hoping someone can help me out since this is the first time I've been exposed to this coding enviroment. Here is what I have:

Assignment setup:
Analog Input 0 // Wind Direction in degrees (0° to 360°)
Analog Input 1 // Wind Speed in miles per hour (MPH)
Analog Input 2 // Temperature in degrees Fahrenheit (0° to 128° F)
Analog Input 3 // Barometric Pressure in millibars (950 mb to 1050 mb). Note: 1 atmosphere pressure (sea level) ≈ 1 bar ≈ 1000 mb

Each of these sensors has an output that ranges from 0.000 to 5.000V. The relationship between
each sensor’s voltage output and its particular physical value is shown in the look-up table below.

Write a program to read each of these sensors and display their values in degrees, MPH, Celsius,
and atmosphere to the serial monitor once every 2 seconds. The display message should take
the form:

“Wind Direction = XXX.XX degrees”
“Wind Speed = XXX.XXX MPH”
“Temperature = XXX.X degrees C”
“Barometric Pressure = XXXX atm”

Notes on display:

  1. There should be a blank row between each block of values in your display.
  2. You don’t need leading zeros in your numerical value.
  3. You don’t need fractional values for the barometric pressure.
  4. You can spell out the word “degrees” or use the ASCII code for ‘°’.

You must use the provided look-up table (below) in your program to translate voltages to
physical values.

Notes on program:

  1. Review arrays and 2-D arrays.
  2. Review Analog Input
  3. No need for interpolation, just give the closest value in the table.
  4. Verify your program to catch the syntax errors.

Table:

Table to text:
{0.000, 0.000, 0.00, 0.0, 950},
{0.156, 3.125,11.25, 4.0, 953},
{0.313, 6.250,22.50, 8.0, 956},
{0.469, 9.375,33.75, 12.0, 959},
{0.625, 12.500, 45.00, 16.0, 963},
{0.781, 15.625, 56.25, 20.0, 966},
{0.938, 18.750, 67.50, 24.0, 969},
{1.094, 21.875, 78.75, 28.0, 972},
{1.250, 25.000, 90.00, 32.0, 975},
{1.406, 28.125, 101.25, 36.0, 978},
{1.563, 31.250, 112.50, 40.0, 981},
{1.719, 34.375, 123.75, 44.0, 984},
{1.875, 37.500, 135.00, 48.0, 988},
{2.031, 40.625, 146.25, 52.0, 991},
{2.188, 43.750, 157.50, 56.0, 994},
{2.344, 46.875, 168.75, 60.0, 997},
{2.500, 50.000, 180.00, 64.0, 1000},
{2.656, 53.125, 191.25, 68.0, 1003},
{2.813, 56.250, 202.50, 72.0, 1006},
{2.969, 59.375, 213.75, 76.0, 1009},
{3.125, 62.500, 225.00, 80.0, 1013},
{3.281, 65.625, 236.25, 84.0, 1016},
{3.438, 68.750, 247.50, 88.0, 1019},
{3.594, 71.875, 258.75, 92.0, 1022},
{3.750, 75.000, 270.00, 96.0, 1025},
{3.906, 78.125, 281.25, 100.0, 1028},
{4.063, 81.250, 292.50, 104.0, 1031},
{4.219, 84.375, 303.75, 108.0, 1034},
{4.375, 87.500, 315.00, 112.0, 1038},
{4.531, 90.625, 326.25, 116.0, 1041},
{4.688, 93.750, 337.50, 120.0, 1044},
{4.844, 96.875, 348.75, 124.0, 1047},
{5.000, 100.000, 360.00, 128.0, 1050},

I even tried to find/hire tutor(s) for this subject with no luck or way to expensive. Even if you know of a close example that I could use as a template would be helpful as well. Thanks for reading/helping. :grinning:

Write a bit of code that prints the lookup table,

That will be a first start

So, I ran this code and it produced the array (numbers only) just like the above table:

float myArray [33][5]= {
{0.000, 0.000, 0.00, 0.0, 950},
{0.156, 3.125,11.25, 4.0, 953},
{0.313, 6.250,22.50, 8.0, 956},
{0.469, 9.375,33.75, 12.0, 959},
{0.625, 12.500, 45.00, 16.0, 963},
{0.781, 15.625, 56.25, 20.0, 966},
{0.938, 18.750, 67.50, 24.0, 969},
{1.094, 21.875, 78.75, 28.0, 972},
{1.250, 25.000, 90.00, 32.0, 975},
{1.406, 28.125, 101.25, 36.0, 978},
{1.563, 31.250, 112.50, 40.0, 981},
{1.719, 34.375, 123.75, 44.0, 984},
{1.875, 37.500, 135.00, 48.0, 988},
{2.031, 40.625, 146.25, 52.0, 991},
{2.188, 43.750, 157.50, 56.0, 994},
{2.344, 46.875, 168.75, 60.0, 997},
{2.500, 50.000, 180.00, 64.0, 1000},
{2.656, 53.125, 191.25, 68.0, 1003},
{2.813, 56.250, 202.50, 72.0, 1006},
{2.969, 59.375, 213.75, 76.0, 1009},
{3.125, 62.500, 225.00, 80.0, 1013},
{3.281, 65.625, 236.25, 84.0, 1016},
{3.438, 68.750, 247.50, 88.0, 1019},
{3.594, 71.875, 258.75, 92.0, 1022},
{3.750, 75.000, 270.00, 96.0, 1025},
{3.906, 78.125, 281.25, 100.0, 1028},
{4.063, 81.250, 292.50, 104.0, 1031},
{4.219, 84.375, 303.75, 108.0, 1034},
{4.375, 87.500, 315.00, 112.0, 1038},
{4.531, 90.625, 326.25, 116.0, 1041},
{4.688, 93.750, 337.50, 120.0, 1044},
{4.844, 96.875, 348.75, 124.0, 1047},
{5.000, 100.000, 360.00, 128.0, 1050},
};

void setup()
{
Serial.begin(9600);
}

void loop()
{
for(int x = 0; x < 33; ++x)
{
for(int y = 0; y < 5; ++y)
{
Serial.print(myArray[x][y]);
Serial.print("\t");
}
Serial.print("\n");
}
while(1);
}

That’s a good start

Now, define a global variable float x = 2.5;

noticing that the array is sorted in ascending order for the first column, instead of printing all the data, print the line where the first value is closest to x

Not sure where to place, at the beginning of the code?:
float x = 2.5;

or to make the serial monitor display to stop when it reaches 2.5 in the first column...

Hello tracy_c
You can work with a modified map() function too.
Have a nice day and enjoy coding in C++.

May be you need to spend just a bit of time on the basics of C/C++ so that you get a better grasp on local and global variables and functions

Then come back to this assignment

In order to get a more precise result you can do what is called "piecewise linear interpolation". You find the two values in your table on either side of the voltage you are looking up. If the value is, say, 32% of the way between the lower value and higher value, the result is 32% of the way between the first answer and second answer.

This was the first Google hit for 'piecewise linear interpolation C++':
https://people.sc.fsu.edu/~jburkardt/cpp_src/pwl_interp_1d/pwl_interp_1d.html

see notes

You have called column[0] in your table sensor output. You know how to use a for() loop with the index running from 0 to 32 to read values from that column.

You are going to have a float value which is the voltage output of some sensor and you want to find out which value in column[0] is closest to the reading from the sensor.

Say that your sensor is putting out 2.250 volts. You should be able to use a for loop with the sensor output values to find the index of the first value which is larger than your reading of 2.250 volts. You will then also know the index and value of the value which is just less than 2.250 volts in your column[0].

In your table with column[0], the first value greater than 2.250 volts is 2.344 volts which is at index 15, and the value just below is 2.188 which is at index 14. Remember that all the array indexes start at 0.

Then you need to find out which of the two numbers in your case 2.344 and 2.188 is closest to 2.250.

See if you can get to the point where for any arbitrary floating point number between 0 and 5 (which represents the voltage output from some sensor) you can find the two closest numbers in the first column of your table.

1 Like

That’s where I was trying to get the OP to. Seems s/he has challenges declaring a variable, so a bit of groundwork is needed IMHO

1 Like

Lets just keep it simple first - and scan down the table until the "sensor output" exceeds the sensor value;

then pick the required reading from that line?

This has got to be the worst ever use of lookup tables. First, it requires converting an integer (analogRead()) to a float (voltage). Then, all of the 'tables' appear to be perfectly linear!

The first column (wind speed) is:
analogRead(A1) * 100.0 / 1024.0;

The second column (wind direction) is:
analogRead(A0) * 360.0 / 1024.0;

The third column (temperature) is:
analogRead(A2) * 128.0 / 1024.0;

The fourth column (pressure) is:
analogRead(A3) * 100.0 / 1024.0 + 950;

I suppose it's meant as an exercise. indeed using the formula would be so much more direct bur may be in the next chapter they will have a non linear table to deal with...

1 Like

Thanks everyone for your input but I'm getting confused. This is what I'm interpetting the results: Just need each of lines of the array to display vertically...as an example:

float myArray [33][5]= {
{0.000, 0.000, 0.00, 0.0, 950},
{0.156, 3.125,11.25, 4.0, 953},...

To display as:
Wind Direction = 0 degrees
Wind Speed = 0 MPH
Temperature = 0.0 degrees C
Barometric Pressure = 950 atm
...SPACE...
Wind Direction = 11.25 degrees
Wind Speed = 3.125 MPH
Temperature = 4.0 degrees C
Barometric Pressure = 953 atm
...SPACE...and so forth

I did notice that the order of the data in the array isn't in the same order of the display:
{0.156 (Sensor Output - Not needed), 3.125 (Wind Speed), 11.25 (Wind Direction), 4.0 (Temperature, 953 (Barometric Pressure)}. Only need to display 4 of the 5 columns.
I have no idea....
Thanks

This seems like rather a challenging assignment for your first. You may want to do some predecessor projects to get used to arrays and then come back to this one.

Do you think the °F temperature from the table should be converted to °C before display?

Do you think the °F temperature from the table should be converted to °C before display?

Another little gotcha. The table lists the value in mb

@tracy_c Do you know how to uses the array indexes access any value in the table? What value do you think is at
myArray [2][2]?

Too easy. The first "giveaway" is there are 33 entries, zero being unique to the 'floor' value. That leaves 32 lookups with 0 being handle conditionally.

You "can" handle each array separately or as a multi-dimensional array. I think a simple array for example, make it complex later if needed.

{156, 313, 46o, 625, 781, 938 .... } // 32 entries

An analog value is 0-1023 for 10-bit. == 1024 discrete values. We need only 32 to map to our array AND "0" (zero) will not be mapped: note 1023 == 5.000 Volts, array element [32]
Thus read the analog value
Handle 0 in conditional if{} // hard 0 like a grounded input
// for array lookup > 0 < 32 bounds element [0]
// we can scale by 32 any > 0 value
int pointer = analog / 32; // analog is integer and now pointer
The lookup is therefore array[pointer]
BUT ABOVE IS FLAWED !!! we can not get to a hard 5.000 Volt because 1023 / 32 = 31 which would be the 5 Volt directly connected to the input.
Thus we need to handle the unlikely 1023 before scaling just like we did the hard 0 ... which is ground and an unlikely analog input. Therefore we need an if{} to deal with 1023 just after we check for 0.

Just a note about the previous pseudo-code. Some profs may allow the student to check the AD for 0 (zero) and then "bias" the AD input by +1 to force the upper 1023 (5.000Volts) to be 1024 thus aligning the divide by 32.

I did not show it since I do not know enough about the assignment. But that is what I would do as the error is only 1/1024.

Ray