Menu Fermer

Communiquer entre un Arduino et un Raspberry Pi via USB (Python, Java) (1/2)

Un article sur ce sujet a été soumis à developpez.com et est maintenant disponible sous le titre Créer une communication entre Arduino et Raspberry Pi 3 via USB.

Au chapitre 19, j’ai expliqué avoir eu quelques difficultés avec mon capteur ultrasonique et son script Python associé. Un test sur un Arduino m’a permis d’adapter le timing du script Python.

Préparation sur l’Arduino

J’ai donc monté sur mon tout vieux Arduino Duemilanove un capteur ultrasonique et j’y ai ajouté un relais pour jouer avec ce croquis (ou sketch en anglais) développé avec  l’IDE d’Arduino:

Référence et téléchargement du script (dé-zipper d’abord dans Notepad++)

Ce sketch n’est pas grandiose, mais plus ou moins fonctionnel. Il demanderait quelques adaptations. Suivant les objets qui se déplacent devant le capteur, le relais sera actif pour 4 secs.

Le numéro des broches est indiqué en début de sketch et la connexion du capteur ultrasonique est identique à la figure 19-2 du livre. Pour le relais c’est la figure 15-2. Les deux composants n’utilise que du 5V et une planche à pain est nécessaire.

Lorsque nous aurons terminé de déposer ce sketch dans l’IDE de l’Arduino sur notre PC et les tests dans la fenêtre console de ce même IDE, nous retirerons le câble côté PC pour le brancher sur une des 4 entrées USB du Raspberry Pi B ou celle, unique, du Raspberry Pi A+.

Préparation sur le Raspberry Pi

Nous ferons un premier test avec Python, comme d’habitude, avant de passer éventuellement à Java. Il faudra commencer par installer la librairie Python pour l’interface série:

sudo apt-get install python-serial

Un message nous indiquera si cette librairie est déjà installée, mon cas.

Ensuite il faudra déterminer avec la commande ls quel device (/dev) est utilisé (nous sommes déjà dans le répertoire python où nous avons déposé nos autres scripts Python du livre):
pi@raspberrypi:~/python $ ls /dev/tty*

…………………….
/dev/tty10 /dev/tty19 /dev/tty27 /dev/tty35 /dev/tty43 /dev/tty51 /dev/tty6 /dev/ttyprintk
/dev/tty11 /dev/tty2 /dev/tty28 /dev/tty36 /dev/tty44 /dev/tty52 /dev/tty60 /dev/ttyUSB0
/dev/tty12 /dev/tty20 /dev/tty29 /dev/tty37 /dev/tty45 /dev/tty53 /dev/tty61
…………………….

Nous essayerons la commande Linux cat sur ce device /dev/ttyUSB0 qui semble être le bon:

pi@raspberrypi:~/python $ cat /dev/ttyUSB0
Start relais_distance
^C
pi@raspberrypi:~/python $

Le Start relais_distance est bien le premier println de notre script Arduino ci-dessus.

Le script Python

Nous déposerons ensuite un script arduino_usb1.py dans notre répertoire /home/pi/python (attention à l’indentation):

# coding: utf-8
import time
import serial

ser = serial.Serial(‘/dev/ttyUSB0’, 9600)

while 1 :
  print(ser.readline())
t
ime.sleep(0.1)

Il fonctionne:

pi@raspberrypi:~/python $ python arduino_usb1.py
▒Start relais_distance

Distance: 75

Relais ON

Distance: 74

Distance: 74

Distance: 74

Il nous restera à améliorer notre script Arduino, faire quelque chose d’un peu plus intelligent, comme envoyer des données dans l’autre direction et pareil en Java sur ce /dev/ttyUSB0.

Une classe Java sous Windows

Tester un sketch Arduino dans son IDE sur le PC est la manière traditionnelle.

Mais pourquoi donc ne pas écrire une jolie petite classe Java USBPort (même nom de projet) avec Eclipse sur ce même PC Windows et qui fera un travail similaire … et pourrait être étendu:

import java.io.IOException;
import java.io.RandomAccessFile;

public class USBPort implements Runnable {
  private Thread monThread;
  private RandomAccessFile rAF;
  private String portName;

  public USBPort(String portName) {
    this.portName = portName;
    monThread = new Thread(this);
  }

  public void start() {
    try {
      rAF = new java.io.RandomAccessFile(portName, "rwd");
      rAF.writeBytes("\r\n");
    } 
    catch (Exception e) {
      System.out.println("start " + e.toString());
    }

    monThread.start();
  }

  public void run() {
    System.out.println("Lecture du port " + portName);
    
    for (int i = 0; i < 10; i++) {
      String response = null;
      try {
        response = rAF.readLine();
      } 
     catch (IOException e) {
       System.out.println(e.getMessage()); 
     }
     System.out.println(response);
   }
 }

 public static void main(String[] args) {
   String portDevice = "COM3";
   if (args.length > 0) {
     portDevice = args[0];
   }

   USBPort usbPort = new USBPort(portDevice);
   usbPort.start();
 }
}

Nous rebrancherons notre câble USB, cette fois-ci sur le PC. Le port COM3 ici a été identifié avec l’IDE de l’Arduino et dépend du connecteur du PC utilisé. En ayant testé l’interface COM avec l’IDE, la bonne configuration sera mise. Si aucun résultat n’est retourné il faudra adapter correctement le port COM correspondant.

mode COM3 dans une fenêtre DOS CMD va nous fournir l’information et une commande  mode COM3 baud=9600 devrait suffire. Nous avions indiqué la vitesse avec l’instruction Serial.begin(9600);  dans le sketch.

L’envoi de rAF.writeBytes(« \r\n »); permet de redémarrer le sketch sur l’Arduino et le for (int i = 0; i < 10; i++) { de stopper le programme après 10 itération. Si nous exécutions java USBport dans le répertoire bin de notre Workspace d’Eclipse, nous verrions le même résultat:

D:\EclipseWorkspace.......\bin>java USBPort COM3
Lecture du port COM3
Start relais_distance
Distance: 89
Relais ON
Distance: 87
Distance: 87
Distance: 88
Distance: 88
Distance: 87
Distance: 88
Distance: 89

COM3 peut être passé par le args[] du main() de Java.

88 cm: juste! J’ai posé mon Arduino sur une table plus loin avec le mur derrière (pratique mon câble USB de 2 m).

Exécuter USBPort sur le Raspberry Pi

Comme décrit dans mon livre à plusieurs occasions, nous transférerons le fichier USBPort.class depuis le Workspace d’Eclipse sur le Raspberry Pi dans le répertoire habituel /home/pi/java. Il faudra alors faire passer le câble USB du PC sur le Raspberry Pi, évidemment!

La commande ici sera:

java USBPort /dev/ttyUSB0

avec le « device » déterminé ci-dessus. Le résultat sera le même que ci-dessus!

En cas de difficulté avec la configuration du port, la commande stty est équivalente à MODE sous DOS. Par exemple:

sudo stty -F /dev/ttyUSB0 -a
sudo stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb


Dans un second article, plus détaillé que celui-ci et avec un schéma Fritzing, nous reprendrons notre Arduino qui possède déjà un relais, pour:

  • Y ajouter un capteur analogique LM35 (pas possible sur un Raspberry Pi sans interface analogique);
  • Développer un sketch Arduino pour:
    – enclencher le relais (petit chauffage) si la température est trop basse
    – recevoir la température sur le PC
    – décider si le Pi prend le contrôle pour enclencher ou déclencher le relais;
  • Envoyer une nouvelle limite de température;
  • Développer une classe Java dédié au Raspberry Pi pour faire le travail!
Date de la dernière modification: 11 mai 2019