arduino and raspberry 825x510 - Communication entre un Raspberry Pi et un Arduino

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…
raspberrypi arduino i2c - Communication entre un Raspberry Pi et un ArduinoEnfin, 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 :
IMG 9190 300x225 - Communication entre un Raspberry Pi et un Arduino IMG 9192 300x225 - Communication entre un Raspberry Pi et un Arduino

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 :
console find serial 1024x435 - Communication entre un Raspberry Pi et un Arduino

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.

14 réflexions au sujet de “Communication entre un Raspberry Pi et un Arduino”

  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

  2. bonjour. j’aimerais savoir s’il est possible de faire communiquer deux cartes raspberry à travers un LAN.
    exemple: raspberry 1 contrôle un système d’accès par badge et raspberry 2 est un serveur qui vérifie que les informations du badge utilisé sont enregistrer dans la base de données, qui renvoie un ok à raspberry 2, afin que l’accès puisse être autorisé.

  3. Bonjour
    Je cherche désespérément comment contrôler des moteurs alimentes en 12 v à l’aide d’une carte motor shield monté sur un arduino et relié en I2C sur mon raspberry pi 3 par une page Web. Si vous connaissez des articles merci de votre aide.

  4. Bonjour,
    Je voudrais essayer de remplacer mon automate programmable qui gère ma maison (depuis 28 ans 🙂 ) . J’ai 64 entrées TOR (TOout ou Rien) et 48 sorties relais 24V
    On m’a conseillé d’avoir un RAPBERY PI qui commande plusieurs ARDUINO . Qu’en pensez vous ?
    Cordialement
    Régis

    1. Bonjour,
      J’en penses que c’est une excellent idée, potentiellement ambitieuse. Depuis le temps que vous avez posté ce commentaire auquel j’ai sauvagement attendu pour répondre, avez-vous trouvé la façon de s’y prendre? Il me semble qu’il y a des moyens plus ou moins efficaces pour commander plusieurs arduinos, je suis curieux d’en savoir plus.

    1. En effet, je ne l’ai pas mentionné. L’utilisation de l’IDE Arduino ne fait pas partie des objectifs de ce tutoriel écrit sur mon temps personnel et partagé librement, aussi il y aura plusieurs informations que vous n’y trouverez pas dont celle-ci.
      Mes articles ont pour but de partager mes expériences, je n’ai pas la prétention d’en faire plus. Aussi il est probablement nécessaire de combler les trous que je laisse volontairement ou non, par de plus ou moins rapides recherches.
      Si en plus vous me permettez d’améliorer ces articles avec votre feedback sur ces lacunes, je n’en serais que très heureux 🙂

Répondre à Alain Rabe Annuler la réponse

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

Ce site utilise Akismet pour réduire le pourriel. En savoir plus sur comment les données de vos commentaires sont utilisées.