logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak nawiązać połączenie CAN pomiędzy dwoma ESP32 na przykładzie LilyGO T-CAN485?

p.kaczmarek2 27 Wrz 2025 10:29 1038 2

TL;DR

  • Pokazuje połączenie CAN między dwoma modułami LilyGO T-CAN485 z ESP32, zbudowane wokół sterownika TWAI i środowiska PlatformIO.
  • Jedna baza kodu została rozdzielona na dwie wersje projektu, które nadają i odbierają ramki CAN oraz rozróżniają się na dwóch portach COM.
  • Sterownik działał z prędkością 250 kilobitów na sekundę, a magistrala używała alertów zakończenia transmisji, błędów, pełnej kolejki i nowych danych.
  • Po podłączeniu dwóch płytek i wgraniu odpowiednich programów komunikacja działała, a monitory UART pokazywały wzajemne wykrywanie ramek.
  • ESP32 wymaga transceivera CAN, rezystorów terminujących 120 omów na końcach magistrali oraz wspólnej masy.
📢 Słuchaj (AI):
  • Dwa moduły LilyGO T-CAN485 połączone przewodami CAN_H i CAN_L
    Zapraszam na praktyczną demonstrację połączenia CAN pomiędzy dwoma urządzeniami z ESP32. Pokażę tutaj, jak wygląda procedura nadawania i odbierania ramek na podstawie sterownika TWAI, użyję środowiska PlatformIO. TWAI to skrót od Two-Wire Automotive Interface, czyli w wolnym tłumaczeniu interfejs samochodowy dwuprzewodowy. Jest to oficjalna nazwa używana w SDK od Espressif, choć ja tutaj raczej będę stosować ogólnoprzyjętą nazwę CAN.

    Co to jest CAN?
    CAN (Controller Area Network) to standard komunikacji szeregowej zaprojektowany do niezawodnej wymiany danych pomiędzy urządzeniami elektronicznymi w czasie rzeczywistym. Najczęściej wykorzystywany jest w motoryzacji (komunikacja ECU, ABS), automatyce przemysłowej czy systemach IoT.
    Charakteryzuje się:
    - transmisją wielowęzłową (wiele urządzeń na jednej magistrali)
    - detekcją i obsługą błędów na poziomie sprzętowym
    - priorytetyzacją ramek
    - szybkością od kilkudziesięciu kbit/s do 1 Mbit/s (w klasycznym CAN)
    Schemat magistrali CAN pokazuje poniższy obrazek:
    Schemat magistrali CAN z wieloma urządzeniami podłączonymi do linii CAN-Hi i CAN-Low
    Źródło obrazka: wikipedia - Stefan-Xp, licencja CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=3607670
    Z praktycznego punktu widzenia musimy teraz wiedzieć, jak zestawić takie połączenie - tu nie ma osobnych linii RX i TX, tylko są linie H i L. Nie zamieniamy tu H i L - nawyk z UART nie znajduje tu odzwierciedlenia. Dodatkowo na końcach magistrali CAN powinny być rezystory terminujące o wartości 120 omów, masa też powinna być wspólna.

    Plan działania
    ESP32 posiada wbudowany kontroler CAN (TWAI), ale wymaga dodatkowego transceivera (np. SN65HVD230, MCP2551 lub kompatybilny), który dopasuje sygnały logiczne 3,3 V do poziomów magistrali CAN_H / CAN_L. Tu przychodzi nam z pomocą gotowy moduł, który prezentowałem wcześniej:
    LilyGO T-CAN485 - ESP32 do nauki łączności przemysłowej, magistrale RS485 i CAN
    Połączymy ze sobą dwa takie moduły. Przygotujemy jeden program, zasadniczo weźniemy przykład od LilyGo i zrobimy z niego dwie wersje. Obie będą nadawać i odbierać, a my w konsolach UART sprawdzimy, czy płytki wzajemnie się widzą. Przy okazji poznamy jak to wszystko działa.

    Dokumentacja sterownika, którego użyjemy: https://docs.espressif.com/projects/esp-idf/e...ble/esp32/api-reference/peripherals/twai.html

    Projekt PlatformIO
    Na tym etapie możemy już utworzyć projekt w PlatformIO. Aż prosi się tutaj zastosować jedną z właściwości tej platformy - możliwość wygodnego wydzielenia dwóch wersji projektu. Pozwoli to nam jednocześnie obsłużyć dwa porty szeregowe do debugowania oraz rozróżnić co wysyła która płytka.
    Kod: Ini
    Zaloguj się, aby zobaczyć kod

    Można by tu też dziedziczyć po wspólnym projekcie, ale nie chciałem komplikować. Najważniejszy jest to wybór portu COM (dwa różne) oraz załączenie dodatkowego #define dla drugiej kompilacji. Użyjemy tego do rozróżnienia co będzie wysyłane.
    Przygotujmy przykładowy kod projektu. Będzie on zasadniczo lekko zmodyfikowanym przykładem od LilyGo:
    https://github.com/Xinyuan-LilyGO/T-CAN485/bl...rduino-esp32-libs_v3.0.1/examples/CAN/CAN.ino
    Najpierw nagłówki, stałe (piny od CAN) i zmienne.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Potem uruchomienie sterownika. Jest tu nieco więcej kodu, niż przy UART, ale i tak wcale nie jest on trudny. Mamy tu ustawienie pinów oraz szybkości transferu. Zdecydowałem się na 250 kilobitów na sekundę. Potem możemy skonfigurować alerty CAN, które pozwalają nam reagować na różne zdarzenia w magistrali. W przykładzie włączamy alerty związane z zakończeniem transmisji, błędami, pełną kolejką odbiorczą i nowymi danymi do odczytu. Dzięki temu nasza aplikacja będzie wiedziała, kiedy wysyłanie lub odbiór wiadomości się powiodło, kiedy wystąpił błąd magistrali, lub kiedy kolejka odbiorcza jest pełna.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Następnie mamy funkcję wysyłającą wiadomość. Tu jest inaczej niż w UART - wysyłamy gotowe ramki. Określamy dla niej identyfikator, typ ramki (standardowa/rozszerzona, dane/zdalna), długość danych oraz same dane (warunkowo, różne w każdej wersji), a następnie próbujemy ją wysłać funkcją twai_transmit(), sprawdzając, czy operacja się powiodła.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Po drugiej stronie mamy funkcję odbioru ramki. Tu też mamy dostęp do jej identyfikatora, długości i danych.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Zostaje jeszcze funkcja setup, czyli ogólna konfiguracja pinów i załączenie sterownika CAN. To tutaj dla przejrzystości dodałem informacje o tym, która z wersji programu została uruchomiona.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Na koniec funkcja loop, czyli to, co wykonuje się w pętli. Najpierw mamy tu odczyt alarmów. Odczyt ten jest blokujący - czas blokady podany jest w tickach RTOS, z tego powodu w argumencie użyto pdMS_TO_TICKS. Potem odczytywane są alarmy i status. Sprawdzana jest flaga odbioru - wtedy wywoływana jest obsługa pakietu. Również okresowo wysyłany jest nowy pakiet.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Zostaje tylko połączyć ze sobą dwie płytki tak, jak pokazałem na schemacie i wgrać na nie odpowiednie programy. PlatformIO bardzo to ułatwia, można zestawić obok siebie nawet dwa monitory portów szeregowych i porównywać co się dzieje:
    Okno Visual Studio Code z kodem i wynikami transmisji CAN z dwóch urządzeń ESP32
    Zasadniczo widać, że wszystko działa. Na tej bazie można realizować własną komunikację poprzez protokół CAN.

    Podsumowanie
    W ten sposób można skomunikować ze sobą dwa lub więcej urządzeń przez magistralę CAN. CAN początkowo mógł wydawać się dość trudny, ale moim zdaniem ta krótka prezentacja pokazała, że w rzeczywistości jest bardzo prosty w obsłudze. Gotowa biblioteka wszystko sprawdza, obsługuje błędy, oraz podaje nam jak na tacy gotowe ramki wraz z informacjami o nich.
    Czy korzystaliście z CAN, a jeśli tak, to w jakich projektach?

    Fajne? Ranking DIY
    Pomogłem? Kup mi kawę.
    O autorze
    p.kaczmarek2
    Moderator Smart Home
    Offline 
    Inżynier programista z wieloletnim doświadczeniem embedded i full stack developer.
    Specjalizuje się w: embedded, Full-Stack Developer
    p.kaczmarek2 napisał 14640 postów o ocenie 12653, pomógł 655 razy. Jest z nami od 2014 roku.
  • #2 21702205
    ZbeeGin
    Poziom 39  
    Posty: 4320
    Pomógł: 602
    Ocena: 453
    p.kaczmarek2 napisał:
    Czy korzystaliście z CAN, a jeśli tak, to w jakich projektach?

    Tak. Korzystam z CAN, choć wybrałem MCU nieco przyszłościowo, bo zastosowany STM32 z serii G0B1 dysponuje już jednostką CAN FD. Jako transciever wybrano układ ATA6561, który ze względu na dualność zasilania może pracować z logiką 3.3V bez konieczności stosowania level-shifter'a.
  • #3 21703645
    DJ_KLIMA
    Poziom 25  
    Posty: 661
    Pomógł: 67
    Ocena: 220
    Tak, dobrze działa moduł CAN w esp32, stosuje jako proste serwisowe HMI do maszyn ciężkich.
📢 Słuchaj (AI):
REKLAMA