Liczba postów: 878
Liczba wątków: 19
Dołączył: Jun 2018
Reputacja:
42
Masz złe przykłady, to jest dobre tylko jak jeden znak..
Kiedy chcesz wysyłać kilka znaków musisz określić jego długość przypisać do tablicy i oznaczyć koniec lub początek . A odbierający dać w peli by odbierało do tablicy o ile pojawi się początek lub dopóki nie pojawi się koniec do tablicy..
Ale jak znasz długość to nie lepiej float przerobić do init??
22,5 x 10= 225-tablica- wysyłasz - odbierasz - tablica - init/10 - float
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą.
Liczba postów: 18
Liczba wątków: 6
Dołączył: Oct 2015
Reputacja:
0
Pomysł z przerobieniem z folat do int to dobry patent, ale powiedz mi jak mam rozróżnić przesyłane liczby. Chodzi mi o to że chcę przesyłać co jakiś czas dwie zmienne po uart, ale w drugim arduino muszę wiedzieć która jest która.
Liczba postów: 878
Liczba wątków: 19
Dołączył: Jun 2018
Reputacja:
42
10-10-2019, 15:36
(Ten post był ostatnio modyfikowany: 10-10-2019, 15:37 przez Jarewa0606.)
A po co timeout??
Wiedząc co się dostaje i jakie to dane wystarczy by calosc było w buforze serial i tylko odczytujemy
Bez blokady i bez Delay. Tylko jeden for
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą.
Liczba postów: 2,367
Liczba wątków: 0
Dołączył: Oct 2017
Reputacja:
240
Na razie nie robiłem transmisji w ramkach po uart, wystarcza mi przesył tekstem. Ale tak rozważając teoretycznie zauważam kilka potencjalnych zagrożeń.
Nawet taki AVR może wykonywać instrukcję w 50ns (20MHz, dla łatwiejszego liczenia), operacje na bajtach, 8 bitach, w 8-bitowcu są szybkie i trwają jedną- kilka instrukcji. Nie można zakładać, że w buforze czeka cała gotowa ramka, bo jak się zdarzy, że wejdziesz tam tak jak się powinno to robić, czyli że pętla "jałowa" trwa kilka us, to będzie tam 1bajt, może dwa. Przesłanie bajtu z baud 9600 trwa ~1ms, 115200 z 50us. Wolno i szybko zarazem, nawet dla 115k jest to 1000 instrukcji uC. Bufor sprzętowy jest na max 2 bajty. Zakładając, że jest już "available cośtam" odczytujesz 1-2 bajty i masz śmieci, to nawet nie jest jedna liczba float. Zakładając że masz czekać na 10 bajtów może się okazać, że jakieś inne przerwanie lub inna biblioteka zakłóciła przerwania UART na tyle us, że bajt przepadł. Teraz do kolejnego resetu zawsze będziesz odczytywał 9bajtów z jednej ramki i 1 z kolejnej. No i siedział w jakiejś pętli while nie napełni bufora przez 0.5-10ms (10ms to już 200 tys. instrukcji)?
W nadajniku UART jest oczywiście podobna sytuacja, Ty sobie robisz write(dane,10bajtów) i lecisz dalej, ale to nie koniec wysyłania, dalej biblioteka już w tle ustawia sobie kolejkę, wrzuca bajt do nadajnika i czeka na przerwanie nadajnika dopóki ma w buforze dane do wysłania, przerwanie-wysyła, przerwanie-wysyła. W tym czasie może wyjść inne przerwanie i nadawanie kolejnych bajtów jest zawieszone. Przerwanie inne się kończy, wrzucany jest kolejny bajt i tak aż wyśle te 10.
Z timeout wiesz, że jak odebrałeś 9 bajtów i jest pauza powyżej 3-10ms (dla 9600), a dane wysyłasz co 50ms, to na pewno powinieneś zacząć od nowa. Jeśli sterujesz jakimś pojazdem/latawcem to też brak danych, nowej ramki oznacza utratę komunikacji, pojazd należy zatrzymać, kopterka delikatnie zawiesić i po paru s, jeśli sterownik nie dobiegnie w zasięg samemu powoli wylądować.
Nie można też tego robić na żywioł w nadajniku, że bez delay. Może być bez delay, ale co jakiś czas. Jak widać można sobie nawet 20 razy zrobić write by wysłać kolejne 10 bajtów zanim w ogóle pierwsza ramka zostanie nadana w całości. Po kilku obiegach pętli bufor nadawczy biblioteki UART zostanie przejechany zanim tyknie sekunda.
Liczba postów: 878
Liczba wątków: 19
Dołączył: Jun 2018
Reputacja:
42
No tak tylko on tu chce dwie zmienne wysłać i podejrzewam że raz na 200ms pewnie mu spokojnie wystarczy...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą.
Liczba postów: 2,367
Liczba wątków: 0
Dołączył: Oct 2017
Reputacja:
240
Naucz się używać millis() zamiast delay. No w setup to jeszcze OK, ale potem, zanim wejdziesz w loop wyczyść bufor danych, które mogły w tym czasie przylecieć, po prostu zanim wejdziesz w loop odczytaj wszystko w pętli while do jakiejś zmiennej lokalnej bajt typu śmieć. Ale to nie daje gwarancji, czy przypadkiem nie wywalisz pierwszego bajtu z paczki 4 Twojego floata.
Użyłeś gotowej funkcji Arduino odbierającej określoną liczbę bajtów. No OK, ja bym tak nie zrobił, napisałem wcześniej czemu - odbierasz pierwszy i czekasz ileś tam us/ms na kolejne bajty. Po tym delay jest do niczego niepotrzebny. W nadajniku nadajesz co określony czas, tu od biedy delay OK, ale odbiornik ma być zawsze gotowy do odbioru i obróbki tych danych.
Ja odczytywałbym tylko 1 bajt, po zebraniu 4 miałbym float'a i go używał.
Generalnie to zrealizowałeś moje obawy w swoim kodzie - nie panujesz nad tym co kiedy przylatuje i co to jest.
Jak nauczysz się używać millis to już wiedza, że nadajesz co 20ms, a w odbiorniku od 10ms nie było danych to możesz się spodziewać, że kolejny bajt będzie pierwszy załatwia sprawę. Ale nie wtedy gdy czekasz w funkcji read ?ms, bo nie zmierzysz ile czekasz. Jeden bajt (lub ile tam jest, a max 4) i powrót do loop.