Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] How to implement a look up table in C programming for the below table?

Status
Not open for further replies.

Upendra007

Newbie
Newbie level 3
Joined
Aug 23, 2017
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Location
Bangalore
Activity points
60
In one of my application I need to use look up table in C.
I need to pick the data depending on two variable parameters temperature and pressure
for example if temp=0 and pressure=750 then I have to pick 14.37.and so on Thanks in advance
Please see the attached table.
 

Attachments

  • my table.jpeg
    my table.jpeg
    153.5 KB · Views: 229

The straight solution is to store all these arrays in variables (actually, const) and access them according to the input such as with switch (pressure)...case:Value[temperature], but the most appropriate solution might be try to find the descriptive equation of this phenomenon and calculate the function in runtime, although this would require more aritmetic processing from cpu.
 
Unless you can find a formula to produce the same result or can live with an approximation based on sections of the results, you have to store the whole table. As it makes a large table you might be best to store it as a file on disc if that is possible, then use random file access to read the specific value as 500 floating point numbers takes up a lot of space. If you store them sequentially you can access them as (column number * number of rows) + row number.

If you want to store them in memory, use:
const float MyTable[10][50] = {list of numbers.....

then access the values as:
value = MyTable[Torr][Temperature];

Brian.
 
Hi,

I agree. I`d try to find a formula.
If not for the whole tbale then for the horizontal or the vertical part - whichone is easier.

If table: I´d save some memory by multiplying the table values with 100 and store them as 16 bit integers.

Maybe you can reduce table item count by using linear interpolation.

Klaus
 
I do not like the idea of using tables to describe the sensor response, as this makes the calibration process less "programmable". When using a formula, it is possible to make adjustments just changing few parameters of the (e.g polynomial) function.
 
@andre_teprom,Exactly but there is no formula for this, and it makes me use a look up table .With switch and case also it will increase the number of lines of coding better i would try with array of structures .please help me in that ,Thank you.

@bewixt,you are correct the formula would make really helpful and its a good way actually unfortunately it doesn't.
I would like to use the memory as you mentioned by implementing an array ,i tried like this to access but i couldn't finish well at the end ,Can you please brief me in accessing values acc to temp and pressure .Thank you .
 

You keep saying there is no formula.

Perhaps there is no formula given, but it is highly likely there is a relationship between the input and the output. You have to determine a relationship that curve fits the data within error limits you can tolerate. That curve fit equation is the formula you then use in your program.

I get the feeling you might only have to curve fit only the vertical data for one column and then have a minor scaling factor from column to column, but that is only a gut feeling (given the data from column to column goes up in what appears a linear fashion).

Have you tried a 3D plot of the data to get a feel for how the data behaves. It's probably a sloping surface with the highest point being the max pressure and lowest temp and is more than likely a flat surface. Though there might be some non-linearity at the lowest temps (based on spot checks of the table).

- - - Updated - - -

Maybe put the data into Matlab and use this function:
https://www.mathworks.com/help/curvefit/surface-fitting.html?requestedDomain=www.mathworks.com#responsive_offcanvas
 

@bewixt,you are correct the formula would make really helpful and its a good way actually unfortunately it doesn't.
I would like to use the memory as you mentioned by implementing an array ,i tried like this to access but i couldn't finish well at the end ,Can you please brief me in accessing values acc to temp and pressure .Thank you .

I did!
By using a two dimensional array with the columns as one dimension and the row as the other, you can look up the value from it by using temperature and pressure as the array index. For example, if you dimensioned them as I suggested earlier, your figure of temperature 0 and pressure 750 would be accessed as value = MyArray[0][0];.
You would have to work out the column number from the pressure but it looks like "column = (pressure - 750)/5;" would be suitable.

The drawback is the array size, especially if you have to store the whole table because it has 500 entries and each is the size of a 'float' which is typically 6 bytes. You could consider multiplying all the table values by 100 then dividing the value you look up by 100. It would let you store the values as integers which need less space and are faster to calculate with. For example, save 14.37 as 1437.

Brian.
 
In case of a low memory-sized microcontroller, if I were in your shoes,
I might go a little further from just storing integers instead of floats and use
chars (bytes) for most of the data.

For every line in the table, I use 2bytes + 9bytes (struct p_line).
With a total of 50 lines, we have a required space of 550 bytes.
For each line (specific temp value) you store the initial value for pressure 750 and you also
store the 9 increments that advance the required value to the net pressure level.
The search is done sequensialy with a loop of max 9 iterations.
Code follows

Code:
struct p_line {
	unsigned v750;
	signed char delta[9];
} TP[51] = {
	{1432,	15,10,9,10,10,9,10,10,9},
	{1395,...},
	...
};

unsigned getTP(unsigned temp,unsigned pres){
	unsigned tp; signed char *idx;
	if(temp>50 || (pres % 5)!=0 || pres<750 || pres>795)
		return 0;//out of limits
	tp = TP[temp].v750;
	idx = TP[temp].delta;
	while(pres>750){
		tp += *idx++;
		pres-=5;
	}
	return tp;
}

ps. I haven't tested it with a real compiler, so some minor erros may occur
 
Hi,

I agree. I`d try to find a formula.
If not for the whole tbale then for the horizontal or the vertical part - whichone is easier.

If table: I´d save some memory by multiplying the table values with 100 and store them as 16 bit integers.

Maybe you can reduce table item count by using linear interpolation.

Klaus


Hi, I have read about linear interpolation https://helloacm.com/cc-function-to-compute-the-bilinear-interpolation/
unfortunately i couldn't work out well .I have made it with arrays using switch and case , yet need to reduce the lines @xenos implemented well working on it .appreciates you all for such a wonderful support .Thank you
 

Should delta[] icrement values limited below 16, data memory can be even more reduced with a slight exacerbation in performance by using a
struct liken the following one:

Code:
struct p_line2 {
	unsigned v750;
	struct {
		unsigned lsb:4;
		unsigned msb:4;
	} delta[5];
};	//beware of the mcu endianess during both initialization and usage of the values
Total data memory required is 50*2 + 50*5 = 350bytes

Moreover, it is feasible to make it even more confusing :lol: :
Code:
unsigned tp[51] = {...};
unsigned char deltas[(9*50+1)/2] = {...};
unsigned char geti(int i){//get a 4bit delta value
	if(i & 1)//beware of the mcu endianess and the way that delta[] initialization is done
		return deltas[i>>1] >> 4;
	//else
	return deltas[i>>1] & 0x0f;
}
where the deltas for temperature i are stored from geti(i*9) upto get(i*9+9)
Total data memory required is 50*2 + 225 = 325 bytes.
The deltas[] array initialization may be a little tricky.


This is the naive (and typical for modern RAMy mcu) solution with the maximum speed performance suffering only in data memory space that uses one 2d array of integers, as betwixt mentioned already.

Code:
int TP[51][10] = {
      ........................,
      ........................,
};
int tp(int temp,int pres){
          assert(pres>=750 && pres<=795);
          assert(temp>=0 && temp<=50);
          return TP[temp][(pres-750)/5];
}

RAM required is 50*10*2=1000bytes

To sum up, there are a handful of solutions to choose, but you should stick with the one that you do understand, depending on your hardware, your knowledge and of course, your experience.
 
Last edited:
Although the suggested methods for efficient table coding, e.g. the delta representation are interesting, I would start with basic 2D linear interpolation, may be even using float constants, verify correct operation and check if the intended accuracy can be achieved with fewer points.

Conversion to integer (fixed point) arithmetic and possible table minimization comes second.

The OP didn't tell anything about the used processor, we don't know if there's an actual resource problem. If not (e.g. using a recent arm processor), float tables can be just fine.

Start to design the basic interpolation algorithm using four table points surrounding the t,p point.

- - - Updated - - -

As a side remark, I was formerly convinced that approximation formulas (e.g. polynomials) are preferable to table interpolation in most situations. Now I know that it's not the case. I agree with the rating in the below linked application note: Linear piecewise approximation is "Most useful in most situations".
https://www.analog.com/media/en/technical-documentation/application-notes/AN-0970.pdf
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top