dejmieno Napisano Czerwiec 28, 2017 Udostępnij Napisano Czerwiec 28, 2017 Witam, Zastanawia mnie, czy łączenie kilku arduino poprzez I2C może pełnić rolę "wielowątkowości", albo raczej symulować procesory wielo corowe. Czy takie coś ma prawo bytu? Zastanawia mnie jak szybka jest komunikacja I2C i jakie byłyby strat w szybkości, gdyby kilka arduino równolegle przetwarzało dane. Z tego co zauważyłem to wysyłanie poprzez UART do PC jest bardzo wolne.
wn2001 Czerwiec 28, 2017 Udostępnij Czerwiec 28, 2017 Witaj, jak robiłem MicroMouse'a, to wziąłem dwa Nano - jedno tylko analizowało odczyty z czujników i je linearyzowało, a drugie sterowało dwoma silnikami krokowymi i zapamiętywało trasę, jak się potem okazało - zbędnie, bo jedno w zupełności by starczyło Czy to jest wielowątkowość to nie wiem, ale na pewno można zrobić z tym ciekawe rzeczy To jest pętla loop() z programu do Nano, który czytało czujniki i potem je wysyłało /*pobór napięć z fototranzystorów - przy włączonych i wyłączonych diodach, możesz poczytać o czujnikach w MM */ digitalWrite(5, HIGH); digitalWrite(6, HIGH); delay(1); on_pb = analogRead(A1); on_lb = analogRead(A2); delay(1); digitalWrite(5, LOW); digitalWrite(6, LOW); delay(1); off_pb = analogRead(A1); off_lb = analogRead(A2); delay(1); pb=on_pb-off_pb; lb=on_lb-off_lb; delay(1); digitalWrite(4, HIGH); digitalWrite(7, HIGH); delay(1); on_pp = analogRead(A0); on_lp = analogRead(A3); delay(1); digitalWrite(4, LOW); digitalWrite(7, LOW); delay(1); off_pp = analogRead(A0); off_lp = analogRead(A3); delay(1); pp=on_pp-off_pp; lp=on_lp-off_lp; delay(1); //// linearyzacja if (lp>=100) { if (lp>=930) linear_lp=0; else if (lp>=870 && lp<930) linear_lp=1; else if (lp>=750 && lp<870) linear_lp=2; else if (lp>=615 && lp<750) linear_lp=3; else if (lp>=530 && lp<615) linear_lp=4; else if (lp>=460 && lp<530) linear_lp=5; else if (lp>=395 && lp<460) linear_lp=6; else if (lp>=350 && lp<395) linear_lp=7; else if (lp>=320 && lp<350) linear_lp=8; else if (lp>=290 && lp<320) linear_lp=9; else if (lp>=260 && lp<290) linear_lp=10; else if (lp>=240 && lp<260) linear_lp=11; else if (lp>=215 && lp<240) linear_lp=12; else if (lp>=200 && lp<215) linear_lp=13; else if (lp>=190 && lp<200) linear_lp=14; else if (lp>=180 && lp<190) linear_lp=15; else if (lp>=170 && lp<180) linear_lp=16; else if (lp>=165 && lp<170) linear_lp=17; else if (lp>=160 && lp<165) linear_lp=18; else if (lp>=155 && lp<160) linear_lp=19; else if (lp>=140 && lp<155) linear_lp=20; else if (lp<140) linear_lp=21; } else linear_lp=31; Wire.beginTransmission(9); // transmit to device #9 Wire.write(linear_lp); Wire.endTransmission(); // stop transmitting //// if (lb>=100) { if (lb>=930) linear_lb=0; else if (lb>=870 && lb<930) linear_lb=1; else if (lb>=750 && lb<870) linear_lb=2; else if (lb>=615 && lb<750) linear_lb=3; else if (lb>=530 && lb<615) linear_lb=4; else if (lb>=460 && lb<530) linear_lb=5; else if (lb>=395 && lb<460) linear_lb=6; else if (lb>=350 && lb<395) linear_lb=7; else if (lb>=320 && lb<350) linear_lb=8; else if (lb>=290 && lb<320) linear_lb=9; else if (lb>=260 && lb<290) linear_lb=10; else if (lb>=240 && lb<260) linear_lb=11; else if (lb>=215 && lb<240) linear_lb=12; else if (lb>=200 && lb<215) linear_lb=13; else if (lb>=190 && lb<200) linear_lb=14; else if (lb>=180 && lb<190) linear_lb=15; else if (lb>=170 && lb<180) linear_lb=16; else if (lb>=165 && lb<170) linear_lb=17; else if (lb>=160 && lb<165) linear_lb=18; else if (lb>=155 && lb<160) linear_lb=19; else if (lb>=140 && lb<155) linear_lb=20; else if (lb<140) linear_lb=21; } else linear_lb=31; Wire.beginTransmission(9); // transmit to device #9 Wire.write(linear_lb+32); // sends x, dodawanie jest zrobione w celu odczytu, która liczba jest która Wire.endTransmission(); // stop transmitting //// if (pb>=100) { if (pb>=930) linear_pb=0; else if (pb>=870 && pb<930) linear_pb=1; else if (pb>=750 && pb<870) linear_pb=2; else if (pb>=615 && pb<750) linear_pb=3; else if (pb>=530 && pb<615) linear_pb=4; else if (pb>=460 && pb<530) linear_pb=5; else if (pb>=395 && pb<460) linear_pb=6; else if (pb>=350 && pb<395) linear_pb=7; else if (pb>=320 && pb<350) linear_pb=8; else if (pb>=290 && pb<320) linear_pb=9; else if (pb>=260 && pb<290) linear_pb=10; else if (pb>=240 && pb<260) linear_pb=11; else if (pb>=215 && pb<240) linear_pb=12; else if (pb>=200 && pb<215) linear_pb=13; else if (pb>=190 && pb<200) linear_pb=14; else if (pb>=180 && pb<190) linear_pb=15; else if (pb>=170 && pb<180) linear_pb=16; else if (pb>=165 && pb<170) linear_pb=17; else if (pb>=160 && pb<165) linear_pb=18; else if (pb>=155 && pb<160) linear_pb=19; else if (pb>=140 && pb<155) linear_pb=20; else if (pb<140) linear_pb=21; } else linear_pb=31; Wire.beginTransmission(9); // transmit to device #9 Wire.write(linear_pb+64); // sends x Wire.endTransmission(); // stop transmitting*/ //// if (pp>=100) { if (pp>=930) linear_pp=0; else if (pp>=870 && pp<930) linear_pp=1; else if (pp>=750 && pp<870) linear_pp=2; else if (pp>=615 && pp<750) linear_pp=3; else if (pp>=530 && pp<615) linear_pp=4; else if (pp>=460 && pp<530) linear_pp=5; else if (pp>=395 && pp<460) linear_pp=6; else if (pp>=350 && pp<395) linear_pp=7; else if (pp>=320 && pp<350) linear_pp=8; else if (pp>=290 && pp<320) linear_pp=9; else if (pp>=260 && pp<290) linear_pp=10; else if (pp>=240 && pp<260) linear_pp=11; else if (pp>=215 && pp<240) linear_pp=12; else if (pp>=200 && pp<215) linear_pp=13; else if (pp>=190 && pp<200) linear_pp=14; else if (pp>=180 && pp<190) linear_pp=15; else if (pp>=170 && pp<180) linear_pp=16; else if (pp>=165 && pp<170) linear_pp=17; else if (pp>=160 && pp<165) linear_pp=18; else if (pp>=155 && pp<160) linear_pp=19; else if (pp>=140 && pp<155) linear_pp=20; else if (pp<140) linear_pp=21; } else linear_pp=31; Wire.beginTransmission(9); // transmit to device #9 Wire.write(linear_pp+96); // sends x Wire.endTransmission(); // stop transmitting*/ delay(10); Wiem, wiem, kod jest daleki od optymalnego, ale to co powinno Cię zainteresować - w moim przypadku, przesyłanie 4 bajtów przebiegało bez problemu przy 20 milisekundach przerwy w pętli loop - przy czym powtarzam, ze mnie żaden programista, ale w moim przypadku 4 bajty co 20ms w zupełności wystarczyło Polecam książkę "Arduino dla zaawansowanych" R. Andersona i D. Cervo'a - jest tam cały dział o łączeniu Arduino poprzez I2C oraz SPI
quandziadek Lipiec 1, 2017 Udostępnij Lipiec 1, 2017 Teoretycznie jeśli miałbyś małą ilość danych do przetworzenia, ale ich przetwarzanie zajmuje bardzo długo czasu, to faktycznie można by tak zrobić, aby przetwarzać te dane równolegle. W praktyce nie ma to specjalnie sensu, bo taniej byłoby zastosować po prostu lepszy procesor, który wykona te wszystkie operacje szybciej niż kilka Arduino. Według dokumentacji ATMega328p, która to jest w Arduino, obsługuje I2C (w dokumentacji Atmela znajdziesz I2C jako TWI) z częstotliwością 400kHz, co daje w grubym przybliżeniu 50kB/s.
deshipu Lipiec 1, 2017 Udostępnij Lipiec 1, 2017 Próba implementowania wątków takich jak w "dużych" systemach operacyjnych na kilku Arduino może być ciekawa z akademickiego punktu widzenia, ale wydaje mi się bardzo niepraktyczna. Natomiast na własnej skórze się przekonałem, że czasem warto użyć osobnych mikrokontrolerów do przetwarzania danych z osobnych czujników i generalnie do sterowania różnymi częściami robota, odciążając w ten sposób centralny mikrokontroler, który wówczas może się zająć wysokopoziomowym sterowaniem całości. Taka modułowa architektura nie tylko ułatwia pisanie kodu, ale także jego testowanie -- nie musimy mieć całego działającego robota, możemy zbudować i testować pojedynczy moduł i być dosyć pewni, że po podłączeniu zadziała. Pozwala to też na dość łatwe eksperymentowanie z wymienianiem całych fragmentów. Jedyne, co trzeba mieć ustandaryzowane i przemyślane, to protokoły komunikacji -- jak zwykle API jest najtrudniejszym problemem.
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »