De µSCOPE

Een armelui's oscilloscoop

Ronald Dekker


De µscope heeft ook in Elektuur gestaan !
Klik hier voor een pdf versie van dat verhaal.


De µSCOPE

De oscilloscoop is nog altijd één van de belangrijkste meetinstrumenten van de elektronicus. Dankzij het aanbod van talrijke, vaak zeer redelijk geprijsde USB scoopjes, is een dergelijk instrument nu binnen het bereik van iedereen gekomen. Dat was vijfentwintig jaar geleden wel anders! Een (goede) oscilloscoop was toen een zeer kostbaar instrument dat slechts voor een enkeling was weggelegd. Nu waren elektronica hobbyisten in die tijd niet voor een kleintje vervaard en menigmaal werd de soldeerbout ter hand genomen om zelf zo’n instrument in elkaar te zetten. De elektronicabladen in de jaren zestig en zeventig publiceerden talrijke meer en minder complexe ontwerpen, vrijwel uitsluitend gebaseerd op buizen. In 1975 werd dit tijdperk afgesloten toen Elektuur zijn volledig getransistoriseerde “Elektorscoop” publiceerde. Desondanks vormde de aanschaf van een dure kathodestraalbuis en voedingstransformator voor velen een onhaalbare drempel. Om ook die categorie hobbyisten tegemoet te komen ontwikkelde Elektuur in 1978 de “Videoscope”. De videoscope sampelde het analoge ingangssignaal, sloeg deze op in een emmertjesgeheugen (CCD) en zette het vervolgens om naar een standaard (zwart/wit) videosignaal waarna het op een gewone TV bekeken kon worden. Om het signaal op de gebruikelijke manier te bekijken moest de TV dan wel op z’n kant worden gezet, maar een kniesoor die daar een probleem van maakte. Al met al was het toch wel een complex ontwerp dat tientallen ICs en diverse printen besloeg. Uiteraard kan dat tegenwoordig simpeler. De huidige generatie microcontrollers is zo krachtig dat zo´n videoscope concept geheel in software kan worden gerealiseerd. Onlangs kreeg de auteur van dit artikel een exemplaar van de 12f675 in handen. Bij de bestudering van de datasheet van deze kleine acht pens microcontroller van Microchip bleek dat in de kleine behuizing alle componenten voor een miniatuur videoscope aanwezig waren. Het µscope project was daarmee geboren, met als belangrijkste uitdaging zo’n complexe taak in een kleine microcontroller te realiseren. Het resultaat is samengevat in dit artikel waarin een volledig functionele (geheugen) oscilloscoop wordt beschreven die het analoge ingangssignaal bemonstert en vervolgens via de standaard video ingang van de TV laat zien (figuur 1). Alhoewel het doel van dit project uitdrukkelijk niet was om een hoogwaardig meetinstrument te bouwen, zijn met deze schakeling, die voor een paar euro gebouwd kan worden, toch signalen tot enkele kilohertzen goed te bekijken. Deze “armelui’s scope” zal daarom wellicht menig jeugdige hobbyist goede diensten kunnen bewijzen.


figuur 1. De µSCOPE in werking


to top of page back to homepage

De 12F675

De 12F675 is één van de kleinste telgen uit de microcontroller familie van de firma Microchip. In de acht pens behuizing bevindt zich een 14-bits processor core, 1k word FLASH geheugen, 64 bytes RAM en 128 bytes EEPROM. Naast de standaard peripherals zoals twee timers, een watchdog timer etc. beschikt de 12F675 bovendien ook nog over een 10 bits AD converter met sample-and-hold, een comperator en een instelbare spanningsreferentie. Al deze componenten zijn onder software besturing te configureren en figuur 2 laat zien hoe dat voor de µscope is gedaan. Pin 6 wordt gebruikt als de analoge ingang van de 12F675. Inwendig is deze via de sample-and-hold verbonden met de AD converter. Daar de voedingsspanning als referentiespanning wordt gebruikt door de AD converter, beslaat het meetbereik precies 0 tot 5V. Pin 6 is ook verbonden met één van de ingangen van de comperator die gebruikt wordt om de trigger functie van de µscope te implementeren. Het triggerniveau wordt ingesteld met behulp van de 5 bits programmeerbare spanningsreferentie bron. Met deze 5 bits kan het triggerniveau worden ingesteld tussen 0.42 V en 3.59 V. Daar softwarematig ook nog het uitgangssignaal van de comperator kan worden geïnverteerd, kan gekozen worden voor een triggering op positieve of negatieve flank. Het ingangscircuit van de µscope is uiterst simpel gehouden en kan door iedereen worden uitgebreid afhankelijk van de wensen. Het ingangssignaal wordt DC ontkoppeld door C6. Met R8 en R9 wordt het “nul niveau” vervolgens ingesteld op de halve voedingsspanning. De eerste beveiligingslinie tegen overspanningen wordt gevormd door R7, D1 en D2. De beide diodes begrenzen de spanning op pin 6 van de 12F675 tussen 0 en 5 V terwijl R7 ervoor zorgt dat de stroom hierbij niet te hoog oploopt. In het geval dat de interne overspanning beveiliging van de 12F675 eerder aanspreekt, wordt de stroom beperkt tot R6.


figuur 2. Het schema van de µSCOPE


to top of page back to homepage

Beeldopbouw

Er is gekozen voor een videosignaal zonder interliniering. Interliniering zorgt in dit soort toepassingen slechts voor een onrustig beeld, terwijl het het programma nodeloos ingewikkeld maakt. De rasterfrequentie is daarom 50 Hz, waarbij ieder raster bestaat uit 312 beeldlijnen van 64 µs (figuur 3). Een lijn synchronisatie puls van 4 µs geeft het begin aan van een nieuwe lijn. De raster synchronisatie puls wordt gegenereerd gedurende de eerste 3 lijnen van ieder raster.

Met behulp van een eenvoudig circuitje bestaande uit R2 tot en met R5 en T1 worden de video- en synchronisatiesignalen gecombineerd tot een standaard composite videosignaal dat rechtstreeks of de videoingang van de TV kan worden aangesloten. Om de werking te doorzien denken we T1 even weg. De weerstanden R2 en R3 zorgen er samen met de afsluitweerstand van de video ingang van de TV (75 ohm naar massa) voor dat een logisch laag niveau op uitgang GP0 resulteert in 0.3 V op de video uitgang (zwart) en een logisch hoog niveau in 1.0 V (wit). Een hoog niveau op uitgang GP2 zorgt voor een synchronisatie puls doordat T1 nu het video niveau naar 0 V trekt (ultra zwart). In principe kan dit schakelingetje worden uitgevoerd met slechts 3 weerstanden [1]. Dat is hier echter niet mogelijk: tijdens bepaalde gedeelten van het videosignaal wordt, om voldoende snelheid te halen tijdens de generatie van de karakters op het scherm, data in het GPIO register geroteerd. Om te voorkomen dat deze data ongewenste synchronisatie pulsen zou veroorzaken, wordt GP2 dan ook kortstondig even als input geschakeld. Transistor T1 voorkomt op deze momenten een ongedefinieerd potentiaal op de video output. In figuur 2 is te zien dat beide uitgangen GP0 en GP2 ook worden gebruikt om de drie menutoetsjes uit te lezen. Dit gebeurt op een onzichtbaar moment tijdens één van de drie beeldsynchronisatie lijnen.

De door de Microchip gespecificeerde maximale klok frequentie is 20 MHz. Dit bleek net iets te krap om een, qua verhouding, aangenaam oscilloscoopbeeld te genereren. Het bleek gelukkig mogelijk de 12f675 ook nog op 27 MHz te laten draaien. Dit is dan wel zo’n beetje het uiterst haalbare. Alleen bij 5 V voedingsspanning heeft de oscillator nog voldoende versterking om aan te slaan. Daar de meeste 27 MHz kristallen 3e overtoon kristallen zijn, is een filtertje in de vorm van C2 en L1 toegevoegd om oscillatie op de 9 MHz grondtoon te onderdrukken.


figuur 3. De gebruikte beeldopbouw.


to top of page back to homepage

Het Programma

Zo eenvoudig als de hardware van de µscope is, zo uitdagend bleek het schrijven van het programma. Het real time genereren van een complex videosignaal is geen eenvoudige taak, zeker niet als tegelijkertijd ook nog eens een oscilloscoop en gebruikersinterface moeten worden geïmplementeerd. Niet alleen qua kloksnelheid wordt het uiterste van de processor gevraagd, ook het 1k word programmageheugen is letterlijk tot de laatste byte gebruikt. Het RAM geheugen van 64 bytes bleek zelfs net iets te krap. Gelukkig werd timer 1 niet gebruikt, zodat de registers hiervan nog als twee extra bytes RAM geheugen konden worden ingeschakeld. De schaarste aan geheugen en snelheid noopten tot het zoeken naar inventieve oplossingen. Natuurlijk had er gekozen kunnen worden voor een snellere processor met meer geheugen, maar dan zou er een gedeelte van de charme van dit project verloren zijn gegaan.

Zoals al is geconstateerd beslaat iedere beeldlijn bij een klokfrequentie van 27 MHz 432 machinecycli. Duurt een beeldlijn één machinecyclus langer of korter, dan is dat direct in het beeld zichtbaar. Dit betekent dat als een stukje programma dat tijdens het schrijven van een beeldlijn wordt uitgevoerd vertakkingen bevat, elke tak in lengte exact gelijk moet zijn. Daar dit in het algemeen niet het geval zal zijn, moeten de kortere takken met behulp van NOP instructies gelijk in lengte aan de langste gemaakt worden. Hoe dit in zijn werk gaat, wordt geïllustreerd met het stukje programmacode in figuur 4. In dit voorbeeld betreft het een subroutine waarin een dubbelbytes teller bij elke aanroep wordt verlaagd. Bereikt de teller nul, dan wordt deze weer met een bepaalde waarde geïnitialiseerd. In het stroom diagram worden de drie takken van de routine geïdentificeerd: A, B en C. Het stukje assemblercode boven de stippellijn representeert de langste tak C. Nu wordt voor iedere tak het aantal machinecycli uitgerekend. Het blijkt dat tak C negen machinecycli verbruikt. Het stuk code onder de stippellijn zorgt er voor dat ook de andere twee takken een lengte van negen cycli krijgen. Als geheugen schaars is, kunnen vervolgens in een laatste optimalisatieslag ook nog alle dubbele NOP instructies worden vervangen door één GOTO instructie daar deze twee machinecycli gebruikt. Alhoewel er ongetwijfeld geavanceerde compilers zijn, die met dit soort programma optimalisatie een eind zullen komen, is in dit geval toch maar het hele programma met de hand in assembler geschreven. De assembler listing van het programma is te downloaden en rijkelijk voorzien van commentaar zodat het programma voor iedereen te volgen is.

Het grootste gedeelte van het programma bestaat een synchrone subroutine (sync_blck), die zorgt voor de generatie van het videosignaal. Om deze taak op te splitsen in hanteerbare subblokken, is het totale beeld opgebouwd uit een aantal typen beeldlijnen. Elk type beeldlijn wordt gegenereerd door een verschillende subroutine. Deze subroutines zijn in de programma listing te herkennen aan de labels “line_xxx”. Zo genereert de routine line_sync bijvoorbeeld een raster synchronisatie puls. De routine line_blank zorgt voor een zwarte lijn, terwijl line_view het eigenlijke oscilloscoop beeld verzorgt etc. Een “routine dispatcher” zorgt ervoor dat de diverse line routines een bepaald aantal keer na elkaar op het juiste moment worden uitgevoerd totdat het totale beeld, bestaande uit 312 lijnen, is opgebouwd. Elke lijn, inclusief overhead van de dispatcher, duurt precies 64 µs. De processor kan dus gedurende een beeldlijn heel wat werk verzetten.

Om bepaalde taken, zoals de gebruikers interface, asynchroon te kunnen afhandelen, wordt in een aantal speciale beeldlijnen (line_async) in een zwart gedeelte boven in het scherm, de synchrone routine tijdelijk verlaten. Voordat de synchrone routine echter wordt verlaten, wordt timer 0 zodanig ingesteld dat deze precies voor het volgende data sample een interrupt genereert. Hierdoor wordt het synchrone gedeelte weer hervat, zodat de totale lengte van de beeldlijn weer exact 432 machinecycli beslaat.


figuur 4. Voorbeeld dat illustreerd hoe een programma met behulp van NOP instructies altijd even lang gemaakt kan worden.


to top of page back to homepage

Data acquisitie en weergave

Van het 64 bytes grote interne RAM geheugen zijn 50 bytes gereserveerd voor de opslag van de data samples. Alhoewel de AD converter een resolutie van tien bits heeft, worden slechts de 7 meest significante bits gebruikt. Deze 7 bits representeren 128 spanningswaarden tussen 0 en 5 V, overeenkomend met een gedeelte op het beeldscherm ter hoogte van 128 beeldlijnen. De routine get_AD verzorgt de eigenlijke data acquisitie. Deze routine wordt vier keer per beeldlijn, verdeeld over de lijn, aangeroepen zodat de minimale tijd tussen twee samples 64/4=16 µs bedraagt. Het eerste wat de routine verzorgd is de trigger functie. Als reeds aan de trigger conditie is voldaan, maar het sample geheugen is nog niet geheel gevuld is, wordt een nieuw data sample opgeslagen. Was nog niet aan de trigger conditie voldaan, dan onderzoekt de routine of dit nu misschien wel het geval is. Indien de tijdbasis op een lagere sample snelheid is ingesteld, wordt afhankelijk van de tijdbasis instelling, slechts 1 op de 2, 1 op de 4, 1 op de 8 etc. samples daadwerkelijk gebruikt. Voordeel van deze methode is dat de trigger functie, onafhankelijk van de tijdbasis instelling, steeds op maximale snelheid blijft draaien, waardoor tijdbasis jitter wordt gereduceerd.

De op deze manier opgeslagen datasamples worden door de synchrone beeldroutines gebruikt om het oscilloscoop beeld op te bouwen. Zoals al eerder is vermeld correspondeert ieder van de 128 mogelijke meetwaarden met een lijn van het oscilloscoop beeld. Het beeld wordt opgebouwd door van iedere pixel uit het beeld de sample waarde te vergelijken met het momentane lijnnummer. Zijn deze gelijk dan wordt de pixel aangezet en anders blijft de pixel zwart. Een recht toe recht aan programmering van deze handelingen zou ca. 5 instructies kosten. Veel te lang voor een mooie kleine pixel. Er is daarom gebruik gemaakt van een truc waarbij de meetwaarden cyclisch worden geïncrementeerd. In figuur 5 wordt het principe hiervan aan de hand van een vereenvoudigd voorbeeld geïllustreerd. Zoals te zien in figuur 5 zijn er van een zaagtandvormig signaal negen samples genomen, waarbij er voor de eenvoud van het voorbeeld slechts 6 mogelijke datawaarden zijn (0-5). Vervolgens worden nu bij iedere nieuwe beeldlijn alle sample waarden geïncrementeerd. Bij die samples waar hierbij een carry optreedt (overgang van 5 naar 0) wordt de pixel aangezet. Indien er geen carry optreedt blijft de desbetreffende pixel donker. Na zes beeldlijnen hebben we op deze manier de originele meetwaarden weer terug. In figuur 5 is ook de assembler code weergegeven voor deze procedure. Door na verhoging van een pixel direct de carry in het video uitgangsbit te roteren (bit 0 in GPIO) is het gebruik van tijdrovende conditionele sprongen overbodig geworden en worden per pixel slechts twee instructies (296 ns) gebruikt! Wie in de programma listing de routine line_view opzoekt, zal merken dat dit zelfs te snel bleek en dat er per pixel een nop is toegevoegd. Het enige nadeel van deze werkwijze is dat het relatief veel programma geheugen kost.


figuur 5. Principe van de beeldopbouw door middel van het cyclisch verhogen van de meetdata.


to top of page back to homepage

De bediening

Een relatief groot gedeelte van het programma is besteed aan de bediening, welke gebeurt via een een drietal druktoetsjes en een aantal primitieve menu’s onder het oscilloscoop beeld. De generatie van de karakters in het menu was nog een uitdaging op zichzelf. De tijd tussen twee karakters is namelijk zo kort, dat hierin slechts enkele instructies kunnen worden uitgevoerd. Alle tekst moet daarom, voordat de lijnen waarin de karakters worden geschreven, “bit-mapped” klaarstaan in het geheugen. Daar het RAM geheugen volledig wordt gebruikt voor data opslag en de werkregisters, is hiervoor het EEPROM geheugen gebruikt. Alhoewel het schrijven van een byte in dit geheugen enkele milliseconden duurt, is dit geheugen gelukkig wel, zij het indirect, op volle snelheid uitleesbaar. Het schrijven in de EEPROM gebeurt dan ook in het asynchrone deel van het programma dat, zoals al vermeld, de bediening van de µscope voor zijn rekening neemt. Via een karakter look-up tabel worden de karakters zodanig over het EEPROM geheugen verdeeld dat de synchrone routines (line_txt) de data op hoge snelheid sequentieel uit het geheugen kan lezen.

De bediening van de µscope is overigens zeer eenvoudig. Met de cursor toets kan de cursor onder één van de vijf menu’s worden gezet. Vervolgens kan met behulp van de up of down toetsen de desbetreffende instelling worden veranderd. In het meest linkse menu wordt gekozen tussen normaal gebruik (?), bevriezen van het beeld (?) en een tussenvorm, waarbij het ingangssignaal slechts periodiek wordt gesampled (?|). Deze laatste functie geeft met name bij hoge frequenties een rustiger beeld. In het tweede menu kan de trigger polariteit worden ingesteld (pos,neg) of geheel worden uitgeschakeld (-). Met de cursor op het derde menu kan het trigger niveau worden veranderd met behulp van de up en down toetsen. Het ingestelde niveau wordt zichtbaar gemaakt met een kleine marker aan de rand van het oscilloscoop beeld. Dat slechts een beperkt aantal niveaus kan worden ingesteld is een beperking van de interne spanningsreferentie. Door op de up (of down) toets te drukken als de cursor onder de S staat kunnen de instellingen in het EEPROM geheugen worden weggeschreven en worden ze bij inschakeling van de µscope opnieuw geladen. In het laatste menu wordt de tijdbasis ingesteld. De op het scherm getoonde tijd is de totale tijd van alle vijftig samples in milliseconden. Omdat er maar twee karakters beschikbaar waren, moest hier wel wat worden afgerond. De exacte tijdbasis waarden zijn: 0.8, 1.6, 3.2, 6.4, 12.8, 25.6, 51.2 en 102.4 milliseconden.
to top of page back to homepage

Zelf aan de slag

De schakeling van de µscope is zo eenvoudig, dat opbouw op een stukje gaatjes print voor niemand een probleem hoeft te zijn (figuur 6). Om te voorkomen dat de oscillator afslaat als trimmer C2 met een schroevendraaier wordt aangeraakt, moet het schroefje van C2 met massa worden verbonden. Voor het programmeren van de 12f675 werd een zogenaamde “Tait style” programmer [2] gebruikt welke via de printerpoort van de PC wordt aangestuurd door het programma PP06 [3]. Voor wie het wat moderner wil aanpakken is de WISP programmer van Wouter van Ooijen een goed alternatief [4,5]. De gehele schakeling gebruikt nog geen 10 mA. Voeding uit een 4.5 V batterij is dus zeer goed mogelijk. Na opbouw van de schakeling en controle op fouten wordt de µscope op de video ingang van de TV aangesloten. Na het aansluiten van de batterij, wordt C2 verdraaid tot dat een mooi stabiel beeld verschijnt. Het juiste instelpunt is even zoeken en het kan mogelijk zijn dat de batterij even moet worden losgenomen om de oscillator op de juiste frequentie te laten starten. De µscope is nu klaar voor gebruik en een ingangssignaal kan nu worden aangesloten. Wie de gevoeligheid wat wil vergroten kan voor de ingang een versterkertje plaatsen. Daar het hier niet gaat om een hoogwaardig meetinstrument, kan met een standaard op-amp schakelingetje worden volstaan. Een leuke bijkomstigheid is dat het oscilloscoopbeeld natuurlijk prima met een video recorder kan worden opgenomen.

Wie een beetje is uitgekeken op de µscope zal wellicht zelf wel eens willen proberen een programma te schrijven dat direct een videosignaal genereert. Om de drempel hiervoor wat te verlagen kan het assembler programma example.pic worden gedownload. Dit uitgeklede programmaatje dat slechts een wit blokje en een stippellijn op het scherm laat zien, is zo eenvoudig dat het principe van de beeldopbouw eenvoudig te volgen is. Met wat creativiteit zijn er tal van leuke video genererende schakelingetjes denkbaar. Hopelijk zal de realisatie hiervan net zoveel plezier geven als is beleefd aan de bouw en programmering van de µscope.


figuur 6. Opbouw van de µSCOPE op een stukje experimenteer print.


to top of page back to homepage

Download the files

download hier de gecomprimeerde map met source en hex files
to top of page back to homepage

Web links

[1] http://www.rickard.gunee.com/projects/video/pic/howto.php
[2] http://www.bobblick.com/techref/projects/picprog/picprog.html
[3] http://pp06.sourceforge.net/pp06.html
[4] http://www.voti.nl/wisp628/index.html
[5] http://www.picbasic.nl/index.html




De µSCOPE aan het werk. Let op de cursor die de gewenste functie aanduid.
Let ook op de cursor op de linker as die het trigger niveau aangeeft.



terug naar homepage

Syed Zeeshan Shah made a university project out of the µSCOPE. Well done!!


Dmitrij Kazakov’s versie van de µSCOPE


Vespira’s version of the µSCOPE on YouTube