W dzisiejszym artykule zajmiemy się komunikacją szeregową. Zaczniemy od bardzo podstawowych rzeczy a skończymy na zaawansowanej transmisji danych
Co będzie nam potrzebne:
- Komputer
- Kabel USB
- Arduino IDE
- Arduino UNO (lub inne)
Na początek zajmiemy się prostym skryptem, który ma za zadanie odesłać wysłane dane. Czyli jeżeli wyślemy 4 odeśle nam 4 itd.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/*Zmienną byte używamy do tymczasowego przechowywania danych pochodzących z komputera czyli to co wpiszemy*/ byte byteRead; void setup() { // Uruchamiamy transmisję szergową Serial.begin(9600); } void loop() { /* Sprawdzamy czy jakieś dane zostały wysłane z komputera jeżeli tak to:*/ if (Serial.available()) { /* zapisujemy do zmiennej byteRead */ byteRead = Serial.read(); /*wyspiujemy wczytaną wartość na monitor szeregowy */ Serial.write(byteRead); } } |
Cały szkic wgrywamy do Arduino po czym odpalamy monitor szeregowy. Wszystko powinno działać poprawnie.
Teraz zajmiemy się wysyłaniem i odbieraniem więcej niż jednej zmiennej
Załóżmy że mamy parę numerów króre chcemy wysłąć do naszej płytki jak je rozdzielić?
Odpowiedzią są organiczniki czyli przecinki. Jest to dobry sposób rozdzielania strumienia liczb.
Organiczniki pomogą nam w interpretacji ciągu liczb.
Jeżeli masz następujący ciąg znaków 1234567 to dzięki przecinkom możesz podzielić go na kilka różnych ciągów i zapisać go w różnych formach. Na przykład
123,456,7
12,3,45,6
Przy takim zapisie chcemy aby nasz monitor szeregowy zwrócił dane w odpowiedniej segregacji
Aby to zrobić musimy napisać program, który powinien wyglądać mniej więcej tak. Nie będę go jakoś specjalnie omawiał ponieważ jest dość prosty
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
byte byteRead; void setup() { // Turn the Serial Protocol ON Serial.begin(9600); } void loop() { /* Sprawdzamy czy jakieś dane zostały wysłane z komputera jeżeli tak to:*/ if (Serial.available()) { /* Jezeli tak to zapisujemy je do zmiennej byteRead byteRead = Serial.read(); //sprawdzamy czy odebraliśmy przecinek (według tabeli ASCII) if(byteRead==44){ Serial.println(); }else{ //wysyłamy zmienną do monitora szeregowego Serial.write(byteRead); } } |
Teraz zajmiemy się prostymi operacjami matematycznymi.
Może wydawać się to bardzo prostym zadaniem jednak niestety nie jest tak kolorowo.
Jeżeli wysyłamy do Arduino liczbę 79 to otrzymuje ono 7 oraz 9 w postaci bitowej czyli 55 i 57. Po czym gdy to wyświetlamy podmienia wszystko za pomocą tabeli ASCII
Najprostszym sposobem przekształcania tych cyfr z powrotem na 7 i 9 jest odjęcie 48 od każdej otrzymanej cyfry a potem połączenie tych 2(lub więcej) cyfr jedną liczbę.
W takim razie jak napisać kod który będzie dodawał dwa podane przez użytkownika liczby oraz odsyłał odpowiedź?
1. Odejmujemy 48 od odebranych bajtów. Jeżeli bajty są w zakresie od 48 do 57 (cyfry 0-9 w ASCII)
Przykład: 55-48=7
57-48=9
2. mnożymy przedostatnią cyfrę razy 10
Przykład: (7*10)+9=79
Jeżeli mamy większy numer to tworzymy go na takiej zasadzie:
na przykład 1264
1=1
(1*10)+2=10+2=12
(12*10)+6=120+6=126
(126*10)+8=1260+4=1264
3. Używamy znaku + jako separatora aby można było wpisać drugą liczbę
4. Przechwytujemy drugą liczbę według kroków 1 i 2
5. Czekamy na znak „=”
6. Dodajemy dwa numery do siebie i odsyłamy odpowiedź
A w kodzie możne to wyglądać na przykład tak:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
byte byteRead; long num1, num2,answer; boolean mySwitch=false; void setup() { Serial.begin(9600); num1=0; num2=0; } void loop() { while (Serial.available()) { byteRead = Serial.read(); if(byteRead>47 && byteRead<58){ if(!mySwitch){ num1=(num1*10)+(byteRead-48); }else{ num2=(num2*10)+(byteRead-48); } } if(byteRead==61){ answer=num1+num2; Serial.print(num1); Serial.print("+"); Serial.print(num2); Serial.print("="); Serial.println(answer); num1=0; num2=0; mySwitch=false; }else if (byteRead==43){ mySwitch=true; } } } |
Wysyłanie oraz podwajanie liczb Typu Double
Teraz zajmiemy się chyba czymś najtrudniejszym dzisiaj. Postaramy się przesłać oraz dodać liczby typu double.
WAŻNE
Gdy Arduino wyświetla liczbę double lub float przy uzyciu funkcji Serial.print() z automatu zaokrągla ją do dwch miejsc po przecinku. Na przykład liczba 1,234567 pojawi się jako 1,23 a liczba 1,999999999999996 pojawi się jako 2,00.
Żeby to sprawdzić skorzystajmy z następującego kodu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
double myDub1, myDub2; void setup(){ Serial.begin(9600); myDub1=1.234567; myDub2=1.999999999999996; Serial.print("myDub1 (1.234567) : "); Serial.println(myDub1); Serial.print("myDub2 (1.999999999999996) : "); Serial.println(myDub2); } void loop(){ } |
Teraz polecam Ci samemu przetestować ten kod.
Okej. Jeżeli rozumiemy już te zależność możemy przejść do głównej części.
Jeżeli wyślemy do Arduino 0.2 to otrzyma on takie bajty : 48 46 50
Możemy wykorzystać punkt dziesiętny jako ogranicznik.
No to teraz w 5 krokach przedstawię Ci jak szybko podwoić liczbę zmiennoprzecinkową.
1. Arduino pobiera wszystkie liczby przed kropką wykorzystując te technikę co przy int’ach.
2.Gdy Arduino odbierze 46 (kropkę) przechodzi do odbierania cyfr po kropce
3. Arduino pobiera numery po kropce przy użyciu podobnej techniki jak w kroku 1
4. Przekształcamy oraz mnożymy razy 2
5. Wyświetl podwojoną wartość podwojoną na monitorze szeregowym.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
byte byteRead; double num1, num2; double complNum,answer,counter; int numOfDec; boolean mySwitch=false; void setup() { Serial.begin(9600); num1=0; num2=0; complNum=0; counter=1; numOfDec=0; } void loop() { while (Serial.available()) { byteRead = Serial.read(); if(byteRead>47 && byteRead<58){ if(!mySwitch){ num1=(num1*10)+(byteRead-48); }else{ num2=(num2*10)+(byteRead-48); counter=counter*10; numOfDec++; } } if(byteRead==61){ complNum=num1+(num2/(counter)); answer=complNum*2; Serial.print(complNum,numOfDec); Serial.print(" x 2 = "); Serial.println(answer,numOfDec); num1=0; num2=0; complNum=0; counter=1; mySwitch=false; numOfDec=0; }else if (byteRead==46){ mySwitch=true; } } } |
To już wszystko na dziś 😀
Mam nadzieję, że artykuł Ci się podobał. Jeżeli nie śledzisz RoboBlog’a jeszcze na Facebooku to serdecznie zapraszam KLIK