Bedrade communicatie

bedrade schakelingZo simpel is het om twee Arduino's met elkaar te kunnen laten "praten" ...
Je kunt twee of meer Arduino's met elkaar laten communiceren via enkele draadjes. Dit is bijvoorbeeld nuttig als je met één Arduino niet genoeg rekenkracht hebt, of als je verschillende taken hebt die je niet goed kunt combineren. Stel je hebt een robot gebouwd: je zou kunnen besluiten de motorsturing door de ene Arduino en het uitlezen van sensoren door een andere Arduino te laten doen. De zeer goedkope Arduino nano is hier erg geschikt voor.
De makkelijkste manier om de Arduino's met elkaar te laten communiceren is door twee draadjes tussen twee pinnen te leggen. Je kunt dan precies hetzelfde programma gebruiken als voor de Bluetooth communicatie via twee HC-05's. Serieel is immers serieel, of dat nu via Bluetooth gaat of via draadjes.
Je sluit de draden altijd gekruist aan, dus - als je voor beide Arduino's dezelfde pinnen wil gebruiken - gaat 2 naar 3 en 3 naar 2. Natuurlijk kun je andere pinnen gebruiken, maar dan moet je dat wel opgeven in de derde regel van deze sketch. Als je voor beide Arduino's verschillende pinnen gebruikt dan moet je twee versies van het programma gebruiken: niet handig maar het kan. Bij sommige Arduino's kun je niet alle pinnen gebruiken, bijvoorbeeld bij de Arduino niet 13 voor RX.
Het voorbeeeldprogramma is in wezen hetzelfde als het Bluetooth testprogramma, alleen heb ik de baudrate van de bedrade communicatie sterk verhoogd. Ook hier kiest de Arduino een naam op grond van gegevens is de chip. Meestal zul je dat niet nodig hebben. Verderop staat een voorbeeld waarbij dat niet gebruikt wordt. Later: netwerken van Arduino's.
#include <SoftwareSerial.h>
#include <avr/boot.h>  // Alleen nodig als je de ID van de chip wil lezen
SoftwareSerial Draad(2, 3); // Sluit pin 2 aan op 3 van de andere Arduino en omgekeerd

byte ID[10];
byte Naam1[] = {0x59, 0x36, 0x36, 0x32, 0x38, 0x37, 0xFF, 0x0F, 0x22, 0x18}; // Zet hier het adres in van een van je HC-05's
byte Naam;

void setup() {
  Draad.begin(115200);
  Serial.begin(9600);
  for (byte i = 0; i < 10; i++) ID[i] = boot_signature_byte_get(i + 14);
  Serial.print("{"); for (byte i = 0; i < 10; i++) {
    Serial.print("0x");
    Serial.print(ID[i], HEX);
    if (i < 9) Serial.print(",");
    else Serial.println("};");
  }
  if ( memcmp(ID, Naam1, 10) == 0 ) Naam = 1; else Naam = 2;
  Serial.print("Ik ben Arduino "); Serial.println(Naam);
  Serial.println("Typ een commando en verzend dat..");
  Serial.println("Ontvangen: ");
}

void loop() {
  if (Draad.available() > 0) Serial.write(Draad.read()); // Bericht van andere Arduino
  if (Serial.available()) {
    byte C = Serial.read();
    Draad.write(C);
  }
}

Serieel zonder SoftwareSerial

Je kunt ook communiceren zonder de SoftwareSerial bibliotheek te gebruiken. Je gebruikt dan de hardware poorten TX en RX (bij de meeste Arduino's digitaal 0 en 1). Een nadeel is dat je de Seriële monitor nu niet kunt gebruiken om het programma te debuggen. Als de Arduino's autonoom zijn (d.w.z. na opstarten doet de gebruiker niets meer), dan heb je het probleem dat de Arduino's tegelijk gaan zenden. In diverse communicatiesystemen zijn daar oplossingen voor bedacht, maar nu zul jij dat zelf moeten doen. Ik heb me hier gemakkelijk vanaf gemaakt door een willekeurige tijd te wachten voordat ze gaan zenden. De kans dat ze allebei tegelijk beginnen is daarmee zo goed als nul. Daarna zenden ze omstebeurt. Omdat (meestal) bij het uploaden de poorten TX en RX worden gebruikt moet je tijdens het uploaden de kabeltjes (aan een kant) even los halen. Je hebt een korte tijd nadat de Arduino's zijn gestart om de kabeltjes weer aan te sluiten en als dat niet lukt dan kun je gewoon de Arduino's resetten. Na enige tijd besluit een van de Arduino's tegen de ander te zeggen dat deze een led moet aandoen. De ander doet dat en zend na enige tijd de opdracht dat de eerste zijn led moet aandoen en hij zet zijn eigen led uit. Zo zie je de led op een neer springen tussen beide Arduino's. De duur dat de leds aan of uit zijn wordt tussen bepaalde grenzen willekeurig gekozen.
Je kunt zelf uiteraard ingewikkelder communicatie programmeren. In een echte applicatie zou je ook een timeout moeten invoeren: als de andere Arduino niet binnen een bepaalde tijd reageert (hier 2 s) dan heeft hij je bericht gemist en moet je het opnieuw verzenden. Beter nog is elke keer een zogenaamde "acknowledge" te sturen. Voor deze eenvoudige toepassing gaat dat echter te ver.
De sketch gaat uit van de led op pin 13. Veel (maar niet alle) Arduino's doen dan een led aan op de Arduino zelf. Door het pinnummer te veranderen kun je een andere ledpin gebruiken. Bij de Arduino Uno en de nano kun je zonder veel gevaar een extra led rechtstreeks op pin 13 aansluiten.
// Communicatie tussen 2 Arduino's
// Maak tijdens het uploaden de RX en TX kabeltjes aan een kant los
#define led 13 // Default led, of sluit hier een eigen led op aan
boolean Wacht = true, Aan = false;
unsigned long Start;

void setup() { // Sluit RX van Arduino_1 aan op TX van Arduino_2 en omgekeerd
  Serial.begin(57600); // Stel verbinding met andere Arduino in, welke baudrate je kiest is niet belangrijk
  pinMode(led, OUTPUT);
  randomSeed(analogRead(A0)); // Zorg dat er niets is aangesloten op A0
  Start = millis();
}

void loop() {
  if ( Serial.available() ) {
    Wacht = false;
    Aan = Serial.read(); // Lees wat de andere Arduino te zeggen heeft
    digitalWrite(led, Aan); // De andere Arduino zegt dat ik de led aan of uit moet doen
    delay(500 + random(1500)); // Wacht enige tijd
    digitalWrite(led, !Aan);
    Serial.write(Aan); // Zeg dat de andere Arduino zijn led uit of aan moet doen
    while ( !Serial.available() ); // Wacht tot de ander een signaal stuurt
  }
  if ( !Wacht ) return; // De conversatie is opgestart, vanaf nu gaan we om en om zenden
  if ( (millis() - Start) > 2000 + random(1000) ) { // Wacht tussen de 2 en 3 seconden
    Wacht = false; // Niet langer wachten: de conversatie is opgestart door mij
    Serial.write(HIGH); // Zeg tegen de andere Arduino dat hij de led aan moet doen
  }
}