Inhoudsopgave:

Arduino UNO Logic Sniffer - Ajarnpa
Arduino UNO Logic Sniffer - Ajarnpa

Video: Arduino UNO Logic Sniffer - Ajarnpa

Video: Arduino UNO Logic Sniffer - Ajarnpa
Video: How and Why to Use a Logic Analyzer 2024, November
Anonim
Arduino UNO Logic Sniffer
Arduino UNO Logic Sniffer

Dit project begon als een eenvoudig experiment. Tijdens mijn onderzoek naar de datasheet van de ATMEGA328P voor een ander project, vond ik iets nogal interessants. De Timer1 Input Capture Unit. Het stelt de microcontroller van onze Arduino UNO in staat om een signaalrand te detecteren, een tijdstempel op te slaan en een interrupt te activeren, allemaal in hardware.

Ik vroeg me toen af in welke toepassing het nuttig zou kunnen zijn en hoe ik het kon testen. Omdat ik al een tijdje een logische analysator wil hebben, heb ik besloten om er een in mijn Arduino UNO-bord te implementeren, gewoon om de functie te testen en te kijken of we er goede resultaten uit kunnen halen.

Ik ben niet de enige die dit idee had, en je zult er genoeg vinden door gewoon te googelen op "Arduino Logic Analyzer". Aan het begin van het project, omdat het net begon als een experiment, was ik me er niet eens van bewust dat mensen het al hadden gemaakt, en was ik onder de indruk van de goede resultaten die ze behaalden met dit kleine stukje hardware. Ik kon echter geen ander project vinden met behulp van de input capture-eenheid, dus als je dit al hebt gezien, laat het me dan weten!

Om samen te vatten, mijn logica-analysator zal:

  • Heb één kanaal,
  • Een grafische interface hebben,
  • Communiceer met de interface via USB,
  • Draai op een Arduino UNO-bord.

Het zal eindelijk een geheugendiepte van 800 samples hebben en met succes een UART-bericht van 115200 baud kunnen vastleggen (ik heb het niet echt getest op hogere snelheden).

Deze instructable bevat zowel de "hoe het werkt" als "hoe het te gebruiken" delen van dit project, dus voor degenen die niet geïnteresseerd zijn in de technische kant, kun je direct naar stap 4 springen.

Benodigdheden

Ik wilde de analyser zo eenvoudig mogelijk houden, zodat ik heel weinig hardware nodig had.

Je zal nodig hebben:

  • Een Arduino UNO-bord (of gelijkwaardig zolang het afhankelijk is van de ATMEGA328P MCU),
  • Een computer,
  • Iets om te debuggen (een ander Arduino UNO-bord werkt prima om wat tests uit te voeren).

De code voor zowel de Arduino UNO als de webinterface vind je hier. Je hebt ook de software p5.serialcontrol en PulseView nodig.

Stap 1: Werkingsprincipe

Werkend principe
Werkend principe

Het idee is eenvoudig. U kiest de opname-instellingen en klikt op "ophalen". De webinterface stuurt ze naar de p5.serialcontrol-software, waarmee we de seriële interface vanuit een browser kunnen gebruiken, omdat deze er geen directe toegang toe heeft. De p5.serialcontrol-software stuurt de informatie vervolgens door naar het Arduino UNO-bord, dat de gegevens vastlegt en via hetzelfde pad terugstuurt naar de interface.

Eenvoudig! Nou… Aangezien ik niet echt goed ben in het programmeren van interfaces tussen mens en machine of webtechnologieën, is de mijne zeker een beetje lelijk en buggy. Maar het stelt me in staat om een opname te starten en mijn gegevens terug te halen, waarvoor het is ontworpen, dus ik denk dat het prima is. Voor serieuzer analysewerk importeer ik mijn records in PulseView, dat gemakkelijk te gebruiken is en een goede set functies en protocoldecoders biedt, zoals we later zullen zien.

De input capture-eenheid van de Arduino UNO kan worden geconfigureerd om verschillende klokdivisies te gebruiken, waardoor de resolutie wordt verlaagd, maar de vertraging vóór overloop wordt vergroot. Het kan ook triggeren bij stijgende, dalende of beide randen om te beginnen met het vastleggen van de gegevens.

Stap 2: Arduino UNO Sketch

Arduino UNO-schets
Arduino UNO-schets

Ik heb de schets geschreven en gecompileerd met de Arduino IDE. Ik begon eerst met het instellen van de Timer1 in de "Normale" bedrijfsmodus door naar de TCCR1A- en TCCR1B-registers in de setup () te schrijven. Ik heb toen een aantal functies gemaakt om het gebruik ervan in de toekomst een beetje te vergemakkelijken, zoals die om de klokafdeling met de naam "setTim1PSC()" in te stellen. Ik heb ook functies geschreven om de Timer1-invoeropname-eenheid en overlooponderbrekingen te activeren en deactiveren.

Ik heb de array "samples" toegevoegd, die de verkregen gegevens bevat. Het is een globale array die ik heb ingesteld op "vluchtig" om te voorkomen dat de compiler optimalisaties uitvoert en in flash zet, zoals het deed tijdens mijn eerste compilaties. Ik definieerde het als een "uint16_t" -array, aangezien de Timer1 ook 16-bits is, met een lengte van 810. We stoppen met vastleggen bij 800-waarden, maar omdat de test om duidelijke snelheidsredenen buiten de interrupts wordt gedaan, koos ik ervoor om 10 meer waarden om overlopen te voorkomen. Met een paar extra variabelen voor de rest van de code, gebruikt de sketch 1313 bytes (88%) geheugen, waardoor we 235 bytes vrij RAM hebben. We hebben al een hoog geheugengebruik en ik wilde niet meer samplecapaciteit toevoegen, omdat dit raar gedrag zou kunnen veroorzaken vanwege te weinig geheugenruimte.

In mijn zoektocht om de uitvoeringssnelheid altijd te verhogen, gebruikte ik functieaanwijzers in plaats van if-statements binnen de interrupts, om hun uitvoeringstijd tot een minimum te beperken. De capture-pin is altijd het Arduino UNO-nummer 8, omdat het de enige is die is aangesloten op de ingangscapture-eenheid van Timer1.

Het opnameproces wordt weergegeven op de afbeelding hierboven. Het begint wanneer de Arduino UNO een geldig UART-dataframe ontvangt met de gewenste opname-instellingen. We verwerken die instellingen vervolgens door de juiste registers te configureren om op de gekozen rand vast te leggen en de juiste klokindeling te gebruiken. We schakelen dan de PCINT0 (pin change) interrupt in om de eerste signaalflank te detecteren. Wanneer we het krijgen, resetten we de Timer1-waarde, schakelen we de PCINT0-interrupt uit en schakelen we de ICU (Input Capture Unit)-interrupt in. Vanaf dat moment zal elke dalende/stijgende flank van het signaal (afhankelijk van de gekozen configuratie) de input capture-eenheid activeren, waardoor een tijdstempel van deze gebeurtenis in het ICR1-register wordt opgeslagen en een interrupt wordt uitgevoerd. In deze interrupt plaatsen we de ICR1-registerwaarde in onze "samples"-array en verhogen de index voor de volgende opname. Wanneer de Timer1 of de array overloopt, schakelen we de capture-interrupt uit en sturen we de gegevens terug naar de webinterface via UART.

Ik besloot om een pin change interrupt te gebruiken om de opname te activeren, omdat de input capture-eenheid alleen de ene of de andere rand kan vastleggen, niet beide. Het veroorzaakt ook een probleem wanneer u beide randen wilt vastleggen. Mijn oplossing is dan om bij elk opgehaald monster het bit dat de randselectie in het invoerregistratiecontroleregister regelt, om te keren. Op die manier verliezen we in uitvoeringssnelheid, maar we kunnen nog steeds de functionaliteiten van de input capture-eenheid gebruiken.

Dus, zoals je misschien hebt gemerkt, leggen we niet echt elk monster vast met vaste tijdsintervallen, maar we leggen het moment vast waarop een signaalovergang plaatsvindt. Als we bij elke klokcyclus één monster hadden genomen, zelfs met de hoogste klokdeling, zouden we de buffer in ongeveer 0,1 s hebben gevuld, ervan uitgaande dat we het uint8_t-type gebruikten, de kleinste in het geheugen zonder structs te gebruiken.

Stap 3: Webinterface en P5.js

Webinterface en P5.js
Webinterface en P5.js

Zoals de titel al aangeeft, is de webinterface gemaakt met behulp van p5.js. Voor degenen die het nog niet kennen, raad ik je ten zeerste aan om de website te gaan bekijken, want het is echt een goede bibliotheek. Het is gebaseerd op Processing, is gemakkelijk te gebruiken, stelt u in staat om zeer snel goede resultaten te krijgen en is goed gedocumenteerd. Het is om al die redenen dat ik deze bibliotheek heb gekozen. Ik gebruikte ook de quicksettings.js-bibliotheek voor de menu's, de grafica.js-bibliotheek om mijn gegevens te plotten en de p5.serialport-bibliotheek om te communiceren met de Arduino UNO.

Ik zal niet te veel tijd besteden aan de interface, omdat ik deze zojuist heb ontworpen voor gegevensvoorbeeld en instellingencontrole, en ook omdat het helemaal niet het onderwerp van mijn experiment was. Ik zal echter in de volgende delen de verschillende stappen uitleggen om het hele systeem te gebruiken, en zo de verschillende beschikbare bedieningselementen uitleggen.

Stap 4: Systeemconfiguratie

Het eerste is om de Arduino UNO en interfacecode hier te downloaden, als dat nog niet is gebeurd. U kunt vervolgens uw Arduino UNO-bord herprogrammeren met de "UNO_LS.ino"-schets via de Arduino IDE.

U zou de p5.serialcontrol-software moeten hebben gedownload van de github-repository. U moet het zipbestand ophalen dat overeenkomt met uw besturingssysteem (ik heb het alleen op Windows getest). Pak de zip uit in een map, start het uitvoerbare bestand dat erin wordt gevonden en laat het zo. Probeer geen verbinding te maken met een seriële poort, laat hem gewoon op de achtergrond draaien, hij zal als relais worden gebruikt.

Open de map "Interface". U zou een bestand met de naam "index.html" moeten vinden. Open het in uw browser, het is de webinterface.

En dat is het! U hoeft geen extra bibliotheken te downloaden, alles moet worden opgenomen in het pakket dat ik heb verstrekt.

Stap 5: Aansluiting, configuratie en acquisitie

Aansluiting, configuratie en acquisitie
Aansluiting, configuratie en acquisitie

Om de interface op het Arduino UNO-bord aan te sluiten, selecteert u gewoon de overeenkomstige poort in de lijst en drukt u op de knop "Openen". Als de bewerking succesvol was, zou het bericht "status" iets moeten weergeven als "COMX geopend".

U kunt nu uw opname-opties kiezen. De eerste is de randselectie. Ik raad je aan altijd "Beide" te gebruiken, omdat dit je de beste weergave van het echte signaal geeft. Als de instelling "Beide" het signaal niet kan opvangen (als de signaalfrequentie bijvoorbeeld te hoog is), kunt u het proberen met de instelling "Rising" of "Falling" edge, afhankelijk van het signaal dat u probeert te zien.

De tweede instelling is de klokverdeling. Het geeft je de resolutie waarmee je het signaal kunt opvangen. U kunt ervoor kiezen om de delingsfactor in te stellen op "8", "64", "256" en "1024". Het Arduino UNO-bord gebruikt een 16MHz-kwarts om de microcontroller te klokken, dus de bemonsteringsfrequentie zal "16MHz / delingsfactor" zijn. Wees voorzichtig met deze instelling, want het bepaalt ook hoe lang je een signaal kunt opvangen. Aangezien de Timer1 een 16-bits timer is, is de toegestane opnametijd vóór overloop "(2^16)*(divisiefactor)/16MHz". Afhankelijk van de instelling die je hebt gekozen, varieert deze tussen ~33ms en 4,2s. Houd je keuze in je achterhoofd, je hebt hem later nodig.

De laatste instelling is de noise cancelling. Ik heb er niet veel op getest en je zult het in 99% van de gevallen niet nodig hebben, dus laat het gewoon niet aangevinkt. Voor degenen die er nog steeds nieuwsgierig naar zijn, kun je zoeken naar de noise cancelling in het Timer/Counter1 gedeelte van de ATMEGA328P's datasheet.

Vergeet niet om pin 8 van het Arduino UNO-bord op uw signaal aan te sluiten en de aarde aan elkaar te verbinden om dezelfde spanningsreferentie te hebben voor zowel het testcircuit als de logische analysator. Als u aardingsisolatie nodig heeft, of signalen met een ander niveau dan 5V wilt meten, moet u waarschijnlijk een opto-isolator aan uw circuit toevoegen.

Zodra alles correct is geconfigureerd, kunt u op de knop "Verwerven" drukken.

Stap 6: Resultaten vastleggen en CSV-gegevens exporteren

Resultaten vastleggen en CSV-gegevens exporteren
Resultaten vastleggen en CSV-gegevens exporteren

Zodra uw Arduino UNO een opname heeft voltooid, stuurt hij de gegevens automatisch terug naar de webinterface, die ze zal plotten. Met de rechter slider kan je in- of uitzoomen, en met de onderste door de samples reizen.

De plot geeft u alleen een voorbeeld en heeft geen tools voor gegevensanalyse. Om uw gegevens verder te analyseren, moet u deze dus in PulseView importeren.

De eerste stap is het exporteren van een csv-bestand met al uw gegevens. Om dit te doen, hoeft u alleen maar op de knop "Exporteren" in de webinterface te klikken. Sla uw bestand op een bekende locatie op wanneer daarom wordt gevraagd.

Open nu PulseView. Klik in de bovenste menubalk op "Openen" (mappictogram) en selecteer "Door komma's gescheiden waarden importeren…". Selecteer het eerder gegenereerde csv-bestand met uw gegevens.

Er verschijnt een klein venster. Laat alles zoals het is, u hoeft alleen de instelling "Samplerate" aan te passen aan de klokverdelingsfactor die is gekozen voor de opname. Uw samplefrequentie zal "16MHz/(division factor)" zijn. Klik vervolgens op "Ok", uw signaal zou op het scherm moeten verschijnen.

Stap 7: PulseView-signaalanalyse

PulseView-signaalanalyse
PulseView-signaalanalyse

PulseView beschikt over veel protocoldecoders. Om ze te openen, klikt u op "Protocoldecoder toevoegen" in de bovenste menubalk (meest rechtse tool). Voor mijn experiment heb ik zojuist een eenvoudig UART-bericht verzonden met 9600 bauds, dus ik zocht naar "UART".

Het voegt een kanaal toe met een tag aan de linkerkant (net zoals die voor uw gegevens). Door op de tag te klikken, kunt u de instellingen van de decoder wijzigen. Nadat ik de juiste had gekozen, kon ik hetzelfde bericht ophalen als dat van mijn testapparaat. Dit toont aan dat het hele systeem werkt zoals verwacht.

Stap 8: Conclusie

Conclusie
Conclusie

Zelfs als het project in het begin een experiment was, ben ik blij met de resultaten die ik heb gekregen. Ik kon zonder enig probleem UART-signalen samplen tot 115200 bauds in "Beide" edge-modus, en het lukte me zelfs om tot 230400 bauds te gaan in "Falling" edge-modus. Op de foto hierboven zie je mijn testopstelling.

Mijn implementatie heeft verschillende nadelen, te beginnen met het feit dat het slechts één signaal tegelijk kan vastleggen, aangezien alleen de Arduino UNO's pin 8 "input capture-capabel" is. Als je op zoek bent naar een Arduino-logica-analysator met meer kanalen, ga dan naar die van Catoblepas.

Je kunt niet verwachten dat een Arduino UNO signalen met hoge frequenties (sommige MHz) kan opvangen, omdat hij alleen op 16 MHz is geklokt (als iemand het heeft gedaan, zou ik graag de methode willen zien). Ik ben echter nog steeds onder de indruk van de resultaten die we kunnen halen uit deze ATMEGA328P-microcontroller.

Ik denk niet dat ik veel aan de code ga doen. Ik voerde mijn experimenten uit en kreeg de resultaten waarnaar ik op zoek was. Maar als iemand een bijdrage wil leveren, voel je vrij om mijn code geheel of gedeeltelijk aan te passen en opnieuw te distribueren.

Dat was mijn eerste Instructable, en een lange denk ik. Ik hoop dat het een interessante lezing voor je was.

Laat het me weten als je fouten vindt, of als je vragen hebt!

Aanbevolen: