Innehållsförteckning:

Supersnabba analoga spänningar från Arduino: 10 steg (med bilder)
Supersnabba analoga spänningar från Arduino: 10 steg (med bilder)

Video: Supersnabba analoga spänningar från Arduino: 10 steg (med bilder)

Video: Supersnabba analoga spänningar från Arduino: 10 steg (med bilder)
Video: Quantum Computers Are Coming … But Why Should You Care? 2024, Juli
Anonim
Image
Image

Denna instruktionsbok visar hur man genererar supersnabba analoga spänningsändringar från en Arduino och ett enkelt motstånd och kondensatorpar. En applikation där detta är användbart är att generera grafik på ett oscilloskop. Det finns flera andra projekt som har gjort detta. Johngineer visar ett enkelt julgran med pulsbreddsmodulation (PWM). Andra har förbättrat projektet genom att använda en motståndsstege eller använda ett dedikerat digitalt till analogt omvandlarchip.

Att använda PWM orsakar mycket flimmer, medan användning av en motståndsstege eller en digital-till-analog omvandlare kräver fler utgångsstiften och komponenter som kanske inte är lätt tillgängliga. Kretsen jag använder är samma döda enkla motstånd och kondensatorpar som används i julgransdemon, men fungerar med betydligt mindre flimmer.

Först kommer jag att guida dig genom processen att bygga kretsen. Sedan kommer jag att lära dig hur du lägger till din egen bild. Slutligen kommer jag att introducera teorin om vad som gör det snabbare.

Om du gillade denna instruerbara, överväg att rösta på den!:)

Steg 1: Bygg kretsen

Bygga kretsen
Bygga kretsen

För att bygga kretsen behöver du följande:

a) En Arduino baserad på Atmel 16MHz ATmega328P, till exempel en Arduino Uno eller Arduino Nano.

b) Två motstånd med värde R som är minst 150Ω.

c) Två kondensatorer av värde C så att C = 0,0015 / R, exempel:

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

Anledningarna till att välja dessa värden är tvåfaldiga. I första hand vill vi hålla strömmen på Arduino -stiften under den maximala märkströmmen på 40mA. Med ett värde på 150Ω begränsas strömmen till 30mA när den används med Arduino -matningsspänningen på 5V. Större värden på R minskar strömmen och är därför acceptabla.

Den andra begränsningen är att vi vill hålla tiden konstant, som är produkten av R och C, lika med cirka 1,5 ms. Programvaran har specifikt trimmats för den här tidskonstanten. Även om det är möjligt att justera värdena för R och C i programvaran, finns det ett smalt intervall runt vilket det kommer att fungera, så välj komponenter så nära det föreslagna förhållandet som möjligt.

En mer ingående förklaring till varför RC -konstanten är viktig kommer att ges i teoridelen, efter att jag har visat dig hur du monterar demonstrationskretsen.

Steg 2: Konfigurera oscilloskopet

Uppställning av oscilloskopet
Uppställning av oscilloskopet

Demonstrationen kräver ett oscilloskop inställt på X/Y -läge. Testkablarna måste anslutas som visas i schemat. Ditt oscilloskop kommer att skilja sig från mitt, men jag går igenom de nödvändiga stegen för att ställa in X/Y -läge på min enhet:

a) Ställ in den horisontella svepningen som ska styras av kanal B (X -axeln).

b) Ställ in oscilloskopet på tvåkanalsläge.

c) Ställ in volt/div på båda kanalerna så att den kan visa spänningar från 0V till 5V. Jag ställde in min på 0,5V/div.

d) Ställ kopplingsläget på DC på båda kanalerna.

e) Justera positionen för X och Y så att pricken är i nedre vänstra hörnet på skärmen när Arduino stängs av.

Steg 3: Ladda ner och kör programvaran

Image
Image

Ladda ner programvaran från Fast Vector Display For Arduino -förvaret. Programvaran är licensierad under GNU Affero Public License v3 och kan fritt användas och modifieras enligt villkoren i den licensen.

Öppna filen "fast-vector-display-arduino.ino" i Arduino IDE och ladda upp till din Arduino. För en stund kommer du att se en "Gott nytt år" -animation på din oscilloskopskärm.

Jag utvecklade detta projekt som en personlig hackaton under veckorna fram till jul, så det finns ett jul- och nyårstema -meddelande som du kan se genom att ändra PATTERN -variabeln i koden.

Steg 4: Skapa din egen anpassade ritning

Förstå varför PWM är så långsam
Förstå varför PWM är så långsam

Om du vill skapa din egen ritning kan du klistra in punktkoordinater i Arduino -skissen på linjen som definierar USER_PATTERN.

Jag fann att Inkscape är ett ganska bra verktyg för att göra en anpassad ritning:

  1. Skapa text med ett stort, djärvt teckensnitt som Impact.
  2. Markera textobjektet och välj "Objekt till sökväg" från "Sökväg" -menyn.
  3. Välj enskilda bokstäver och överlappa dem för att skapa en ansluten form
  4. Välj "Union" från "Path" -menyn för att kombinera dem till en enda kurva.
  5. Om det finns hål i några bokstäver, skär ett litet hack genom att rita en rektangel med rektangelverktyget och subtrahera det från konturen med verktyget "Difference".
  6. Dubbelklicka på sökvägen för att visa noder.
  7. Rektangel markera alla noder och klicka på verktyget "Gör valda noder hörn".
  8. Spara SVG -filen.

Det viktiga är att din ritning ska ha en enda stängd väg och inga hål. Se till att din design har färre än cirka 130 poäng.

Steg 5: Klistra in koordinaterna från SVG -filen i Arduino IDE

  1. Öppna SVG -filen och kopiera ut koordinaterna. Dessa kommer att vara inbäddade i "sökväg" -elementet. Det första paret av koordinater kan ignoreras; ersätt dem med 0, 0.
  2. Klistra in koordinaterna i Arduino -skissen inuti parenteserna direkt efter "#define USER_PATTERN".
  3. Ersätt alla mellanslag med kommatecken, annars får du ett kompileringsfel. Verktyget "Ersätt och hitta" kan vara till hjälp.
  4. Kompilera och kör!
  5. Om du har problem, titta på seriekonsolen för eventuella fel. I synnerhet kommer du att se meddelanden om ditt mönster har för många punkter för den interna bufferten. I sådana fall kommer bilden att uppvisa överdriven flimmer.

Steg 6: Förstå varför PWM är så långsam

För att börja, låt oss granska beteendet hos en kondensator när den laddas.

En kondensator som är ansluten till en spänningskälla Vcc kommer att öka sin spänning enligt en exponentiell kurva. Denna kurva är asymptotisk, vilket betyder att den kommer att sakta ner när den närmar sig målspänningen. För alla praktiska ändamål är spänningen "tillräckligt nära" efter 5 RC -sekunder. RC kallas "tidskonstanten". Som vi såg tidigare är det en produkt av värdena för motståndet och kondensatorn i din krets. Problemet är att 5 RC är en ganska lång tid för att uppdatera varje punkt i en grafisk display. Detta leder till mycket flimmer!

När vi använder pulsbreddsmodulation (PWM) för att ladda en kondensator har vi det inte bättre. Med PWM växlar spänningen snabbt mellan 0V och 5V. I praktiken betyder det att vi snabbt växlar mellan att trycka in laddning i kondensatorn och dra ut lite av den direkt igen - denna push och pull är snarare som att försöka springa ett maraton genom att ta ett stort steg framåt och sedan ett litet steg bakåt om och om igen.

När du gör ett genomsnitt är beteendet att ladda en kondensator med PWM exakt samma som om du hade använt en konstant spänning på Vpwm för att ladda kondensatorn. Det tar fortfarande cirka 5 RC sekunder för oss att komma "tillräckligt nära" till önskad spänning.

Steg 7: Gå från a till B, en smula lite snabbare

Få från a till B, en smula lite snabbare
Få från a till B, en smula lite snabbare

Antag att vi har en kondensator som redan är laddad upp till Va. Antag att vi använder analogWrite () för att skriva ut det nya värdet av b. Hur lång tid måste du vänta på att spänningen Vb ska uppnås?

Om du gissade 5 RC -sekunder är det fantastiskt! Genom att vänta 5 RC sekunder kommer kondensatorn att laddas till nästan Vb. Men om vi vill kan vi faktiskt vänta lite mindre.

Titta på laddningskurvan. Du ser, kondensatorn var redan på Va när vi började. Det betyder att vi inte behöver vänta tiden t_a. Vi skulle bara behöva om vi laddade kondensatorn från noll.

Så genom att inte vänta den tiden ser vi en förbättring. Tiden t_ab är faktiskt lite kortare än 5 RC.

Men håll ut, vi kan göra så mycket bättre! Titta på allt det utrymmet ovanför v_b. Det är skillnaden mellan Vcc, den maximala spänningen som är tillgänglig för oss och den Vb vi tänker nå. Kan du se hur den extra spänningen kan hjälpa oss att komma dit vi vill gå mycket snabbare?

Steg 8: Gå från a till B, med en turboladdare

Gå från a till B, med en turboladdare!
Gå från a till B, med en turboladdare!

Det är rätt. Istället för att använda PWM vid målspänningen V_b håller vi den vid en konstant Vcc under mycket, mycket kortare tid. Jag kallar detta Turbo Charger -metoden och det får oss dit vi vill gå riktigt, riktigt snabbt! Efter tidsfördröjningen (som vi måste beräkna) slår vi på bromsarna genom att byta till PWM vid V_b. Detta förhindrar att spänningen överskrider målet.

Med denna metod är det möjligt att ändra spänningen i kondensatorn från V_a till V_b på en bråkdel av tiden än att bara använda PWM. Så här får du platser, älskling!

Steg 9: Förstå koden

Förstå koden
Förstå koden

En bild är värd tusen ord, så diagrammet visar data och operationer som utförs i koden. Från vänster till höger:

  • Grafikdata lagras i PROGMEM (det vill säga flashminne) som en lista över punkter.
  • Varje kombination av translation, skalning och rotationsoperationer kombineras till en affin transformationsmatris. Detta görs en gång i början av varje animeringsram.
  • Poäng läses en efter en från grafikdata och multipliceras var och en med den lagrade transformationsmatrisen.
  • De transformerade punkterna matas genom en saxalgoritm som beskär alla punkter utanför det synliga området.
  • Med hjälp av en RC -fördröjningssökningstabell konverteras punkterna till körspänningar och tidsfördröjningar. RC-fördröjningssökningstabellen lagras i EEPROM och kan återanvändas för flera körningar av koden. Vid start kontrolleras RC -uppslagstabellen för noggrannhet och eventuella felaktiga värden uppdateras. Användningen av EEPROM sparar värdefullt RAM -minne.
  • Drivspänningarna och fördröjningarna skrivs till den inaktiva ramen i rambufferten. Rambufferten innehåller plats för en aktiv ram och en inaktiv ram. När en fullständig ram har skrivits görs den inaktiva ramen aktiv.
  • En avbrottsrutin återupptäcker kontinuerligt bilden genom att läsa av spänningsvärden och fördröjningar från den aktiva rambufferten. Baserat på dessa värden justerar den utgångstapparnas arbetscykler. Timer 1 används för att mäta tidsfördröjningen ner till några nanosekunder med precision, medan timer 2 används för att styra arbetscykeln för stift.
  • Stiftet med den största förändringen i spänning är alltid "turboladdad" med en driftscykel på noll eller 100%, vilket ger den snabbaste laddnings- eller urladdningstiden. Stiftet med en mindre förändring i spänningen drivs med en arbetscykel som väljs för att matcha övergångstiden för den första stiftet-denna tidsmatchning är viktig för att säkerställa att linjer dras rakt på oscilloskopet.

Steg 10: Med stor hastighet kommer stort ansvar

Eftersom denna metod är så mycket snabbare än PWM, varför använder analogWrite () den inte? Tja, för att bara använda PWM är tillräckligt bra för de flesta program och är mycket mer förlåtande. Metoden "Turbo Charger" kräver dock noggrann kodning och är endast lämplig för specifika fall:

  1. Det är extremt känsligt för timing. När vi når målspänningsnivån måste drivstiftet omedelbart växlas till vanligt PWM -läge för att undvika överskridande av målspänningen.
  2. Det kräver kunskap om RC -konstanten, så dessa värden måste anges i förväg. Med felaktiga värden blir timingen fel och spänningarna felaktiga. Med vanlig PWM finns det en garanti för att du kommer att sätta dig på rätt spänning efter en tid, även om RC -konstanten inte är känd.
  3. Att beräkna det exakta tidsintervallet för laddning av kondensatorn kräver logaritmiska ekvationer som är för långsamma för realtidsberäkning på Arduino. Dessa måste förberäknas före varje animationsram och cachas i minnet någonstans.
  4. Program som behandlar denna metod måste strida mot att förseningarna är mycket olinjära (de är i själva verket exponentiella). Målspänningar nära Vcc eller GND kommer att ta många storleksordningar längre att nå än spänningar nära mittpunkten.

För att övervinna dessa begränsningar gör min vektorgrafikkod följande saker:

  1. Den använder timer 1 vid 16 kHz och en avbrottsrutin för exakt utmatningsmanipulation och timing.
  2. Det kräver ett specifikt värde för RC -tidskonstant för att användas, vilket begränsar valet av kondensator- och motståndsvärden.
  3. Den lagrar tidsfördröjningar för alla punkter i en animeringsram i en minnesbuffert. Detta betyder att rutinen som beräknar tidsfördröjningar går mycket långsammare än avbrottsrutinen som uppdaterar utgångsstiften. Varje ram kan målas flera dussin gånger innan en ny uppsättning fördröjningar för nästa ram är redo att användas.
  4. Användningen av en minnesbuffert sätter en begränsning för antalet punkter som kan dras per bildruta. Jag använder en rymdeffektiv kodning för att få ut det mesta av det tillgängliga RAM -minnet, men det är fortfarande begränsat till cirka 150 poäng. Utöver ett hundratal punkter eller så skulle skärmen börja flimra ändå, så det är en poängpunkt!

Rekommenderad: