Inhoudsopgave:

Supersnelle analoge spanningen van Arduino - Ajarnpa
Supersnelle analoge spanningen van Arduino - Ajarnpa

Video: Supersnelle analoge spanningen van Arduino - Ajarnpa

Video: Supersnelle analoge spanningen van Arduino - Ajarnpa
Video: Output DC or AC Voltage using MCP4725 DAC with LCD and PWM to Voltage Converter with Arduino 2024, Juli-
Anonim
Image
Image

Deze Instructable laat zien hoe je supersnelle analoge spanningsveranderingen kunt genereren van een Arduino en een eenvoudig paar weerstanden en condensatoren. Een toepassing waarbij dit nuttig is, is het genereren van afbeeldingen op een oscilloscoop. Er zijn verschillende andere projecten die dit hebben gedaan. Johngineer toont een eenvoudige kerstboom met behulp van pulsbreedtemodulatie (PWM). Anderen hebben dat project verbeterd door een weerstandsladder te gebruiken of een speciale digitaal-naar-analoog converterchip te gebruiken.

Het gebruik van PWM veroorzaakt veel flikkering, terwijl het gebruik van een weerstandsladder of een digitaal-naar-analoogomzetter meer uitgangspinnen en componenten vereist die mogelijk niet direct beschikbaar zijn. Het circuit dat ik gebruik is hetzelfde doodeenvoudige weerstand- en condensatorpaar als gebruikt in de kerstboomdemo, maar werkt met aanzienlijk minder flikkering.

Eerst zal ik je door het proces van het bouwen van het circuit leiden. Dan zal ik je leren hoe je je eigen afbeelding kunt toevoegen. Ten slotte zal ik de theorie introduceren over wat het sneller maakt.

Als je dit Instructable leuk vond, overweeg dan om ervoor te stemmen!:)

Stap 1: Het circuit bouwen

Het circuit bouwen
Het circuit bouwen

Om het circuit te bouwen, heb je het volgende nodig:

a) Een Arduino gebaseerd op de Atmel 16MHz ATmega328P, zoals een Arduino Uno of Arduino Nano.

b) Twee weerstanden met een waarde R die minimaal 150Ω is.

c) Twee condensatoren met waarde C zodat C = 0,0015 / R, voorbeelden:

  • R = 150Ω en C = 10µ
  • R = 1.5kΩ en C = 1µ
  • R = 15kΩ en C = 100nF
  • R = 150kΩ en C = 10nF

De redenen om voor deze waarden te kiezen zijn tweeledig. In de eerste plaats willen we de stroom op de pinnen van de Arduino onder de maximale nominale stroom van 40mA houden. Het gebruik van een waarde van 150Ω beperkt de stroom tot 30mA bij gebruik met de Arduino-voedingsspanning van 5V. Grotere waarden van R zullen de stroom verminderen en zijn daarom acceptabel.

De tweede beperking is dat we de tijd constant willen houden, wat het product is van R en C, gelijk aan ongeveer 1,5 ms. De software is speciaal afgestemd op deze tijdconstante. Hoewel het mogelijk is om de waarden van R en C in de software aan te passen, is er een smal bereik waaromheen het zal werken, dus kies componenten die zo dicht mogelijk bij de voorgestelde verhouding liggen.

Een meer grondige uitleg over waarom de RC-constante belangrijk is, zal worden gegeven in het theoriegedeelte, nadat ik je heb laten zien hoe je het demonstratiecircuit moet samenstellen.

Stap 2: De oscilloscoop instellen

De oscilloscoop instellen
De oscilloscoop instellen

De demonstratie vereist een oscilloscoop die is ingesteld op X/Y-modus. De meetsnoeren moeten worden aangesloten zoals aangegeven in het schema. Uw oscilloscoop zal verschillen van de mijne, maar ik zal de nodige stappen doorlopen om de X/Y-modus op mijn apparaat in te stellen:

a) Stel de horizontale zwaai in die moet worden bestuurd door kanaal B (de X-as).

b) Stel de oscilloscoop in op tweekanaalsmodus.

c) Stel de volt/div op beide kanalen in zodat deze spanningen van 0V tot 5V kan weergeven. Ik heb de mijne ingesteld op 0,5V/div.

d) Stel de koppelingsmodus op beide kanalen in op DC.

e) Pas de positie van X en Y aan zodat de stip zich in de linkerbenedenhoek van het scherm bevindt wanneer de Arduino is uitgeschakeld.

Stap 3: Download en voer de software uit

Image
Image

Download de software van de Fast Vector Display For Arduino-repository. De software is gelicentieerd onder de GNU Affero Public License v3 en kan vrij worden gebruikt en gewijzigd onder de voorwaarden van die licentie.

Open het bestand "fast-vector-display-arduino.ino" in de Arduino IDE en upload het naar je Arduino. Even ziet u een "Gelukkig Nieuwjaar" -animatie op uw oscilloscoopscherm.

Ik heb dit project ontwikkeld als een persoonlijke hackaton in de weken voorafgaand aan Kerstmis, dus er is een bericht met een kerst- en nieuwjaarsthema dat je kunt zien door de PATTERN-variabele in de code te wijzigen.

Stap 4: Maak uw eigen aangepaste tekening

Begrijp waarom PWM zo traag is
Begrijp waarom PWM zo traag is

Als u uw eigen tekening wilt maken, kunt u puntcoördinaten in de Arduino-schets plakken op de lijn die USER_PATTERN definieert.

Ik ontdekte dat Inkscape een redelijk goed hulpmiddel is voor het maken van een aangepaste tekening:

  1. Maak tekst met een groot, vetgedrukt lettertype zoals Impact.
  2. Selecteer het tekstobject en selecteer "Object naar pad" in het menu "Pad".
  3. Selecteer afzonderlijke letters en overlap ze om een verbonden vorm te maken
  4. Selecteer "Union" in het menu "Pad" om ze te combineren in een enkele curve.
  5. Als er gaten in letters zitten, knip dan een kleine inkeping door een rechthoek te tekenen met het rechthoekgereedschap en trek het van de contour af met het gereedschap "Verschil".
  6. Dubbelklik op het pad om de knooppunten weer te geven.
  7. Rechthoek selecteer alle knooppunten en klik op het gereedschap "Geselecteerde knooppunten hoek maken".
  8. Sla het SVG-bestand op.

Het belangrijkste is dat uw tekening een enkel gesloten pad moet hebben en geen gaten. Zorg ervoor dat uw ontwerp minder dan ongeveer 130 punten heeft.

Stap 5: Plak de coördinaten van het SVG-bestand in de Arduino IDE

  1. Open het SVG-bestand en kopieer de coördinaten. Deze worden ingebed in het "pad"-element. Het eerste paar coördinaten kan worden genegeerd; vervang ze door 0, 0.
  2. Plak de coördinaten in de Arduino-schets tussen de haakjes direct na "#define USER_PATTERN".
  3. Vervang alle spaties door komma's, anders krijg je een compileerfout. De tool "Vervangen en zoeken" kan nuttig zijn.
  4. Compileren en uitvoeren!
  5. Als je problemen hebt, kijk dan op de seriële console voor eventuele fouten. U zult met name berichten zien als uw patroon te veel punten heeft voor de interne buffer. In dergelijke gevallen zal het beeld overmatige flikkering vertonen.

Stap 6: Begrijp waarom PWM zo traag is

Laten we om te beginnen eens kijken naar het gedrag van een condensator tijdens het opladen.

Een condensator die is aangesloten op een spanningsbron Vcc zal zijn spanning verhogen volgens een exponentiële curve. Deze curve is asymptotisch, wat betekent dat hij zal vertragen naarmate hij de doelspanning nadert. Voor alle praktische doeleinden is de spanning "dicht genoeg" na 5 RC-seconden. De RC wordt de "tijdconstante" genoemd. Zoals we eerder zagen, is het het product van de waarden van de weerstand en condensator in uw circuit. Het probleem is dat 5 RC nogal lang duurt voor het bijwerken van elk punt in een grafisch display. Dit leidt tot veel flikkering!

Wanneer we pulsbreedtemodulatie (PWM) gebruiken om een condensator op te laden, zijn we niet beter af. Met PWM schakelt de spanning snel tussen 0V en 5V. In de praktijk betekent dit dat we snel afwisselen tussen het in de condensator duwen van de lading en het er weer een beetje uit trekken -- dit duwen en trekken is net zoiets als proberen een marathon te lopen door een grote stap voorwaarts en dan een kleine stap achteruit te doen opnieuw en opnieuw.

Als je het allemaal uitrekent, is het gedrag van het opladen van een condensator met PWM precies hetzelfde als wanneer je een constante spanning van Vpwm had gebruikt om de condensator op te laden. Het duurt nog steeds ongeveer 5 RC seconden voordat we "dicht genoeg" bij de gewenste spanning komen.

Stap 7: Ga van a naar B, een tikkeltje sneller

Ga van a naar B, een tikkeltje sneller
Ga van a naar B, een tikkeltje sneller

Stel dat we een condensator hebben die al is opgeladen tot Va. Stel dat we analogWrite() gebruiken om de nieuwe waarde van b uit te schrijven. Hoe lang moet u minimaal wachten tot de spanning Vb is bereikt?

Als je 5 RC-seconden hebt geraden, is dat geweldig! Door 5 RC seconden te wachten, wordt de condensator opgeladen tot bijna Vb. Maar als we willen, kunnen we eigenlijk wat minder wachten.

Kijk naar de laadcurve. Zie je, de condensator was al op Va toen we begonnen. Dit betekent dat we niet hoeven te wachten op de tijd t_a. Dat zou alleen moeten als we de condensator vanaf nul zouden opladen.

Dus door die tijd niet te wachten, zien we een verbetering. De tijd t_ab is eigenlijk iets korter dan 5 RC.

Maar wacht even, we kunnen zoveel beter! Kijk naar al die ruimte boven v_b. Dat is het verschil tussen Vcc, de maximale spanning die voor ons beschikbaar is, en de Vb die we willen bereiken. Zie je hoe die extra spanning ons kan helpen om veel sneller te komen waar we heen willen?

Stap 8: Ga van a naar B, met een turbolader

Ga van a naar B, met een turbolader!
Ga van a naar B, met een turbolader!

Klopt. In plaats van PWM te gebruiken bij de doelspanning V_b, houden we deze gedurende een veel, veel kortere periode op een constante Vcc. Ik noem dit de Turbo Charger-methode en het brengt ons heel, heel snel waar we heen willen! Na de tijdvertraging (die we moeten berekenen), trappen we op de rem door over te schakelen naar PWM bij V_b. Dit zorgt ervoor dat de spanning het doel niet voorbijschiet.

Met deze methode is het mogelijk om de spanning in de condensator in een fractie van de tijd te veranderen van V_a naar V_b dan met alleen PWM. Zo krijg je plaatsen, schat!

Stap 9: Begrijp de code

Begrijp de code
Begrijp de code

Een afbeelding zegt meer dan duizend woorden, dus het diagram toont de gegevens en de bewerkingen die in de code worden uitgevoerd. Van links naar rechts:

  • De grafische gegevens worden in PROGMEM (d.w.z. flash-geheugen) als een lijst met punten opgeslagen.
  • Elke combinatie van translatie-, schaal- en rotatiebewerkingen wordt gecombineerd in een affiene transformatiematrix. Dit gebeurt één keer aan het begin van elk animatieframe.
  • Punten worden één voor één gelezen uit grafische gegevens en worden elk vermenigvuldigd met de opgeslagen transformatiematrix.
  • De getransformeerde punten worden door een schaaralgoritme gevoerd dat alle punten buiten het zichtbare gebied bijsnijdt.
  • Met behulp van een RC-delay-opzoektabel worden de punten omgezet in stuurspanningen en tijdvertragingen. De RC-delay-opzoektabel wordt opgeslagen in EEPROM en kan opnieuw worden gebruikt voor meerdere runs van de code. Bij het opstarten wordt de RC-opzoektabel gecontroleerd op juistheid en worden eventuele onjuiste waarden bijgewerkt. Het gebruik van EEPROM bespaart waardevol RAM-geheugen.
  • De stuurspanningen en vertragingen worden naar het inactieve frame in de framebuffer geschreven. De framebuffer bevat ruimte voor een actief frame en een inactief frame. Zodra een volledig frame is geschreven, wordt het inactieve frame actief gemaakt.
  • Een onderbrekingsserviceroutine tekent voortdurend het beeld opnieuw door spanningswaarden en vertragingen uit de actieve framebuffer te lezen. Op basis van die waarden past het de duty-cycles van de uitgangspinnen aan. Timer 1 wordt gebruikt voor het meten van de tijdvertraging tot op enkele nanoseconden nauwkeurig, terwijl timer 2 wordt gebruikt voor het regelen van de duty cycle van pinnen.
  • De pin met de grootste verandering in spanning is altijd "turbo-geladen" met een duty-cycle van nul of 100%, wat de snelste laad- of ontlaadtijd oplevert. De pin met een kleinere verandering in spanning wordt aangedreven met een duty cycle die is gekozen om overeen te komen met de overgangstijd van de eerste pin. Deze tijdsaanpassing is belangrijk om ervoor te zorgen dat lijnen recht op de oscilloscoop worden getrokken.

Stap 10: Met grote snelheid komt grote verantwoordelijkheid

Aangezien deze methode zoveel sneller is dan PWM, waarom gebruikt analogWrite() het dan niet? Nou, omdat het gebruik van alleen PWM goed genoeg is voor de meeste programma's en een stuk vergevingsgezinder is. De "Turbo Charger"-methode vereist echter een zorgvuldige codering en is alleen geschikt voor specifieke gevallen:

  1. Het is extreem gevoelig voor timing. Zodra we het doelspanningsniveau hebben bereikt, moet de stuurpen onmiddellijk in de normale PWM-modus worden geschakeld om te voorkomen dat de doelspanning wordt overschreden.
  2. Het vereist kennis van de RC-constante, dus deze waarden moeten vooraf worden ingevoerd. Met onjuiste waarden is de timing verkeerd en zijn de spanningen onjuist. Met reguliere PWM is er een garantie dat je na verloop van tijd op de juiste spanning zit, zelfs als de RC-constante niet bekend is.
  3. Het berekenen van het precieze tijdsinterval voor het opladen van de condensator vereist logaritmische vergelijkingen die te langzaam zijn voor realtime berekeningen op de Arduino. Deze moeten voor elk animatieframe vooraf worden berekend en ergens in het geheugen worden opgeslagen.
  4. Programma's die met deze methode werken, hebben te maken met het feit dat de vertragingen erg niet-lineair zijn (ze zijn in feite exponentieel). Doelspanningen nabij Vcc of GND zullen vele orden van grootte langer nodig hebben om te bereiken dan spanningen nabij het middelpunt.

Om deze beperkingen te overwinnen, doet mijn vectorafbeeldingscode de volgende dingen:

  1. Het maakt gebruik van Timer 1 op 16 kHz en een onderbrekingsserviceroutine voor nauwkeurige uitvoermanipulatie en timing.
  2. Het vereist een specifieke waarde van de RC-tijdconstante die moet worden gebruikt, waardoor de keuzes van de condensator- en weerstandswaarden worden beperkt.
  3. Het slaat de vertragingen voor alle punten in een animatieframe op in een geheugenbuffer. Dit betekent dat de routine die de tijdvertragingen berekent, veel langzamer werkt dan de interruptserviceroutine die de uitvoerpinnen bijwerkt. Een bepaald frame kan tientallen keren worden geverfd voordat een nieuwe set vertragingen voor het volgende frame klaar is om te worden gebruikt.
  4. Het gebruik van een geheugenbuffer legt een beperking op aan het aantal punten dat per frame kan worden getekend. Ik gebruik een ruimtebesparende codering om het meeste uit het beschikbare RAM-geheugen te halen, maar het is nog steeds beperkt tot ongeveer 150 punten. Voorbij een honderdtal punten of zo, zou het scherm toch beginnen te flikkeren, dus het is een betwistbaar punt!

Aanbevolen: