Sommario:

Tensioni analogiche super veloci da Arduino: 10 passaggi (con immagini)
Tensioni analogiche super veloci da Arduino: 10 passaggi (con immagini)

Video: Tensioni analogiche super veloci da Arduino: 10 passaggi (con immagini)

Video: Tensioni analogiche super veloci da Arduino: 10 passaggi (con immagini)
Video: 7-Arduino semplice - Ingressi analogici 2024, Luglio
Anonim
Image
Image

Questo Instructable mostra come generare cambiamenti di tensione analogici super veloci da un Arduino e una semplice coppia di resistori e condensatori. Un'applicazione in cui ciò è utile è la generazione di grafici su un oscilloscopio. Ci sono molti altri progetti che hanno fatto questo. Johngineer mostra un semplice albero di Natale che utilizza la modulazione di larghezza di impulso (PWM). Altri hanno migliorato quel progetto utilizzando una scala di resistori o utilizzando un chip convertitore digitale-analogico dedicato.

L'utilizzo del PWM provoca molto sfarfallio, mentre l'utilizzo di una scala di resistori o di un convertitore digitale-analogico richiede più pin di uscita e componenti che potrebbero non essere prontamente disponibili. Il circuito che uso è lo stesso resistore semplice morto e coppia di condensatori utilizzati nella demo dell'albero di Natale, ma funziona con uno sfarfallio significativamente inferiore.

Innanzitutto, ti guiderò attraverso il processo di costruzione del circuito. Poi ti insegnerò come aggiungere la tua immagine. Infine, introdurrò la teoria su cosa lo rende più veloce.

Se ti è piaciuto questo Instructable, per favore considera di votarlo!:)

Passaggio 1: costruire il circuito

Costruire il circuito
Costruire il circuito

Per costruire il circuito, avrai bisogno di quanto segue:

a) Un Arduino basato su Atmel 16MHz ATmega328P, come Arduino Uno o Arduino Nano.

b) Due resistori di valore R che sia almeno 150Ω.

c) Due condensatori di valore C tali che C = 0.0015 / R, esempi:

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

Le ragioni per scegliere questi valori sono due volte. In primo luogo, vogliamo mantenere la corrente sui pin di Arduino al di sotto della corrente nominale massima di 40 mA. L'utilizzo di un valore di 150 limita la corrente a 30 mA quando viene utilizzato con la tensione di alimentazione di Arduino di 5 V. Valori maggiori di R diminuiscono la corrente e sono quindi accettabili.

Il secondo vincolo è che vogliamo mantenere il tempo costante, che è il prodotto di R e C, pari a circa 1,5 ms. Il software è stato appositamente messo a punto per questa costante di tempo. Sebbene sia possibile regolare i valori di R e C nel software, esiste un intervallo ristretto attorno al quale funzionerà, quindi scegli i componenti il più vicino possibile al rapporto suggerito.

Una spiegazione più approfondita sul perché la costante RC è importante verrà data nella sezione teorica, dopo che ti ho mostrato come assemblare il circuito dimostrativo.

Passaggio 2: configurazione dell'oscilloscopio

Configurazione dell'oscilloscopio
Configurazione dell'oscilloscopio

La dimostrazione richiede un oscilloscopio impostato sulla modalità X/Y. I puntali devono essere collegati come mostrato negli schemi. Il tuo oscilloscopio sarà diverso dal mio, ma seguirò i passaggi necessari per impostare la modalità X/Y sulla mia unità:

a) Imposta la scansione orizzontale da controllare dal Canale B (l'asse X).

b) Impostare l'oscilloscopio sulla modalità a doppio canale.

c) Impostare i volt/div su entrambi i canali in modo che possa visualizzare tensioni da 0V a 5V. Ho impostato il mio a 0,5 V/div.

d) Impostare la modalità di accoppiamento su DC su entrambi i canali.

e) Regolare la posizione di X e Y in modo che il punto si trovi nell'angolo in basso a sinistra dello schermo quando l'Arduino è spento.

Passaggio 3: scarica ed esegui il software

Image
Image

Scarica il software dal repository Fast Vector Display For Arduino. Il software è concesso in licenza sotto la GNU Affero Public License v3 e può essere utilizzato e modificato liberamente secondo i termini di tale licenza.

Apri il file "fast-vector-display-arduino.ino" nell'IDE di Arduino e caricalo sul tuo Arduino. Per un momento, vedrai un'animazione "Happy New Year" sullo schermo dell'oscilloscopio.

Ho sviluppato questo progetto come hackaton personale nelle settimane che precedono il Natale, quindi c'è un messaggio a tema Natale e Capodanno che puoi vedere modificando la variabile PATTERN nel codice.

Passaggio 4: crea il tuo disegno personalizzato

Comprendi perché il PWM è così lento
Comprendi perché il PWM è così lento

Se desideri creare il tuo disegno, puoi incollare le coordinate dei punti nello schizzo Arduino sulla linea che definisce USER_PATTERN.

Ho scoperto che Inkscape è uno strumento abbastanza buono per creare un disegno personalizzato:

  1. Crea testo utilizzando un carattere grande e in grassetto come Impact.
  2. Seleziona l'oggetto di testo e seleziona "Oggetto su tracciato" dal menu "Percorso".
  3. Seleziona le singole lettere e sovrapponile per creare una forma connessa
  4. Seleziona "Union" dal menu "Path" per combinarli in un'unica curva.
  5. Se ci sono buchi in qualche lettera, taglia una piccola tacca disegnando un rettangolo con lo strumento rettangolo e sottrailo dal contorno usando lo strumento "Differenza".
  6. Fare doppio clic sul percorso per visualizzare i nodi.
  7. Rettangolo seleziona tutti i nodi e fai clic sullo strumento "Crea angolo nodi selezionati".
  8. Salva il file SVG.

L'importante è che il tuo disegno abbia un unico percorso chiuso e senza buchi. Assicurati che il tuo design abbia meno di 130 punti circa.

Passaggio 5: incolla le coordinate dal file SVG nell'IDE di Arduino

  1. Apri il file SVG e copia le coordinate. Questi saranno incorporati nell'elemento "percorso". La prima coppia di coordinate può essere ignorata; sostituirli con 0, 0.
  2. Incolla le coordinate nello schizzo Arduino all'interno delle parentesi subito dopo "#define USER_PATTERN".
  3. Sostituisci tutti gli spazi con virgole, altrimenti otterrai un errore di compilazione. Lo strumento "Sostituisci e trova" può essere utile.
  4. Compila ed esegui!
  5. Se hai problemi, controlla la console seriale per eventuali errori. In particolare, vedrai messaggi se il tuo pattern ha troppi punti per il buffer interno. In tali casi, l'immagine presenterà uno sfarfallio eccessivo.

Passaggio 6: capire perché il PWM è così lento

Per iniziare, esaminiamo il comportamento di un condensatore durante la carica.

Un condensatore collegato a una sorgente di tensione Vcc aumenterà la sua tensione secondo una curva esponenziale. Questa curva è asintotica, il che significa che rallenterà quando si avvicina alla tensione target. Per tutti gli scopi pratici, la tensione è "abbastanza vicina" dopo 5 secondi RC. Il RC è chiamato la "costante di tempo". Come abbiamo visto in precedenza, è il prodotto dei valori del resistore e del condensatore nel circuito. Il problema è che 5 RC è un tempo piuttosto lungo per aggiornare ogni punto in un display grafico. Questo porta a un sacco di sfarfallio!

Quando usiamo la modulazione a larghezza di impulso (PWM) per caricare un condensatore, non stiamo meglio. Con PWM la tensione cambia rapidamente tra 0V e 5V. In pratica, questo significa che si alternano rapidamente tra la spinta della carica nel condensatore e l'estrazione di un po' di essa di nuovo -- questo push and pull è un po' come provare a correre una maratona facendo un grande passo avanti e poi un piccolo passo indietro ancora e ancora.

Quando fai la media di tutto, il comportamento di caricare un condensatore usando PWM è esattamente lo stesso di se avessi usato una tensione costante di Vpwm per caricare il condensatore. Ci vogliono ancora circa 5 secondi RC per arrivare "abbastanza vicino" alla tensione desiderata.

Passaggio 7: ottenere da a a B, un po' più velocemente

Passa da a a B, un tantino più veloce
Passa da a a B, un tantino più veloce

Supponiamo di avere un condensatore già carico fino a Va. Supponiamo di utilizzare analogWrite() per scrivere il nuovo valore di b. Qual è il tempo minimo di attesa per il raggiungimento della tensione Vb?

Se hai indovinato 5 secondi RC, è fantastico! Aspettando 5 secondi RC, il condensatore verrà caricato molto vicino a Vb. Ma se vogliamo, possiamo effettivamente aspettare un po' meno.

Guarda la curva di carica. Vedete, il condensatore era già a Va quando abbiamo iniziato. Ciò significa che non dobbiamo aspettare il tempo t_a. Dovremmo farlo solo se stessimo caricando il condensatore da zero.

Quindi, non aspettando quel momento, vediamo un miglioramento. Il tempo t_ab è in realtà un po' più breve di 5 RC.

Ma aspetta, possiamo fare molto meglio! Guarda tutto quello spazio sopra v_b. Questa è la differenza tra Vcc, la massima tensione a nostra disposizione, e la Vb che intendiamo raggiungere. Riesci a vedere come quella tensione extra può aiutarci ad arrivare dove vogliamo andare molto più velocemente?

Passaggio 8: passa da a a B, con un caricabatterie turbo

Passa da a a B, con un turbocompressore!
Passa da a a B, con un turbocompressore!

Giusto. Invece di utilizzare il PWM alla tensione target V_b, lo manteniamo a un Vcc costante per un periodo di tempo molto, molto più breve. Lo chiamo il metodo Turbo Charger e ci porta dove vogliamo andare molto, molto velocemente! Dopo il tempo di ritardo (che dobbiamo calcolare), tiriamo i freni passando a PWM a V_b. Ciò impedisce alla tensione di superare il bersaglio.

Con questo metodo è possibile modificare la tensione nel condensatore da V_a a V_b in una frazione del tempo rispetto all'utilizzo del solo PWM. Ecco come ottieni posti, piccola!

Passaggio 9: comprendere il codice

Comprendi il codice
Comprendi il codice

Un'immagine vale più di mille parole, quindi il diagramma mostra i dati e le operazioni che vengono eseguite nel codice. Da sinistra a destra:

  • I dati grafici vengono memorizzati in PROGMEM (ovvero, memoria flash) come elenco di punti.
  • Qualsiasi combinazione di operazioni di traslazione, ridimensionamento e rotazione viene combinata in una matrice di trasformazione affine. Questo viene fatto una volta all'inizio di ogni fotogramma di animazione.
  • I punti vengono letti uno per uno dai dati grafici e vengono moltiplicati ciascuno per la matrice di trasformazione memorizzata.
  • I punti trasformati vengono alimentati tramite un algoritmo a forbice che ritaglia tutti i punti al di fuori dell'area visibile.
  • Utilizzando una tabella di ricerca del ritardo RC, i punti vengono convertiti in tensioni di pilotaggio e ritardi. La tabella di ricerca del ritardo RC è memorizzata in EEPROM e può essere riutilizzata per più esecuzioni del codice. All'avvio, la tabella di ricerca RC viene controllata per verificarne l'accuratezza e gli eventuali valori errati vengono aggiornati. L'uso di EEPROM consente di risparmiare preziosa memoria RAM.
  • Le tensioni di pilotaggio e i ritardi vengono scritti nel frame inattivo nel frame buffer. Il frame buffer contiene spazio per un frame attivo e un frame inattivo. Una volta scritto un frame completo, il frame inattivo viene reso attivo.
  • Una routine di servizio di interrupt ridisegna continuamente l'immagine leggendo i valori di tensione e i ritardi dal frame buffer attivo. Sulla base di questi valori, regola i cicli di lavoro dei pin di uscita. Il timer 1 viene utilizzato per misurare il ritardo temporale fino a pochi nanosecondi di precisione, mentre il timer 2 viene utilizzato per controllare il ciclo di lavoro dei pin.
  • Il pin con la maggiore variazione di tensione è sempre "caricato da turbo" con un ciclo di lavoro pari a zero o 100%, fornendo il tempo di carica o scarica più rapido. Il pin con una variazione di tensione minore viene pilotato con un ciclo di lavoro scelto in modo da corrispondere al tempo di transizione del primo pin: questa volta l'adattamento è importante per garantire che le linee vengano tracciate direttamente sull'oscilloscopio.

Passaggio 10: da una grande velocità derivano grandi responsabilità

Poiché questo metodo è molto più veloce di PWM, perché analogWrite() non lo usa? Bene, perché usare solo PWM è abbastanza buono per la maggior parte dei programmi ed è molto più indulgente. Il metodo "Turbo Charger", invece, richiede un'attenta codifica ed è adatto solo a casi specifici:

  1. È estremamente sensibile ai tempi. Una volta raggiunto il livello di tensione target, il pin di guida deve essere immediatamente commutato in modalità PWM normale per evitare il superamento della tensione target.
  2. Richiede la conoscenza della costante RC, quindi questi valori devono essere inseriti in anticipo. Con valori errati, la temporizzazione sarà errata e le tensioni saranno errate. Con il normale PWM, c'è la garanzia che ti sistemerai sulla tensione corretta dopo un po' di tempo, anche se la costante RC non è nota.
  3. Il calcolo dell'intervallo di tempo preciso per caricare il condensatore richiede equazioni logaritmiche che sono troppo lente per il calcolo in tempo reale su Arduino. Questi devono essere pre-calcolati prima di ogni fotogramma di animazione e memorizzati nella cache da qualche parte.
  4. I programmi che si occupano di questo metodo devono fare i conti con il fatto che i ritardi sono molto non lineari (sono, infatti, esponenziali). Le tensioni target vicino a Vcc o GND impiegheranno molti ordini di grandezza in più per raggiungere le tensioni vicino al punto medio.

Per superare queste limitazioni, il mio codice di grafica vettoriale fa le seguenti cose:

  1. Utilizza il timer 1 a 16kHz e una routine di servizio di interruzione per una precisa manipolazione e tempistica dell'output.
  2. Richiede l'utilizzo di un valore specifico della costante di tempo RC, limitando le scelte dei valori di condensatore e resistore.
  3. Memorizza i ritardi temporali per tutti i punti in un frame di animazione in un buffer di memoria. Ciò significa che la routine che calcola i ritardi viene eseguita a una velocità molto più lenta rispetto alla routine del servizio di interrupt che aggiorna i pin di uscita. Un dato frame potrebbe essere dipinto diverse dozzine di volte prima che un nuovo set di ritardi per il frame successivo sia pronto per essere utilizzato.
  4. L'uso di un buffer di memoria pone un vincolo sul numero di punti che possono essere disegnati per frame. Utilizzo una codifica efficiente in termini di spazio per ottenere il massimo dalla RAM disponibile, ma è ancora limitata a circa 150 punti. Oltre un centinaio di punti o giù di lì, il display inizierà comunque a lampeggiare, quindi è un punto controverso!

Consigliato: