Skocz do zawartości

Czy łączenie kilku arduino, może pełnić rolę "wielowątkowości"?


dejmieno

Pomocna odpowiedź

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.

Link do komentarza
Share on other sites

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 😉

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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ę »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.