Sommario:

Attiny85 Programmazione simultanea o zucca con occhi multicolori: 7 passaggi
Attiny85 Programmazione simultanea o zucca con occhi multicolori: 7 passaggi

Video: Attiny85 Programmazione simultanea o zucca con occhi multicolori: 7 passaggi

Video: Attiny85 Programmazione simultanea o zucca con occhi multicolori: 7 passaggi
Video: Programmare un Attiny85 con l'IDE di Arduino - #129 2024, Novembre
Anonim

Di jumbleviewJumbleview.infoSegui di più dell'autore:

L'urlo
L'urlo
L'urlo
L'urlo
Sostituzione della batteria NiCd con alimentatore esterno
Sostituzione della batteria NiCd con alimentatore esterno
Sostituzione della batteria NiCd con alimentatore esterno
Sostituzione della batteria NiCd con alimentatore esterno
Impugnatura per fotocamera digitale
Impugnatura per fotocamera digitale
Impugnatura per fotocamera digitale
Impugnatura per fotocamera digitale

Informazioni: lavoro come ingegnere del software in una delle società della Bay Area (California). Ogni volta che ho tempo, mi piace programmare microcontrollori, costruire giocattoli meccanici e realizzare alcuni progetti di miglioramento della casa. Maggiori informazioni su jumbleview »

Questo progetto mostra come controllare due LED ad anodo comune a tre colori da 10 mm (occhi multicolori di Pumpkin Halloween Glitter) con chip Attiny85. L'obiettivo del progetto è introdurre il lettore nell'arte della programmazione concorrente e nell'uso della libreria di protothread di Adam Dunkels. Questo progetto presuppone che il lettore conosca i controller AVR a 8 bit, possa scrivere alcuni programmi C e abbia una certa esperienza con Atmel Studio.

Codice del progetto pubblicato su GitHub:

Forniture

Prima di programmare è ancora necessario costruire il circuito. Ecco i componenti:

  • Titolare Attiny85 (qualsiasi fornitore elettronico).
  • Due LED 10mm tricolore con anodo comune. LED Adafruit
  • Resistori 100 Ohm, 120 Ohm, 150 Ohm 0,125 o 0,250 Wt (qualsiasi fornitore di elettronica).
  • Intestazione a sei pin per l'interfaccia AVR ISP. Può essere ricavato da questa intestazione Adafruit
  • Alcuni breadboard o modelli stampati. Ho usato questo
  • Interfaccia AVR ISP MKII e Atmel Studio 6.1 (anche la versione successiva dovrebbe funzionare).

Passaggio 1: circuito

Circuito
Circuito

Il design utilizza cinque pin del chip:

  • Due pin utilizzati per controllare gli anodi: ciascun anodo LED è collegato al pin dedicato.
  • Tre pin collegati (tramite resistori) ai catodi dei LED (lo stesso colore del catodo di ciascun led collegato allo stesso pin)

Verrebbe da chiedersi: perché non utilizzare tutti e sei i pin in/out del chip in modo che gli anodi dei LED siano collegati direttamente a +5 v e ogni catodo abbia il suo pin dedicato? Ciò renderà la programmazione semplice. Ahimè, c'è il problema: il pin PB5 (RESET) è un pin debole in grado di fornire solo ~2 mA di corrente, mentre è necessario avere ~20 mA.

Ovviamente si può costruire un amplificatore a transistor per questo pin debole, ma io stesso quando possibile preferisco risolvere il problema tramite il codice.

Passaggio 2: diagramma temporale

Diagramma dei tempi
Diagramma dei tempi

Il diagramma temporale ci aiuta a capire cosa dobbiamo programmare.

Le prime due righe del diagramma mostrano la variazione di tensione sugli anodi dei LED. La tensione sui pin collegati agli anodi LED oscilla con frequenza ~ 250 Hz. Questa oscillazione di tensione per il LED sinistro è opposta all'oscillazione del LED destro. Quando la tensione sull'anodo è alta, il LED corrispondente può essere luminoso. Quando è basso, il LED corrispondente è spento. Ciò significa che ogni LED può essere luminoso per un intervallo di 2 millisecondi e scuro per altri 2 millisecondi. Poiché l'occhio umano ha una certa inerzia, il lampeggiamento di 250 Hz non è percepibile dall'osservatore. Le tre righe inferiori del diagramma mostrano il cambiamento di tensione sui pin collegati ai catodi dei LED. Esaminiamo la prima colonna del diagramma. Mostra il caso in cui il LED sinistro è di colore rosso e il LED destro è di colore verde. Qui i catodi ROSSI rimangono bassi mentre l'anodo sinistro è alto, il catodo VERDE rimane basso mentre l'anodo destro è alto e il catodo BLU rimane basso tutto il tempo. Altre colonne del diagramma mostrano combinazioni di tensione catodica e anodica per vari colori.

Come possiamo vedere c'è interdipendenza sullo stato dei pin. Senza un quadro non sarebbe facile risolverlo. Ed è qui che la libreria protothread torna utile.

Passaggio 3: programmazione. Macro e definizioni

Programmazione. Macro e definizioni
Programmazione. Macro e definizioni

Esempio nelle fasi di programmazione rappresentano una versione leggermente semplificata. Il programma viene abbreviato e alcune definizioni simboliche vengono sostituite con costanti esplicite.

Cominciamo dall'inizio. Il programma include i file forniti con Atmel Studio e l'intestazione della libreria protothread. Poi ci sono due macro per manipolare i livelli dei pin e alcune definizioni per dare nomi logici ai segnali dei pin. Finora niente di speciale.

Passaggio 4: programmazione. Ciclo principale

Programmazione. Ciclo principale
Programmazione. Ciclo principale

Quindi guardiamo alla fine per vedere cosa contiene la procedura principale.

La funzione principale dopo aver eseguito un'inizializzazione rimane in loop per sempre. In quel ciclo esegue i passaggi successivi:

  • Richiama la routine protothread per il LED sinistro. Cambia la tensione di alcuni pin.
  • Fai un ritardo di due millisecondi. Non c'è alcun cambiamento nella tensione dei pin.
  • Richiama il protothread per il LED destro. Cambia un po' di tensione del pin.
  • Fai 2 MS di ritardo. Non c'è alcun cambiamento nella tensione dei pin.

Passaggio 5: programmazione. Funzioni ausiliarie

Programmazione. Funzioni ausiliarie
Programmazione. Funzioni ausiliarie

Prima di iniziare a discutere i protothread, dobbiamo esaminare alcune funzioni di supporto. Innanzitutto ci sono funzioni per impostare un colore particolare. Sono semplici. Esistono tante funzioni quanti sono i colori supportati (sette) e un'altra funzione per impostare il LED scuro (NoColor).

E c'è un'altra funzione che verrà invocata direttamente dalla routine protothread. Il suo nome è DoAndCountdown().

Tecnicamente parlando, l'utilizzo di tale funzione non è obbligatorio, ma l'ho trovato conveniente. Ha tre argomenti:

  • Puntatore alla funzione di impostazione del colore del LED (come RedColor o GreenColor o ecc.)
  • Valore iniziale del contatore inverso: numero di quante volte questa funzione deve essere invocata in una particolare fase del protothread.
  • Puntatore per invertire il contatore. Si presume che quando c'è un cambiamento nel colore che il contatore inverso sia 0, quindi alla prima iterazione il codice assegnerà a quel contatore il valore iniziale. Dopo ogni iterazione il contatore viene decrementato.

La funzione DoAndCountdown() restituisce il valore del contatore inverso.

Passaggio 6: programmazione. Routine Protothread

Programmazione. Routine Protothread
Programmazione. Routine Protothread

Ed ecco il nucleo del framework: routine protothread. Per semplicità esempio limitato solo a tre passaggi: per il cambio di colore in ROSSO, in VERDE e in BLU.

La funzione viene invocata con due argomenti:

  • Puntatore alla struttura protothread. Quella struttura è stata inizializzata da main prima dell'avvio del ciclo principale.
  • Puntatore per invertire il contatore. È stato impostato a 0 da main prima dell'inizio del ciclo principale.

La funzione imposta le tensioni per rendere attivo il LED sinistro e quindi avvia il segmento protothread. Questo segmento si trova tra le macro PT_BEGIN e PT_END. All'interno ci sono del codice che nel nostro caso ripete solo le macro PT_WAIT_UNTIL. Questa macro esegue successivamente:

  • Invocazione della funzione DoAndCountdown. Ciò imposta la tensione sui catodi dei LED per emettere un colore particolare.
  • Risultato restituito rispetto a 0. Se la condizione è 'false', la funzione protothread ritorna immediatamente e fornisce il controllo al ciclo principale.
  • Quando protothread viene invocato la volta successiva, esegue di nuovo il codice prima di PT_BEGIN, quindi salta direttamente all'interno delle macro PT_WAIT_UNTIL da cui è tornato l'ultima volta.
  • Tali azioni vengono ripetute fino a quando il risultato di DoAndCountdown è 0. In tal caso non c'è ritorno, il programma rimane nel protothread ed esegue la riga successiva del codice. Nel nostro caso è il prossimo PT_WAIT_UNTIL ma in generale potrebbe essere quasi qualsiasi codice C.
  • All'esecuzione iniziale del secondo PT_WAIT_UNTIL il contatore inverso è 0, quindi la procedura DoAndCountdown() lo imposta al valore iniziale. Le seconde macro verranno nuovamente eseguite 250 volte fino a quando il contatore di inversione non raggiunge lo 0.
  • Lo stato della struttura pt viene ripristinato non appena il controllo raggiunge le macro PT_END. Quando la funzione protothread viene invocata la prossima volta che il segmento protothread inizia, esegui la riga del codice subito dopo PT_BEGIN.

Esiste una routine di protothread simile per il LED destro. Nel nostro esempio impone semplicemente un diverso ordine di colori, ma se possiamo farlo in modo completamente diverso: non c'è un accoppiamento stretto tra la routine LED sinistra e destra.

Passaggio 7: interni

Interni
Interni

L'intero programma è inferiore a 200 righe di codice (con commenti e righe vuote) e occupa meno del 20% della memoria del codice Attiny85. Se necessario, è possibile utilizzare qui molte altre routine di protothread e assegnare loro una logica molto più complicata.

La libreria Protothreads è la forma più semplice di programmazione simultanea per computer. La programmazione concorrente è un approccio che consente di dividere il programma in parti logiche: a volte vengono chiamate coroutine, a volte thread, a volte task. Il principio è che ciascuna di queste attività può condividere la stessa potenza del processore mantenendo il codice più o meno lineare e indipendente dalle altre parti. Le attività dal punto di vista logico possono essere eseguite contemporaneamente.

Per i controlli di sistemi avanzati di tali attività eseguite dal kernel del sistema operativo o dal runtime del linguaggio incorporato nell'eseguibile dal compilatore. Ma in caso di protothread, il programmatore dell'applicazione lo controlla manualmente utilizzando la libreria di macro protothread nelle routine delle attività e invocando tali routine (di solito fuori dal ciclo principale).

Probabilmente vuoi sapere come funziona effettivamente il protothread? Dove si nasconde la magia? I protothread si basano su una caratteristica speciale del linguaggio C: il fatto che l'istruzione C switch case possa essere incorporata in if o in qualche altro blocco (come while o for). Dettagli che puoi trovare sul sito di Adam Dunkels

Gli interni elettronici di questo progetto sono molto semplici. La foto sopra ti dà qualche indizio. Sono sicuro che puoi fare di meglio.

Consigliato: