Go Down

Topic: Problème de script python pour piloter un arduino (Read 137 times) previous topic - next topic

astrofab

Bonjour à tous !

Je suis débutant dans le monde de l'Arduino et de la programmation. J'ai comme objectif de réaliser un bras robotisé constitué de trois servo pour mettre en place ou retirer un couvercle de télescope afin d'automatiser les prises de vues nocturne.
A l'aide de mBlock et divers morceaux de programme glanés sur le net, j'ai réussi à écrire une petite application fonctionnelle pour l'arduino qui me permet de piloter la fonction d'ouverture et fermeture en local à l'aide de deux boutons poussoir ou par l'intermédiaire de commandes envoyées sur le port série via la prise usb.
Voici le programme Arduino:


Code: [Select]

#include <Arduino.h>
#include <Servo.h>


Servo ServoCapot;
Servo ServoRotation;
Servo ServoTranslation;
const int boutonfermeture2 = 2;
const int boutonouverture3 = 3;
String commande;
int AngleServoCapot;
int AngleServoRotation;
int AngleServoTranslation;
int reception;




void setup()
{
    Serial.begin(115200);
    Serial.flush();
    ServoCapot.attach(10, 500, 2475); // init pin
    ServoRotation.attach(9, 500, 2475); // init pin
    ServoTranslation.attach(8, 500, 2475); // init pin
    pinMode(boutonfermeture2,INPUT);
    pinMode(boutonouverture3,INPUT);
    ServoCapot.write(0); // write to servo
    ServoRotation.write(137); // write to servo
    ServoTranslation.write(47); // write to servo
    AngleServoCapot = 0;
    AngleServoRotation = 137;
    AngleServoTranslation = 47;
   
}


void loop()
{             // put your main code here, to run repeatedly:
   
   while (Serial.available() > 0)
  {
    reception = Serial.read();
    commande += char(reception);
    delay(5);
  }

  if (commande != "")
  {
    traitementserial(); // Appel de la fonction
  }
   if(digitalRead(2) == HIGH)
    {
       fermeture(); // Appel de la fonction
    }
    if(digitalRead(3) == HIGH)
    {
       ouverture(); // Appel de la fonction
    }
}

// Fonctions

void ouverture() // Fonction de traitement de l'ouverture
{
        while(!(((AngleServoTranslation)==(137))))
        {
            _loop();
            ServoTranslation.write((AngleServoTranslation) + (1)); // write to servo
            AngleServoTranslation += 1;
            _delay(0.02);
        }
        _delay(1);
        while(!(((AngleServoCapot)==(180))))
        {
            _loop();
            ServoCapot.write((AngleServoCapot) + (1)); // write to servo
            AngleServoCapot += 1;
            _delay(0.02);
        }
        _delay(1);
        while(!(((AngleServoRotation)==(47))))
        {
            _loop();
            ServoRotation.write((AngleServoRotation) - (1)); // write to servo
            AngleServoRotation += -1;
            _delay(0.02);
        }
 }
 
 void fermeture() // Fonction de traitement de la fermeture
  {
   while(!(((AngleServoRotation)==(137))))
        {
            _loop();
            ServoRotation.write((AngleServoRotation) + (1)); // write to servo
            AngleServoRotation += 1;
            _delay(0.02);
        }
        _delay(1);
        while(!(((AngleServoCapot)==(0))))
        {
            _loop();
            ServoCapot.write((AngleServoCapot) - (1)); // write to servo
            AngleServoCapot += -1;
            _delay(0.02);
        }
        _delay(1);
        while(!(((AngleServoTranslation)==(47))))
        {
            _loop();
            ServoTranslation.write((AngleServoTranslation) - (1)); // write to servo
            AngleServoTranslation += -1;
            _delay(0.02);
        }
    }
   
 void traitementserial() // Fonction de traitement de la commande
{
  if (commande == "ouverture")
  {
    ouverture();
  }
  else if (commande == "fermeture")
  {
    fermeture();
  }
    else
  {
    Serial.print("Commande '" + commande + "' inconnue : ");// Traitement de la commande inconnue.
  }

  if ((AngleServoTranslation)==(47))
  {
    Serial.println("Capot fermé");
  }
  if ((AngleServoTranslation)==(137))
  {
    Serial.println("Capot ouvert");
  }
    commande = "";
}
 void _delay(float seconds){
    long endTime = millis() + seconds * 1000;
    while(millis() < endTime)_loop();
}

 void _loop(){
   
}


J'ai ensuite adapté un petit programme python que j'ai trouvé sur le très intéressant tutoriel « Piloter Arduino depuis un PC avec Python et Boa Constructor » à l'adresse suivante :
https://herve-troadec.developpez.com/tutoriels/arduino/initiation-boa/#LVII-B-5

Ce programme me permet d'envoyer les commandes nécessaires à l'Arduino pour ouvrir et fermer le couvercle.
Voici le programme python:

Code: [Select]

#!/usr/bin/python
# coding: utf8

import serial
import time

print("Initialisation du port")
portCom = serial.Serial()
portCom.port = "/dev/cu.usbserial-1420"
portCom.baudrate = 115200

print("Ouverture du port...")
try:
  portCom.open()
except serial.SerialException:
  print("Un problème s'est produit à l'ouverture du port.\n"
    "Vérifiez que le port utilisé par la carte Arduino est\n"
    "bien '/dev/cu.usbserial-1420'. Si ce n'est pas le cas, modifiez\n"
      "le script Python en conséquence.")
  saisie = ""
  while saisie != "q":
      saisie = str(raw_input("Entrer 'q' pour quitter: "))

while portCom.is_open:
  commande = str(raw_input("Saisir une commande ('q' pour quitter): "))
  if commande != "q":
    portCom.write(commande)   
    time.sleep(10)
    nbCar = portCom.in_waiting
    retour = portCom.read(nbCar)
    print(retour)
    portCom.reset_input_buffer()
  else:
    portCom.close()


Mais mes connaissances en programmation ne me permettent pas de modifier ce programme comme j'aimerais qu'il soit.
En fait, j'aimerais le simplifier au maximum. L'idée est de garder la possibilité de le quitter si il rencontre des difficultés à se connecter au port série de l'arduino mais j'aimerais ne pas avoir à écrire la commande d'ouverture ou de fermeture. Je voudrais avoir deux scripts, un pour l'ouverture et un autre pour la fermeture. Ces scripts envoient juste la commande à l'arduino, vérifient que la commande a bien été envoyée et si oui, il quitte ou si non, un message « erreur » s'écrit.
J'ai essayé ceci mais cela ne marche pas bien. Le programme s'arrête comme si la condition « if retour == "Capot ouvert »: » ne fonctionnait pas
Voici le programme python modifié:

Code: [Select]

#!/usr/bin/python
# coding: utf8

import serial
import time

print("Initialisation du port")
portCom = serial.Serial()
portCom.port = "/dev/cu.usbserial-1420"
portCom.baudrate = 115200

commande = "ouverture"

print("Ouverture du port...")
try:
  portCom.open()
except serial.SerialException:
  print("Un problème s'est produit à l'ouverture du port.\n"
    "Vérifiez que le port utilisé par la carte Arduino est\n"
    "bien '/dev/cu.usbserial-1420'. Si ce n'est pas le cas, modifiez\n"
      "le script Python en conséquence.")
  saisie = ""
  while saisie != "q":
      saisie = str(raw_input("Entrer 'q' pour quitter: "))

while portCom.is_open:
    portCom.write(commande)   
    time.sleep(10)
    nbCar = portCom.in_waiting
    retour = portCom.read(nbCar)
    if retour == "Capot ouvert":
        print(retour)
        portCom.reset_input_buffer()
        portCom.close()
    else:
        print("erreur")
        portCom.close()


Si certains d'entre vous peuvent m'aiguiller, ce serait super cool !

L'idée, au finale, est de faire deux scripts exécutables à l'aide de py2app.

Merci par avance…

hbachetti

Il suffit de supprimer la boucle while.
Évidemment il faut ré-indenter correctement ce qui suit.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

astrofab

#2
Apr 18, 2019, 03:53 pm Last Edit: Apr 18, 2019, 04:11 pm by astrofab
Merci hbachetti !

De quelle boucle while parlez-vous ?

J'ai essayé ça mais ça ne marche pas :

Code: [Select]

#!/usr/bin/python
# coding: utf8

import serial
import time

print("Initialisation du port")
portCom = serial.Serial()
portCom.port = "/dev/cu.usbserial-1420"
portCom.baudrate = 115200

commande = "ouverture"

print("Ouverture du port...")
try:
    portCom.open()
except serial.SerialException:
    print("Un problème s'est produit à l'ouverture du port.\n"
    "Vérifiez que le port utilisé par la carte Arduino est\n"
    "bien '/dev/cu.usbserial-1420'. Si ce n'est pas le cas, modifiez\n"
      "le script Python en conséquence.")
    saisie = ""
    while saisie != "q":
      saisie = str(raw_input("Entrer 'q' pour quitter: "))

    portCom.write(commande)    
    time.sleep(10)
    nbCar = portCom.in_waiting
    retour = portCom.read(nbCar)
    if retour == "Capot ouvert":
        print(retour)
        portCom.reset_input_buffer()
        portCom.close()
    else:
        print("erreur")
        portCom.close()


J'ai aussi essayé ça sans succès :

Code: [Select]

#!/usr/bin/python
# coding: utf8

import serial
import time

print("Initialisation du port")
portCom = serial.Serial()
portCom.port = "/dev/cu.usbserial-1420"
portCom.baudrate = 115200

commande = "ouverture"

print("Ouverture du port...")
try:
    portCom.open()
except serial.SerialException:
    print("Un problème s'est produit à l'ouverture du port.\n"
    "Vérifiez que le port utilisé par la carte Arduino est\n"
    "bien '/dev/cu.usbserial-1420'. Si ce n'est pas le cas, modifiez\n"
      "le script Python en conséquence.")
    saisie = ""
    while saisie != "q":
      saisie = str(raw_input("Entrer 'q' pour quitter: "))

portCom.write(commande)   
time.sleep(10)
nbCar = portCom.in_waiting
retour = portCom.read(nbCar)
if retour == "Capot ouvert":
    print(retour)
    portCom.reset_input_buffer()
    portCom.close()
else:
    print("erreur")
    portCom.close()

hbachetti

Sans les messages d'erreur ... cela va être difficile

/dev/cu.usbserial-1420 : ce device existe t-il ?
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

astrofab

Oui, ce port série est bien celui connecté à l'arduino. Cela communique mais le résultat n'est pas bon.

Dans la première modification la boucle ne s'arrête pas. Je reçois à chaque cycle le message "Capot ouvert" alors qu'il devrait s'arrêter.

Dans les deux autres modifications le programme "quitte" comme si il avait fini mais ne commande pas les servo.

Voilà ce qui se passe.

Go Up