Z powodzeniem postępowałem zgodnie z instrukcjami na tej stronie:
http://www.doctormonk.com/2012/04/raspberry-pi-and-arduino.html
i udało mi się uzyskać komunikację między pi a moim arudino mega dokładnie tak, jak to określa strona internetowa.
Jednak zamiast wysyłać liczbę całkowitą reprezentującą liczbę mrugnięć diody LED, chcę wysłać tekst ASCII, taki jak:
„PRZESUŃ 5 METRÓW DO PRZODU”, „SKRÓCJ W LEWO”, „PRZESUŃ 10 METRÓW DO TYŁU” do arduino z pi.
Napisałem następujący kod:
char inData[64];
char inChar=-1;
void setup(){
Serial.begin(9600);
Serial.begin("Waiting for Raspberry Pi to send a signal...\n");
}
void loop(){
byte numBytesAvailable= Serial.available();
// if there is something to read
if (numBytesAvailable > 0){
// store everything into "inData"
int i;
for (i=0;i<numBytesAvailable;i++){
inChar= Serial.read();
inData[i] = inChar;
}
inData[i] = '\0';
Serial.print("Arduino Received: ");
Serial.println(inData);
}
}
Z powodzeniem sflashowałem powyższy kod do mojego Arduino Mega 2560.
Przełączyłem się na terminal Python na Raspberry Pi i w konsoli wpisałem:
import serial
ser = serial.Serial('/dev/ttyACM1',9600)
ser.write("MOVE")
To, co wyświetla się na monitorze szeregowym mojego Arduino, wygląda następująco:
Arduino Received: M
Arduino Received: O
Arduino Received: V
Arduino Received: E
Ale chcę to:
Arduino Received: MOVE
Jak zmienić powyższy kod, aby wszystkie znaki znalazły się w buforze inData?
Odpowiedzi:
Problem polega na tym, że Arduino tak szybko się zapętla, że wykona
if (numBytesAvailable > 0)
linię kilka razy między każdym znakiem przybywającym przez port szeregowy. Gdy tylko postać przybywa, chwyta ją, zapętla od zera do jednej i drukuje pojedynczą postać.Co powinieneś zrobić, to wysłać znak końca linii ('\ n') po każdej komendzie z twojego programu Python. Następnie miej bufor kodu Arduino dla każdego otrzymanego znaku i działaj na wiadomość dopiero po otrzymaniu znaku końca linii.
Jeśli więc zmienisz kod Pythona, wyślij znak końca wiersza, taki jak:
Zatem twój kod Arduino może być mniej więcej taki:
źródło
Twój Python skrypt wysyła cztery bajty,
M
,O
,V
, iE
. Skąd Arduino ma wiedzieć, że to pojedynczy ciąg? Weź pod uwagę, że kod Python:jest całkowicie identyczny z
z punktu widzenia Arduino. Porty szeregowe przesyłają znaki, a nie ciągi znaków.
W twoim kodzie Arduino jest szybkie (w porównaniu do prędkości 9600 bodów), więc za każdym razem, gdy dzwoni
Serial.available()
, widzi tylko jeden z tych czterech znaków. Właśnie dlatego masz uzyskaną moc wyjściową.Musisz wymyślić jakiś sposób rozgraniczenia ciągów, tj. Oznaczenie ich w jakiś sposób z Pythona, aby Arduino mógł dołączyć pojedyncze znaki, które otrzymuje, do twojej koncepcji wysokiego poziomu łańcucha .
Używanie linii jest proste: wysyłaj każdy ciąg zakończony znakiem nowej linii (
'\n'
). Na Arduino czytaj znaki i dołączaj je do swojego ciągu. Gdy zobaczysz a'\n'
, łańcuch jest skończony i możesz go wydrukować.źródło
Powyższy kod działa idealnie na moim połączeniu między Pi a Arduino
źródło
Użyj
.readline
zamiast.read
Miałem ten sam problem i to natychmiast go rozwiązało. Mam nadzieję, że to pomogło!
źródło
Tak zrobiłem z pierwszego przykładu:
źródło