So senden Sie Nummern über Python 3 und die Modulserie an Arduino UNO

9

Ich bin neu in Arduino (und Computerprogrammierung im Allgemeinen), also entschuldige ich mich, wenn diese Frage albern aussieht.

Sobald ich eine grundlegende Arduino-LED-Verbindung eingerichtet habe, habe ich Probleme, INTEGERS über die serielle Schnittstelle an Arduino zu senden. Ich kann leicht Zeichen wie 'm', 'o' usw. senden. Wenn ich jedoch eine Nummer sende, sieht es so aus, als würde sie einfach nicht verstanden.

Hier ist der Arduino-Code. Idealerweise sollte er einen Wert vom USB-Anschluss über Python oder den seriellen Monitor erhalten und dann die Helligkeit der LED entsprechend dem Wert anpassen. (Wert muss im Bereich [0,255] liegen).

HINWEIS: Ich verwende ARDUINO UNO und 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);
}

Wenn ich jedoch einen Wert in den seriellen Port oder über Python eingebe, zum Beispiel 0, erhalte ich 48 als Antwort (was interessanterweise der ASCII-Code für 0 ist!) Und leuchtet die LED auf, was seitdem nicht mehr passieren sollte bei 0 sollte die LED aus sein !! Mir fehlt etwas, aber ich kann nicht finden, was ... Könnten Sie mir bitte sagen, was los ist?

Hier ist der Code, den ich in Python verwende:

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()

Was mache ich falsch oder missverstehe ich? Danke.

mickkk
quelle
1
Versuchen Siearduino.write(chr(valueToWrite))
Gerben
Diese Lösung funktioniert nicht einmal für Zeichen. Außerdem funktioniert sie in Bezug auf Zeichen einwandfrei, wenn sie nur als Bytes gesendet werden, z. B.: B'm '. Trotzdem danke für die Antwort.
Mickkk

Antworten:

6

Das Parsen auf dem Arduino kann langsam und zeitaufwändig sein (was schlecht ist, wenn Sie die Uhrvorverkalkung verwenden oder zeitkritische Aufgaben haben). Lassen Sie es uns also in Python tun.

Das Problem ist, dass Sie die Zahlen als ASCII senden, während Sie sie als rohe Binärdatei senden müssen. Hier kommt ins structSpiel.

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'#('

Was Sie also wirklich wollen, ist:

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

oder etwas in diesem Sinne.

Ignacio Vazquez-Abrams
quelle
Vielen Dank! Genau das habe ich gesucht!
Mickkk
Trotz allem, was der graue Text im leeren Kommentarfeld sagt, werde ich mich bedanken! Ich habe versucht, einen Bitstrom (FPGA .bin-Programmdatei) mit einem Teensy 3.2 mit Arduino als PC -> Flash-Schnittstelle auf einen SPI-Flash-Chip zu schreiben, und dies war der Schlüssel, damit er auf dem PC funktioniert.
KyranF
1

Serial.read()Liest nur EIN Zeichen von der seriellen Schnittstelle und gibt seinen ASCII-Wert zurück, der erklärt, was 48Sie erhalten haben.

Um eine vollständige Nummer zu lesen, haben Sie zwei Möglichkeiten:

  1. Verwenden Sie Serial.parseInt()diese Option, um so viele Zeichen wie nötig zu lesen und die Konvertierung durchzuführen, bevor Sie die gelesene Nummer als zurückgeben int. Bitte überprüfen Sie die Referenz hier weiter.
  2. Sie lasen eachn Zeichen in einer Schleife (mit Serial.read()) , bis dem letzten, setzen jede Lese charcater in einen Puffer ( charArray) , dann zu einer Reihe mit der Standard - C - Funktion , um die resultierenden Zeichenfolge konvertiert atoi.

Natürlich ist die erste Option die einfachste, aber sie wird zurückgegeben, 0wenn nach einer Zeitüberschreitung von 1s nichts mehr gelesen wird (konfigurierbar mit Serial.setTimeout()).

jfpoilpret
quelle
Diese Antwort war nicht genau das, wonach ich gefragt habe, aber sie war sehr nützlich und ich werde sie verwenden! Vielen Dank für die Hilfe!
Mickkk