Comment envoyer des numéros à Arduino UNO via Python 3 et le module série

9

Je suis nouveau sur Arduino (et la programmation informatique en général), donc je m'excuse si cette question semble idiote.

Une fois que j'ai configuré une connexion Arduino-LED de base, j'ai des problèmes pour envoyer des INTEGERS à Arduino via le port série. Je peux facilement envoyer des caractères tels que «m», «o» et ainsi de suite.

Voici le code Arduino, idéalement, il devrait obtenir une valeur du port USB via python ou le moniteur série, puis régler la luminosité de la LED en fonction de la valeur. (la valeur doit être dans la plage [0,255]).

REMARQUE: j'utilise ARDUINO UNO et PYTHON 3

// --------------------------

int LED = 10;
int number;

void setup(){

pinMode(LED,OUTPUT);
Serial.begin(9600);
}

void loop(){

number = Serial.read();
Serial.print(number);
Serial.print('\n');
if(number == -1){
number = 0;
}

else if(number > 255){

number = 255;

}

else if(number < 0){

number = 0;
}

analogWrite(LED,number);
delay(1000);
}

Cependant, lorsque j'entre une valeur dans le port série ou via Python, par exemple 0, cela me donne 48 comme réponse (ce qui est intéressant, c'est le code ASCII pour 0!) Et allume la LED ce qui n'est pas ce qui devrait arriver puisque à 0 la LED doit être éteinte !! Il me manque quelque chose mais je ne trouve pas quoi ... Pourriez-vous me dire ce qui ne va pas?

Voici le code que j'utilise en Python:

import serial
import time
try:
    arduino = serial.Serial(port,speed)
    time.sleep(2)
    print("Connection to " + port + " established succesfully!\n")
except Exception as e:
    print(e)

#Note: for characters such as 'a' I set data = b'a' to convert the data in bytes
#However the same thing does not work with numbers...
data = 0
data = arduino.write(valueToWrite)
time.sleep(2)
arduino.close()

que fais-je de mal ou de malentendu? Je vous remercie.

mickkk
la source
1
Essayezarduino.write(chr(valueToWrite))
Gerben
Cette solution ne fonctionne même pas pour les caractères. De plus, en ce qui concerne les caractères, cela fonctionne très bien en les envoyant simplement en octets tels que: b'm '. Quoi qu'il en soit, merci pour la réponse.
mickkk

Réponses:

6

L'analyse sur l'Arduino peut être lente et longue (ce qui est mauvais si vous utilisez la pré-mise à l'échelle de l'horloge ou si vous avez des tâches critiques), alors faisons-le en Python.

Le problème est que vous envoyez les nombres en ASCII alors que vous devez les envoyer en binaire brut. C'est là structqu'intervient.

3>> import struct
3>> print(struct.pack('>B', 0))
b'\x00'
3>> print(struct.pack('>B', 255))
b'\xff'
3>> print(struct.pack('>2B', 255, 0))
b'\xff\x00'
3>> print(struct.pack('>H', 9000))
b'#('

Donc ce que vous voulez vraiment, c'est:

data = arduino.write(struct.pack('>B', valueToWrite))

Ou quelque chose à cet effet.

Ignacio Vazquez-Abrams
la source
Merci beaucoup! Ceci est exactement ce que je cherchais!
mickkk
Malgré ce que dit le texte grisé de la boîte de commentaire vide, je vais dire merci! J'essayais d'écrire un flux binaire (fichier programme FPGA .bin) sur une puce flash SPI en utilisant un Teensy 3.2 avec Arduino comme interface PC -> flash, et c'était la clé pour le faire fonctionner du côté PC.
KyranF
1

Serial.read()lit seulement UN caractère du port série et retourne sa valeur ASCII, ce qui explique la 48vous avez.

Pour lire un numéro complet, vous avez 2 options:

  1. Utilisez Serial.parseInt()qui lit autant de caractères que nécessaire et effectue la conversion avant de renvoyer le numéro lu sous la forme d'un int. Veuillez vérifier la référence ici.
  2. Vous lisez chaque caractère dans une boucle (avec Serial.read()) jusqu'à la dernière, placez chaque caractère de lecture dans un tampon ( chartableau) puis convertissez la chaîne résultante en un nombre avec la fonction C standard atoi.

Bien sûr, la première option est la plus simple mais elle reviendra 0si rien n'est lu après un délai de 1 s (configurable avec Serial.setTimeout()).

jfpoilpret
la source
Cette réponse n'était pas exactement ce que je demandais, mais elle a été très utile et je vais l'utiliser! Merci beaucoup pour l'aide!
mickkk