Send multiple variables to another Arduino..?

Hello,

If I have an Arduino 1 with 2 switches, lets say D2 and D3, and Arduino 2 with 2 leds on D2 and D3, how could I get Arduino 1 to send data via Tx, and have Arduino 2 Rx the data, decipher it, and light the correct led?

This is what I know how to do. The one thing I don't know how to do is send a few variables, and receive a few variables.

Arduino 1 (Or something like this):

int button1;
int button2;

void setup(){
     Serial.begin(9600);
     pinMode(2,INPUT);
     pinMode(3,INPUT);
}

void loop(){
     button1=digitalRead(2);
     button2=digitalRead(3);
     Serial.write(?);
     delay(16);
}

Arduino 2 (Or something like this):

int led1;
int led2;

void setup(){
     Serial.begin(9600);
     pinMode(2,OUTPUT);
     pinMode(3,OUTPUT);
}

void loop(){
     if (Serial.avalaible()>0){
         // read and set to variables
     }
     if (led1==1){
          digitalWrite(2,HIGH);
     }else{
          digitalWrite(2,LOW);
     }
     if (led2==1){
          digitalWrite(3,HIGH);
     }else{
          digitalWrite(3,LOW);
     }
     delay(16);
}

how could I get Arduino 1 to send data via Tx

Use Serial.print() or Serial.write().

and have Arduino 2 Rx the data

Use Serial.available() and Serial.read().

decipher it

Depends on what you decide to send.

and light the correct led?

Again, depends on how you send data.

The two switch states could be combined in a single byte (along with 6 other switch states), sent using Serial.write(). Then, there would be only one byte to read and use. Look at bitRead() and bitWrite().

Or you could send more complex information, like “<Switch One is On; Switch Two is Off>”. This is a bit more complex to send and receive, and to collect and parse. But, it’s easier to read and collect meaning from than 0x02.

You just have 2 bit = 4 different values.
To test it easier, I’d propose you send human readable / writable characters. e.g. ‘0’ to ‘3’

‘0’ means both off, ‘1’ means led1, ‘2’ = led2, ‘3’ = led1+2

There’s a difference between characters as you might enter / read them in SerialMonitor and the numbers 0 … 3
e.g.

char data = '0';   // with single quotes !
if (digitalRead(2)) data +=1;
if (digitalRead(3)) data +=2;
Serial.write(data);
delay(500);

This produces a 1 character output, that can be watched in SerialMonitor as a stream of characters like 00011333332 …

A nice decoding trick, knowing that for those characters the lowermost bits are just what you are looking for:

int c = Serial.read();
if (c != -1) {
  digitalWrite(led1, (c & 1) != 0);
  digitalWrite(led2, (c & 2) != 0);
}

Hope this does not kill the fun to find a solution

Thank you, it works great. What if I were to have a ton of buttons, say 10? How would I send all of them and decode them on the other Arduino?

You need two bytes anyway, then, so the problem of synchronistation arises. You do not need to switch all led's at once, what about a protocol like one char telling on/ off, the next telling the led ( 0 ..9 ) or (A .. Z) if its more than 10 ? e.g. "+0-2+3" would switch first led on, third off, fourth on

That could work. Would it send lines like this:

++1+0+0+1 ++0+0+1+1 ++0+1+1+0

Something like that? I used ++ for each new line, but I don't know if you need that. Could you use values instead of 1's and 0's to represent a pot? 0-255 or 0-1023

You can invent any protocol you want. You have both sides in your hand.

With multibyte messages you simply should be able to sychronize it a byte was missed or sender starts while receiver is still in reset. And it helps to have it human readable. Sending and ignoring (or use to sync) newline characters ( often written as '\n' ) is very nice to include in your protocol. Sending a numeric value with Serial.print requires decoding multiple bytes. Nick Gammon has good tutorials for that... Look for "How to send and receive numbers"

If you are sending two bytes anyway, set the leftmost bit to 0 for one set of 7 other values, and 1 for the other set. When you get a byte, you'll know which 7 LEDs the bits are for.

I am confused. And actually, I am using an Arduino Uno and a Vex Pic microcontroller. The reason I said 2 arduinos at the beginning is because I thought it would be easy to replicate on each end. So let me set an example.

If I were going to make a controller, and have an arduino in it, if I had a 2 axis joystick, 4 buttons, and a small screen, how could I write the protocal? (I don't actually have this setup, I just want to find out how to write a protocal that includes all of these elements.)

The arduino would send the buttons and the joystick values to the Vex, and the Vex would send the codes to display text on the screen.

I am confused.

About what?

And actually, I am using an Arduino Uno and a Vex Pic microcontroller. The reason I said 2 arduinos at the beginning is because I thought it would be easy to replicate on each end.

Doesn’t matter, if you control both ends. You can send data however you want, and parse it on the other.

If I were going to make a controller, and have an arduino in it, if I had a 2 axis joystick, 4 buttons,and a small screen, how could I write the protocal?

A protocol is simply an agreed upon specification for the exchange of data. You could send “<xxxx, yyyy, a, b, c, d>” where xxxx and yyyy are the joystick values and a, b, c, and d are the switch states. Then, you need to parse this data, and convert the ASCII characters back to numbers. To send data this way, you need to send up to 24 bytes.

Or, you could encode the 10 bit analog joystick data in 2 bytes, reserving the high order bits for a sequence number, and using the low order 6 bits in each byte to hold the value.

You’d need to send just 5 bytes to transfer all the information.

Which way you go depends on how often you need to send this data. Once an hour? Text is better, because it is human readable, too. 500 times a second? You don’t have time to be converting values to text and back at that rate.

Ok. This may sound stuipd, buy what is the difference between a bit and a byte? I might understand more then.

So I could send . Would I use Serial.write("<".x." “.y.” etc);, Serial.println, or some other method? And how would you read it? Would you do for loops, while loops, if, else? I am not the best programmer :confused:

Soapy29:
Ok. This may sound stuipd, buy what is the difference between a bit and a byte? I might understand more then.

So I could send . Would I use Serial.write("<".x." “.y.” etc);, Serial.println, or some other method? And how would you read it? Would you do for loops, while loops, if, else? I am not the best programmer :confused:

A bit is a binary digit – a yes/no or HIGH/LOW or 1/0. A byte is 8 bits together. A byte is important because all modern processors can only deal with one byte (or larger) at a time.

After you found out the meaning of bit and byte, you should learn about c sntax.

As the first eample worked, you should now learn about serial communication, e.g. the tutorial about sending / receiving numbers I recommended.

Then you should read carefully and find out the difference between Serial.print() and Serial.write().

Then find out how to makeSerial.write("<".x." ".y." etc); compile and then understand why it does what you see.

This may sound stuipd, buy what is the difference between a bit and a byte?

Not stupid at all. The difference is like that between a letter and a word. Each byte contains 8 bits. You can set each bit independently, or you can deal with the byte as a whole.

byte a = 39; // Set several bits at once
byte b = 0;
bitSet(b, 7); // Set only the high order bit
bitSet(b, 3); // Set a bit in the middle

So I could send .

No, you could send “”. Not quite the same. It’s important to recognize the differences.

Would I use Serial.write("<".x." “.y.” etc);

No. You’d need several Serial.print() statements - one for each part ("<", xxxx, yyyy, a, b, c, d, and “>”).

Would you do for loops, while loops, if, else?

No.

I am not the best programmer :confused:

I feel like sending you a get well card. “Get better soon!”.

Alright, I didn't make a protocal or anything, but here is what I did. I used the software serial library to make another 'serial' port, and whatever was typed into the serial viewer of the computer, will be spit out the software serial port to the vex. tThe vex will then read it, and spit it out on to my other laptop. Thing is, it only spits out numbers, not words.

I typed in hello world, and this is what it gave me on different lines:

104 101 108 108 111 32 119 111 114 108 100

But the C code for Vex is weird. To write back to the Arduino, out of its serial port, the syntax is WriteSerialPortTwo();

I'll experiment more. Anyone know how to make it into words again though?

New discovery: When I type a 1, it echos out 49… 49 isn’t one.

New discovery: When I type a 1, it echos out 49.... 49 isn't one.

It certainly is. http://www.asciitable.com/

A '1' has a value of 49 in the ASCII table.

Anyone know how to make it into words again though?

On the Arduino, yes. On the other thing, no.

Post your code!

PaulS:

Anyone know how to make it into words again though?

On the Arduino, yes. On the other thing, no.

Post your code!

#include <SoftwareSerial.h>
SoftwareSerial Serial2(10, 11); // RX, TX
int readserial;

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

void loop(){
   if (Serial.available()>0){
     readserial=Serial.read();
     Serial2.write(readserial);
     Serial.print(readserial);
     Serial.println();
   }
   delay(16);
}
SoftwareSerial Serial2(10, 11); // RX, TX

Serial2 is an instance of the HardwareSerial class for the Mega. I'd recommend a different name.

     Serial2.write(readserial);
     Serial.print(readserial);

The write() and print() methods do different things. The print method convert the value to a string, and sends it. The write method sends the value. If you are trying to debug using the Serial Monitor, using the same method for both streams is generally recommended.