Manipulating Data


I have 80 different variables each containing 2 bytes of data that are being supplied by a data BUS in hexadecimal, both signed and unsigned. I want to convert the data received into a standard unit that will be in float numbers [i.e. degrees, celsius]. Then I want to convert those numbers to be sent out on a secondary BUS in hex again. The data is Tx every 10-50ms dependant on channel.

So workflow is: Input > Input * a = > Standard Unit > ((Standard unit * b) - c) = > Output

Am I best off doing this using 3 data arrays [Input, StandardU & Output] or is there a better way of doing it? The channels of data all have different equations and later down the line I may change the Output BUS which will require a different output transformation [hence why I want to utilise a standard unit].

Currently I have the BUS side of things sorted but I'm unsure on the best way of handling the core data manipulation.

Many thanks,


What do you mean, a data bus? Are you accessing it through a bus interface, like IEEE 488? Or serially? I ask because it may affect the way the data is translated.

I'm using a Due, using the in-built 2x CANbus and a CANshield over the SPI.

All channels Tx & Rx, although the on-board bus will receive more than it will transmit.

You have to read up on variables a bit.

Float, int, byte, bool etc is a type of variable. Being it signed or unsigned, fixed decimal point (or no decimal point) or floating decimal point. But they are types of variables.

hex isn’t a type of variable. Hex is only a representation. Just as decimal, binary, hexadecimal, base-64 etc. It’s just a way of showing the numbers. Like in language one, uno, ein, één, un, 1 all means the same but in another representation (language).

Knowing that, your question doesn’t really make sens…

I understand the basics and maybe should have made my question a bit clearer.

Say I'm handling a variable "temp" which is 100*c.

BUSa will likely have this variable sent as 0x3E8 [1000] BUSb will likely have want this variable sent as 0x320 [800]

I'd like to: 0x3E8 > 100*c > 0x320

IS there a more efficient way of doing this than by utilising 3 different arrays and the various independent sub-routines?

0x3E8 - 200 = 0x320 …

In other words, WHAT is the relation between the variables of bus a and bus b? Is it indeed just 200 lower?

I already know the relationship and they're different for each channel received.

The maths isn't the issue.

Am I best of storing the data in an array when it's received, then applying the maths to a standard unit [and storing this in a second array], then applying the maths for the second bus [and storing this in a third array].

I need to have all three actions, I DO NOT want to do a direct BUSa to BUSb transaction [future development will require use of a different BUS and the standard unit can then be converted by a separate sub-routine for that].

IS there a better way of handling the data in this instance than using the above?

ardler_dan: then applying the maths to a standard unit [and storing this in a second array], then applying the maths for the second bus [and storing this in a third array].

Why do it in a two step matter? That's just wasting computing power, memory, time and precision.... Just get you math right to do it at once. So: - Load values from busA and store it in arrayA - Calculate all the values from arrayA and put them in arrayB - Send arrayB over busB

If you want to have a third bus (busC) just add - Calculate all the values from arrayA and put them in arrayC - Send arrayC over busC

I had the same remark as septillion in mind. Unsigned/signed hexadecimal does not make sense.

What your question boils down to is (if I understand it correctly) 1) You receive data from a channel; on one channel the data represents pressure in mm Hg, on another channel it represents pressure in Pascal, on another channel it represents temperature in degrees Celsius, on other channel it represents temperature in degrees Fahrenheit, on again another channel it represents airflow in litres per hour etc etc. 2) You want to translate that data to a standardized format (e.g. mm Hg, degrees Celsius). That would make sense to me. 3) At occasion, transfer the data to a second bus.

I would only store the input data. At the moment that you want to transfer data to the second bus, use a function to translate to a standardized format. Next call a function that transfers the data with the result of the 'translation'.

You will probably want to use a struct to store the 2 incoming data bytes and a function pointer or make use of classes.

A solution using a struct could be

struct DATA
  // databytes
  byte databytes[2];
  // function to standardize
  float (*standardize)(byte *ptr);

The below are very simple examples for your standardize functions. For each ‘sensor type’, you need one. For you to modify to your needs.

float sensortype1_to_celsius(byte *data)
  int i = data[0]<<8;
  i+= data[1];
  return (float)i;

float sensortype2_to_celsius(byte *data)
  int i = data[1]<<8;
  i+= data[0];
  return (float)i;

You can use an array of these structs

  DATA dta[] = 
    {0x00, 0x00, sensortype1_to_celsius}, // uses sensortype1_to_celsius function to convert
    {0x00, 0x00, sensortype2_to_celsius}, // uses sensortype2_to_celsius function to convert
    {0x00, 0x00, sensortype1_to_celsius}, // uses sensortype1_to_celsius function to convert
    {0x00, 0x00, sensortype1_to_celsius}, // uses sensortype1_to_celsius function to convert

Elements 0, 2 and 3 are of ‘sensor type’ 1, element 1 is of ‘sensor type’ 2. You can add your other ‘sensors’ to this array.

Below a simple C example (for a PC) to print the standardized data

  printf("standardized data = %f\n", dta[0].standardize(dta[0].databytes));
  printf("standardized data = %f\n", dta[1].standardize(dta[1].databytes));

You can replace the printf by some Serial.print for the Arduino.

Note: you can add more variables to the struct; e.g. an unsigned long indicating the interval for transmission on the second bus.

Thanks for that, I've not worked with structs before so will do some more reading - my previous coding was a few years back now and whilst most of it's at hand and working this is the first time I've had to manipulate data in this way.

I'll have a play later this week when I'll have time to get everything hooked up together.