Indholdsfortegnelse:

Superhurtige analoge spændinger fra Arduino: 10 trin (med billeder)
Superhurtige analoge spændinger fra Arduino: 10 trin (med billeder)

Video: Superhurtige analoge spændinger fra Arduino: 10 trin (med billeder)

Video: Superhurtige analoge spændinger fra Arduino: 10 trin (med billeder)
Video: Formant Speech Synthesis Analog 2 sec Talk Generator (part 1 the intro) 2024, Juli
Anonim
Image
Image

Denne instruktør viser, hvordan man genererer superhurtige analoge spændingsændringer fra en Arduino og et simpelt modstands- og kondensatorpar. En applikation, hvor dette er nyttigt, er at generere grafik på et oscilloskop. Der er flere andre projekter, der har gjort dette. Johngineer viser et simpelt juletræ ved hjælp af pulsbreddemodulation (PWM). Andre har forbedret dette projekt ved at bruge en modstandsstige eller ved hjælp af en dedikeret digital-til-analog konverterchip.

Brug af PWM forårsager meget flimmer, mens brug af en modstandsstige eller en digital-til-analog-omformer kræver flere udgangsstifter og komponenter, som muligvis ikke er let tilgængelige. Det kredsløb, jeg bruger, er det samme døde simple modstands- og kondensatorpar, som det blev brugt i juletræsdemoen, men fungerer med betydeligt mindre flimmer.

Først vil jeg guide dig gennem processen med at opbygge kredsløbet. Så vil jeg lære dig, hvordan du tilføjer dit eget billede. Endelig vil jeg introducere teorien om, hvad der gør det hurtigere.

Hvis du kunne lide denne Instructable, kan du overveje at stemme på den!:)

Trin 1: Opbygning af kredsløbet

Bygger kredsløbet
Bygger kredsløbet

For at bygge kredsløbet skal du bruge følgende:

a) En Arduino baseret på Atmel 16MHz ATmega328P, såsom en Arduino Uno eller Arduino Nano.

b) To modstande af værdi R, der er mindst 150Ω.

c) To kondensatorer af værdi C, således at C = 0,0015 / R, eksempler:

  • R = 150Ω og C = 10µ
  • R = 1,5 kΩ og C = 1 µ
  • R = 15kΩ og C = 100nF
  • R = 150kΩ og C = 10nF

Årsagerne til at vælge disse værdier er todelt. Primært ønsker vi at holde strømmen på Arduino -stifterne under den maksimale nominelle strøm på 40mA. Brug af en værdi på 150Ω begrænser strømmen til 30mA, når den bruges med Arduino -forsyningsspændingen på 5V. Større værdier af R vil reducere strømmen og er derfor acceptable.

Den anden begrænsning er, at vi ønsker at holde tiden konstant, som er produktet af R og C, lig med ca. 1,5 ms. Softwaren er specielt indstillet til denne tidskonstant. Selvom det er muligt at justere værdierne for R og C i softwaren, er der et snævert område, som det vil arbejde omkring, så vælg komponenter så tæt på det foreslåede forhold som muligt.

En mere grundig forklaring på, hvorfor RC -konstanten er vigtig, vil blive givet i teoriafsnittet, efter at jeg har vist dig, hvordan du samler demonstrationskredsløbet.

Trin 2: Opsætning af oscilloskopet

Opsætning af oscilloskopet
Opsætning af oscilloskopet

Demonstrationen kræver et oscilloskop indstillet til X/Y -tilstand. Testledningerne skal tilsluttes som vist i skemaerne. Dit oscilloskop vil afvige fra mit, men jeg går igennem de nødvendige trin for at konfigurere X/Y -tilstand på min enhed:

a) Indstil den vandrette sweep, der skal kontrolleres af kanal B (X -aksen).

b) Indstil oscilloskopet til dual channel mode.

c) Indstil volt/div på begge kanaler, så den kan vise spændinger fra 0V til 5V. Jeg satte min til 0,5V/div.

d) Indstil koblingstilstanden til DC på begge kanaler.

e) Juster placeringen af X og Y, så prikken er i nederste venstre hjørne af skærmen, når Arduino slukkes.

Trin 3: Download og kør softwaren

Image
Image

Download softwaren fra Fast Vector Display For Arduino -depotet. Softwaren er licenseret under GNU Affero Public License v3 og kan frit bruges og ændres under vilkårene i denne licens.

Åbn filen "fast-vector-display-arduino.ino" i Arduino IDE og upload til din Arduino. På et øjeblik vil du se en "Godt nytår" -animation på din oscilloskopskærm.

Jeg udviklede dette projekt som en personlig hackaton i ugerne op til jul, så der er en meddelelse om jul og nytår, du kan se ved at ændre PATTERN -variablen i koden.

Trin 4: Opret din egen brugerdefinerede tegning

Forstå, hvorfor PWM er så langsom
Forstå, hvorfor PWM er så langsom

Hvis du ønsker at oprette din egen tegning, kan du indsætte punktkoordinater i Arduino -skitsen på linjen, der definerer USER_PATTERN.

Jeg fandt ud af, at Inkscape er et ret godt værktøj til at lave en brugerdefineret tegning:

  1. Opret tekst ved hjælp af en stor, fed skrift, f.eks. Impact.
  2. Vælg tekstobjektet, og vælg "Objekt til sti" i menuen "Sti".
  3. Vælg individuelle bogstaver og overlap dem for at lave en tilsluttet form
  4. Vælg "Union" i menuen "Path" for at kombinere dem til en enkelt kurve.
  5. Hvis der er huller i bogstaver, skal du klippe et lille hak ved at tegne et rektangel med rektangelværktøjet og trække det fra konturen ved hjælp af værktøjet "Difference".
  6. Dobbeltklik på stien for at vise noderne.
  7. Marker alle noder i rektanglet, og klik på værktøjet "Lav hjørner for valgte noder".
  8. Gem SVG -filen.

Det vigtige er, at din tegning skal have en enkelt lukket sti og ingen huller. Sørg for, at dit design har færre end cirka 130 punkter.

Trin 5: Indsæt koordinaterne fra SVG -filen i Arduino IDE

  1. Åbn SVG -filen og kopier koordinaterne. Disse vil blive integreret i elementet "sti". Det første par koordinater kan ignoreres; erstatte dem med 0, 0.
  2. Indsæt koordinaterne i Arduino -skitsen inde i parenteserne lige efter "#define USER_PATTERN".
  3. Udskift alle mellemrum med kommaer, ellers får du en kompileringsfejl. Værktøjet "Erstat og find" kan være nyttigt.
  4. Kompilér og kør!
  5. Hvis du har problemer, skal du se den serielle konsol for eventuelle fejl. Især vil du se meddelelser, hvis dit mønster har for mange punkter til den interne buffer. I sådanne tilfælde vil billedet udvise overdreven flimmer.

Trin 6: Forstå, hvorfor PWM er så langsom

Lad os for det første gennemgå en kondensators adfærd, mens den oplades.

En kondensator, der er forbundet til en spændingskilde Vcc, øger sin spænding i henhold til en eksponentiel kurve. Denne kurve er asymptotisk, hvilket betyder, at den vil bremse, når den nærmer sig målspændingen. Af alle praktiske formål er spændingen "tæt nok" efter 5 RC sekunder. RC kaldes "tidskonstanten". Som vi så tidligere, er det et produkt af værdierne for modstanden og kondensatoren i dit kredsløb. Problemet er, at 5 RC er en temmelig lang tid til at opdatere hvert punkt i et grafisk display. Dette fører til meget flimmer!

Når vi bruger pulsbreddemodulation (PWM) til at oplade en kondensator, har vi det ikke bedre. Med PWM skifter spændingen hurtigt mellem 0V og 5V. I praksis betyder det, at vi hurtigt skifter mellem at skubbe ladning ind i kondensatoren og trække lidt af den lige ud igen - dette skub og træk er snarere som at prøve at løbe et maraton ved at tage et stort skridt fremad og derefter et lille skridt baglæns om og om igen.

Når du gennemsøger det hele, er opførslen ved at oplade en kondensator ved hjælp af PWM nøjagtig den samme, som hvis du havde brugt en konstant spænding på Vpwm til at oplade kondensatoren. Det tager stadig omkring 5 RC sekunder for os at komme "tæt nok" på den ønskede spænding.

Trin 7: Kom fra a til B, en smule bit hurtigere

Kom fra a til B, en smule bit hurtigere
Kom fra a til B, en smule bit hurtigere

Antag, at vi har en kondensator, der allerede er opladet op til Va. Antag, at vi bruger analogWrite () til at skrive den nye værdi af b. Hvad er den mindste tid, du skal vente på, at spændingen Vb opnås?

Hvis du gættede 5 RC sekunder, er det fantastisk! Ved at vente 5 RC sekunder oplades kondensatoren til næsten Vb. Men hvis vi vil, kan vi faktisk vente lidt mindre.

Se på ladningskurven. Du ser, kondensatoren var allerede på Va, da vi begyndte. Det betyder, at vi ikke behøver at vente tiden t_a. Det skulle vi kun, hvis vi oplader kondensatoren fra nul.

Så ved ikke at vente den tid, ser vi en forbedring. Tiden t_ab er faktisk lidt kortere end 5 RC.

Men vent, vi kan gøre det meget bedre! Se alt det rum over v_b. Det er forskellen mellem Vcc, den maksimale spænding, vi har til rådighed, og den Vb, vi agter at nå. Kan du se, hvordan den ekstra spænding kan hjælpe os med at komme langt, hvor vi vil hen langt hurtigere?

Trin 8: Kom fra a til B, med en turbolader

Kom fra a til B, med en turbolader!
Kom fra a til B, med en turbolader!

Det er rigtigt. I stedet for at bruge PWM ved målspændingen V_b, holder vi den ved en stabil Vcc i en meget, meget kortere periode. Jeg kalder dette Turbo Charger -metoden, og det bringer os, hvor vi vil hen virkelig, virkelig hurtigt! Efter tidsforsinkelsen (som vi skal beregne), slår vi på bremserne ved at skifte til PWM ved V_b. Dette forhindrer spændingen i at overskride målet.

Med denne metode er det muligt at ændre spændingen i kondensatoren fra V_a til V_b på en brøkdel af tiden end kun at bruge PWM. Sådan får du steder, skat!

Trin 9: Forstå koden

Forstå koden
Forstå koden

Et billede er tusind ord værd, så diagrammet viser data og de operationer, der udføres i koden. Fra venstre mod højre:

  • Grafikdataene gemmes i PROGMEM (det vil sige flashhukommelse) som en liste over punkter.
  • Enhver kombination af translation, skalering og rotation operationer kombineres til en affin transformationsmatrix. Dette gøres én gang i starten af hver animationsramme.
  • Punkter læses en efter en fra grafikdata og ganges hver med den lagrede transformationsmatrix.
  • De transformerede punkter føres gennem en sakse -algoritme, der beskærer alle punkter uden for det synlige område.
  • Ved hjælp af en RC -forsinkelsesopslagstabel konverteres punkterne til kørselsspændinger og tidsforsinkelser. RC-forsinkelsessøgningstabellen gemmes i EEPROM og kan genbruges til flere kørsler af koden. Ved opstart kontrolleres RC -opslagstabellen for nøjagtighed, og eventuelle forkerte værdier opdateres. Brugen af EEPROM sparer værdifuld RAM -hukommelse.
  • Drivspændinger og forsinkelser skrives til den inaktive ramme i rammebufferen. Rammebufferen indeholder plads til en aktiv ramme og en inaktiv ramme. Når en komplet ramme er skrevet, gøres den inaktive ramme aktiv.
  • En afbrydelsesrutine tegner konstant billedet ved at aflæse spændingsværdier og forsinkelser fra den aktive rammebuffer. Baseret på disse værdier justerer det output-benenes driftscyklusser. Timer 1 bruges til at måle tidsforsinkelsen ned til et par nanosekunder med præcision, mens timeren 2 bruges til at styre arbejdscyklussen for stifter.
  • Stiften med den største ændring i spænding er altid "turboladet" med en driftscyklus på nul eller 100%, hvilket giver den hurtigste opladnings- eller afladningstid. Stiften med en mindre ændring i spændingen drives med en driftscyklus, der er valgt til at matche overgangstiden for den første pin-denne tidsmatchning er vigtig for at sikre, at linjer trækkes lige på oscilloskopet.

Trin 10: Med stor fart kommer stort ansvar

Da denne metode er så meget hurtigere end PWM, hvorfor bruger analogWrite () den ikke? Jo, fordi at bruge bare PWM er godt nok til de fleste programmer og er meget mere tilgivende. "Turbo Charger" -metoden kræver imidlertid omhyggelig kodning og er kun egnet til specifikke tilfælde:

  1. Det er ekstremt følsomt for timing. Når vi når målspændingsniveauet, skal drivstiften straks skiftes til normal PWM -tilstand for at undgå overskridelse af målspændingen.
  2. Det kræver kendskab til RC -konstanten, så disse værdier skal indtastes på forhånd. Med forkerte værdier vil timingen være forkert, og spændingerne vil være forkerte. Med almindelig PWM er der garanti for, at du efter et stykke tid vil slå dig ned på den korrekte spænding, selvom RC -konstanten ikke er kendt.
  3. At beregne det præcise tidsinterval til opladning af kondensatoren kræver logaritmiske ligninger, der er for langsomme til beregning i realtid på Arduino. Disse skal forudberegnes før hver animationsramme og gemmes i hukommelsen et eller andet sted.
  4. Programmer, der beskæftiger sig med denne metode, må bestride det faktum, at forsinkelserne er meget ikke-lineære (de er faktisk eksponentielle). Målspændinger nær Vcc eller GND vil tage mange størrelsesordener længere at nå end spændinger nær midtpunktet.

For at overvinde disse begrænsninger gør min vektorgrafikkode følgende ting:

  1. Den bruger Timer 1 ved 16 kHz og en afbrydelsesrutine til præcis outputmanipulation og timing.
  2. Det kræver en specifik værdi af RC -tidskonstant, der skal bruges, hvilket begrænser valgene af kondensator- og modstandsværdier.
  3. Det gemmer tidsforsinkelser for alle punkterne i en animationsramme i en hukommelsesbuffer. Dette betyder, at rutinen, der beregner tidsforsinkelserne, kører med en meget langsommere hastighed end afbrydelsesrutinen, der opdaterer output -benene. Enhver given ramme kan blive malet flere dusin gange, før et nyt sæt forsinkelser til den næste ramme er klar til brug.
  4. Brugen af en hukommelsesbuffer sætter en begrænsning på antallet af punkter, der kan trækkes pr. Ramme. Jeg anvender en pladseffektiv kodning for at få mest muligt ud af den tilgængelige RAM, men den er stadig begrænset til omkring 150 punkter. Ud over hundrede eller deromkring punkter eller deromkring, ville displayet alligevel begynde at flimre, så det er et punktum!

Anbefalede: