Por que conectar dous arduínos?
Imos conectar dous arduinos entre si para que funcionen de maneira sincronizada. Hai diversas ocasións nas que podemos necesitalo, pero vou resaltar dúas delas:
Programas en paralelo

Se usásemos un microprocesador (como no caso dun LEGO ou unha Raspberry Pi) isto non tería problema, pois permite a execución de varios programas de maneira simultánea.
Unha solución é utilizar dúas placas: unha encárgase do control do motor de apertura e peche da porta e outra das luces, son, alarma, etc., e sincronizamos os dous programas mediante o envío de mensaxes desde unha placa a outra.
Necesitamos moitos pins

Sin embargo pode ser tamén interesante traballar na clase a conexión entre arduínos. Por exemplo, nun proxecto dun cruce de semáforos, un compoñente do equipo pódese encargar do control dos LEDs dos semáforos e do son dos pasos de peóns, e outro de programar nunha matriz de LEDs o boneco que se move cando o semáforo está verde. No canto de unificar todo iso nunha única placa (non nos chegarían os pins), facer de novo as conexións e unificar os programas nun programa global podemos facer que o programa de control dos semáforos envíe unha orde a outra placa para que active a matriz de LEDs cando se precise.
Conexión serial:

Para poder establecer a comunicación serie entre dous arduínos requírense unha conexión serie Rx-Tx cruzada e unir as masas:
- Para envío de datos do mestre ao escravo: Pin Tx do mestre co pin Rx do escravo.
- Para envío de datos do escravo ao mestre: Pin Tx do escravo co pin Rx do mestre.
- Unión das masas dos dispositivos.
A distancia máxima que soporta o bus serie depende da velocidade de transmisión de datos pero aproximadamente a 9600 baudios podemos poñer unha distancia máxima de 15 metros.
Montaxe
Hai dúas maneiras de facer isto:
- Mediante os pins Rx (pin 0) e Tx (pin 1) das placas. Neste caso antes de subir el código a cada Arduíno cómpre desconectar os pins Rx e Tx, pois estes pins tamén son usados para comunicarse por USB e non poderiamos instalar o programa.
- Habilitando outros pins dixitais da placa para que fagan a función Rx e Tx. Desta maneira non é necesario desconectar a comunicación para poder instalar os programas mediante USB.

Antes de instalar os programas fíxate ben a que porto tes conectada cada placa, pois cada unha levará un programa diferente. No caso de dúbidas deixa conectado o cable USB só da placa na que queiras instalar o programa e desconecta o da outra.
Prácticas:
Imos facer dúas prácticas, unha sinxela na que un pulsador conectado á placa 1controla un LED conectado á placa 2, e outra na que se move un servo conectado á placa 1 e uns LEDs conectados á placa 2 escintilan segundo sexa o movemento do servo.
- Se utilizamos a conexión Rx=0 e Tx=1, nos programas, para enviar e recibir datos, utilízanse os mesmos comandos que utilizamos para comunicarnos coa consola serie:
Serial.print('A'); Serial.available(); Serial.parseInt(); Serial.read(); etc. - Se habilitamos outros pins Rx e Tx (no noso caso Rx=7 e Tx=8), hai que instalar a librería SoftwareSerial.h e indicar os pins Rx e Tx que queremos habilitar mediante a instrución
SoftwareSerial nomedaplaca(7, 8);
Os comandos utilizamos son moi similares aos que utilizamos para comunicarnos coa consola serie, só hai que substituír “Serial” polo nome da placa.
nomedaplaca.begin(9600); // Inicia a comunicación serie nomedaplaca.print('A'); nomedaplaca.available(); nomedaplaca.read(); etc
Segundo sexa a conexión que vaias utilizar elixe as prácticas correspondentes.
1. Proba (pins 0-1)
1. Probamos: Imos facer unha práctica sinxela para entender como hai que facer para enviar datos dunha placa a outra: Nun Arduíno conectamos un pulsador e noutro conectamos un LED. O LED debe cambiar de estado cada vez que prememos no pulsador.

// Declaración de variables:
int pulsador=2;
// Configuración:
void setup(){
Serial.begin(9600); // Inicia a comunicación serie
}
// Programa:
void loop() {
if (digitalRead(pulsador)==1){
while(digitalRead(pulsador)==1); // Agarda mentres o pulsador esta premido
delay(20); // tempo para evitar o efecto rebote do pulsador
Serial.print('A'); // Envía o dato A
}
}
Programa da placa 2:
// Declaración de variables:
int led=13;
char sinal;
int estado=0; // variable na que almacenamos o estado do LED
// Configuración:
void setup(){
Serial.begin(9600); // Inicia a comunicación serie
pinMode (led, OUTPUT);
digitalWrite(led, LOW);
}
// Programa:
void loop(){
if (Serial.available()) { // Se recibe un dato
sinal = Serial.read(); // Lemos o dato
if (sinal == 'A') { // Se o dato é A cambiamos o estado do led
if (estado==0) {
digitalWrite(led, HIGH);
estado=1;
}
else{
digitalWrite(led, LOW);
estado=0;
}
}
}
}
Lembra que se envías un número e non un carácter, para recibilo no canto de usar Serial.read() debes usar Serial.parseInt()
2. Servo e luz (pins0-1)
2. Movemento e luz (pins 0-1): Imos facer que un servo se mova lentamente de o a 180º e despois en sentido contrario de forma cíclica. Cada vez que xira nun sentido escintila un LED verde, e cando xira en sentido contrario escintila un LED vermello.

#include <Servo.h>
// Declaración de variables:
Servo meuservo; // poñémoslle nome ao servo: "meuservo"
// Configuración:
void setup(){
Serial.begin(9600); // Inicia a comunicación serie
meuservo.attach(6); // servo conectado no pin 6
}
// Programa:
void loop() {
meuservo.write(0); // Parte da posición de 0º
Serial.print('A'); // Envía o dato A
for(int i=0;i<=180;i++){
meuservo.write(i);
delay (20);
}
Serial.print('B'); // Envía o dato B
for(int i=180;i>=0;i--){
meuservo.write(i);
delay (20);
}
}
Programa da placa 2:
// Declaración de variables:
int ledverde=12;
int ledvermello=13;
int sinal;
// Configuración:
void setup(){
Serial.begin(9600); // Inicia a comunicación serie
pinMode (ledverde, OUTPUT);
pinMode (ledvermello, OUTPUT);
}
// Programa:
void verde(){
digitalWrite(ledverde, HIGH);
delay(100);
digitalWrite(ledverde, LOW);
delay(100);
}
void vermello(){
digitalWrite(ledvermello, HIGH);
delay(100);
digitalWrite(ledvermello, LOW);
delay(100);
}
void loop(){
if(Serial.available()){ // Se hai un dato
sinal = Serial.read(); // Lemos o dato
Serial.print(sinal);
if (sinal == 'A') { // Se o dato é 'A'
while(!Serial.available()){ // executamos verde mentres non haxa un novo dato
verde();
}
}
if (sinal == 'B'){
while(!Serial.available()){
vermello();
}
}
}
}
3. Proba (pins 7-8)
3. Probamos (pins 7-8): Imos facer unha práctica sinxela para entender como hai que facer para enviar datos dunha placa a outra: Nun Arduíno conectamos un pulsador e noutro conectamos un LED. O LED debe cambiar de estado cada vez que prememos no pulsador.

#include <SoftwareSerial.h>
SoftwareSerial placa1(7, 8); // RX, TX
// Declaración de variables:
int pulsador=2;
// Configuración:
void setup(){
placa1.begin(9600); // Inicia a comunicación serie
}
// Programa:
void loop() {
if (digitalRead(pulsador)==1){
while(digitalRead(pulsador)==1); // Agarda mentres o pulsador esta premido
delay(20); // tempo para evitar o efecto rebote do pulsador
placa1.print('A'); // Envía o dato A
}
}
Programa da placa 2
#include <SoftwareSerial.h>
SoftwareSerial placa2(7, 8); // RX, TX
// Declaración de variables:
int led=13;
int sinal;
int estado=0; // variable na que almacenamos o estado do LED
// Configuración:
void setup(){
placa2.begin(9600); // Inicia a comunicación serie
pinMode (led, OUTPUT);
digitalWrite(led, LOW);
}
// Programa:
void loop(){
if (placa2.available()) { // Se recibe un dato
sinal = placa2.read(); // Lemos o dato
if (sinal == 'A') { // Se o dato é A cambiamos o estado do led
if (estado==0) {
digitalWrite(led, HIGH);
estado=1;
}
else{
digitalWrite(led, LOW);
estado=0;
}
}
}
}
4. Servo e luz (pins 7-8)
4. Movemento e luz (pins 7-8): Imos facer que un servo se mova lentamente de o a 180º e despois en sentido contrario de forma cíclica. Cada vez que xira nun sentido escintila un LED verde, e cando xira en sentido contrario escintila un LED vermello.

#include <Servo.h>
#include <SoftwareSerial.h>
SoftwareSerial placa1(7, 8); // RX, TX
// Declaración de variables:
Servo meuservo; // poñémoslle nome ao servo: "meuservo"
// Configuración:
void setup(){
placa1.begin(9600); // Inicia a comunicación serie
meuservo.attach(6); // servo conectado no pin 6
}
// Programa:
void loop() {
meuservo.write(0); // Parte da posición de 0º
placa1.print('A'); // Envía o dato A
for(int i=0;i<=180;i++){
meuservo.write(i);
delay (20);
}
placa1.print('B'); // Envía o dato B
for(int i=180;i>=0;i--){
meuservo.write(i);
delay (20);
}
}
Programa da placa 2
#include <SoftwareSerial.h>
SoftwareSerial placa2(7, 8); // RX, TX
// Declaración de variables:
int ledverde=12;
int ledvermello=13;
int sinal;
// Configuración:
void setup(){
placa2.begin(9600); // Inicia a comunicación serie
pinMode (ledverde, OUTPUT);
pinMode (ledvermello, OUTPUT);
}
// Programa:
void verde(){
digitalWrite(ledverde, HIGH);
delay(100);
digitalWrite(ledverde, LOW);
delay(100);
}
void vermello(){
digitalWrite(ledvermello, HIGH);
delay(100);
digitalWrite(ledvermello, LOW);
delay(100);
}
void loop(){
if(placa2.available()){ // Se hai un dato
sinal = placa2.read(); // Lemos o dato
placa2.print(sinal);
if (sinal == 'A') { // Se o dato é 'A'
while(!placa2.available()){ // executamos verde mentres non haxa un novo dato
verde();
}
}
if (sinal == 'B'){
while(!placa2.available()){
vermello();
}
}
}
}
Prácticas:
- Outras accións: Engade á práctica “Probamos” outro botón, de xeito que cando o premamos envíe outro dato diferente, e que a placa escrava execute outra acción diferente (que o LED escintile, que soe unha melodía, etc.)
- Datos de volta: Nas anteriores prácticas o mestre funcionou como transmisor (Tx) e o escravo coma receptor (Rx). Fai agora que a segunda placa devolva un dato á primeira despois de executar un proceso, e que ao recibilo realice algunha acción.