PYTHON
ARDUINO ET LA LIAISON USB

Introduction

Le moniteur série et le traceur série de l'EDI Arduino permettent juste d'effectuer des tests. La présentation imposée par l'EDI reste sommaire et non modifiable. De surcroît, l'EDI doit être démarré.

Pour développer une véritable IHM (interface homme machine), il faut se tourner vers un langage capable de traiter la liaison USB. Parmi ces langages, le Python est une solution très efficaces.

Récupérer sur le PC les données provenant de la carte Arduino

Afficher du texte, des nombres

Code pour la carte Arduino

Le code à charger sur la carte Arduino UNO est le même que celui du compteur, disponible dans la partie Débuter avec Arduino.

unsigned int compteur = 0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.print("Compteur : ");
  Serial.println(compteur);
  compteur++;
  delay(2000);
}

Code en Python

Un exemple de code à faire tourner sur le PC est proposé ci-dessous.

#!/usr/bin/python3

import serial
portUSB=serial.Serial('/dev/ttyUSB0', 115200)
# portUSB=serial.Serial('COM3', 115200)

while True:
  lu=portUSB.readline()[:-2] 
  print('Texte retourné par la carte Arduino UNO : ', lu.decode('utf-8'))

Explications :

Tracer une courbe

Code pour la carte Arduino

Le code à charger sur la carte Arduino UNO est le même que celui de la sinusoïde, disponible dans la partie Débuter avec Arduino.

float v=0.0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println(round(511.5*sin(v)+511.5));
  v=v+0.1;
  delay(20);
} 

Code en Python

Un exemple de code à faire tourner sur le PC est proposé ci-dessous.

#!/usr/bin/python3

duree=5
dt=0.02

import matplotlib.pyplot as plt
import serial
portUSB=serial.Serial('/dev/ttyUSB0', 115200)
# portUSB=serial.Serial('COM3', 115200)

instant=[]
valeur=[]
t=0
while (t<duree) :
  lu=portUSB.readline()[:-2]
  valeur.append(int(lu.decode('utf-8')))
  instant.append(t)
  t=t+dt
  
plt.grid(True)
plt.plot(instant,valeur)
plt.show()

Résultat :

Explications :

Tracer une courbe - variante

Plutôt que d'envoyer des octets désignant des caractères, la carte Arduino UNO transmet des octets représentant des nombres. La plage de valeurs à communiquer dépassant 256, chaque nombre utilise deux octets, suivis d'un troisième pour le saut de ligne.

Code pour la carte Arduino

float v=0.0;
int e;

void setup() {
  Serial.begin(115200);
}

void loop() {
  e=round(511.5*sin(v)+511.5);
  Serial.write(e/256);
  Serial.write(e%256);
  Serial.write(10);
  v=v+0.1;
  delay(20);
}

Code en Python

Un exemple de code à faire tourner sur le PC est proposé ci-dessous.

#!/usr/bin/python3

duree=8
dt=0.02

import matplotlib.pyplot as plt
import serial
portUSB=serial.Serial('/dev/ttyUSB0', 115200)
# portUSB=serial.Serial('COM3', 115200)

instant=[]
valeur=[]
t=0
while (t<duree) :
  try :
    lu=portUSB.readline()[:-1]
    valeur.append(lu[0]*256+lu[1])
    instant.append(t)
    t=t+dt
  except :
    pass

plt.grid(True)
plt.plot(instant,valeur)
plt.show() 

Piloter la carte Arduino depuis le PC

Piloter la DEL de la carte en envoyant un caractère

Le programme à installer sur la carte Arduino UNO provient de la partie Débuter avec Arduino.

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  while (Serial.available()==0) { }
  int octet = Serial.read();
  if (octet == 97) {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  if (octet == 101) {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Exemple de programme en Python :

#!/usr/bin/python3

import serial
portUSB=serial.Serial('/dev/ttyUSB0',115200)
# portUSB=serial.Serial('COM3', 115200)

print ("Entrer a pour allumer la DEL, e pour l'éteindre, s pour stopper.")
while True:
  car = input("Saisir votre commande : ")
  if (car=='s'):
    portUSB.close()
    break
  portUSB.write(car.encode('utf-8'))
# portUSB.write(bytes(car, 'utf-8'))

Piloter la carte Arduino avec une chaîne de caractères

Un exemple de programme à installer sur la carte Arduino UNO :

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  while (Serial.available() > 0) {
    String commande = Serial.readString();
    commande.trim();
    if (commande == "Allumer DEL") {
      digitalWrite(LED_BUILTIN, HIGH);
    }
    if (commande == "Eteindre DEL") {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}

Le code en Python est similaire au précédent. A la différence du moniteur série de l'EDI Arduino, l'envoi d'une chaîne de caractères ne s'accompagne pas de l'ajout du caractère '\n'. Le code doit donc être légèrement adapté.

#!/usr/bin/python3

import serial
portUSB=serial.Serial('/dev/ttyUSB0',115200)
# portUSB=serial.Serial('COM3', 115200)

print ("Entrer Eteindre DEL, Allumer DEL ou Stop.")
while True:
  txt = input("Saisir votre commande : ")
  if (txt=="Stop"):
    portUSB.close()
    break
  txt = txt+"\n"
  portUSB.write(txt.encode('utf-8'))

Etablir un dialogue

Un simple aller-retour

Programme a installer sur la carte Arduino UNO :

void setup() {
  Serial.begin(115200);
  delay(100);
  while (Serial.read()!=-1);
}

void loop() {
  while (Serial.available()==0) { }
  String texte=Serial.readString();
  Serial.println(texte);
}

Programme en Python :

#!/usr/bin/python3
import serial
portUSB=serial.Serial('/dev/ttyUSB0',115200)
# portUSB=serial.Serial('COM3', 115200)

while True:
  texte = input("Saisir un texte : ")
  portUSB.write(texte.encode('utf-8'))
  retour = portUSB.readline()
  print("Texte reçu par la carte Arduino : ", retour.decode('utf-8'))

Exemple de calcul

Le code à charger sur la carte Arduino UNO est le même que celui disponible dans la partie Débuter avec Arduino.

void setup() {
  Serial.begin(115200);
  delay(100);
  while (Serial.available()!=0) { Serial.read(); }
}

void loop() {

  Serial.println("Entrer un nombre entier : nb1 = ?");
  while (Serial.available()==0) { }
  String ch_nb1=Serial.readString();

  Serial.println("Entrer un autre nombre entier : nb2 = ?");
  while (Serial.available()==0) { }
  String ch_nb2=Serial.readString();

  int nb1 = ch_nb1.toInt();
  int nb2 = ch_nb2.toInt();
  int nb3 = 2*nb1+nb2;
 
  Serial.print("2 x nb1 + nb2 = 2 x ");
  Serial.print(nb1);
  Serial.print(" + ");
  Serial.print(nb2);
  Serial.print(" = ");
  Serial.println(nb3);
  
}

Le code en Python devient :

#!/usr/bin/python3
import serial
portUSB=serial.Serial('/dev/ttyUSB0',115200)
# portUSB=serial.Serial('COM3', 115200)

while True:
  message1 = portUSB.readline()[:-2]
  nb1 = input(message1.decode('utf-8'))
  portUSB.write(nb1.encode('utf-8'))
  message2 = portUSB.readline()[:-2]
  nb2 = input(message2.decode('utf-8'))
  portUSB.write(nb2.encode('utf-8'))
  resultat = portUSB.readline()[:-2]
  print(resultat.decode('utf-8'))

Exercice d'application

Réaliser un programme pour calculer l'indice de masse corporelle :