It's a basic one: I have two values from two different analogRead pins:

int val1;
int val2;

For example, val1 = 10 and val2 = 10. How could I put these two values into a variable val3 = val1 + val2 that will give the answer 1010, instead 20 ?

  • 1
    val = (val1*100) + (val2%100) – Mikael Patel Jul 28 '16 at 12:40
  • val = (val1 << 8) + (val2 & 0xff) – Mikael Patel Jul 28 '16 at 12:41
  • float val = val1 + (val2 / 100.0) – Mikael Patel Jul 28 '16 at 12:42
  • 2
    It is far from clear what you think you are attempting to achieve. I suspect you may be suffering from an XY problem where you think you have come up with a solution to a problem, and are asking for help with the solution, when you don't actually really understand what the problem is, and so your solution won't actually do what you expect it to do. – Majenko Jul 28 '16 at 15:21
  • 2
    For instance, have you considered what will happen if val1 is 3, or val2 is 400? Concatenating integers makes little to no sense, and I suspect you actually want to do something else entirely. – Majenko Jul 28 '16 at 15:26

If you are reading from the analog pins then the values are 10 bits (not 8 as suggested above). Are you looking at concatenating 2 10 bit numbers or 2 16 bit numbers or are you using a zero or duo in which case they could be 12 bit numbers.

In any case:

const int BITMASK = 0x3FF;  // 10 bits = 0x3FF, 12 = 0xFFF, 16 = 0xFFFF
const int BITWIDTH = 10;
long result = ((value1 & BITMASK) << BITWIDTH) | (value2 & BITMASK);

I suspect it won't give you the answer you want, but...

  • Sound promising... I will take a look – Diego Dyan Jul 28 '16 at 16:18

It sounds to me, from your comments, that what you want to do is turn this:

myRadio.transmit(val1);
myRadio.transmit(val2);

into something more like this:

myVal = join(val1, val2);
myRadio.transmit(myVal);

That's all pseudocode of course, and those functions are in themselves nonsense, but it serves to illustrate.

So you want to turn two values into one single block of data for sending thus reducing the overall transmission overhead of the packet (one large packet instead of two smaller packets).

What you are actually looking for is called a struct and looks something like this:

struct MyData {
    int val1;
    int val2;
};

That creates a new variable type which contains two sub-variables in it. You then use it like any other variable:

struct MyData data;

You can then get at the values inside it with:

data.val1 = analogRead(A1);
data.val2 = analogRead(A2);

And the whole thing can be transmitted in one block with whatever functions your RF library provides:

myRadio.transmit(&data, sizeof(struct MyData));

Receiving at the other end is just the same - as long as the receiving end has the same structure. Receive into a MyData structure variable and you can get at the individual sub-variables:

struct MyData data;
myRadio.receive(&data, sizeof(struct MyData));
Serial.print(data.val1);
Serial.print(",");
Serial.println(data.val2);

Of course, you need to read up on whatever library it is you're using to do your transmitting and receiving to find the actual correct functions to call to transmit and receive a block of data like that...

This is not even remotely related to Arduino but mathematics. As Mikael Patel pointed out this can be done fairly easy. You might tell us your intent. If you are seeking for a way to pack values tightly you may consider Integer Sequence Enconding. But without more detailed information this will be just a guess.

  • The intent is stated in the question as handling numbers read from two analog pins. – Code Gorilla Jul 28 '16 at 14:13
  • 1
    Well that is what he tells us, he wants to achieve. But I'm not sure he really knows what he wants to do with that. Why does it make sense to "concatenate" two integer values in decimal? Why not hex? What is the goal with that? What are the sources of the analog reads? – Kwasmich Jul 28 '16 at 14:24
  • Actually, it can be done arithmetically with no problem, but I used 10 + 10 = 1010 just for example. I am open to suggestions if I need to convert to HEX or BIN. I thought it was a question easy to be solved and it was just me that was missing something. – Diego Dyan Jul 28 '16 at 16:11
  • I am using a MEGA2560 to read several sensors (termistors, encoders, RTC, etc) and transmits this data over a RF433 module to an UNO. The module only send pointers pointed to strings. What I am doing is converting the data from sensors into string and sending one by one through RF. I have a Python script reading the data on the other side, if I could concatenate all the data from the sensors to send all at once will be much easy for me handle this data in Python. – Diego Dyan Jul 28 '16 at 16:17
  • @DiegoDyan - based on what you have just said I think you need to look in a different direction. Please see my 2nd answer. – Code Gorilla Jul 28 '16 at 17:01

You want to send a string of data that represents the data from a number of sensors. For example let's say you have 2 10 bit analog readings and 4 Boolean readings, high or low from the digital pins. You can compress this into 24 bits of data, or 3 bytes.

If your transmission library supports binary writing and reading then you can send it as 3 unsigned chars.

If your transmission library doesn't support binary then you can either base64 encode it as 4 bytes. (The numbers are converted into printable characters that represent their value). Or a more light weight solution would be to write each byte as two hexadecimal digits.

You pack the data into three bytes by using bit masking and shifting (as per my other answer).

int sensor1data = 512;      
int sensor2data = 64;
bool digital1 = true;
bool digital2 = false;
bool digital3 = false;
bool digital4 = true;

unsigned char data[3]{ 0, 0, 0 };

// Take the top 8 bits of the 10 bit data on sensor1data 
// 0x300 takes the 2 lowest bits of the upper byte
// 0x0FC takes the 6 highest bits of the lower byte.
// Shift the result 2 places right so the what was bit 2
// of the upper byte becomes the most significant bit (MSb) 
// in the result byte.
data[0] = (sensor1data & 0x3FC) >> 2;

// Take the 2 lowest bits of the lower byte (0x03) 
// Shift the 6  places left to make them the MSb of the 
// result byte.
data[1] = ((sensor1data & 0x3) << 6);
// Take the 6 MSbs of the sensor2data and left shift them 
// so that they become the LSbs of the result byte.
// The result is ORed onto what is already in the result 
// to retain the previous instruction.
data[1] |= ((sensor2data & 0x3F0) >> 4);

// Take the 4 LSbs of sensor2data and shift them right 
// for places to ocupy the 4 MSbs of the result.
data[2] = ((sensor2data & 0xF) << 4);
// OR each of the flags into the result, shifting by 
// a different amount each time.
data[2] |= (digital1 ? 1 : 0) << 3; // I explicitly convert the bool to an int 
data[2] |= (digital2 ? 1 : 0) << 2; // because some older compilers don't always
data[2] |= (digital3 ? 1 : 0) << 1; // use 1 for true.
data[2] |= (digital4 ? 1 : 0);
  • This is a very elegant solution! – Diego Dyan Jul 31 '16 at 12:27

If you know in advance how many variables' values you want to transmit:

char output[100+1];
....    
snprintf(output, sizeof(buffer), "%d,%d,$d\n", val, val2, val3);

If not and you need to build the string "as you go":

char output[100+1] = "";
char oneVal[12+1];
...
snprintf(oneVal, sizeof(buf), "%d,", value);
strcat(output, oneVal);

// more of the above, possibly in a loop.
...
strcat(output, "\n");      // if you need a newline at the end

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.