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

ESP32 komunikacja SPI z enkoderem absolutnym AS5048A

madiz08 08 Jan 2020 10:26 1158 21
  • #1
    madiz08
    Level 14  
    Kupiłem ostatnio kilka enkoderów AS5048A, komunikujących się z masterem po SPI. Zmontowałem takie połączenie:

    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A

    i wgrałem znaleziony przykład:
    Code: c
    Log in, to see the code


    Niestety po wgraniu kodu do ESP32 dev Module, mam same zera bez względu czy przykładam magnes czy też nie. Jak wrócę z tym do domu to pierwsza rzeczą która sprawdzę to, czy na oscyloskopie mam sygnał SCL oraz czy co sekundę mam stan niski na pinie 27, ale chciałbym tez zapytać czy może coś jest nie tak z kodem lub pinologią?
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
  • #3
    madiz08
    Level 14  
    Wcześniej też próbowałem z pinów HSPI i też nie było jakiejkolwiek różnicy. Na chwilę obecną skróciłem kod z linku jedynie do obsługi HSPI.
    Code: c
    Log in, to see the code

    Jednak nie bardzo rozumiem jego działanie.
    Jak używałem I2C to wiedziałem, że najpierw trzeba nawiązac połaczenie, podać adres, adres rejestru, ile bajtów itd...
    W przypadku SPI wiem, że w momencie podbrania danych ze slave, pin CS ma być w stanie niskim, SCL to zegar, a MoSI i MISO to coś na zasadzie RX TX.

    W pętli loop mam wywołanie funkcji komunikacyjnej:
    Code: c
    Log in, to see the code

    Czy moglibyście wytłumaczyć co zawiera beginTransaction, i co kryje się za poleceniem transfer(stuff);

    https://www.mouser.com/datasheet/2/588/AS5048_DS000298_3-00-522570.pdf

    Dodano po 11 [minuty]:

    Chodzi mi o informacje w jaki sposób mam odebrać dwa bajty z informacją o pozycji enkodera

    Dodano po 16 [minuty]:


    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    Powyżej mam adres odczytu pozycji, ale jak wykożystać to w kodzie, żeby odczytać zawartość rejestru pod adresem 0x3FFE?
  • Helpful post
    #4
    khoam
    Level 42  
    madiz08 wrote:
    co zawiera beginTransaction

    beginTransaction(SPISettings settings);
    SPISettings:
    uint32_t clock (domyślnie 1000000)
    uint8_t bitOrder (domyślnie SPI_MSBFIRST)
    uint8_t dataMode (domyślnie SPI_MODE0)
    Funkcja zakłada blokadę SPI_MUTEX_LOCK w danym wątku, który jest później zwalniany przez endTransaction().

    madiz08 wrote:
    co kryje się za poleceniem transfer(stuff);

    void transfer(uint8_t * buffer, uint32_t size) - odebrane dane trafiają do tego samego bufora (w miejsce wysłanych); rozmiar bufora powinien być odpowiednio duży
    uint8_t transfer(uint8_t data) - dotyczy tylko wysłania i odebrania jednego bajtu
    https://www.arduino.cc/en/Reference/SPITransfer

    Całość obsługi SPI jest dość dobrze opisana pod tym linkiem (dotyczy również ESP32):
    https://www.arduino.cc/en/Reference/SPI

    madiz08 wrote:
    Powyżej mam adres odczytu pozycji, ale jak wykożystać to w kodzie, żeby odczytać zawartość rejestru pod adresem 0x3FFE?

    W dużym skrócie: wysłać stosowną komendę (w buforze transfer()) i odebrać odpowiedź (też w buforze transfer()).

    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
  • #5
    madiz08
    Level 14  
    Juz miałem sie z tym poddać. Próbowałem na UNO i MEGA i tez zerowy odczyt. W końcu, korzystając z linku:
    https://forum.arduino.cc/index.php?topic=155238.0
    zauważyłem, że MOSI jest na stałe podpięte do 3V3 i nagle wszystko zaczęło działać. Poniżej przesyłam gotowca do odczytu AS5048A na ESP32
    Code: c
    Log in, to see the code

    Dziękuje za linki do SPI, sporo wiadomości mi to dało
  • Helpful post
    #6
    khoam
    Level 42  
    Jeżeli MOSI jest na stałe podpięte do HIGH, to oznacza to dla AS5048A tryb "Read only" - w dokumentacji, do której link podałeś w poście #3 jest to opisane na stronie 13. Nie oznacza to jednak, że tak ma być. Może zechcesz programować enkoder i zmieniać jego ustawienia? ;)

    Sugerowałbym przenieść wyświetlanie wyniku Serial.println(result) za komendę hspi->endTransaction(). Nie powinno się blokować dostępu do kanału SPI innym wątkom na czas dłuższy niż to konieczne.
  • #7
    madiz08
    Level 14  
    Oczywiście, że chciałbym móc go programować, a bardziej trafne słowo to umieć. Najbardziej zależałoby mi na ustawieniu pozycji zerowej. Funkcję Transfer rozumiem jako przesłanie odpowiedniego bajtu, a w odpowiedzi funkcja zwraca w miejsce tego bajtu odpowiedź.
    Nie rozumiem dlaczego ta odpowiedź przychodzi po wysłaniu dwóch bajtów o wartości 0? Wiem, że wartość jest 14-bitowa, dlatego nie patrzymy na dwa najstarsze bity, ale dlaczego wysyłamy 0?
    Czy tak na prawdę to nie jest 0, tylko pierwszy bajt z tablicy?
    Adres rejestru z którego chciałbym odczytać pozycję to 0x3FFE. Myślałem, że to będzie działać na zasadzie, że rozbijam tą wartość na dwa bajty, do starszego dostawiam jedynkę w 15-ty bit, aby dać znać, że to jest odczyt i wysyłam to do enkodera. Próbowałem też Transfer(Val16), ale też nic.
  • #9
    madiz08
    Level 14  
    Teraz już wszystko rozumiem. Prześledzenie
    Code: c
    Log in, to see the code
    wszystko mi wyjaśniło. Czyli wysyłamy odpowiednią komendę + jedynka z przodu, a następnie wysyłamy 0 jako odczyt. Wcześniej wysyłałem to pierwsze, ale nie wiedziałem, ze następnie należy wysłać 0 aby otrzymać odpowiedź. Zamawiam przewody 6-żyłowe ekranowane i jak przyjdą to spróbuję zamontować te enkodery do swojego robota zamiast AS5600. Mam nadzieję, że jeżeli będą podłączone bezpośrednio do ESP32, to nie będzie zakłóceń.
    Dziękuję.
  • #10
    khoam
    Level 42  
    madiz08 wrote:
    Mam nadzieję, że jeżeli będą podłączone bezpośrednio do ESP32, to nie będzie zakłóceń.

    Jakiej długości będzie ten kabel 6-żyłowy?
  • #11
    madiz08
    Level 14  
    ten od najdalszej osi 180cm
  • #12
    madiz08
    Level 14  
    Dzisiaj polutowałem enkodery do przewodu ekranowanego
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A

    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    i tymczasowo podłączyłem 2 z 5 enkoderów testowo w połączeniu "3 Wire Mode (read only)"
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    Jutro postaram lub pojutrze (jeżeli w pracy nie będę miał wyjazdów), postaram się zmontować enkodery na poszczególnych osiach i zobaczymy jak to będzie działało.
    Proszę tylko o informacje czy taki odczyt jest optymalny?
    Code: c
    Log in, to see the code


    Code: c
    Log in, to see the code
  • #13
    khoam
    Level 42  
    madiz08 wrote:
    Proszę tylko o informacje czy taki odczyt jest optymalny?

    Obiekt klasy SPSettings można utworzyć tylko raz i póżniej z niego korzystać w pętli:
    Code: c
    Log in, to see the code
    Code: c
    Log in, to see the code
  • #14
    madiz08
    Level 14  
    Dzisiaj na spokojnie podłączyłem wszystko, odseparowałem napięcie sterowania 5V od napięcia zasilania silników. Po włączeniu sterowania i swobodnym przesuwaniem osi 0 błędów odczytu, ale niestety po włączeniu zasilania silników z automatu błędne odczyty.
    No już nie wiem skąd te zakłócenia. Te same enkodery stosowane są w profesjonalnych zastosowaniach firmy Boston Dynamisc, która stosuje je w swoich silnikach robiąc takie cuda:
    https://www.youtube.com/watch?v=NR32ULxbjYc
    Być może moim problemem jest to, że enkodery i magnesy nie są w metalowej puszce tworzącej ekran Faraday-a i pole magnetyczne silników wpływa na ich odczyt, a być może samo ESP32 jest zbyt podatne na zakłócenia.
    Ogólnie komunikacja z AS048A rozwiązana, ale szkoda, że nie z pozytywnym skutkiem :)
  • #15
    khoam
    Level 42  
    madiz08 wrote:
    Po włączeniu sterowania i swobodnym przesuwaniem osi 0 błędów odczytu, ale niestety po włączeniu zasilania silników z automatu błędne odczyty.

    Czy możesz podejrzeć na oscyloskopie, jak te zakłócenia na szynie SPI wyglądają po włączeniu silników?

    madiz08 wrote:
    a być może samo ESP32 jest zbyt podatne na zakłócenia

    Jeżeli to jest standardowy moduł z ESP32 to nie był projektowany pod kątem odporności na tego rodzaju zakłócenia Jak blisko ten moduł znajduje się silnika? W pierwszej kolejności to bym ekranował moduł elektroniki z ESP32 oraz zastosował zewnętrzną antenę WiFi dla ESP32.

    Może wrzuć zdjęcie, jak ten cały układ wygląda?
  • #16
    madiz08
    Level 14  
    No faktycznie, oscyloskop! Niestety jest on z niższej pułki, ale co nieco pokazuje:

    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    Powyżej sygnał MISO w odstępach czasowych przy wyłączonych silnikach

    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    a tutaj w przybliżeniu. Niestety mój oscyloskop nie daje możliwości pełnego wglądu w cała ramkę
    Poniżej zobacz proszę jak wygląda sygnał po włączeniu zasilacza do sieci:
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    a w przybliżeniu:
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    Przesyłam też krótki filmik, gdzie pokazane jest, jak to wygląda przed włączeniem i po włączeniu silników.



    https://www.youtube.com/watch?v=qlD52KkkEK8&feature=youtu.be jeżeli filmik się nie odpali
    W programie mam, że jeżeli odczyt będzie większy lub mniejszy o 300 jednostek pozycji od poprzedniego odczytu, to ma wywalić błąd z alarmem. Sreial.print tu nie ma na nic wpływu. Próbowałem sterować robotem bez seriala i też błędy pozycji niestety.
    Mam chwilowy problem z przerzuceniem zdjęć z telefonu, ale na zdjęciu z poprzednim multiplexerem I2C wyglądało to podobnie:
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    Teraz jest płytka, do której podpinane są ekranowane przewody enkoderów i łącząca wszystkie:
    +Vcc
    GND do którego podpięty jest ekran
    MISO
    SCK
    te 4 powyższe przewody na wyjściu z płytki idą około 10cm przewodami do ESP32. Każdy przewód CS też idzie luźno do ESP32. Już dzisiaj nie dam rady, bo wychodzę z domu, ale jutro chciałbym spróbować podpiąć płytkę enkoderową do Arduino Mega z wgranym programem jedynie odczytu i zobaczymy czy tez będzie to samo. Dzięki za podpowiedź ze sprawdzeniem sygnału na oscyloskopie
  • #17
    khoam
    Level 42  
    madiz08 wrote:
    Teraz jest płytka, do której podpinane są ekranowane przewody enkoderów i łącząca wszystkie:

    Napisz proszę dokładnie w jaki sposób podłączyłeś ekran z tych przewodów. Z obu stron przewodów?
  • Helpful post
    #18
    Slawek K.
    Level 35  
    Przewody silników powinny być też ekranowane, temat znany np. z drukarek 3D gdzue bliskość przewodów silników i np. przewodów kranćówek powodowaly załączanie stopu z uwagi na generowane zakłócenia.


    Pozdr
  • #19
    madiz08
    Level 14  
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    Tak to wygląda jeżeli chodzi o przewody enkoderów
    Odnośnie przewodów silników, to trochę żałuję, że od razu nie zastosowałem przewodów z ekranem. Jeżeli to miałoby pomóc to na pewno je wymienię na ekranowane.
    Zaraz się zbieram, żeby poprzełączać wszystko na odczyt pozycji z Arduino Mega, z czystej ciekawości czy zmiana mikrokontrolera będzie tu miała jakikolwiek wpływ na poprawność odczytu.
  • #20
    khoam
    Level 42  
    W dłuższych przewodach z sygnałami pomiarowymi, w tym wypadku szyna SPI, ekran powinno się podłączać do masy tylko z jednej strony, w tym wypadku od strony ESP32.
    W przewodach, gdzie płynie większy prąd, ekran powinno się podłączać z obu stron do masy.
  • #21
    madiz08
    Level 14  
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    Na szybko zmontowałem coś takiego jak powyżej i jest to samo, co prawda teraz tylko błędny odczyt z jednego enkodera (później go rozkręcę), ale jest.

    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A
    ESP32 komunikacja SPI z enkoderem absolutnym AS5048A

    Sygnał SCK wydaje się ok, sygnały CS są na 100% idealne. Jeżeli chodzi o MISO to zastanawiam się dlaczego po odczytach sygnał nie spada błyskawicznie do zera, tylko często schodzi powolnie do potencjału masy.
    Pin MOSI od strony Arduino mam niepodpięty

    Dodano po 2 [minuty]:

    Rozumiem, spróbuję też odłączyć ekran od strony enkoderów

    Dodano po 4 [godziny] 32 [minuty]:

    Hmmm... Jedyne co zrobiłem to odizolowałem ekran od masy przy każdym enkoderze według wytycznych i ku mojemu zdziwieniu (ponieważ zawsze mi mówiono, że ekran powinien być tam gdzie się tylko da) kompletny brak błędnych odczytów. Wpisałem w kodzie, żeby zliczał błędne odczyty i wyświetlał co sekundę stan tego licznika i przez ponad godzinę stan licznika wynosił 0, także super, dziękuję za taką wskazówkę. Na razie mam taki wynik dla Arduino Mega, jutro postaram się porządnie poukładać przewody w połączeniu z ESP32 i mam nadzieję, ze w końcu uda się "pojeździć robotem" :)
    Ale zastanawia mnie dlaczego odizolowanie masy od ekranu przy enkoderze wpłynęło na lepsze niwelowanie zakłóceń?
  • #22
    khoam
    Level 42  
    madiz08 wrote:
    Ale zastanawia mnie dlaczego odizolowanie masy od ekranu przy enkoderze wpłynęło na lepsze niwelowanie zakłóceń?

    W dużym skrócie: przez ekran przestały płynąć zakłócenia z enkodera do Mega :)
    Ekran przewodu podłączony do masy z dwóch stron to trochę działa jak antena odbiorcza dla zakłóceń. Im dłuższy, tym lepsza antena.