Arduino persistance de Vision afficher

une persistance de l’affichage de la vision (PoV) est une ligne de LED qui clignotent sur les colonnes d’un message.  Lorsque la matrice de LED est déplacée, comme lorsqu’il est monté sur une roue de bicyclette, le message peut être lu comme si c’était l’échelle de plusieurs LED, au lieu d’une seule ligne.

La configuration matérielle pour un affichage de PoV est assez simple, mais cette instructable contient le code qui définit l’affichage peut être commandé et programmé facilement via la connexion série, paramètres d’affichage peuvent être enregistrés afin qu’ils sont automatiquement chargés et exécutés lorsque mis sous tension d’une batterie.

Vous voulez un Conseil de Microcontrôleur AVR Arduino, comme Uno, Nano ou mini.  Environ 10 LEDs et 10 résistances d’environ 100 à 220 ohms.

Pour notre exemple, nous supposerons un écran LED 10.  Fil de la LED en série avec une résistance aux broches d’e/s numériques 3-10 et les disposer dans une ligne droite.

Charger le croquis ci-joint.

À partir de la série monitor (ou l’émulateur de terminal), tapez h pour obtenir le menu aide.  Cela montrera plusieurs commandes.

Ma classe de lecteur série compresse les espaces blancs, ainsi vous voudrez utiliser. pour représenter « off » dans les paramètres de la ligne.  Voir le Quelab.dat exemple ligne paramètre d’entrée fichier joint.  Les lignes de ce fichier peuvent être coupés et collés dans un émulateur de terminal pour définir le message de PoV.

Une fois votre affichage souhaité a été chargé, utilisez le s) commande pour enregistrer ses paramètres d’EEPROM pour être utilisé à la prochaine remise à zéro.

 int dummy=0; // this is to force sketch to put arduino include here #define MODE_UNKNOWN 0 #define MODE_PoV 1 #define MODE_RANDOM 2 #define MODE_CYLON 3 #define MAX_COLS 96 #define SERIAL_BUF_LEN (MAX_COLS+15) #include SerialLineBuffer LineBuf; struct { short nCols; // no. columns in buffer short spaceCols; // no. columns "space" time before repeat or reverse short mode; // MODE_ code from above short cylonCols; // no. cols of time for each cylon flash int colTime; // milliseconds/column int misc[3]; // reserved for future use short disp[MAX_COLS]; // display flags } State; // These are the DI/O pins used for the display #define NPINS 10 int ledPins[NPINS] = {12,11,10,9,8,7,6,5,4,3}; #include void loadState() { int n = sizeof(State); byte *bp = (byte *)(&State); for(int i=0; i < n; i++, bp++) *bp = EEPROM.read(i); if (!validState()) initState(); } void saveState() { int n = sizeof(State); byte *bp = (byte *)(&State); for(int i=0; i < n; i++, bp++) EEPROM.write(i,*bp); } // set state to a reasonable default void initState() { State.nCols = 2; State.spaceCols = 1; State.cylonCols = 10; State.mode = MODE_PoV; State.colTime = 10; // ms for (int i=0; i < MAX_COLS; i++) State.disp[i] = (i&1)?0x5555:0x2aaa; saveState(); } void setup() { int i; for (i=0;i { pinMode(ledPins[i],OUTPUT); } pinMode(13,OUTPUT); // use on-board LED // restore state from EEPROM loadState(); Serial.begin(9600); } void loop() { checkCommand(); int i,dt,k; dt = State.colTime; switch (State.mode) { case MODE_CYLON: dt *= State.cylonCols; for (i=0; i < NPINS; i++) { digitalWrite(ledPins[i],HIGH); delay(dt); digitalWrite(ledPins[(i+NPINS-1)%NPINS],LOW); delay(dt); } for (i=NPINS-2; i >= 0; i--) { digitalWrite(ledPins[i],HIGH); delay(dt); digitalWrite(ledPins[(i+1)%NPINS],LOW); delay(dt); } break; case MODE_PoV: for (i=0; i < State.nCols; i++) { short mask=1; for (k=0; k < NPINS; k++, mask <<= 1) digitalWrite(ledPins[k],(mask & State.disp[i])?HIGH:LOW); } for (k=0; k < NPINS; k++) digitalWrite(ledPins[k],LOW); delay(State.spaceCols*dt); break; default: // random default { dt *= 10; k = random(100); int lvl = (k<50)?LOW:HIGH; int j = random(NPINS); digitalWrite(ledPins[j],lvl); delay(dt); } } digitalWrite(13,digitalRead(13)?LOW:HIGH); // toggle heartbeat } // poll for commands from serial port void checkCommand() { short mask; if (!LineBuf.isComplete()) return; char key = lowCase(*(LineBuf.get())); switch(key) { //short mask; //int k; //char *b; case 'h' : Serial.println(" h) help (print this message)"); Serial.println(" s) save state"); Serial.println(" r) random lights mode"); Serial.println(" c) cylon mode"); Serial.println(" p) PoV sign mode"); Serial.println(" n) no. cols to display"); Serial.println(" t) col time, ms"); Serial.println(" b) blank cols between repeat"); Serial.println(" i) re-Initialize state"); Serial.print( " Lx) Set pattern for line x, 0<=x<="); Serial.println(NPINS); break; case 's' : saveState(); break; case 'r' : State.mode = MODE_RANDOM; break; case 'p' : State.mode = MODE_PoV; break; case 'c' : State.mode = MODE_CYLON; break; case 'i' : initState(); break; case 'n' : State.nCols =nextInt(LineBuf.get()+1); break; case 't' : State.colTime =nextInt(LineBuf.get()+1); break; case 'b' : State.spaceCols=nextInt(LineBuf.get()+1); break; case 'l' : { char *b = LineBuf.get()+1; int k = ((int)(*b)) - ((int)'0'); if ((k<0) || (k > 15)) break; b++; short mask = (short)(1< for (int i=0; i < State.nCols; i++, b++) { if (isOn(*b)) State.disp[i] |= mask; else State.disp[i] &= ~mask; } break; } default : Serial.print("Unrecognized Command : <"); Serial.print(LineBuf.get()); Serial.println(">"); Serial.println("Send command h for help."); } printState(); printMsg(); } void printState() { Serial.print(State.nCols); Serial.print(" Columns "); Serial.print(State.spaceCols); Serial.print(" "); Serial.print(State.colTime); Serial.println("ms/col"); Serial.flush(); } void printMsg() { int i,k; Serial.println(); for (i=0; i < State.nCols; i++) Serial.print("-"); short mask=1; for(k=0; k < NPINS; k++, mask <= 1) { for (i=0; i < State.nCols; i++) Serial.print(State.disp[k]&mask?"X":" "); Serial.println("|"); } Serial.println(); for (i=0; i < State.nCols; i++) Serial.print("-"); Serial.println(); Serial.flush(); } // parse next int from a string int nextInt(const char *s) { const char *c = s; int val = 0; for(;;) { int k = ((int)(*c)) - ((int)'0'); if ((k<0)||(k>9)) return val; val *= 10; val += k; c++; } } bool isOn(const char c) { if ((c=='0') || (c=='.') || (c==' ') || (c==0)) return false; //if ((c=='1')||(lowCase(c)=='x')) return true; return true; } bool validState() { // check for silly state, set to default if inconsistent if ((State.mode <= 0) || (State.mode > 3) || (State.nCols< 1) || (State.nCols>MAX_COLS)) return false; if ((State.spaceCols < 1) || (State.spaceCols > 10*MAX_COLS)) return false; if ((State.colTime < 1) || (State.colTime > 10000)) return false; if ((State.cylonCols < 1) || (State.cylonCols > 10000)) return false; return true; } 

---ioUtil.h

 class SerialLineBufferPrivates; class SerialLineBuffer { public: SerialLineBuffer(); //~SerialLineBuffer(); bool isComplete(); // reads from serial, return true if 0 or EOLN void clear(); void begin(); int length() const; int maxLength() const; char *get(); // retrieve current buffer and clear char buf[SERIAL_BUF_LEN+1]; protected: int _maxLength, _len; bool _complete; private: //class SerialLineBufferPrivates *Priv; }; char lowCase(const char a); int caseCmp(const char a0, const char b0); char *extractKey(char *cmdStr, char **val); bool keyMatch(const char *key, const char *key1); 

---ioUtil.cpp

 #include #define NULL 0 // don't want to depend on ctype.h, just for this! bool isBlank(int c) { if(c == 7) return(false); // bell return( (c <= ' ') || (c > '~') ); } #if defined(ARDUINO) && ARDUINO >= 100 #include #warning ARDUINO #else #error ARDUINO not >= 100 #include #endif void SerialLineBuffer::begin() { _maxLength = SERIAL_BUF_LEN; // AVR dynamic mem is tricky _len = 0; _complete = false; } SerialLineBuffer::SerialLineBuffer() { begin(); } bool isTerminator(int c) { if (c == 0) return(true); if (c == ';') return(true); // sending \n to serial is tricky. accept this too. //if ((c=='\n') || (c=='\r') || (c=='\m')) return(true); if ((c>=10) && (c<=13)) return(true); // \r, \n, form feed, vert tab return(false); } /// read from serial, return true if 0 or EOLN bool SerialLineBuffer::isComplete() { if (_complete) return(true); // don't read more until this line is consumed // add characters from serial while(Serial.available() > 0) { int nextByte = Serial.read(); //Serial.print("Got ");Serial.println(nextByte); if ((nextByte < 0) || (nextByte >= 256)) return(_complete); if (isTerminator(nextByte)) { //Serial.print("terminator ");Serial.println(nextByte); buf[_len] = 0; _complete = (_len > 0); return(_complete); } if (isBlank(nextByte)) { //Serial.print("blank ");Serial.println(nextByte); if (_len > 0) // ignore leading whitespace { if (buf[_len-1] != ' ') // compact space to 1 space { buf[_len++] = ' '; // convert all space to ' ' } } } else { buf[_len++] = (char)nextByte; } // don't allow overflow if (_len >= _maxLength) { Serial.println("\nOverflow. truncating command string"); _complete = true; } } return(_complete); } void SerialLineBuffer::clear() { _len = 0; _complete = false; } int SerialLineBuffer::length() const { return(_len); } int SerialLineBuffer::maxLength() const { return(_maxLength); } /// retrieve current buffer and clear char *SerialLineBuffer::get() { buf[_len]=0; clear(); return(buf); } //----------------------------------------------------------- /// split a keyword-value pair string into a key string and value string const char nullChar = 0; // static is scary on AVR char *extractKey(char *cmdStr, char **val) { *val = (char *)&nullChar; if (cmdStr == NULL) return(NULL); char *key = cmdStr; while (*key) // process comments { if (*key == '#') *key=0; // comment else key++; } key = cmdStr; while(*key && isBlank(*key)) key++; // trim leading space *val = key; while(**val && !isBlank(**val)) *val += 1; // skip key **val = 0; *val += 1; while(**val && isBlank(**val)) *val += 1; // skip whitespace return(key); } char lowCase(const char a) { if ((a >= 'A') && (a <= 'Z')) { int sft = ((int)'a') - ((int)'A'); int b = (int)a + sft; return((char)b); } return(a); } int caseCmp(const char a0, const char b0) { char a = lowCase(a0); char b = lowCase(b0); if (a < b) return(-1); return((a>b)?1:0); } bool keyMatch(const char *key0, const char *key1) { //Serial.print("keyMatch(");Serial.print(key0);Serial.print(",");Serial.print(key1);Serial.print(")="); while(*key0 || *key1) { if (caseCmp(*key0, *key1)) { //Serial.println("false"); return(false); } if (*key0) key0++; if (*key1) key1++; } //Serial.println("true"); return(true); } 

---Exemple de données d’entrée

 L0..Q.............l......b.... L1.QQQ............l......b.... L2Q...Q...........l......b.... L3Q...Q.u..u..ee..l..a.a.b.b.. L4Q...Q.u..u.e..e.l.a.aa.bb.b. L5Q...Q.u..u.e..e.l.a..a.b..b. L6Q.Q.Q.u..u.eeee.l.a..a.b..b. L7Q..Q..u..u.e....l.a..a.b..b. L8.Q.Q..u..u.e..e.l.a.aa.bb.b. L9.QQ.Q..uu...ee..l..a.a.b.b.. 
Mots clés: Arduino, Affichage, Série, Pov

Articles Liés

Arduino TFT prévision Station météo avec ESP8266

Arduino TFT prévision Station météo avec ESP8266

Ce projet, s'appuie sur les prévisions météo Wunderground via Internet.Fiche technique :1. 3 jours météo (basse & haute temps, probablement des précipitations, icônes d'État)2. courant météo (température actuelle, %feelslike% temp, humidité, pression
Défilement d’UART serial Arduino afficher terminal en utilisant un TFT 2.2"

Défilement d’UART serial Arduino afficher terminal en utilisant un TFT 2.2"

J'ai fait des projets basés autour d'un écran TFT 2.2" qui utilise le pilote ILI9341, cet affichage peut être connecté à et contrôlé par un Arduino UNO. Comme un peu de fond, je vous entends peut trouver mon instructable ici utile.Lors du débogage d'
Cylindre POV avec Arduino Due

Cylindre POV avec Arduino Due

Le cylindre de POV affiche des images GIF animées sur un cylindre rotatif. Les images GIF peuvent être téléchargés à partir d'un PC via Bluetooth.IntroductionL'année dernière, j'ai décidé de commencer mon premier projet Arduino. Mon travail s'inspire
POV avec Arduino Nano

POV avec Arduino Nano

Bonjour à tousJ'ai été impressionné par deux articles sur Instructables.com Magic-POV-Wand-yet-another-POV-toy et persistance-de-Vision-Wand. Ils ont expliqué dans les moindres détails, pour construire un POV LED et surtout afficher un nom ou un mess
Uber domotique w / Arduino & Pi

Uber domotique w / Arduino & Pi

[MODIFIER] J'ai créé un forum pour collaborer sur le code de la porte d'entrée.http://homeautomation.Proboards.com/Board/2/openha...Il y a quelques années, je suis devenu propriétaire d'un chien pour la première fois. Je n'aimais pas laissant Cody da
Poisson Feeder Arduino Raspberry Pi lien

Poisson Feeder Arduino Raspberry Pi lien

« Quel une ennuyeuse boîte noire »Oui, c'est, mais :– Il nourrit de mon poisson quand je ne suis pas là.– Il se nourrit en un temps prédéfini.– Il détecte la nourriture donnée aux poissons– Vous pouvez vous connecter à distance dans le pi framboise p
Arduino personnalisé MIDI Controller

Arduino personnalisé MIDI Controller

Bonjour et Bienvenue à cette instructable sur comment construire un contrôleur MIDI USB personnalisé, bon marché et facile, basé sur Arduino. Les meilleures nouvelles : aucun souci avec interfaces USB-MIDI ou outils logiciels tels que MIDI sans poil,
L’Arduino Internet Gizmo

L’Arduino Internet Gizmo

The Arduino Internet Gizmo est un périphérique USB, Arduino et RFID pour surfer sur le web.  Le truc fonctionne en plaçant une balise RFID sur le dessus du gizmo.  Le gizmo lit le tag RFID et envoie le numéro de balise via le port USB à un programme
Comment connecter des Symbols de cristal liquide à Arduino

Comment connecter des Symbols de cristal liquide à Arduino

Vue d'ensembleDans ce tutoriel, vous allez apprendre à connecter un affichage à cristaux liquides (LCD) à un Arduino Uno et faire afficher des trucs. Affichages à cristaux liquides vous seront utiles si vous souhaitez afficher des informations sur un
Matrice de LED Arduino

Matrice de LED Arduino

Dans ce bref didacticiel, vous apprendrez comment faire une matrice de LED alimenté par Arduino. Contrairement à plusieurs autres modèles, celui-ci utilise un ordinateur « compagnon » pour informer l'Arduino qui LEDs doivent être alimentées.J'ai four
Arduino mur éviter robot

Arduino mur éviter robot

Cette instructable suppose que très peu en ce qui concerne les connaissances préalables.S'il y a les endroits que vous vous sentez pourraient être améliorées ou clarifié, s'il vous plaît n'hésitez pas à message ou commentaire et je mettrai à jour.Voi
3 axe Arduino accéléromètre / inclinomètre (Tilt / Roll / lacet)

3 axe Arduino accéléromètre / inclinomètre (Tilt / Roll / lacet)

de l'esprit à http://arduinotronics.blogspot.com/Ans, j'ai vu un gadget de tableau de bord soigné pour une Jeep qui avait deux photos d'une Jeep sur l'appareil. Comme vous avez conduit, les deux images seraient déplacer, affichage inclinaison et roul
Faire un moniteur de qualité de P2, 5/air avec Arduino UNO

Faire un moniteur de qualité de P2, 5/air avec Arduino UNO

Faire une PM2, 5 à surveiller avec Arduino UNOConseil d'utilisation unoR3 de l'Arduino et un tube de 4 numérique compatible arduino pour recueillir et afficher la valeur de P2, 5.capteur de P2, 5 d'un laser SDS011 (www.inovafitness.com) est utilisé p
Évitement Robot Arduino

Évitement Robot Arduino

Dans le marché du robot, il y a beaucoup de kit robot intelligent d'évitement à vendre, mais je n'aime pas acheter kit fini, pour développer des vieux jouets de voiture rc dans boîte de rangement est défi plus. Construire un robot d'évitement à l'aid