Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Komunikacja dwóch arduino

Janek11111111 31 May 2018 12:27 3846 19
  • #1
    Janek11111111
    Level 6  
    Witam, czy znajdzie się jakaś dobra dusza która poratuje kodem ewentualnie odeślę mnie w odpowiednie miejsce. Chcę wysłać kilka zmiennych typu int z jednego arduino do drugiego. Może być UART może być i2c z zastrzeżeniem że to Master ma wysyłać dane do Slava. Bardzo proszę o pomoc.
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • #3
    Janek11111111
    Level 6  
    To nie rozwiązuje moich problemów :(
  • #4
    viayner
    Level 42  
    Witam,
    w czym problem ? nie umiesz wyslac ?
    Napisales ze mozesz uzyc UART wiec jeden nadaje a drugi odbiera, mozesz dac transmisje zwrotna aby sprawdzic czy nie bylo bledow.
    https://www.arduino.cc/en/Serial/read
    https://www.arduino.cc/en/Serial/Write
    moze nie zajmuj sie I2C skoro masz problem z Uart. W I2C ustawiasz kto jest master a kto slave.
    Opisz dokladnie problem ale Uart tu wystarczy. Nie definjujesz mastera i slave ale szyna jest jednokoerunkowa wiec to wymusza kto nadaje.
    Pozdrawiam
  • #5
    Janek11111111
    Level 6  
    Układ wygląda następująco:
    Komunikacja dwóch arduino
    Chcę aby dane sczytywane z Arduino Nano trafiały do Megi i Due, ale mam z tym problem. Znalazłem bibliotekę do komunikacji po i2c gdzie master wysyła, slave odbiera (i2c_anything) niestety nie jest ona obsługiwana przez Due. Mam problem bo nie potrafię wysłać pakietu danych typu intiger z jednego Arduino do drugiego.
  • #6
    viayner
    Level 42  
    Witam,
    a "musisz" wysylac integer ? jakos przez Uart mozna wyslac wszystko tylko kwestia interpretacji danych.
    Popraw mnie jezeli sie myle:
    Integer - wartosc 2 bajtowa wiec musisz wyslac 2 bajty i wysylasz je przez port szeregowy a odbiorca dane odbudowuwyje np. mlodszybajt+256*starszybajt czy cos w tym rodzaju - o co chodzi ?
    Mozesz wyslac nawet integer jako jej reprezentacje ascii i odbudowac liczbe w odbiorniku.
    Czego nie umiesz zrobic ?
    Jakie odleglosci ?
    Pozdrawiam
  • #7
    Anonymous
    Anonymous  
  • #8
    viayner
    Level 42  
    Witam,
    a mozesz opisac dokladnie co wysylasz i co ma byc odebrane,
    I2C tu sie nie sprawdzi bo to szyna 2-kierunkowa a ma byc jeden nadajnik i 2 odbiorcow - jednoczesnie ? wiec bedzie kolizja gdy obydwaj zazadaja dostepu do szyny I2C, problem rozwiazywalny ale wniskujac po pytaniach autor nie w obecnym stanie.
    Prosze sprostuj jezeli sie myle:
    - nadaje Nano
    - odbieraja jednoczesnie Mega i Due ale nie jest wymagana transmisja zwrotna
    - "mususz" wyslac "integer"
    -- podziel liczbe INT na 2 bajty jak sugerowalem:
    https://www.arduino.cc/reference/en/language/structure/bitwise-operators/bitshiftright/
    a w odbiornikach odbuduj i gotowe
    - jaka odleglosc transmisji ?
    - jaka wymagana szybkosc transmisji?
    - jezeli Mega i Due wykonuja jakies skomplikowane obliczenia i czasy sa wazne to rozwaz przerwania na przyjecie znaki na Uart, jezeli nie jest to krytyczne to poprostu w petli.
    Pozdrawiam
  • #9
    Janek11111111
    Level 6  
    Odległości między urządzeniami wynoszą ok 10 cm. Dane które wysyłam to:
    temperatura otoczenia -40 ÷ 50 °C
    wilgotność 0 ÷100 %
    ciśnienie 300 ÷ 1100 hPa
    termopara -20÷1300 °C
    prędkość obrotowa 1000 ÷ ??? obr/min
    Część z tych danym można wysłać jako 1 bajt reszty już nie. Nie mam sprecyzowanych wymagać co to szybkości transmisji oprócz prędkości obrotowej (tutaj jest potrzeba odczytu kilku razy na sekundę).
    -nadaje Nano,
    -odbierają jednocześnie Mega i Due ale nie jest wymagana transmisja zwrotna
    -tak, muszę wysłać "integer"
    Przy rozdzieleniu bitów nie potrafię tego poskładać dla tego proszę o pomoc i udostępnienie jakiegoś programu.
  • #10
    Anonymous
    Anonymous  
  • #11
    viayner
    Level 42  
    Witam,
    Zgadzam sie ze I2C moze miec wiele slave ale nie tu gdzie mamy 2 slave jednoczesnie. Musialby kolega wysylac najpierw do jednego a potem do drugiego i mamy 3 przewody.
    Dlatego sugeruje Uart mamy 2 przewody GND i TX i rownolegle odbieranie przez dwoch slave.
    Wracajac do problemu:
    INT to wartosc -32767 do 32768, 2^16 to znak.
    Uzywajac przesuwania bitowego jak w zalaczonych linkach wysylasz mlodszy baj i starszy i odwrotna kombinacja przesuwania bitowego odbudowywujesz liczbe.
    Moze inaczej napisz co wysylasz ale nie interesuje mnie ze to temperaatura tylko co to za wartosci albo moze z czego to odczytujesz i jak.
    Przykladowo DS18s20 tak naprawde odczutujesz z niego 2 bajty i z nich jest "skladana" temperatura ze skali +125 do -55 z rozdzielczoscia 0.0625C. I o to cie pytam, wysyalasz oryginalne bajty a skladaniem zajmuja sie odbiorcy.
    Jezeli to za trudne to czemu nie wyslesz wersji prostej - poprostu ciagu znakow ascii?
    Zamieniasz twoja liczbe na string i wysulasz go na Uart odbeirasz string i zamieniasz na liczbe.
    Pozdrawiam

    PS moze inaczej czy kolega autor nadaza za naszymi uwagami ?
  • #12
    Anonymous
    Anonymous  
  • #13
    Janek11111111
    Level 6  
    Moglibyście podesłać jakieś programy? W teorii wszystko fajnie pięknie ale z praktyczną realizacją mam problem.
    Znalazłem taki w którym slave wysyła do mastera zmienne typu float ale ne potrafię go przerobić pod swoje potrzeby ale wiem że się da
    Slave:
    Code: c
    Log in, to see the code


    Master:
    Code: c
    Log in, to see the code


    Jeśli korzystam z programu z tej strony: https://www.arduino.cc/en/Tutorial/MasterWriter
    i dopisując tylko odpowiednie adresy działa tak jak bym chciał, bo wysyła do kilku slavów, ale tylko jeden bajt. Najlepiej byłoby to połączyć tylko nie wiem jak.
    Co się tyczy funkcji przerwań, wydaje się być fajna opcją ale nie mam pojęcia jak się za to zabrać
  • #14
    Anonymous
    Anonymous  
  • #15
    Janek11111111
    Level 6  
    Próbowałem i niestety nic z tego nie czaje. Znalazłem za to taki program wysyłający 5 zmiennych typu bite po serialu

    Sender
    Code: c
    Log in, to see the code


    Reciver
    Code: c
    Log in, to see the code


    ktoś wie jak go można przerobić żeby wysyłał intigery ?
  • #16
    ditomek
    Level 22  
    Wysłanie zmienne po serialu to instrukcja Serial.println(zmienna). Jeśli z tym masz problem to faktycznie jesteś w ciemnej du... Znacznie bardziej skomplikowany jest odbiór.
    W przykładach w IDE masz "serial event" krótki i prosty przykład jak odbierać ciąg znaków zakończony CR+LF. Spróbuj czy będziesz umiał nadać coś jednym arduinem i odebrać drugim wg tego przykładu. Na początek odebrany string wyślij na konsole i jak to będzie ci działać to pomyślisz jak z tego stringa wydłubać integera....
    PS.
    Pomijam kwestie elektryczne. Zakładam ze podłączenie arduin jest Ci znane
  • #17
    viayner
    Level 42  
    Witam,
    widze ze kolega chyba nie ogarnia sposobu komunikacji.
    Napisalem juz o przeksztalcaniu liczb, transmisja czy to I2C czy Usart bedzie 8bitowa, moze nie zapedziaj sie do zaawansowanych sposobow komunikacji skoro masz problem z konwersja Int do Bin.
    Skoro uparles sie na tego integera.
    Czytales wogole tego linka ?
    https://www.arduino.cc/reference/en/language/structure/bitwise-operators/bitshiftright/
    Jezli masz zmienna typu integer powiedzmy II oraz dwie zmienne typu byte powiedzmy BB1 i BB2 to
    przyporzadkowanie BB = II da ci mlodszy bajt bajt z integera, moze na przykladach:
    II = 32225 a wiec 7DE1H lub binarnie 0111 1101 1110 0001
    II = 0111 1101 1110 0001, po "rozsunieciu" na starszy i mlodszy bajt II = 01111101 11100001 i masz dwa bajty mimo ze masz integera.
    Teraz gdy BB1 = II to BB1 = 11100001 bo "tylko" 8 bitow sie zmiesci i to tych mlodszych
    dalej BB2 = II >> 8 to BB2= 01111101 bo przesunales liczbe o 8 pozycji (czyli II = 00000000 01111101 a miesci sie tylko 8 mlodszych bitow)
    Wysyalasz BB1 i BB2 dowolnym sposobem, Odbierasz i masz BB1 i BB2 jako byte ale musi byc integer wiec:
    II = BB1 + 256*BB2 i gotowe.
    Czy teraz rozumiesz.
    Pozdrawiam
  • #18
    onehour
    Level 11  
    Witam, widzę, że problem chyba jeszcze nie został rozwiązany mimo, że wszystkie potrzebne informacje już się przewinęły.
    Zatem pozwoliłem sobie zebrać to w jakąś całość:
    1. komunikacja przez UART wydaje się najprostszym rozwiązaniem,
    2. dane umieszczamy w strukturze,
    3. aby przygotować dane do wysłania nie stosujemy żadnych skomplikowanych przekształceń tylko rzutowanie typów,
    4. dane wysyłamy poleceniem Serial.write(), a odczytujemy poleceniem Serial.readBytes().

    Oczywiście należy pamiętać aby pin TX układu nadawczego połączyć z pinem RX układu odbiorczego, nie inaczej.

    Spróbowałbym zastosować takie rozwiązanie:
    Code: c
    Log in, to see the code


    Code: c
    Log in, to see the code


    Ale prawdę mówiąc zastanowiłbym się czy w tym przypadku najlepszą opcją nie byłoby wykorzystanie SPI.
  • #19
    Janek11111111
    Level 6  
    onehour, dziękuję Ci za odpowiedź, czegoś takiego szukałem.
    Problem rozwiązałem w trochę inny sposób. Źródłem moich wszystkich bolączek okazało się Arduino Due , którego nie potrafiłem skomunikować z innymi układami dla tego zastąpiłem je Arduino Mega. Do komunikacji wykorzystałem magistralę I2C z wykorzystaniem biblioteki "I2C_Anything"(dodana w załączniku).
    Schemat układu wygląda następująco:
    Komunikacja dwóch arduino
    Master
    Code: c
    Log in, to see the code


    Slave 1

    Code: c
    Log in, to see the code


    U mnie się to sprawdza, mogę dodać więcej urządzeń kwestia tylko wpisania adresu. może być więcej zmiennych wtedy po stronie maser dopisuję np. " I2C_writeAnything (Z);" a po stronie slava w funkcji receiveEvent dopisuję "I2C_readAnything (Z);", dla argumentu funkcji if "+ (sizeof Z)" i wszystko działa elegancko.
  • #20
    Anonymous
    Anonymous