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

ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia

p.kaczmarek2 12 Jul 2020 10:46 4623 1
Nazwa.pl
  • ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Witajcie moi drodzy
    Przedstawię tutaj mojego shielda (nakładkę) na Arduino UNO opartego o układ ENC424j600. Shield ten pozwala podłączyć Arduino do internetu bez żadnego lutowania, a nawet bez użycia kabelków i płytek stykowych. W temacie dam jedenaście pełnych przykładów jego użycia z moimi komentarzami, dotyczyć one będą tematów takich jak UDP, TCP, NTP, DNS, DHCP i HTTP.

    Wstęp
    Jakiś czas temu opublikowałem na DIY projekt bazujący na ENC424j600 w temacie o nazwie Moduł łączności Ethernet ENC424J600 (czyli taki lepszy ENC28J60), tutaj:
    https://www.elektroda.pl/rtvforum/topic3636658.html
    Tak się złożyło, że po wykonaniu tamtego projektu zostało mi parę części, więc uznałem, że mogę je jeszcze jakoś lepiej wykorzystać, by nie kurzyły się w szufladzie.
    Zobaczyłem też, że choć jest wiele shieldów łączności Ethernet dla Arduino, to shielda opartego ENC424J600 chyba nie ma - stąd wziął się pomysł.
    Zasadniczo do tego projektu musiałem zaprojektować i zamówić tylko PCB - resztę już miałem na stanie.

    Spis treści przykładów
    W tym temacie zawarłem następujące przykłady użycia Arduino z ENC424 (a nawet niekoniecznie - te same metody można zastosować dla innych układów/modułów sieciowych):
    - Przykład ENC424J600 na Arduino nr 1 - przypisujemy IP, pingowanie
    - Przykład ENC424J600 na Arduino nr 2 - serwer TCP echo
    - Przykład ENC424J600 na Arduino nr 3 - prosty klient DNS
    - Przykład ENC424J600 na Arduino nr 4 - DHCP czyli automatyczne przypisywania konfiguracji IP dla Arduino
    - Przykład ENC424J600 na Arduino nr 5 - DHCP + DNS
    - Przykład ENC424J600 na Arduino nr 6 - klient UDP usługi NTP
    - Przykład ENC424J600 na Arduino nr 7 - serwer TCP kalkulator
    - Przykład ENC424J600 na Arduino nr 8 - serwer HTTP czyli nasza strona WWW
    - Przykład ENC424J600 na Arduino nr 9 - klient HTTP (wysyłamy zapytanie GET)
    - Przykład ENC424J600 na Arduino nr 10 - klient HTTP i argumenty zapytania GET
    - Przykład ENC424J600 na Arduino nr 11 - klient HTTP - zapytanie GET reverse geocoding
    Pełny kod Arduino każdego przykładu jest w treści tematu, nie trzeba nic pobierać.

    Krótki słowniczek
    W temacie używam dość dużo pojęć z którymi niektórzy mogą nie być zapoznani, dlatego umieszczam tutaj krótki słowniczek skrótów i wyjaśnień co jest czym. Wyjaśnienia poniżej oczywiście są bardzo uproszczone, nic nie zastąpi lektury dobrej książki.
    UDP - User Datagram Protocol - bezpołączeniowy protokół internetowy, szybki lecz nie oferujący mechanizmów kontroli transmisji, może gubić pakiety, itd.
    TCP - Transmission Control Protocol - połączeniowy protokół internetowy, wymaga nawiązania połączenia, zapewnia dostarczenie danych do celu, nieco wolniejszy.
    DNS - Domain Name System - system nazw domenowych, w dużym skrócie zamienia nazwe hostu np. 'elektroda.pl' na jego adres IP np. 104.109.65.140
    DHCP - Dynamic Host Configuration Protocol - protokół dynamicznego konfigurowania hostów, z reguły chodzi na routerze, automatycznie przypisuje hostom adresy IP ( z reguły zmienne), IP bramy sieciowej, maskę, itp. Przeciwieństwo konfigurowania IP 'na sztywno'.
    NTP - Network Time Protocol - protokół sieciowy synchronizacji czasu. Opiera się na UDP, pozwala na synchronizację czasu pomiędzy komputerami. Można z niego pomocą pobrać aktualny czas z serwera.
    HTTP - Hypertext Transfer Protocol - protokół przesyłania dokumentów sieci WWW. Opiera sie na TCP, jest tekstowy. To poprzez ten protokół działają strony internetowe
    HTML - HyperText Markup Language - język znaczników do tworzenia dokumentów stron WWW. Pozwala formułować akapity, linki, nagłówki, listy, ustawiać czcionki, i znacznie, znacznie więcej.
    W celu dokładniejszego poznania opisanych tu pojęć odsyłam do lepszych źródeł, np. nawet do wikipedii.

    Projekt shielda
    Schemat i PCB wykonałem w darmowej wersji programu Eagle. Punktem początkowym był design Arduino UNO (też w Eagle, na szczęście) i design mojej poprzedniej płytki pod ENC424:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Większość połączeń musiałem jednak poprowadzić od nowa:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    ENC424J600 podłączyłem do pinów SPI od Arduino UNO, czyli:
    - pin 11 - MOSI
    - pin 12 - MISO
    - pin 13 - SCK
    - pin 10 - SS
    Jednakże na płytce przed tymi pinami dałem zworki, na wypadek gdyby coś poszło nie tak.
    Samo podłączenie Ethernetu do ENC424J600 jest zrealizowane zgodnie z notą katalogową:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Warto tu jednak zaznaczyć, że w projekcie użyłem tzw. złącza 'magjack', które ma w sobie już wszystko to co zaznaczyłem czerwoną ramką (czyli transformatorki, rezystory 75 omów, itp). Konkretnie to użyłem JXD0-0006NL.
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Schemat wewnętrzny złącza pokazanego wyżej:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Nota katalogowa JXD0-0006NL:
    JXD0-000..L.pdf Download (462.64 kB)
    ENC424J600 zasilany jest z 3.3V (5V go uszkodzi), więc na płytkę dałem też LDO 3.3V MIC2940A-3.3WU w obudowie TO-263:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Nota katalogowa MIC2940A:
    MIC2940A-4...06000A.pdf Download (1.38 MB)
    Ten regulator napięcia na płytce może być zasilany z 5V z Arduino, albo bezpośrednio z jego VIN (MIC działa z VIN aż do +26V). Może być też całkiem pominięty (ale odradzam, bo to niepotrzebnie by obciążało 3.3V z Arduino).
    Do SPI nie musiałem konwertować poziomów logicznych, gdyż piny ENC424 są '5V-tolerant':
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Dodatkowo na pokładzie zostało troszkę miejsca, więc umieściłem tam trzy kości SRAM, też na SPI, a dokładnie 23LC1024:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Mam pewien koncept, do czego je mogę wykorzystać.
    Każdy z tych kości ma oczywiście osobny pin Chip Select (aktywne urządzenie na magistrali SPI wybiera się za pomocą tego pinu).
    Elementy SMD na płytce starałem się umieszczać w tych bardziej przyjaznych obudowach do lutowania dla początkujących, czyli 0805, a nie np. mniejszej 0603.
    Końcowo płytka wyszła tak:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Pełny projekt Eagle do pobrania:
    shield_enc..._eagle.zip Download (97.17 kB)Points: 4 for user
    Pliki gerber do utworzenia płytki:
    shield_enc...erbers.zip Download (198.51 kB)Points: 3 for user
    Schemat do pobrania:
    shield_ENC..._sch-1.png Download (120.58 kB)Points: 1 for user
    Płytki zamówiłem jak zwykle w Chinach - 5 sztuk.

    Lutowanie shielda
    Płytki przed lutowaniem:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Na początku przylutowałem najtrudniejszy element, czyli sam ENC424 w obudowie TQFP44:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Następnie kolejno małe elementy SMD:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Nie miałem rezonatora kwarcowego 25MHz w odpowiedniej obudowie do montażu powierzchniowego, więc użyłem zwykłego przewlekanego, po prostu odgiąłem mu piny:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Niestety odpowiednie złącza Ethernet (JXD0-0006NL PulseJack produkcji Pulse) mi się skończyły, więc musiałem poradzić sobie odpowiednikiem tego złącza o zgodnym układzie wyprowadzeń lecz bez diod LED RX/TX, czyli J00-0061NL:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Pociągnęło to za sobą potrzebę przylutowania osobnych ledów. Ostatecznie płytka wyszła tak:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Nie przylutowałem wszystkich pamięci na SPI, tylko jedną.
    Po wyczyszczeniu z topnika:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Obok Arduino UNO (tego, co użyłem do testów z tematu):
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Jak na razie zlutowałem dwie sztuki mojego shielda, zostało mi kilka PCB, chętnych zapraszam na PW.

    Test obsługi pamięci 23LC1024
    Przed przejściem do tematów powiązanych z ENC424J600 sprawdziłem czy pamięć SRAM 23LC1024 na pokładzie płytki działa. Pamięć ta podłączona jest też na SPI, ma jedynie osobny pin SS (tzw. Chip Select) pozwalający wybrać z którym peryferium na płytce w danym momencie Arduino się komunikuje. Właściwie to na PCB jest miejsce na trzy sztuki 23LC1024, ale ja przylutowałem tylko jedną.
    Do obsługi 23LC1024 użyłem biblioteki stąd:
    https://forum.arduino.cc/index.php?topic=182918.0
    Biblioteka w załączniku:
    SpiRAM_23L...v0.1.4.zip Download (3.32 kB)
    Pełny kod testowego kodu z biblioteki (nie modyfikowałem go; jest dobry taki jaki jest; zmieniłem tylko pin SS na 8):
    Code: c
    Log in, to see the code

    Rezultat w Serial Monitor:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    23LC1024 działa - testy zapisu/odczytu wykonują się poprawnie.

    Biblioteka obsługi ENC424J600 dla Arduino UNO
    Biblioteki do obsługi ENC424J600 nie musiałem samodzielnie pisać - na Githubie istniała już gotowa, UltratronicsEthernet, autorstwa brupje. To jest właśnie urok Arduino, że praktycznie do większości nieco bardziej popularnych układów są już gotowe rozwiązania.
    Użyta biblioteka jest dostępna tutaj:
    https://github.com/brupje/UltratronicsEthernet
    Kopia zapasowa repozytorium do pobrania:
    Ultratroni...200712.zip Download (111 kB)
    Bibliotekę dodaje się do Arduino poprzez Sketch->Include Library->Add .ZIP Library
    Biblioteka ta tutaj stanowi przerobioną wersję ogólnie znanej biblioteki Ethernet dla Arduino. Po prostu autor przeportował ją pod ENC424.
    Tutaj jest dokumentacja pierwowzoru, który był dla modułów W5100 itp:
    https://www.arduino.cc/en/reference/ethernet

    Moje poprawki biblioteki UltratronicsEthernet
    Niestety po kilku testach okazało się, że działa mi z tej biblioteki tylko TCP. DNS wcale nie odpowiadał, DHCP też nie, a nawet nie działało wysyłanie pakietów po UDP.
    Zacząłem sprawdzać i debugować, co może być nie tak.
    Szybko doszedłem do wniosku, że pierwszy pakiet protokołu DHCP, tzw. DHCP Discovery wygląda tak:
    
    1A 68 D3 93 B6 E7 BE 97 B5 5A BF EB 3B DA DB E0 27 DC 25 16 3D 32 AD 88 3E A4 6 31 97 B9 8B 2F A0 54 1 BC 29 38 C8 B9 B2 EF 1 1 6 0 0 0 3 31 0 0 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 BA A
    

    A raczej na pewno nie powinien tak wyglądać - zgodnie z dokumentacją protokołu DHCP pierwszy pakiet powinien zaczynać się od 0xFF 0xFF 0xFF 0xFF, czyli 255.255.255.255, czyli adresu rozgłoszeniowego. Ciąg dalszy pakietu (od 1 1 6 0 0 3 31) wygląda z kolei okej. Są to kolejno DHCP_BOOTREQUEST (1), DHCP_HTYPE10MB (1), DHCP_HLENETHERNET (6), DNS_HOPS (0).
    Kolejne testy pokazały, że "1A 68 D3 93 B6 E7 BE 97 B5 5A BF EB" itp. to tak naprawdę są śmieci z pamięci. W bibliotece był błąd na skutek którego nagłówek pakietu IP nie był przesyłany do ENC424.
    Naprawiłem to poprzez dopisanie kodu który przed wysłaniem pakietu ponownie wysyła jego bajty poprzez SPI do ENC, choć myślę że można by to jeszcze usprawnić.
    Od tego momentu pakiet Discovery od DHCP zaczął wyglądać poprawnie, DHCP i UDP ruszyło.
    Oprócz tego w kodzie nie spodobał mi się ten warunek:
    Code: c
    Log in, to see the code

    Usuwał on nieco dłuższe pakiety. Zmieniłem wartość len na nieco większą, choć tu też jest problem z ilością pamięci RAM na Arduino Mimo wszystko od tego momentu biblioteka stała się w pełni użyteczna. Po prostu trzeba pamiętać o limitacjach platformy z której się korzysta.
    Zmodyfikowana przeze mnie bieżąca wersja biblioteki (to tej wersji użyłem do przykładów z tematu):
    arduino_ui...200712.zip Download (106.08 kB)Points: 0.5 for user

    Przykład ENC424J600 na Arduino nr 1 - przypisujemy IP, pingowanie
    Najprostszy serwer w bibliotece UltratonicsEthernet można zrealizować tak:
    Code: c
    Log in, to see the code

    Ważne jest o tym, by pamiętać o wywoływaniu Ethernet.maintain() możliwie często, gdyż funkcja ta obsługuje zdarzenia powiązane z siecią, nawet zapytania ping.
    Oczywiście wartości:
    - IPAddress myIP(192,168,0,126); - adresu IP płytki
    - IPAddress myDNS(8,8,8,8); - adresu DNS
    - IPAddress myGW(192,168,0,1); - adresu gateway/bramy domyślnej
    - IPAddress mySN(255,255,255,0); - maski sieciowej
    powinny być zgodne z naszą siecią do której podłączamy płytkę, możemy je łatwo poznać np. na Windowsie używając komendy ipconfig /all.
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Widoczność płytki na naszej sieci można sprawdzić z poziomu Windowsa za pomocą komendy 'ping <IP_PLYTKI>', rezultat poniżej:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia

    Przykład ENC424J600 na Arduino nr 2 - serwer TCP echo
    W oparciu o kod z poprzedniego akapitu można zrobić prosty serwer TCP echo, czyli serwer który zwróci nam to co do niego wysłaliśmy. Serwer będzie również drukować odebrane pakiety na UART, byśmy mogli zweryfikować w Serial Monitor co się dzieje.
    Code: c
    Log in, to see the code

    (w przykładach tej biblioteki na githubie też macie serwer echo, ale zrealizowany inaczej, używający malloc i free)
    Do takiego serwera możemy podłączyć się poprzez TCP. Najprościej chyba jest użyć do tego programu Putty w trybie Raw:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Rezultat testów w Putty:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Rezultat w terminalu:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia

    Przykład ENC424J600 na Arduino nr 3 - prosty klient DNS
    DNS (Domain Name System) jest usługą na której opiera się cały internet jaki znamy - służy on do zamiany nazwy hosta (np. elektroda.pl) na adres IP (np. 104.109.65.140). Mój shield dla Arduino też jest do tego zdolny, co jest przedstawione w przykładzie poniżej:
    Code: c
    Log in, to see the code

    Rezultat działania (dla hostu elektroda.pl):
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Rezultat działania (dla hostu google.com):
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia

    Przy okazji zrobiłem też eksperyment - zmieniłem adres serweru DNS (wcześniej: 8.8.8.8) na adres IP mojego komputera i za pomocą Wiresharka sprawdziłem co przyjdzie. Oto rezultaty:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Jak widać Wireshark poprawnie wykrył, że nadszedł pakiet DNS. Moja maszyna go nie obsłużyła, bo nie mam postawionej na niej usługi DNS, ale z pewnością by mogła.

    Przykład ENC424J600 na Arduino nr 4 - DHCP czyli automatyczne przypisywania konfiguracji IP dla Arduino
    Kolejną rzeczą wartą sprawdzenia jest DHCP - Dynamic Host Configuration Protocol. DHCP pozwala klientom automatycznie pobrać konfigurację sieci od routera. Nie musimy im sami konfigurować IP, maski, bramy domyślnej, itp, wszystko ustawia się samo.
    Poniżej przykład pobierającego konfiguracje przez DHCP:
    Code: c
    Log in, to see the code

    Rezultat w terminalu:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Rezultat pingowania nadanego IP:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Rezultat pracy DHCP też można podejrzeć na niektórych routerach, w historii zdarzeń:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Oczywiście, jak zmienimy w kodzie MAC na inny to przypisany zostanie nam inny adres IP (tamten wcześniej użyty będzie mieć jeszcze lease):
    Code: c
    Log in, to see the code

    Inny adres IP przypisany przez router:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia

    Przykład ENC424J600 na Arduino nr 5 - DHCP + DNS
    Teraz pora na połączenie dwóch poprzednich przykładów. Program pobiera automatycznie konfiguracje sieci a potem określa IP hostów z tablicy. Kod:
    Code: c
    Log in, to see the code

    Do listy hostów dodałem tutaj adres nieistniejącej strony, by przedstawić co wtedy wyświetli program.
    Rezultat działania kodu:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia

    Przykład ENC424J600 na Arduino nr 6 - klient UDP usługi NTP
    NTP (Network Time Protocol) to prosty protokół internetowy pozwalający na synchronizację czasu między urządzeniami. Opiera się on na UDP i w zasadzie ogranicza się do wysłania zapytania do serwera NTP i odebrania odpowiedzi. Można go bardzo prosto użyć na Arduino.
    Serwerów NTP w sieci jest mnóstwo i są do użycia jak najbardziej za darmo, można znaleźć ich listę tutaj:
    https://www.pool.ntp.org/zone/europe
    Wartość czasu w NTP wyrażona jest za pomocą 32-bitowego integera (jest to ilość sekund od 1 stycznia 1900) , którego musimy jeszcze odpowiednio odkodować, ale na szczęście mamy do tego gotowe mechanizmy z biblioteki Arduino time.h.
    Należy tu pamiętać jednak, że time.h na Arduino jest nieco inne niż te np. na Windowsie, o czym mówi sama dokumentacja AVR-GCC:
    Quote:

    Though not specified in the standard, it is often expected that time_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.

    Ale to żaden problem. Poniżej przedstawiam jak można odebrać czas NTP i wyświetlić go na 3 różne sposoby:
    - sposób pierwszy - funkcja ctime
    - sposób drugi - 'na piechotę', bez użycia funkcji bibliotecznych
    - sposób trzeci - gmtime
    Pełny kod:
    Code: c
    Log in, to see the code

    W powyższym kodzie polecam zwrócić uwagę na dwie rzeczy.
    - NTP_OFFSET - jest to stała z time.h, z AVR-GCC, służąca do poprawnej konwersji czasu ze standardu NTP do tego co mamy na Arduino
    - TIMEZONE_GMT_OFS - jest to zmienna określająca przesunięcie godziny (strefę czasową), która jest zdefiniowana na początku kodu
    Rezultat działania kodu:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Na powyższym zrzucie ekranu widać rezultaty dwóch zapytań NTP pomiędzy którymi był odstęp czasowy około 5 sekund. Zapytania NTP warto jest wysyłać co jakiś czas, albo przynajmniej sprawdzać ich rezultat, bo protokół UDP jest bezpołączeniowy i nie daje żadnej gwarancji, że pakiet dotrze do celu.

    Przykład ENC424J600 na Arduino nr 7 - serwer TCP kalkulator
    Poprzedni mój przykład serwera TCP ("serwer TCP echo") można łatwo zmodyfikować tak, by zademonstrować parsing danych wysyłanych przez klienta oraz konwersje napisu (typ char) na liczbę zmiennoprzecinkową (float) za pomocą funkcji atof.
    W tym celu zrobiłem prosty kalkulator, który odbiera tekst w formacie "2+2" i zwraca wynik tak opisanego działania matematycznego. Wspiera cztery działania - dodawanie, odejmowanie, dzielenie i mnożenie.
    Pełny kod:
    Code: c
    Log in, to see the code

    Najważniejszym fragmentem powyższego kodu jest pętla for która znajduje w napisie znak oraz funkcja pomocnicza 'mySubStrFloat' która wyciąga z napisu fragment reprezentujący daną liczbę. Kod nie zawiera żadnego sprawdzania błędów.
    Do tego serwera TCP można łatwo podłączyć się poprzez Putty w trybie RAW (czyli czyste TCP, bez HTTP). Rezultat testów w Putty:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Widać, że Arduino przy wyświetlaniu floatów zaokrągla do 2 miejsc po przecinku, ale to już jest kwestia tamtejszej implementacji atof a nie mojego kodu.

    Przykład ENC424J600 na Arduino nr 8 - serwer HTTP czyli nasza strona WWW
    Przykład ten to chyba najbardziej charakterystyczne zastosowanie ENC28J60 (i użytego tutaj ENC424J600) wśród hobbystów. Nasza własna strona WWW, w pełni na Arduino. Użyty protokół tutaj to oczywiście HTTP (który opiera się na TCP i korzysta z reguły z portu 80), a sam język strony WWW to HTML.
    Kod tego przykładu bazowałem na dokumentacji Arduino https://www.arduino.cc/en/Tutorial/WebServer
    Jedynie nieco go ulepszyłem i dodałem linijkę Ethernet.maintain(), która w tej wersji biblioteki ENC424 jest niezbędna do wywołania ręcznie.
    Pełny kod poniżej:
    Code: c
    Log in, to see the code

    Rezultat w przeglądarce:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Rezulat w serial monitor (widać tutaj jak wygląda zapytanie wysyłane przez przeglądarkę do Arduino, słynne HTTP GET):
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Powyższy kod jeszcze dodatkowo wyświetla na stronie odczyt z wejść analogowych Arduino (piny A1, A2, itp.). Aby ten odczyt miał sens, należy coś do nich podłączyć - na przykład potencjometry:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Odczyty dla różnych ustawień potencjometrów:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia


    Przykład ENC424J600 na Arduino nr 9 - klient HTTP (wysyłamy zapytanie GET)
    Tutaj pokażę jak możemy wysłać zapytanie GET do serwera HTTP. GET jest to zapytanie o konkretną stronę internetową/dokument/plik na serwerze. GET jest wysyłane jako czysty tekst, poprzez protokół TCP.
    Dla przykładu tutaj wyślę GET do serwera który zwraca sam nasz adres IP (oczywiście też z nagłówkiem HTTP OK).
    Serwer ten to http://ipinfo.io/ .
    Link do usługi zwracającej samo IP jako tekst w HTTP: http://ipinfo.io/ip
    Przy okazji też po raz kolejny użyję tutaj usługi DNS. W kodzie podam nazwę domenową serwera, a biblioteka Ethernet sama zamieni ją na IP.
    Poniżej pełny kod:
    Code: c
    Log in, to see the code

    Rezultat działania kodu:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Warto zwrócić uwagę, że odpowiedź serwera najpierw zawiera nagłówek HTTP (HTTP kod 200 OK), a potem dane które już są wyświetlane w przeglądarce.


    Przykład ENC424J600 na Arduino nr 10 - klient HTTP i argumenty zapytania GET
    Zapytanie GET z protokołu HTTP omówione w poprzednim akapicie może posiadać argumenty. Zapisane są one w samym linku, po znaku '?', za pomocą znaków '=', a kolejne argumenty oddzielone są od siebie '&'. W taki sposób:
    
    https://www.elektroda.pl/rtvforum/privmsg.php?mode=reply&p=5758394
    

    Tutaj bazowy URL to jest:
    
    https://www.elektroda.pl/rtvforum/privmsg.php
    

    Reszta natomiast to są argumenty:
    
    mode=reply&p=5758394
    

    Wartość argumentu 'mode' to 'reply', a wartość argumenty 'p' to 5758394.
    Przedstawię tutaj, jak takie argumenty można wysłać z poziomu Arduino.
    Potrzebny do tego będzie też serwer WWW, na którym uruchomimy skrypt PHP który odbierze te argumenty i przetworzy.
    Taki serwer możemy postawić sami na własnej maszynie (np. za pomocą Xampp) albo kupić w sieci, albo... skorzystać z któregoś z darmowych serwerów z PHP, takie usługi też są.
    Dla przykładu zrealizujemy tutaj prosty kalkulator - skrypt PHP odbierze dwie liczby i zwróci wynik operacji na nich.
    Skrypt powinien zwracać czysty tekst, a nie dokument HTML, więc dodatkowo zmienimy jego content-type.
    Oto skrypt:
    Code: php
    Log in, to see the code

    Teraz potrzebny też będzie kod na Arduino, który wyśle poprzez GET wartości zmiennych 'pierwsza' i 'druga'.
    Dane te umieszcza się w samej ścieżce do pliku w zapytaniu GET - przykład kodu poniżej:
    Code: c
    Log in, to see the code

    Do liczb w kodzie powyżej użyłem typu int, więc musiałem jeszcze zamienić je na napis (tablicę charów) za pomocą sprintf.
    Rezultat działania w Serial Monitor:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Kod działa - argumenty są poprawnie wysyłane i odbierane przez skrypt PHP po stronie serwera. Na Arduino można by się pokusić o lepszy parsing odpowiedzi HTTP, ale to już zależy do czego chcemy wykorzystać GET. Jeśli chcemy np. za pomocą GET wysyłać wyniki pomiarów do serwera WWW i tam zapisywać je w bazie danych SQL, to w zasadzie samej odpowiedzi na GET nawet nie musimy parsować.
    Na koniec jeszcze mogę wspomnieć, że wysyłanie zapytań GET można testować poprzez program Putty - po prostu wpisuje się w nim treść zapytania. Wygląda to tak:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia

    Przykład ENC424J600 na Arduino nr 11 - klient HTTP - zapytanie GET reverse geocoding
    Reverse geocoding jest to proces zamiany koordynatów (szerokość i długość geograficzna) na słowny opis danej lokacji (nazwa miasta, ulicy, itp).
    W internecie dostępne są różne usługi oferujące reverse geocoding - część z nich jest płatna, część jest darmowa (ale z reguły ma limity zapytań oraz wymaga rejestracji w celu zdobycia klucza API), część korzysta z HTTPS a część z HTTP.
    Tutaj przedstawię jak można użyć takiej usługi na przykładzie geocode.arcgis.com . Strona ta oferuje reverse geocoding bez potrzeby rejestracji i po czystym HTTP, zapytanie GET.
    Dokumentację tej usługi możecie znaleźć tutaj:
    https://developers.arcgis.com/rest/geocode/api-reference/geocoding-geocode-addresses.htm
    Zasadniczo całe użycie tej usługi sprowadza się do wysłania jednego GETa do serwera z parametrami zakodowanymi w samym URL, np takiego:
    
    http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode?f=pjson&featureTypes=&location=-117.205453%2C34.037988
    

    Można sprawdzić jak to działa w przeglądarce - kliknąć na link poniżej:
    http://geocode.arcgis.com/arcgis/rest/service...reTypes=&location=-117.205453%2C34.037988
    Dodatkowo sprawdziłem też działanie tego w Putty, by określić jaki nagłówek GET muszę wysłać.
    Opracowałem następujący kod:
    Code: c
    Log in, to see the code

    Powyższy kod najpierw określa IP serwera geocode za pomocą DNS, a potem wysyła do niego zapytanie co znajduje się na pozycji GPS -117.205453 34.037988.
    Rezultat działania:
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    ENC424J600 Arduino Ethernet Shield - pełny projekt i 11 przykładów użycia
    Jak widać przykład reverse geocoding działa poprawnie - zwraca pełny zestaw informacji na temat danego punktu na mapie. Można potem te informacje parsować i wyciągnąć z nich to, co nas konkretnie interesuje.

    Co można by zrobić lepiej, uwagi
    Przedstawioną tu płytkę, przykłady a nawet bibliotekę można by znacznie ulepszyć.
    - płytkę można przerobić tak by elementy były w obudowach 0603 a nie (głównie) w 0805 i coś jeszcze na niej zmieścić
    - w bibliotece można ulepszyć komunikację z ENC424 poprzez SPI (tam był błąd związany z UDP; naprawiłem go wpisując osobno każdy bajt, a można też je wpisać po kolei; nie ulepszyłem tego bo i tak już działało, a czas na optymalizację jeszcze mam)
    - w niektórych przykładach przydałoby się lepiej parsować odpowiedź GET i nie zamykać przedwcześnie połączenia (może się zdarzyć, że available() zwróci 0 a potem dopiero dojdzie ciąg dalszy danych)
    - w bibliotece można by dokończyć (chyba nie są sprawne) #define/#ifdef pozwalające wyłączyć np. całkiem DHCP lub DNS gdy go nie używamy (DHCP jest tak podpięte do biblioteki w funkcji tick()/maintain() że nawet gdy go nie używamy to zajmuje pamięć)

    Podsumowanie
    Projekt okazał się nieco trudniejszy niż myślałem - początkowo założyłem, że biblioteka UltratonicsEthernet dla Arduino będzie w pełni funkcjonalna, a jednak musiałem ją poprawiać. Na szczęście po kilku godzinach debugowania i wypisywania pakietów na UART udało mi się znaleźć błąd i wszystko ruszyło.
    Na koniec jeszcze podkreślę, że użyta tu biblioteka jest niemalże identyczna ze strony użytkownika z normalną biblioteką Ethernet dla Arduino, więc przygotowane przykłady mogą tez się przydać jak używacie innego układu niż ENC424 będący tematem tego postu.

    Cool? Ranking DIY
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • Nazwa.pl
  • #2
    Mamut
    Level 18  
    Według datasheeta maksymalna częstotliwość zegara SPI dla ENC424J600 to 14 MHz. ATmega328P będąca podstawą budowy Arduino Uno powinna być w stanie osiągnąć 10 MHz przy taktowaniu 20 MHz i wyłączonych preskalerach. Czy robił może kolega jakieś testy możliwości układu ENC? Pytam bo myślę o pewnym zastosowaniu, nie tyle wymagającym wymiany dużej ilości danych, ile interesują mnie małe zwłoki czasowe między odebraniem pakietu a wykonaniem akcji (i vice versa).