Jestem nowy w Arduino (i ogólnie programowaniu komputerowym), więc przepraszam, jeśli to pytanie wygląda głupio.
Po skonfigurowaniu podstawowego połączenia arduino-LED mam problemy z wysyłaniem INTEGERÓW do arduino przez port szeregowy. Mogę łatwo wysyłać znaki, takie jak „m”, „o” itd. Jednak jeśli wyślę numer, wygląda na to, że po prostu go nie dostanie.
Oto kod Arduino, najlepiej powinien uzyskać wartość z portu USB przez python lub monitor szeregowy, a następnie dostosować jasność diody LED zgodnie z wartością. (wartość musi mieścić się w zakresie [0,255]).
UWAGA: Używam ARDUINO UNO i 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);
}
Jednak gdy wprowadzam wartość do portu szeregowego lub przez Python, na przykład 0, daje mi 48 jako odpowiedź (co, co ciekawe, jest kodem ASCII dla 0!) I zapala diodę, co nie powinno się zdarzyć, ponieważ przy 0 dioda LED powinna zgasnąć !! Coś mi brakuje, ale nie mogę znaleźć ... Czy mógłbyś mi powiedzieć, co jest nie tak?
Oto kod, którego używam w Pythonie:
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()
co robię źle lub nieporozumienie? Dziękuję Ci.
źródło
arduino.write(chr(valueToWrite))
Odpowiedzi:
Analiza na Arduino może być powolna i czasochłonna (co jest złe, jeśli używasz wstępnego skalowania zegara lub wykonujesz zadania o krytycznym czasie), więc zróbmy to w Pythonie.
Problem polega na tym, że wysyłasz liczby jako ASCII, podczas gdy musisz wysyłać je jako surowe dane binarne. To jest, gdzie
struct
przychodzi.Więc tak naprawdę chcesz:
lub coś w tym rodzaju.
źródło
Serial.read()
czyta tylko JEDEN znak z portu szeregowego i zwraca jego wartość ASCII, co wyjaśnia48
otrzymaną wartość.Aby odczytać pełny numer, masz 2 opcje:
Serial.parseInt()
która odczytuje tyle znaków, ile potrzeba i wykonuje konwersję przed zwróceniem odczytanego numeru jakoint
. Więcej informacji znajdziesz tutaj.Serial.read()
) aż do ostatniego, umieścić każdy charcater wczytywane do bufora (char
array), a następnie przekonwertować ciąg wynikowy do numeru ze standardową funkcją Catoi
.Oczywiście pierwsza opcja jest najłatwiejsza, ale wróci,
0
jeśli po upływie limitu czasu nic nie zostanie odczytane (konfigurowalne za pomocąSerial.setTimeout()
).źródło