La scorsa settimana, ho costruito un cubo LED Come creare un cubo LED Arduino pulsante che sembra uscito dal futuro Come creare un cubo LED Arduino pulsante che sembra uscito dal futuro Se vi siete divertiti con alcuni progetti Arduino per principianti, ma sono alla ricerca di qualcosa di un po 'permanente e di un altro livello di eccezionale, quindi l'umile cubo 4 x 4 x LED è ... Per saperne di più - 64 LED che puoi programmare per creare fantastici spettacoli di luci futuristiche - e io spero anche tu, perché è un grande progetto per motivarti ed espandere il tuo skillset Arduino. Ti ho lasciato con alcune app di base per farti pensare, ma oggi presenterò alcuni altri bit di software che ho realizzato per il cubo, insieme a spiegazioni sul codice. Lo scopo di questo è sia di darti un po 'di spie luminose da eseguire, ma anche di conoscere alcuni dei limiti della programmazione del cubo e di imparare alcuni nuovi concetti di programmazione nel processo.
Questa è una codifica piuttosto avanzata; hai davvero bisogno di aver letto tutti i miei precedenti tutorial di Arduino e la nostra guida Arduino per principianti prima di personalizzare il codice fornito.
App 1: Mini Snake
Piuttosto che eseguire una sequenza di sequenza simile a un serpente, volevo programmare un serpente, un artificio che avrebbe reso le sue scelte casuali ed essere completamente imprevedibile. È limitato a solo 2 segmenti, che spiegherò più avanti, e puoi vedere la demo qui sotto. Scarica il codice completo qui.
Quando si ha a che fare con lo spazio 3D, sono necessarie 3 coordinate per un singolo punto: X, Y e Z.
Tuttavia, nel nostro cubo, i piani X e Z sono rappresentati da pin LED, mentre Y è direttamente mappato ai piani catodici. Per facilitare il lavoro con queste coordinate e capire il movimento attorno al cubo, ho quindi creato un nuovo tipo di dati (usando struct) per rappresentare un singolo punto sul cubo - che ho chiamato "xyz". Consiste di due soli numeri interi: "xz" e "y". Con questa struttura, potrei quindi rappresentare anche una direzione, indicata di seguito nel nostro sistema di coordinate speciali (xz, y):
Movimento Y (su, giù) : (xz, y + 1), (xz, y-1)
Movimento Z (avanti, indietro) : (xz-1, y), (xz + 1, y)
Movimento X (sinistra, destra) : (xz + 4, y), (xz-4, y)
Ad esempio, per spostare il LED in posizione (0, 0) da una a sinistra, applichiamo (xz + 4, y) e finiamo con (0, 4) .
Ci sono alcuni limiti che possono essere posti sul movimento - vale a dire che le coordinate Y possono essere solo possibili da 0 a 3 (0 è lo strato inferiore, 3 è superiore) e le coordinate XZ possono essere solo da 0 a 15 . Un ulteriore limite è posto sul movimento Z per evitare di "saltare" dalla parte posteriore verso la parte anteriore del cubo e viceversa. In questo caso, usiamo la funzione modulo per testare multipli di 4 e negare il tentativo di movimento. Questa è la logica rappresentata nella funzione valid (), che restituisce un valore true se la direzione proposta è una mossa accettabile e false altrimenti. Ho aggiunto un'ulteriore funzione per verificare una direzione inversa, ovvero se il serpente si sta dirigendo in una direzione, non vogliamo che vada all'indietro su se stesso, anche se è altrimenti una posizione valida in cui spostarsi - e un funzione move (), che prende una coordinata, una direzione e restituisce la nuova coordinata.
Le funzioni di tipo XYZ, valid (), move () e inverse () possono essere trovate nel file xyz.h nei download. Se ti stai chiedendo perché questo è stato messo in un file separato invece del file del programma principale, è a causa di alcune complicate regole del compilatore Arduino che impediscono alle funzioni di restituire i tipi di dati personalizzati ; devono essere collocati nel loro file, quindi importati all'inizio del file principale.
Di nuovo nel file di runtime principale, una serie di direzioni memorizza tutti i possibili movimenti che il serpente può compiere; possiamo semplicemente scegliere un membro dell'array casuale per ottenere una nuova direzione. Le variabili vengono anche create per memorizzare la posizione corrente (ora), la direzione precedente e la posizione precedente. Il resto del codice dovrebbe essere abbastanza ovvio per te; solo per creare loop e accendere e spegnere i LED. Nel ciclo principale, controlliamo se la direzione proposta è valida, e se è così andiamo in quel modo. In caso contrario, selezioniamo una nuova direzione.
L'unica cosa da sottolineare nel ciclo principale è alcuni controlli per correggere un bug che ho riscontrato nel multiplexing: se la nuova posizione si trovava sullo stesso piano catodico o sullo stesso pin dell'anodo, la disattivazione del LED precedente avrebbe comportato l'uscita di entrambi. È anche a questo punto che ho realizzato che andare oltre un serpente a 2 segmenti sarebbe stato impossibile con la mia attuale implementazione: provare ad accendere 3 LED in una disposizione ad angolo. Non è possibile, perché con i piedini 2 e 2 LED attivati, si accendono 4 LED, non 3. Questo è un problema inerente al nostro design cubo multiplex limitato, ma non preoccuparsi: abbiamo semplicemente bisogno di usare il potere della persistenza di visione per riscrivere il metodo di disegno.
Persistenza della visione significa che quando la luce raggiunge i nostri occhi in sequenza - più velocemente di quanto possiamo elaborarla - sembra essere una singola immagine. Nel nostro caso, invece di disegnare tutti e quattro i layer contemporaneamente, dovremmo disegnare il primo, disattivarlo, disegnare il secondo e disattivarlo: più velocemente di quanto possiamo dire ogni cambiamento sta accadendo. Questo è il principio su cui funzionano gli scrittori di messaggi, come questo:
Nuovo metodo di disegno con Persistenza della visione
Prima di tutto, una nuova routine di sorteggio. Ho creato una matrice bidimensionale di bit 4 x 16 (true o false) per essere una rappresentazione letterale dello stato del cubo LED. La routine di sorteggio implementerà la persistenza della visione semplicemente iterando su questo e scaricando ogni strato nel cubo per un breve momento. Continuerà a disegnarsi nello stato corrente fino a quando è trascorso il tempo di aggiornamento, a quel punto passeremo il controllo al ciclo principale (). Ho salvato questa sezione del codice in questo file LED_cube_POV, quindi se vuoi semplicemente saltare nella programmazione dei tuoi giochi e simili, allora sentiti libero di usarlo come base.
App 2: Game of Life
Per ora, sviluppiamo questo in una versione base di Conway's Game Of Life. Per quelli di voi che non hanno familiarità (provate a cercarlo su Google per trovare un'animazione di uova di Pasqua fantastica), il Game of Life è un esempio di automi cellulari che crea un affascinante schema di comportamento emergente dato solo da alcune semplici regole.
http://www.youtube.com/watch?v=XcuBvj0pw-E
Questo è, ad esempio, il modo in cui le formiche sembrano muoversi con intelligenza e una mente alveare, nonostante il fatto biologico che esse effettivamente seguono solo le regole ormonali basilari. Ecco il codice completo per il download: premi il pulsante di ripristino per riavviare. Se ti ritrovi a ottenere lo stesso modello più e più volte, prova a tenere premuto il pulsante di riposo più a lungo.
http://www.youtube.com/watch?v=iBnL8pulJ
Ecco le regole del gioco della vita:
- Ogni cellula vivente con meno di due vicini di casa muore, come se fosse causata da sottopopolazioni.
- Qualsiasi cellula vivente con due o tre vicini di casa vive fino alla prossima generazione.
- Ogni cellula vivente con più di tre vicini di casa muore, come per sovraffollamento.
- Qualsiasi cellula morta con esattamente tre vicini di casa diventa una cellula viva, come se fosse riprodotta.
Esegui il codice. Noterai che entro 5-10 "generazioni" gli automi si sono probabilmente fermati, stabilizzandosi su una certa posizione; a volte questo modello stabile cambierà posizione e cambierà direzione. In rari casi, potrebbero persino essersi completamente estinti. Questa è una limitazione di avere solo LED 4x4x4 con cui lavorare, ma è comunque un buon esercizio di apprendimento.
Per spiegare il codice:
- Potrebbe non essere familiare con la funzione memcpy () . L'ho usato per salvare lo stato precedente del gioco, poiché gli array non possono essere assegnati l'uno all'altra come normali variabili: è necessario copiare effettivamente attraverso lo spazio di memoria (in questo caso, 64 bit).
- La funzione howManyNeighbours () dovrebbe essere auto esplicativa, ma nel caso non lo fosse - questo metodo prende una singola coordinata e scorre attraverso ogni possibile vicino (la stessa serie di direzioni precedentemente utilizzate nell'app snake), per verificare se sono valide . Quindi controlla se quei LED vicini erano "accesi" nello stato di gioco precedente e conta quanti ce ne sono.
- La funzione principale di questa app Game of Life è progressGame (), che applica le regole degli automi allo stato attuale del gioco.
Miglioramenti : ho speso molto tempo su questo fino ad ora, ma potresti provare ad aggiungere un controllo che ripristina automaticamente la scheda dopo circa 5 generazioni dello stesso modello. quindi per favore fatemelo sapere! Suggerirei anche di provare ad aggiungere la metodologia POV al gioco snake per rendere possibilmente possibile un serpente più lungo.
Questo è tutto per me oggi. Potrei rivedere altre app cubo Arduino LED in un secondo momento, ma spero che dovresti essere in grado di modificare il mio codice e creare le tue regole di gioco: facci sapere cosa ti viene in mente nei commenti, quindi possiamo scaricare tutti le tue creazioni! Come sempre, sarò qui per rispondere alle tue domande e difendere le mie orrende capacità di codifica.
Immagine di credito: coordinate cartesiane - utente Wikimedia Sakurambo