Communication entre un Raspberry Pi et un Arduino

Nous avons appris à lire et émettre des signaux RF et Infrarouge à l’aide d’un Arduino. La prochaine étape? Construire une application web qui va recevoir des commandes et les envoyer à l’Arduino. Une application web ne pouvant pas exister sur un Arduino, cela impliquera de passer par un Raspberry Pi. Il s’agira donc d’abord de comprendre comment faire communiquer ces deux devices, et pour cela deux possibilités : I2C ou USB.

 

Cet article fait partie d’une série en plusieurs parties :

Partie 1 : Lire et émettre un signal radio 433MHz
Partie 2 : Lire un signal infrarouge
Partie 3 : Emettre un signal infrarouge
> Partie 4 : Communication entre un Raspberry Pi et un Arduino
Partie 5 : Intégration via NodeJS, configuration du système complet de domotique

 

 

Quelle méthode, I2C ou USB ?

Pour répondre à cette question, je commencerais par dire que l’avantage d’une connexion USB est d’alimenter l’Arduino sans devoir multiplier les soudures ou les sources d’alimentation externes, dérivations, etc. On branche, ça marche, point.

En plus cela nous permet de plus librement sortir l’Arduino de son environnement en cas de problème. C’est un détail, mais lorsqu’il a fallu que je mette le code à jour j’étais content de pouvoir juste le débrancher et le sortir…

Enfin, j’ai lu que la connexion I2C nécessitait de rajouter quelques composants pour avoir une connexion stable.

Sans cela la librairie Arduino Wire nécessaire pour communiquer via cette connexion pourrait freeze au moindre bit corrompu, ou demanderait une réinitialisation au complet en cas de déconnexion en cours de communication. Je ne sais pas à quel point c’est fréquent, mais je n’ai trouvé aucune justification réelle pour passer du temps à le savoir.

Du côté d’une communication par connexion USB, il n’y a rien à ajouter comme bibliothèque, le code est on ne peut plus simple !

Bref, j’ai vu de potentielles complications à utiliser I2C (que ce soit matérielles comme software), et je n’ai pu voir que des avantages à utiliser l’USB pour mon usage sommes toutes assez simple. Le choix était fait ! J’ai juste pris un peu de temps pour me bricoler un câble MicroUSB/USB plus court avec un point de soudure, c’était plus pratique à ranger dans la première version de ma boite de domotique :

 

Préparer le terrain : Sur l’Arduino

Le code à uploader sur l’Arduino pour tester la connexion est extrêmement simple. Ce qu’on va essayer de faire c’est d’écrire une lettre dans la console série de l’Arduino depuis le Pi. L’Arduino va écouter ce port série, et dès que quelque chose y est écris PAF, on le recopie !

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  while (Serial.available())  {
    message = Serial.read()-'0';  // on soustrait le caractère 0, qui vaut 48 en ASCII
    Serial.println(message);
  }
  delay(10);
}

Maintenant branchez l’Arduino sur un port USB du Pi, ouvrez le moniteur série, et allons côté Raspberry et code Python…

 

Raspberry Pi et Arduino communication USB

 

Préparer le terrain : Sur le Raspberry Pi

Deux choses à faire pour cela :

  • Installer pyserial pour parler au port USB avec un script Python (qui fera deux lignes)
  • Identifier le port USB utilisé (pour être certain de parler au bon)

Commençons par nous connecter en ssh sur le Raspberry Pi. Je vais supposer que cette partie est connue, si non il y a tout plein d’articles sur le web qui en parlent 😉

De là, installons pyserial :

sudo apt-get install python-serial

Ensuite, pour savoir quel port est utilisé, utilisez la commande :

ls /dev/tty*

Ce qui donne :

 

Maintenant que nous avons l’identifiant du port USB sur lequel est branché l’Arduino, regardons le code Python qui est comme promis, très très simple :

 

import sys     # pour la gestion des parametres
import serial  # bibliothèque permettant la communication série
#On écrit dans l'interface /dev/ttyUSB0 à 9600 bauds
ser = serial.Serial('/dev/ttyUSB0', 9600)
#On écrit dans la console série de l'Arduino la lettre passée en paraètre lors de l'éxecution de la commande :
ser.write(sys.argv[1])

 

Depuis votre console ssh en supposant que vous avez python d’installé (qui l’est par défaut je crois) :

  • cd /home/pi
  • nano test.py
  • Copiez collez le code ci-dessus
  • Ctrl+X / Y pour sauvegarder
  • Puis lancez la commande python test.py a

Normalement, vous devriez observer sur le moniteur série de l’Arduino le chiffre 49, qui est le code Ascii de la lettre a minuscule passée en paramètre du script python.

Et voilà, félicitations, vous avez établi un lien de communication entre votre Arduino et votre Raspberry Pi !

 

La suite ?

Et bien pour la suite, les possibilités sont grandes. Depuis l’Arduino, on pourra faire un switch/case sur ce que nous pouvons lire dans la console :

 

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  while (Serial.available())  {
    message = Serial.read()-'0';  // on soustrait le caractère 0, qui vaut 48 en ASCII
    Serial.println(message);
    switch(message)
    {
      case 49: // Code Ascii de la lettre a minuscule
        Serial.println("On vient de taper la lettre a")
      break;
      default:
        Serial.println("Default");
    }
  }
  delay(10);
}

 

Et depuis une application node hébergée sur le Pi, on pourrait lancer l’exécution du script python avec un paramètre, en fonction de ce que l’on souhaite faire. Voici par exemple un extrait de mon appli que j’ai baptisé avec beaucoup d’imagination « Remote », avec la fonction qui pilote l’émetteur RF433MHz qui est sur l’Arduino :

 

function executePythonScript(msg){
    logger.trace("Sending command " + msg + "(" + commands[msg] + ") to arduino");
    var options = {scriptPath:pyScripts, args:[ commands[msg] ]};
    PythonShell.run('RFremote.py', options, function (err) {
      if (err){
        logger.error('RFremote.py failed to run'); res.sendStatus(404);
        throw err;
      }
    });
}

 

Si vous avez des suggestions d’amélioration de cet article, n’hésitez pas à les partager, tout travail est perfectible !

 

Mise à jour : Communication de l’Arduino vers le Raspberry Pi

Merci à Alain pour son commentaire ayant motivé cet ajout de paragraphe 🙂

Sur l’Arduino

Sur l’Arduino, on peut tester la valeur reçue depuis un récepteur radio (Voir l’article Comment lire et émettre un signal radio RF 433Mhz avec un Arduino Nano) et la tester pour effectuer une action, en l’occurence pourquoi pas écrire sur le port série qui sera ensuite lu par le Raspberry Pi.

#include
RCSwitch mySwitch = RCSwitch();
void setup() {
    Serial.begin(9600);
    mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
}
void loop() {
    mySwitch.getReceivedValue();
    if (mySwitch.available()) {
        int value = mySwitch.getReceivedValue();
        switch(value) {
            case 1234:
                //actions comme Serial.println("Cas1");
            break;
            case 5678:
                //actions comme Serial.println("Cas2");
            break;
    }
    mySwitch.resetAvailable();
    }
}

Sur le Raspberry Pi

Du côté du Pi si vous avez suivi ce tutoriel vous avez tout ce dont vous avez besoin. La différence, c’est qu’au lieu d’écrire dans la console de l’Arduino avec ser.write(sys.argv[1]) depuis notre script Pyhton, on va plutôt lire ce qu’il nous dit avec :

ser.readline();

En stockant cela dans une variable, vous pourrez ensuite la tester et effectuer des actions en fonction de sa valeur.

2 commentaires

  1. Bonjour
    débutant sur l’arduino, je voudrais faire l’inverse de cet exemple : Utiliser l’Arduino avec un récepteur 433Mhz et exécuter du code (python ou Nodejs) sur le PI…Auriez vous un exemple?
    merci d’avance

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *