Spisu treści:

Arduino UNO Logic Sniffer: 8 kroków (ze zdjęciami)
Arduino UNO Logic Sniffer: 8 kroków (ze zdjęciami)

Wideo: Arduino UNO Logic Sniffer: 8 kroków (ze zdjęciami)

Wideo: Arduino UNO Logic Sniffer: 8 kroków (ze zdjęciami)
Wideo: 35 przerażających filmów o duchach: mega kompilacja z 2023 r. [V1] 2024, Lipiec
Anonim
Sniffer logiczny Arduino UNO
Sniffer logiczny Arduino UNO

Ten projekt rozpoczął się od prostego eksperymentu. Podczas moich badań nad arkuszem danych ATMEGA328P dla innego projektu, znalazłem coś dość interesującego. Jednostka przechwytywania wejścia Timer1. Umożliwia mikrokontrolerowi naszego Arduino UNO wykrywanie krawędzi sygnału, przechowywanie znacznika czasu i wyzwalanie przerwań, wszystko to sprzętowo.

Zastanawiałem się wtedy, w jakiej aplikacji może się przydać i jak to przetestować. Ponieważ od jakiegoś czasu chcę mieć analizator stanów logicznych, postanowiłem spróbować zaimplementować go na mojej płycie Arduino UNO, aby przetestować tę funkcję i sprawdzić, czy możemy uzyskać z niego dobre wyniki.

Nie jestem jedyną osobą, która wpadła na ten pomysł, a znajdziesz ich mnóstwo, po prostu googlując „Arduino Logic Analyzer”. Na początku projektu, który dopiero zaczynał się jako eksperyment, nie zdawałem sobie nawet sprawy, że ludzie już to zrobili, i byłem pod wrażeniem dobrych wyników, jakie osiągnęli dzięki temu małemu sprzętowi. Nie mogłem jednak znaleźć innego projektu korzystającego z modułu przechwytywania danych wejściowych, więc jeśli już to widziałeś, daj mi znać!

Podsumowując, mój analizator stanów logicznych:

  • Mieć jeden kanał,
  • Mieć interfejs graficzny,
  • Komunikować się z interfejsem przez USB,
  • Działa na płytce Arduino UNO.

W końcu będzie miał głębokość pamięci 800 próbek i był w stanie z powodzeniem przechwycić wiadomość UART 115200 bodów (tak naprawdę nie testowałem jej przy wyższych prędkościach).

Ta instrukcja zawiera zarówno części tego projektu „jak to działa”, jak i „jak z tego korzystać”, więc dla tych, którzy nie są zainteresowani stroną techniczną, możesz bezpośrednio przejść do kroku 4.

Kieszonkowe dzieci

Chciałem, aby analizator był jak najprostszy, więc wymagał bardzo mało sprzętu.

Będziesz potrzebować:

  • Płytka Arduino UNO (lub jej odpowiednik, o ile opiera się na MCU ATMEGA328P),
  • Komputer,
  • Coś do debugowania (inna płyta Arduino UNO działa dobrze, aby wykonać kilka testów).

Kod zarówno dla Arduino UNO, jak i interfejsu internetowego można znaleźć tutaj. Potrzebne będzie również oprogramowanie p5.serialcontrol i PulseView.

Krok 1: Zasada działania

Zasada działania
Zasada działania

Pomysł jest prosty. Wybierasz ustawienia przechwytywania i klikasz „pozyskaj”. Interfejs sieciowy prześle je do oprogramowania p5.serialcontrol, które pozwala nam korzystać z interfejsu szeregowego z przeglądarki, ponieważ nie ma do niego bezpośredniego dostępu. Oprogramowanie p5.serialcontrol przekazuje następnie informacje do płyty Arduino UNO, która przechwytuje dane i wysyła je z powrotem do interfejsu tą samą ścieżką.

Łatwo! Cóż… Ponieważ nie jestem zbyt dobry w programowaniu interfejsu człowiek/maszyna ani w technologiach internetowych, mój jest z pewnością trochę brzydki i pełen błędów. Ale pozwala mi rozpocząć przechwytywanie i odzyskać moje dane, do czego został zaprojektowany, więc myślę, że jest w porządku. Do poważniejszych prac analitycznych importuję swoje rekordy do PulseView, który jest łatwy w użyciu i oferuje dobry zestaw funkcji i dekoderów protokołów, jak zobaczymy później.

Moduł przechwytywania sygnału wejściowego Arduino UNO można skonfigurować tak, aby używał różnych podziałów zegara, zmniejszając w ten sposób rozdzielczość, ale zwiększając opóźnienie przed przepełnieniem. Może również wyzwalać się przy wzroście, spadku lub obu krawędziach, aby rozpocząć przechwytywanie danych.

Krok 2: Szkic Arduino UNO

Szkic Arduino UNO
Szkic Arduino UNO

Napisałem i skompilowałem szkic za pomocą Arduino IDE. Najpierw zacząłem od ustawienia Timera1 w "Normalnym" trybie działania, zapisując jego rejestry TCCR1A i TCCR1B w setup(). Następnie stworzyłem kilka funkcji, aby nieco ułatwić jego użycie w przyszłości, na przykład tę, która ustawia podział zegara o nazwie "setTim1PSC()". Napisałem również funkcje do aktywacji i dezaktywacji jednostki przechwytywania wejścia Timer1 i przerwań przepełnienia.

Dodałem tablicę "samples", w której będą przechowywane zebrane dane. Jest to tablica globalna, którą ustawiłem na "ulotną", aby uniemożliwić kompilatorowi dokonywanie optymalizacji i umieszczanie jej we flashu, tak jak to robiłem podczas moich pierwszych kompilacji. Zdefiniowałem ją jako tablicę „uint16_t”, ponieważ Timer1 jest również 16-bitowy i ma długość 810. Przerywamy przechwytywanie przy 800 wartościach, ale ponieważ test jest wykonywany poza przerwaniami z oczywistych względów szybkości, zdecydowałem się zachować 10 więcej wartości, aby zapobiec przepełnieniu. Z kilkoma dodatkowymi zmiennymi dla reszty kodu, szkic wykorzystuje 1313 bajtów (88%) pamięci, pozostawiając nam 235 bajtów wolnej pamięci RAM. Mamy już duże zużycie pamięci i nie chciałem zwiększać pojemności próbek, ponieważ mogłoby to powodować dziwne zachowania z powodu zbyt małej ilości pamięci.

W moim dążeniu do zwiększenia szybkości wykonywania, użyłem wskaźników funkcji zamiast instrukcji if wewnątrz przerwań, aby skrócić czas ich wykonywania do minimum. Pin przechwytywania zawsze będzie Arduino UNO numer 8, ponieważ jest to jedyny podłączony do jednostki przechwytywania wejścia Timer1.

Proces przechwytywania pokazano na powyższym obrazku. Rozpoczyna się, gdy Arduino UNO otrzyma prawidłową ramkę danych UART, zawierającą żądane ustawienia przechwytywania. Następnie przetwarzamy te ustawienia, konfigurując odpowiednie rejestry do przechwytywania na wybranej krawędzi i stosując odpowiedni podział zegara. Następnie włączamy przerwanie PCINT0 (zmiana pinów) w celu wykrycia pierwszego zbocza sygnału. Kiedy to otrzymamy, resetujemy wartość Timer1, wyłączamy przerwanie PCINT0 i włączamy przerwanie ICU (Input Capture Unit). Od tego momentu każdy opadający/wznoszący się zbocze sygnału (w zależności od wybranej konfiguracji) będzie wyzwalał jednostkę przechwytywania sygnału wejściowego, zapisując w ten sposób znacznik czasu tego zdarzenia w rejestrze ICR1 i wykonując przerwanie. W tym przerwaniu umieszczamy wartość rejestru ICR1 w naszej tablicy "samples" i zwiększamy indeks dla następnego przechwytywania. Kiedy Timer1 lub tablica się przepełni, wyłączamy przerwanie przechwytywania i wysyłamy dane z powrotem do interfejsu sieciowego przez UART.

Zdecydowałem się użyć przerwania zmiany pinów, aby wyzwolić przechwytywanie, ponieważ jednostka przechwytywania wejścia pozwala przechwytywać tylko na jednej lub drugiej krawędzi, a nie na obu. Powoduje to również problem, gdy chcesz uchwycić obie krawędzie. Moim rozwiązaniem jest wtedy odwrócenie bitu, który kontroluje wybór krawędzi w rejestrze sterowania przechwytywaniem wejściowym przy każdej pobranej próbce. W ten sposób tracimy szybkość wykonywania, ale nadal możemy korzystać z funkcji jednostki przechwytywania danych wejściowych.

Tak więc, jak być może zauważyłeś, tak naprawdę nie rejestrujemy każdej próbki w ustalonych odstępach czasu, ale rejestrujemy moment, w którym następuje zmiana sygnału. Gdybyśmy przechwycili jedną próbkę w każdym cyklu zegara, nawet z najwyższym podziałem zegara, wypełnilibyśmy bufor w około 0,1 s, zakładając, że używamy typu uint8_t, który jest najmniejszym w pamięci bez użycia struktur.

Krok 3: Interfejs sieciowy i P5.js

Interfejs sieciowy i P5.js
Interfejs sieciowy i P5.js

Jak wskazuje tytuł, interfejs WWW powstał przy pomocy p5.js. Tym, którzy jeszcze jej nie znają, gorąco polecam odwiedzić stronę internetową, ponieważ jest to naprawdę dobra biblioteka. Jest oparty na przetwarzaniu, jest łatwy w użyciu, pozwala bardzo szybko uzyskać dobre wyniki i jest dobrze udokumentowany. Z tych wszystkich powodów wybrałem tę bibliotekę. Użyłem również biblioteki quicksettings.js do menu, biblioteki grafica.js do wykreślania moich danych oraz biblioteki p5.serialport do komunikacji z Arduino UNO.

Nie będę spędzał zbyt wiele czasu nad interfejsem, ponieważ zaprojektowałem go właśnie do podglądu danych i kontroli ustawień, a także dlatego, że w ogóle nie był przedmiotem mojego eksperymentu. W następnych częściach wyjaśnię jednak różne etapy korzystania z całego systemu, wyjaśniając w ten sposób różne dostępne elementy sterujące.

Krok 4: Konfiguracja systemu

Pierwszą rzeczą jest pobranie Arduino UNO i kodu interfejsu tutaj, jeśli jeszcze nie zostało to zrobione. Następnie możesz przeprogramować swoją płytkę Arduino UNO za pomocą szkicu „UNO_LS.ino” za pośrednictwem Arduino IDE.

Powinieneś pobrać oprogramowanie p5.serialcontrol z repozytorium github. Musisz pobrać plik zip pasujący do twojego systemu operacyjnego (testowałem go tylko w systemie Windows). Wypakuj plik zip do folderu, uruchom plik wykonywalny w nim znaleziony i zostaw go w ten sposób. Nie próbuj łączyć się z żadnym portem szeregowym, po prostu pozostaw go w tle, będzie używany jako przekaźnik.

Otwórz folder „Interfejs”. Powinieneś znaleźć plik o nazwie „index.html”. Otwórz go w przeglądarce, jest to interfejs sieciowy.

I to wszystko! Nie musisz pobierać dodatkowych bibliotek, wszystko powinno być zawarte w dostarczonym przeze mnie pakiecie.

Krok 5: Połączenie, konfiguracja i akwizycja

Połączenie, konfiguracja i akwizycja
Połączenie, konfiguracja i akwizycja

Aby podłączyć interfejs do płytki Arduino UNO, wystarczy wybrać odpowiedni port z listy i nacisnąć przycisk „Otwórz”. Jeśli operacja się powiodła, komunikat „stan” powinien wyświetlać coś w rodzaju „Otwarto COMX”.

Możesz teraz wybrać opcje przechwytywania. Pierwszy to wybór krawędzi. Zalecam, aby zawsze używać „Both”, ponieważ zapewni to najlepszą reprezentację rzeczywistego sygnału. Jeśli ustawienie „Oba” nie przechwytuje sygnału (na przykład, jeśli częstotliwość sygnału jest zbyt wysoka), możesz spróbować z ustawieniem krawędzi „Rising” lub „Falling”, w zależności od sygnału, który próbujesz zobaczyć.

Drugie ustawienie to podział zegara. Poda ci rozdzielczość, z jaką będziesz w stanie przechwycić sygnał. Możesz ustawić współczynnik podziału na „8”, „64”, „256” i „1024”. Płytka Arduino UNO wykorzystuje kwarc 16 MHz do taktowania mikrokontrolera, więc częstotliwość próbkowania będzie wynosić „16 MHz/współczynnik podziału”. Uważaj na to ustawienie, ponieważ określa ono również, jak długo będziesz w stanie przechwycić sygnał. Ponieważ Timer1 jest zegarem 16-bitowym, dozwolony czas przechwytywania przed przepełnieniem będzie wynosić „(2^16)*(współczynnik podziału)/16MHz”. W zależności od wybranego ustawienia będzie on wynosić od ~33ms do 4,2s. Zapamiętaj swój wybór, będziesz go później potrzebować.

Ostatnim ustawieniem jest tłumienie szumów. Nie przeprowadziłem na nim wielu testów i nie będziesz go potrzebował w 99% przypadków, więc po prostu pozostaw to niezaznaczone. Dla tych, którzy są nadal ciekawi, możesz poszukać tłumika szumów w sekcji Timer/Counter1 w arkuszu danych ATMEGA328P.

Nie zapomnij podłączyć styku 8 płyty Arduino UNO do sygnału i połączyć razem, aby uzyskać to samo napięcie odniesienia zarówno dla obwodu testowego, jak i analizatora logicznego. Jeśli potrzebujesz izolacji uziemienia lub chcesz mierzyć sygnały o poziomach różnych od 5 V, prawdopodobnie będziesz musiał dodać do obwodu optoizolator.

Gdy wszystko jest poprawnie skonfigurowane, możesz nacisnąć przycisk „Zdobądź”.

Krok 6: Przechwytywanie wyników i eksport danych CSV

Przechwytywanie wyników i eksport danych CSV
Przechwytywanie wyników i eksport danych CSV

Gdy Arduino UNO zakończy przechwytywanie, automatycznie odeśle dane z powrotem do interfejsu internetowego, który je wykreśli. Możesz powiększać lub pomniejszać za pomocą prawego suwaka i podróżować po próbkach za pomocą dolnego.

Wykres daje tylko podgląd i nie ma żadnych narzędzi do analizy danych. Dlatego, aby przeprowadzić dalszą analizę swoich danych, będziesz musiał zaimportować je do PulseView.

Pierwszym krokiem jest wyeksportowanie pliku csv zawierającego wszystkie Twoje dane. Aby to zrobić, wystarczy kliknąć przycisk „Eksportuj” w interfejsie internetowym. Po wyświetleniu monitu zapisz plik w znanej lokalizacji.

Teraz otwórz PulseView. Na górnym pasku menu kliknij „Otwórz” (ikona folderu) i wybierz „Importuj wartości rozdzielane przecinkami…”. Wybierz wcześniej wygenerowany plik csv zawierający Twoje dane.

Pojawi się małe okno. Zostaw wszystko tak, jak jest, wystarczy zmodyfikować ustawienie „Samplerate” zgodnie z współczynnikiem podziału zegara wybranym do przechwytywania. Twoja częstotliwość próbkowania będzie wynosić „16 MHz/(współczynnik podziału)”. Następnie kliknij „OK”, Twój sygnał powinien pojawić się na ekranie.

Krok 7: Analiza sygnału PulseView

Analiza sygnału PulseView
Analiza sygnału PulseView

PulseView zawiera wiele dekoderów protokołów. Aby uzyskać do nich dostęp, kliknij „Dodaj dekoder protokołu” na górnym pasku menu (narzędzie najbardziej po prawej). W moim eksperymencie wysłałem prostą wiadomość UART z prędkością 9600 bodów, więc wyszukałem „UART”.

Doda kanał z tagiem po lewej stronie (tak jak ten dla twoich danych). Klikając na tag, możesz zmienić ustawienia dekodera. Po wybraniu właściwych udało mi się pobrać taką samą wiadomość, jak ta wysłana przez moje urządzenie testowe. To pokazuje, że cały system działa zgodnie z oczekiwaniami.

Krok 8: Wniosek

Wniosek
Wniosek

Nawet jeśli projekt był na początku eksperymentem, jestem zadowolony z rezultatów, jakie uzyskałem. Mogłem bez problemu próbkować sygnały UART z prędkością do 115200 bodów w trybie zbocza "Both", a nawet udało mi się osiągnąć 230400 bodów w trybie zbocza "Falling". Możesz zobaczyć moją konfigurację testową na powyższym obrazku.

Moja implementacja ma kilka wad, zaczynając od tego, że może przechwytywać tylko jeden sygnał na raz, ponieważ tylko pin 8 Arduino UNO jest „zdolny do przechwytywania sygnału wejściowego”. Jeśli szukasz analizatora logicznego Arduino z większą liczbą kanałów, sprawdź jeden z Catoblepas.

Nie można oczekiwać, że Arduino UNO będzie w stanie przechwytywać sygnały o wysokich częstotliwościach (niektóre MHz), ponieważ jest taktowany tylko na 16 MHz (jeśli ktoś to zrobił, byłbym zainteresowany jego metodą). Jednak nadal jestem pod wrażeniem wyników, jakie możemy uzyskać z tego mikrokontrolera ATMEGA328P.

Nie sądzę, że zrobię dużo pracy nad kodem. Przeprowadziłem eksperymenty i uzyskałem wyniki, których szukałem. Ale jeśli ktoś chce wnieść swój wkład, nie krępuj się modyfikować i rozpowszechniać całego lub części mojego kodu.

To był mój pierwszy Instructable i myślę, że długi. Mam nadzieję, że była to dla Ciebie ciekawa lektura.

Daj mi znać, jeśli znajdziesz błędy lub masz jakieś pytanie!

Zalecana: