Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Mini LED-matrixklok

Componenten en benodigdheden

Arduino Nano R3
× 1
Maxim Integrated DS3231M - ±5ppm, I2C real-time klok
× 1
Drukknop, tijdelijk
× 2
Led-matrixmodule 32x8
× 1

Benodigde gereedschappen en machines

Soldeerbout (algemeen)

Apps en online services

Arduino IDE

Over dit project

Op de pagina "Nick's LED Projects" vond ik een klokproject dat de tijd weergeeft op 4 matrixen met 8x8 leds. Hij bouwde de klok met matrijzen van de "ICStation"-winkel die DIY-kits voor matrixmodulepanelen verkoopt.

Met een minimale verandering in de code, heb ik mijn klok gemaakt met MAX7219 dot matrix module icrocontroller vier-in-één Display die volledig is opgevouwen en veel goedkoper is. Ik heb het gekocht bij AliExpress.

De klok heeft veel functies:

- Basismodus met grote cijfers

- Schuifmodus waarbij cijfers op en van het scherm rollen

- Kleine cijfers met secondenmodus

- Tijd geschreven in woorden, b.v. "tien over twaalf"

- Datumweergave

- 12/24 uur optie

- Helderheidsoptie

- Willekeurige klokmodusoptie die de weergavemodus om de paar uur verandert.

- Drukknopgestuurde menu's voor instelling en weergaveselectie.

Zoals je op het circuit kunt zien, hebben we, behalve matrices, een arduino-bord, een real-time klokmodule en twee drukknoppen nodig voor instellingen. U kunt bibliotheken en aangepaste code downloaden via de onderstaande links.

Code

  • code
  • Bibliotheken
codeArduino
/************************************************** *************************Mini Clock v1.0, juli 2014 door Nick HallVerdeeld onder de voorwaarden van de GPL.Voor hulp bij het bouwen van de klok zie mijn blog:http://123led.wordpress.com/Getest op IDE v1.6.5 ****************************** *****************************************///include bibliotheken:#include "LedControl.h"#include  // Font library#include  // DS1307 clock#include "RTClib.h" // DS1307 clock#include  // Button library by Alexander Brevig// Setup LED Matrix// pin 12 is aangesloten op de DataIn op het display// pin 11 is aangesloten op de CLK op het display// pin 10 is aangesloten op LOAD op het displayLedControl lc =LedControl(12, 11, 10, 4); // stelt de 3 pinnen in als 12, 11 &10 en stelt vervolgens 4 displays in (max is 8 displays) // globale variabelenbyte-intensiteit =7; // Standaard intensiteit/helderheid (0-15) byte clock_mode =0; // Standaard klokmodus. Standaard =0 (basic_mode) bool random_mode =0; // Definieer willekeurige modus - verandert het weergavetype om de paar uur. Standaard =0 (uit)byte old_mode =clock_mode; // Slaat de vorige klokmodus op, dus als we naar een datum gaan of wat dan ook, weten we naar welke modus we terug moeten gaan after.bool ampm =0; // Definieer 12 of 24 uur tijd. 0 =24 uur. 1 =12 uurbyte change_mode_time =0; // Houdt het uur vast wanneer de klokmodus de volgende keer zal veranderen als in willekeurige modus. unsigned lange vertragingstijd =500; // We wachten altijd een beetje tussen updates van de displayint rtc[7]; // Bevat real-time klok outputchar days [7][4] ={ "Sun", "Mon", "Tue", "Wed", "Do", "Fri", "Sat"}; //day array - gebruikt in slide, basic_mode en jumble modes (de DS1307 geeft 1-7 waarden weer voor de dag van de week)char daysfull[7][9] ={ "zondag", "maandag", "dinsdag", "wo ", "Donderdag", "Vrijdag", "Zaterdag"};char suffix[4][3] ={ "st", "nd", "rd", "th"}; // date suffix array, gebruikt in slide, basic_mode en jumble modes. bijv. 1e 2e ...//definieer constanten#define NUM_DISPLAY_MODES 3 // Nummerweergavemodi (waarbij nul behouden blijft als de eerste modus)#define NUM_SETTINGS_MODES 4 // Nummerinstellingsmodi =6 (waarbij nul behouden blijft als de eerste modus)# definieer SLIDE_DELAY 20 // De tijd in milliseconden voor het dia-effect per teken in de diamodus. Maak dit hoger voor een langzamer effect#define cls clear_display // Clear displayRTC_DS1307 ds1307; // Maak RTC-objectButton buttonA =Button (2, BUTTON_PULLUP); // Setup-knop A (met behulp van knopbibliotheek) Button buttonB =Button (3, BUTTON_PULLUP); // Setup-knop B (met behulp van knopbibliotheek) void setup () { digitalWrite (2, HIGH); // schakel pullup-weerstand in voor knop op pin 2 digitalWrite (3, HIGH); // schakel pullup-weerstand in voor knop op pin 3 digitalWrite (4, HIGH); // zet pullup-weerstand aan voor knop op pin 4 Serial.begin (9600); //start serieel //initialiseer de 4 matrixpanelen // we hebben het aantal apparaten al ingesteld toen we LedControl maakten int devices =lc.getDeviceCount(); // we moeten alle apparaten in een lus initialiseren voor (int adres =0; adres =0 &&x <=7) { adres =3; } if (x>=8 &&x <=15) { adres =2; x =x - 8; } if (x>=16 &&x <=23) { adres =1; x =x - 16; } if (x>=24 &&x <=31) { adres =0; x =x - 24; } if (val ==1) { lc.setLed(adres, y, x, waar); } else { lc.setLed(adres, y, x, false); }}//clear screenvoid clear_display() { for (byte adres =0; adres <4; adres++) { lc.clearDisplay(adres); }}//fade screen downvoid fade_down() {//fade from global intensity to 1 for (byte i =intensity; i> 0; i--) { for (byte address =0; address <4; address++) { lc .setIntensity(adres, ik); } vertraging (30); // verander dit om de fade-downsnelheid te wijzigen} clear_display (); // wis weergave volledig (uit) // reset intentsity naar globale waarde voor (byte-adres =0; adres <4; adres ++) { lc.setIntensity (adres, intensiteit); }}//power up led test &display softwareversie nummervoid printver() { byte i =0; char ver_a[9] ="Vers 1.0"; char ver_b[9] =" Hallo! "; //test alle leds. for (byte x =0; x <=31; x++) { for (byte y =0; y <=7; y++) { plot(x, y, 1); } } vertraging (500); fade_down(); while (ver_a[i]) { puttinychar((i * 4), 1, ver_a[i]); vertraging (35); i++; } vertraging (700); fade_down(); ik =0; while (ver_b[i]) { puttinychar((i * 4), 1, ver_b[i]); vertraging (35); i++; } vertraging (700); fade_down();}// puttinychar// Kopieer een glyph van 3x5 tekens uit de myfont-gegevensstructuur om het geheugen weer te geven, met de linkerbovenhoek op de opgegeven coördinaat// Dit is niet geoptimaliseerd en gebruikt eenvoudig plot() om elke dot.void puttinychar te tekenen (byte x, byte y, char c){ byte punten; if (c>='A' &&c <='Z' || (c>='a' &&c <='z') ) { c &=0x1F; // A-Z verwijst naar 1-26 } else if (c>='0' &&c <='9') { c =(c - '0') + 32; } else if (c ==' ') { c =0; // spatie } else if (c =='.') { c =27; // punt } else if (c ==':') { c =28; // dubbele punt } else if (c =='\'') { c =29; // enkel aanhalingsteken } else if (c =='!') { c =30; // enkel aanhalingsteken } else if (c =='?') { c =31; // enkel aanhalingsteken} voor (byte col =0; col <3; col++) {dots =pgm_read_byte_near(&mytinyfont[c][col]); for (char row =0; row <5; row++) { if (dots &(16>> row)) plot(x + col, y + row, 1); else plot(x + col, y + rij, 0); } }} ongeldig putnormalchar(byte x, byte y, char c){ byte punten; // if (c>='A' &&c <='Z' || (c>='a' &&c <='z') ) { // c &=0x1F; // A-Z verwijst naar 1-26 // } if (c>='A' &&c <='Z' ) { c &=0x1F; // A-Z verwijst naar 1-26 } else if (c>='a' &&c <='z') { c =(c - 'a') + 41; // A-Z verwijst naar 41-67 } else if (c>='0' &&c <='9') { c =(c - '0') + 31; } else if (c ==' ') { c =0; // spatie } else if (c =='.') { c =27; // punt } else if (c =='\'') { c =28; // enkel aanhalingsteken } else if (c ==':') { c =29; // clock_mode selector pijl} else if (c =='>') { c =30; // clock_mode selector pijl} else if (c>=-80 &&c <=-67) { c *=-1; } for (char col =0; col <5; col++) { dots =pgm_read_byte_near(&myfont[c][col]); for (char row =0; row <7; row++) {//check de coördinaten op het scherm voordat je probeert te plotten //if ((x>=0) &&(x <=31) &&(y>=0) &&(y <=7)){ if (dots &(64>> rij)) { // slechts 7 rijen. plot(x + col, y + rij, 1); } else { plot(x + col, y + rij, 0); } //} } }}//small_mode//toon de tijd in kleine 3x5 tekens met seconden displayvoid small_mode() { char textchar[8]; // de 16 tekens op het display byte min =100; // minuten byte sec =rtc [0]; //seconden byte old_secs =sec; // houdt oude secondenwaarde vast - van de laatste keer dat seconden werden bijgewerkt o weergave - gebruikt om te controleren of seconden zijn gewijzigd cls(); // voer de hoofdlus van de klok uit zolang run_mode true retourneert while (run_mode()) { get_time(); // controleer op druk op de knop als (buttonA.uniquePress ()) { switch_mode (); opbrengst; } if (buttonB.uniquePress()) { display_date(); opbrengst; } // als seconden zijn gewijzigd, werk ze dan bij op het scherm secs =rtc[0]; if (secs! =old_secs) {//secs char buffer [3]; itoa(sec, buffer, 10); //fix - zoals anders als num voorloopnul heeft, b.v. "03" seconden, itoa verbergt dit naar tekens met spatie "3". if (sec <10) { buffer [1] =buffer [0]; buffer[0] ='0'; } puttinychar( 20, 1, ':'); // seconden dubbele punt puttinychar (24, 1, buffer [0]); //seconden puttinychar (28, 1, buffer [1]); //seconden old_secs =sec; } // als de minuut verandert, verandert de tijd if (mins! =rtc [1]) { // reset deze voor vergelijking de volgende keer mins =rtc [1]; byte-uren =rtc[2]; if (hours> 12) { hours =hours - ampm * 12; } if (hours <1) { hours =hours + ampm * 12; } //byte dow =rtc[3]; // de DS1307 geeft 0 - 6 weer waarbij 0 =zondag 0 - 6 waarbij 0 =zondag. //byte datum =rtc[4]; //set karakters char buffer [3]; itoa(uren, buffer, 10); //fix - zoals anders als num voorloopnul heeft, b.v. "03" uur, itoa verbergt dit naar tekens met spatie "3". if (uren <10) { buffer [1] =buffer [0]; // als we in de 12-uursmodus zijn, blanco de voorloopnul. if (ampm) { buffer [0] =' '; } else { buffer[0] ='0'; } } // stel uren in chars textchar [0] =buffer [0]; textchar[1] =buffer[1]; tekstchar[2] =':'; itoa (minuten, buffer, 10); if (min <10) { buffer [1] =buffer [0]; buffer[0] ='0'; } //set mins tekens textchar [3] =buffer [0]; textchar[4] =buffer[1]; //do seconden textchar [5] =':'; buffer[3]; seconden =rtc[0]; itoa(sec, buffer, 10); //fix - zoals anders als num voorloopnul heeft, b.v. "03" seconden, itoa verbergt dit naar tekens met spatie "3". if (sec <10) { buffer [1] =buffer [0]; buffer[0] ='0'; } //set seconden textchar [6] =buffer [0]; textchar[7] =buffer[1]; byte x =0; byte y =0; // druk elke char af voor (byte x =0; x <6; x++) { puttinychar (x * 4, 1, textchar [x]); } } vertraging (50); } fade_down();}// basic_mode()// toon de tijd in 5x7 karaktersvoid basic_mode(){ cls(); char-buffer [3]; // voor de conversie van int naar char om rtc-waarden in chars om te zetten, kunnen we op het scherm afdrukken byte offset =0; // gebruikt om de x-positie van de cijfers te compenseren en het display te centreren wanneer we in de 12-uursmodus zijn en de klok slechts 3 cijfers weergeeft. bijv. 3:21 byte x, y; //gebruikt om een ​​doorzichtige doos over de linker "1" van het scherm te tekenen wanneer we rollen van 12:59 -> 01:00 uur in 12-uursmodus. //doe 12/24 uur conversie als ampm ingesteld op 1 byte uur =rtc[2]; if (hours> 12) { hours =hours - ampm * 12; } if (hours <1) { hours =hours + ampm * 12; } // doe offset-conversie als (ampm &&uur <10) { offset =2; } // stel de volgende minuut in, we tonen de datum op //set_next_date(); // aanvankelijk zet mins op waarde 100 - dus het zal nooit gelijk zijn aan rtc[1] in de eerste lus van de klok, wat betekent dat we de klokweergave tekenen als we de functie byte secs =100 invoeren; byte minuten =100; aantal int =0; // voer de hoofdlus van de klok uit zolang run_mode true teruggeeft terwijl (run_mode ()) { // haal de tijd van de klokchip get_time (); // controleer op druk op de knop als (buttonA.uniquePress ()) { switch_mode (); opbrengst; } if (buttonB.uniquePress()) { display_date(); opbrengst; } //controleer of het tijd is om de datum automatisch weer te geven //check_show_date(); // teken het knipperen:alsof de seconden zijn veranderd. if (secs! =rtc [0]) { // update secs met nieuwe waarde secs =rtc [0]; // tekenen:plot (15 - offset, 2, 1); //toppunt plot (15 - offset, 5, 1); // laagste punt telling =400; } // als het aantal op is, zet dan het volgende uit:if (count ==0) { plot (15 - offset, 2, 0); //toppunt plot (15 - offset, 5, 0); //bottom point } else { count--; } // teken het scherm opnieuw als de knop wordt ingedrukt of als mins !=rtc[1] dwz als de tijd is veranderd ten opzichte van wat we in mins hadden opgeslagen, (wordt ook geactiveerd bij de eerste keer dat de functie wordt geopend wanneer min 100 is) if (mins!=rtc [1]) { // update minuten en uren met de nieuwe waarden mins =rtc [1]; uur =rtc[2]; // stel de uren van ampm in op 12-uursmodus als (uren> 12) { hours =hours - ampm * 12; } if (hours <1) { hours =hours + ampm * 12; } itoa(uren, buffer, 10); // als uren <10 het aantal b.v. "3" uur, itoa verbergt dit naar tekens met spatie "3 " die we niet willen als (uren <10) { buffer[1] =buffer[0]; buffer[0] ='0'; } //uren afdrukken // als we in 12-uursmodus en uren <10 staan, druk dan de voorloopnul niet af en stel de offset in zodat we het display centreren met 3 cijfers. if (ampm &&uur <10) { offset =2; // als de tijd 01:00 uur is, wis dan het hele scherm omdat de offset op dit moment verandert en we de oude 12:59 moeten wissen if ((hours ==1 &&mins ==0) ) { cls(); } } else { // else geen offset en print uren tientallen digit offset =0; // als de tijd 10:00 uur is, wis dan het hele scherm omdat de offset op dit moment verandert en we de oude 9:59 moeten wissen if (hours ==10 &&mins ==0) { cls(); } putnormalchar(1, 0, buffer[0]); } // print uren een cijfer putnormalchar (7 - offset, 0, buffer [1]); // mins afdrukken // voorloopnul toevoegen als min <10 itoa (minuten, buffer, 10); if (min <10) { buffer [1] =buffer [0]; buffer[0] ='0'; } //print min tientallen en enen cijfers putnormalchar (19 - offset, 0, buffer [0]); putnormalchar(25 - offset, 0, buffer [1]); } } fade_down();}//like basic_mode maar met slide effectvoid slide() { byte digits_old[4] ={99, 99, 99, 99}; //oude waarden waarin we de tijd opslaan. Stel in op iets dat in eerste instantie nooit met de tijd overeenkomt, zodat alle cijfers worden getekend als de modus begint byte digits_new[4]; // nieuwe cijfers tijd zal verschuiven om byte digits_x_pos [4] ={25, 19, 7, 1} te onthullen; //x pos waarvoor elk cijfer moet worden getekend bij char old_char [2]; // gebruikt wanneer we itoa gebruiken om het huidige cijfer (type byte) in een char te transponeren om door te geven aan de animatiefunctie char new_char [2]; //gebruikt wanneer we itoa gebruiken om het nieuwe cijfer (type byte) om te zetten in een char om door te geven aan de animatiefunctie //old_chars - slaat de 5 dag- en datumachtervoegseltekens op het scherm op. bijv. "ma" en "st". We voeren deze in de dia-animatie in als het huidige teken wanneer deze tekens worden bijgewerkt. // We hebben ze aanvankelijk als A verzonden, die worden gebruikt wanneer de clocl de modus binnengaat en er geen laatste tekens worden opgeslagen. //char old_chars[6] ="AAAAAA"; //plot de dubbele punt van de klok op het scherm cls(); putnormalchar( 13, 0, ':'); byte old_secs =rtc[0]; //opslag seconden in old_secs. We vergelijken seconden en oude seconden. Als ze anders zijn, tekenen we de hoofdlus van de display //run clock opnieuw zolang run_mode true teruggeeft terwijl (run_mode()) { get_time(); // controleer op druk op de knop als (buttonA.uniquePress ()) { switch_mode (); opbrengst; } if (buttonB.uniquePress()) { display_date(); opbrengst; } // als seconden zijn gewijzigd, werk dan de weergave bij if (rtc[0]!=old_secs) { old_secs =rtc[0]; //doe 12/24 uur conversie als ampm ingesteld op 1 byte uur =rtc[2]; if (hours> 12) { hours =hours - ampm * 12; } if (hours <1) { hours =hours + ampm * 12; } // splits alle datum en tijd in individuele cijfers - plak in digits_new array //rtc[0] =secs //array pos en digit opgeslagen //digits_new[0] =(rtc[0]%10); //0 - seconden enen //digits_new[1] =((rtc[0]/10)%10); //1 - seconden tientallen //rtc[1] =minuten digits_new[0] =(rtc[1] % 10); //2 - minuten enen digits_new[1] =((rtc[1]/10) % 10); //3 - minuten tientallen //rtc[2] =uur digits_new[2] =(uren % 10); //4 - uur enen digits_new[3] =((uren / 10) % 10); //5 - tientallen uren //rtc[4] =datum //digits_new[6] =(rtc[4]%10); //6 - datums //digits_new[7] =((rtc[4]/10)%10); //7 - datumtientallen // teken het beginscherm van alle tekens. Hierna tekenen we gewoon de wijzigingen. // vergelijk de cijfers 0 tot 3 (minuten en uren) voor (byte i =0; i <=3; i++) { // kijk of het cijfer is veranderd... if (digits_old[i]!=digits_new[i]) { // voer een animatiereeks van 9 stappen uit voor elk op zijn beurt voor (byte seq =0; seq <=8; seq ++) {// converteer cijfer naar string itoa (digits_old [i], old_char, 10); itoa(digits_new[i], new_char, 10); // indien ingesteld op 12-uurmodus en we staan ​​op cijfer 2 (uur tientallen-modus), controleer dan of dit een nul is. Als dat zo is, maak het dan leeg zodat we 14:00 uur krijgen en niet 14:00 uur if (ampm &&i ==3) { if (digits_new[3] ==0) { new_char[0] =' '; } if (digits_old[3] ==0) { old_char[0] =' '; } } // teken het animatieframe voor elk cijfer slideanim (digits_x_pos[i], 0, seq, old_char[0], new_char[0]); vertraging (SLIDE_DELAY); } } } /* // vergelijk datumcijfers 6 (enen) en (7) tientallen - als een van deze twee verandert, moeten we de datumregel bijwerken. We vergelijken datumtientallen, bijvoorbeeld van 31 jan -> 1 feb, dan verandert het cijfer niet als ((digits_old[6] !=digits_new[6]) || (digits_old[7] !=digits_new[7])) { // verander de getoonde dag. De onderstaande lus gaat op zijn beurt door elk van de 3 tekens, b.v. "MON" voor (byte day_char =0; day_char <=2; day_char++) {//voer de animatiereeks uit voor elke char voor (byte seq =0; seq <=8; seq++){ //de dag (0 - 6 ) Lees dit getal in de dagen char-array. het secondennummer in de array 0-2 krijgt de 3 tekens van de dagnaam, b.v. m o n slideanim(6*day_char,8,seq,old_chars[day_char],days[rtc[3]][day_char]); //6 x day_char geeft ons de x pos voor de char delay (SLIDE_DELAY); } // sla de oude tekens op in de array old_chars op array pos 0-2. We gebruiken dit de volgende keer dat we de dag veranderen en voeren het naar de animatie als het huidige teken. De bijgewerkte char wordt ingevoerd als de nieuwe char. old_chars[day_char] =dagen[rtc[3]][day_char]; } // verander de datum tiental (indien nodig) en enen. (de cijfers van de datum zullen altijd veranderen, maar door dit in de 'if'-lus te plaatsen, wordt het een beetje netter qua code.) for (byte i =7; i>=6; i--){ if (digits_old[i] !=digits_new[i]) { for (byte seq =0; seq <=8; seq++){ itoa(digits_old[i],old_char,10); itoa(digits_new[i],new_char,10); slideanim(digits_x_pos[i],8,seq,old_char[0],new_char[0]); vertraging (SLIDE_DELAY); } } } // druk het dagsuffix "nd" "rd" "th" etc. af. Datum eerste work-out 2 letter suffix - bijv. st, nd, rd, th byte s =3; // de pos om onze achtervoegselarray uit te lezen. bytedatum =rtc[4]; if(datum ==1 || datum ==21 || datum ==31) { s =0; } else if (datum ==2 || datum ==22) { s =1; } else if (datum ==3 || datum ==23) { s =2; } for (byte suffix_char =0; suffix_char <=1; suffix_char++){ for (byte seq =0; seq <=8; seq++){ slideanim((suffix_char*6)+36,8,seq,old_chars[suffix_char+3 ],suffix[s][suffix_char]); // we geven de old_char array char door als de huidige char en de suffix array als de nieuwe char delay (SLIDE_DELAY); } //save de suffic char in de oude chars array op array pos 3 en 5. We gebruiken deze chars de volgende keer dat we het achtervoegsel veranderen en het aan de animatie toevoegen als de huidige char. De bijgewerkte char wordt ingevoerd als de nieuwe char. old_chars[suffix_char+3] =suffix[s][suffix_char]; } }// end do date line */ // save digita array tol old voor vergelijking volgende lus voor (byte i =0; i <=3; i++) { digits_old[i] =digits_new[i]; } }//secs/oldsecs }//while loop fade_down();}//aangeroepen door slide//dit tekent de animatie van de ene char die aanschuift en de andere die wegschuift. Er zijn 8 stappen in de animatie, we noemen de functie om een ​​van de stappen te tekenen van 0-7//invoeren zijn char x en y, animatieframe volgorde (0-7) en de huidige en nieuwe tekens die worden getekend.void slideanim(byte x, byte y, byte sequence, char current_c, char new_c) {// Om de ene char uit en de andere te schuiven hebben we 9 stappen of frames achter elkaar nodig... // seq# 0123456 <-rijen van het scherm // | ||||||| // seq0 0123456 START - alle rijen van het display 0-6 tonen de huidige tekens rijen 0-6 // seq1 012345 huidige char gaat één rij omlaag op het display. We zien alleen de rijen 0-5. Er zijn op weergaveposities 1-6 Er is een lege rij bovenaan ingevoegd // seq2 6 01234 huidige char gaat 2 rijen omlaag. we zien nu alleen rijen 0-4 bij displayrijen 2-6 op het display. Rij 1 van het display is leeg. Rij 0 toont rij 6 van de nieuwe char // seq3 56 0123 // seq4 456 012 half old / half new char // seq5 3456 01 // seq6 23456 0 // seq7 123456 // seq8 0123456 END - alle rijen tonen de nieuwe char //van bovenaf kunnen we zien... //currentchar loopt van 0-6, dan 0-5, dan 0-4 helemaal naar 0. De startpositie van Y wordt elke keer met 1 rij verhoogd. // nieuwe char voert 6 uit, dan 5-6, dan 4-6 en dan 3-6. begin Y-positie wordt elke keer met 1 rij verhoogd. // als het volgnummer lager is dan 7, moeten we het huidige teken tekenen als (volgorde <7) { byte dots; // if (current_c>='A' &&|| (current_c>='a' &¤t_c <='z') ) {// current_c &=0x1F; // A-Z verwijst naar 1-26 // } if (current_c>='A' &¤t_c <='Z' ) { current_c &=0x1F; // A-Z verwijst naar 1-26 } else if (current_c>='a' &¤t_c <='z') { current_c =(current_c - 'a') + 41; // A-Z verwijst naar 41-67 } else if (current_c>='0' &¤t_c <='9') { current_c =(current_c - '0') + 31; } else if (current_c ==' ') { current_c =0; // spatie } else if (current_c =='.') { current_c =27; // punt } else if (current_c =='\'') { current_c =28; // enkel aanhalingsteken} else if (current_c ==':') { current_c =29; // dubbele punt } else if (current_c =='>') { current_c =30; // clock_mode selector pijl} byte curr_char_row_max =7 - sequentie; // het maximale aantal rijen om te tekenen is 6 - volgnummer byte start_y =volgorde; // y-positie om te beginnen - is hetzelfde als het volgnummer. We verhogen dit elke lus // plot elke rij tot rijmaximum (berekend vanaf het volgnummer) voor (byte curr_char_row =0; curr_char_row <=curr_char_row_max; curr_char_row++) { for (byte col =0; col <5; col++) {dots =pgm_read_byte_near(&myfont[current_c][col]); if (dots &(64>> curr_char_row)) plot(x + col, y + start_y, 1); //plot geleid op else plot (x + col, y + start_y, 0); //else plot begon } start_y++;//voeg er een toe aan y zodat we de volgende rij een naar beneden tekenen } } //teken een lege regel tussen de karakters als de reeks tussen 1 en 7 ligt. Als we dit niet doen, krijgen we de overblijfselen van de laatste positie van de huidige tekens op het scherm if (reeks>=1 &&reeks <=8) { for (byte col =0; col <5; col++) { plot(x + col, y + (reeks - 1), 0); // de y-positie om de lijn te tekenen is gelijk aan het volgnummer - 1 } } // als de reeks hoger is dan 2, moeten we ook beginnen met het tekenen van de nieuwe char if (reeks>=2) { // werk char byte uit stippen; //if (new_c>='A' &&new_c <='Z' || (new_c>='a' &&new_c <='z') ) { // new_c &=0x1F; // A-Z verwijst naar 1-26 //} if (new_c>='A' &&new_c <='Z' ) { new_c &=0x1F; // A-Z verwijst naar 1-26 } else if (new_c>='a' &&new_c <='z') { new_c =(new_c - 'a') + 41; // A-Z verwijst naar 41-67 } else if (new_c>='0' &&new_c <='9') { new_c =(new_c - '0') + 31; } else if (new_c ==' ') { new_c =0; // spatie } else if (new_c =='.') { new_c =27; // punt } else if (new_c =='\'') { new_c =28; // enkel aanhalingsteken} else if (new_c ==':') { new_c =29; // clock_mode selector pijl} else if (new_c =='>') { new_c =30; // clock_mode selector pijl} byte newcharrowmin =6 - (sequentie - 2); //minimaal rijnummer om te tekenen voor nieuwe char - dit genereert een uitvoer van 6 tot 0 wanneer volgnummers 2-8 worden ingevoerd. Dit is de minimale rij om te tekenen voor de nieuwe char byte start_y =0; // y-positie om te beginnen - is hetzelfde als het volgnummer. we verhogen het elke rij // plot elke rij vanaf rijminimum (berekend op volgnummer) tot 6 for (byte newcharrow =newcharrowmin; newcharrow <=6; newcharrow++) { for (byte col =0; col <5; col++ ) { dots =pgm_read_byte_near(&myfont[new_c][col]); if (dots &(64>> newcharrow)) plot(x + col, y + start_y, 1); //plot geleid op else plot (x + col, y + start_y, 0); //else plot begon } start_y++;//voeg er een toe aan y zodat we de volgende rij een naar beneden tekenen } }}// print een klok met woorden in plaats van getallenvoid word_clock() { cls(); char nummers [19][10] ={ "een", "twee", "drie", "vier", "vijf", "zes", "zeven", "acht", "negen", "tien", "elf", "twaalf", "dertien", "veertien", "vijftien", "zestien", "zeventien", "achttien", "negentien" }; char numberstens[5][7] ={ "tien", "twintig", "dertig", "veertig", "vijftig"}; // mogelijk 3 regels om char str_a [8] weer te geven; char str_b[8]; char str_c[8]; //byte hours_y, mins_y; //hours en mins en posities voor uren en mins regels byte hours =rtc[2]; if (hours> 12) { hours =hours - ampm * 12; } if (hours <1) { hours =hours + ampm * 12; } krijg tijd(); // haal de tijd uit de klokchipbyte old_mins =100; // mins opslaan in old_mins. We vergelijken minuten en oude minuten en als ze anders zijn, tekenen we de weergave opnieuw. Stel dit in eerste instantie in op 100, zodat de weergave wordt getekend wanneer de modus start. byte minuten; // voer de hoofdlus van de klok uit zolang run_mode true teruggeeft terwijl (run_mode ()) { // controleer of de knop wordt ingedrukt als (buttonA.uniquePress ()) { switch_mode (); opbrengst; } if (buttonB.uniquePress()) { display_date(); } krijg tijd(); // haal de tijd van de klok chip mins =rtc [1]; //mins ophalen //if mins anders is dan old_mins - weergave opnieuw tekenen if (mins! =old_mins) { // update old_mins met de huidige mins-waarde old_mins =mins; // reset deze voor vergelijking de volgende keer min =rtc [1]; uur =rtc[2]; // maak uren in 12-uur formaat if (hours> 12) { hours =hours - 12; } if (uren ==0) { uur =12; } //mins-waarde opsplitsen in twee afzonderlijke cijfers int minsdigit =rtc[1] % 10; byte minsdigitten =(rtc[1]/10) % 10; //if mins <=10 , dan moet de bovenste regel "minsdigti past" lezen en de onderste regel hours if (mins <10) { strcpy (str_a, numbers[minsdigit - 1]); strcpy (str_b, "VERLEDEN"); strcpy (str_c, getallen [uren - 1]); } //if mins =10, kan minsdigit niet gebruiken zoals hierboven, dus een speciaal geval om 10 voorbij /n uur af te drukken. if (min ==10) { strcpy (str_a, getallen [9]); strcpy (str_b, "VERLEDEN"); strcpy (str_c, getallen [uren - 1]); } // als de tijd niet op het uur staat - d.w.z. beide min-cijfers zijn niet nul, // laat dan de eerste regel "hours" en 2 &3e regels "minstens" "mins" lezen, b.v. "drie /n twintig /n één" else if (minsdigitten !=0 &&minsdigit !=0 ) { strcpy (str_a, numbers[hours - 1]); // als minuten in de tienerjaren is, gebruik dan tieners uit de getallenreeks voor de 2e regel, b.v. "vijftien" //if (mins>=11 &&mins <=19) { if (mins <=19) { strcpy (str_b, numbers[mins - 1]); } else { strcpy (str_b, numberstens[minsdigitten - 1]); strcpy (str_c, getallen [minsdigit - 1]); } } // als het mincijfer nul is, print het dan niet. lees lees "uren" "minstens" b.v. "drie /n twintig" else if (minsdigitten !=0 &&minsdigit ==0 ) { strcpy (str_a, numbers[hours - 1]); strcpy (str_b, numberstens[minsdigitten - 1]); strcpy (str_c, ""); } // als beide minuten nul zijn, dwz het is op het uur, staat op de bovenste regel "uren" en op de onderste regel staat "o'clock" else if (minsdigitten ==0 &&minsdigit ==0 ) { strcpy (str_a, cijfers [uren - 1]); strcpy (str_b, "O'CLOCK"); strcpy (str_c, ""); } }// end worknig out time //run in a loop //print line a "twaalf" byte len =0; while (str_a[len]) { len++; }; // krijg lengte van berichtbyte offset_top =(31 - ((len - 1) * 4)) / 2; // //plot uren lijn byte i =0; while (str_a[i]) { puttinychar((i * 4) + offset_top, 1, str_a[i]); i++; } // houd het display ingedrukt maar controleer op het indrukken van de knop int counter =1000; while (teller> 0) { // controleer op druk op de knop als (buttonA.uniquePress()) { switch_mode(); opbrengst; } if (buttonB.uniquePress()) { display_date(); } vertraging(1); balie--; } fade_down(); // print lijn b len =0; while (str_b[len]) { len++; }; //krijg de lengte van het bericht offset_top =(31 - ((len - 1) * 4)) / 2; ik =0; while (str_b[i]) { puttinychar((i * 4) + offset_top, 1, str_b[i]); i++; } // houd het display ingedrukt maar controleer op knopdrukken teller =1000; while (teller> 0){ if (buttonA.uniquePress()) { switch_mode(); opbrengst; } if (buttonB.uniquePress()) { display_date(); } vertraging(1); balie--; } fade_down(); // print regel c als die er is. len =0; while (str_c[len]) { len++; }; //krijg de lengte van het bericht offset_top =(31 - ((len - 1) * 4)) / 2; ik =0; while (str_c[i]) { puttinychar((i * 4) + offset_top, 1, str_c[i]); i++; } teller =1000; while (teller> 0) { // controleer op druk op de knop als (buttonA.uniquePress()) { switch_mode(); opbrengst; } if (buttonB.uniquePress()) { display_date(); } vertraging(1); balie--; } fade_down(); // houd het scherm leeg, maar controleer of er op de knop wordt gedrukt voordat u opnieuw begint. teller =1000; while (teller> 0) { // controleer op druk op de knop als (buttonA.uniquePress()) { switch_mode(); opbrengst; } if (buttonB.uniquePress()) { display_date(); } vertraging(1); balie--; } } fade_down();}/// scroll message - momenteel niet gebruikt - te traag.void scroll() { char message[] ={"Hallo daar"}; cls(); byte p =6; //huidige pos in stringbyte chara [] ={0, 1, 2, 3, 4, 5}; // tekens uit string int x [] ={0, 6, 12, 18, 24, 30}; //xpos voor elke char byte y =0; //y pos // clear_buffer(); while (message[p] !='\0') { //teken alle 6 karakters voor (byte c =0; c <6; c++) { putnormalchar(x[c],y,message[chara[c] ] ); // teken een lijn met pixels uitgeschakeld na elke char, anders bevatten de gaten tussen de chars pixels van de vorige char voor (byte yy =0; yy <8; yy ++) { plot (x [c] + 5, jj, 0); } // haal er één uit elke tekenpositie x[c] =x[c] - 1; } // reset een char als deze van het scherm is verdwenen voor (byte i =0; i <=5; i++) { if (x[i] <-5) { x[i] =31; karakter[i] =p; p++; } } }}//display_date - druk de dag van de week, datum en maand af met een knipperende cursor effectvoid display_date(){ cls(); // lees de datum van de DS1307 byte dow =rtc [3]; // dag van de week 0 =zondag byte datum =rtc [4]; byte maand =rtc[5] - 1; //array van maandnamen om op het display af te drukken. Sommige zijn ingekort omdat we maar 8 karakters hebben om te spelen met char maandnamen [12][9] ={ "januari", "februari", "maart", "april", "mei", "juni", "juli" , "Augustus", "Sept", "Oktober", "November", "December" }; // druk de dagnaam af // haal de lengte van de tekst in pixels, op die manier kunnen we deze op het scherm centreren door de resterende pixels b2 te delen en die te gebruiken als een offset-byte len =0; while(daysfull[dow][len]) { len++; }; byte offset =(31 - ((len-1)*4)) / 2; //our offset to centre up the text //print the name int i =0; while(daysfull[dow][i]) { puttinychar((i*4) + offset , 1, daysfull[dow][i]); i++; } vertraging (1000); fade_down(); cls(); // print date numerals char buffer[3]; itoa(date,buffer,10); offset =10; //offset to centre text if 3 chars - e.g. 3rd // first work out date 2 letter suffix - eg st, nd, rd, th etc // char suffix[4][3]={"st", "nd", "rd", "th" }; is defined at top of code byte s =3; if(date ==1 || date ==21 || date ==31) { s =0; } else if (date ==2 || date ==22) { s =1; } else if (date ==3 || date ==23) { s =2; } //print the 1st date number puttinychar(0+offset, 1, buffer[0]); //if date is under 10 - then we only have 1 digit so set positions of sufix etc one character nearer byte suffixposx =4; //if date over 9 then print second number and set xpos of suffix to be 1 char further away if (date> 9){ suffixposx =8; puttinychar(4+offset, 1, buffer[1]); offset =8; //offset to centre text if 4 chars } //print the 2 suffix characters puttinychar(suffixposx+offset, 1, suffix[s][0]); puttinychar(suffixposx+4+offset, 1, suffix[s][1]); vertraging (1000); fade_down(); //print the month name //get length of text in pixels, that way we can centre it on the display by divindin the remaining pixels b2 and using that as an offset len =0; while(monthnames[month][len]) { len++; }; offset =(31 - ((len-1)*4)) / 2; //our offset to centre up the text i =0; while(monthnames[month][i]) { puttinychar((i*4) +offset, 1, monthnames[month][i]); i++; } vertraging (1000); fade_down();}//dislpay menu to change the clock modevoid switch_mode() { //remember mode we are in. We use this value if we go into settings mode, so we can change back from settings mode (6) to whatever mode we were in. old_mode =clock_mode; char* modes[] ={ "Basic", "Small", "Slide", "Words", "Setup" }; byte next_clock_mode; byte firstrun =1; //loop waiting for button (timeout after 35 loops to return to mode X) for (int count =0; count <35; count++) { //if user hits button, change the clock_mode if (buttonA.uniquePress() || firstrun ==1) { count =0; cls(); if (firstrun ==0) { clock_mode++; } if (clock_mode> NUM_DISPLAY_MODES + 1 ) { clock_mode =0; } //print arrown and current clock_mode name on line one and print next clock_mode name on line two char str_top[9]; //strcpy (str_top, "-"); strcpy (str_top, modes[clock_mode]); next_clock_mode =clock_mode + 1; if (next_clock_mode> NUM_DISPLAY_MODES + 1 ) { next_clock_mode =0; } byte i =0; while (str_top[i]) { putnormalchar(i * 6, 0, str_top[i]); i++; } firstrun =0; } vertraging(50); }}//run clock main loop as long as run_mode returns truebyte run_mode() { //if random mode is on... check the hour when we change mode. if (random_mode) { //if hour value in change mode time =hours. then reurn false =i.e. exit mode. if (change_mode_time ==rtc[2]) { //set the next random clock mode and time to change it set_next_random(); //exit the current mode. retourneer 0; } } //else return 1 - keep running in this mode return 1;}//set the next hour the clock will change mode when random mode is onvoid set_next_random() { //set the next hour the clock mode will change - current time plus 1 - 4 hours get_time(); change_mode_time =rtc[2] + random (1, 5); //if change_mode_time now happens to be over 23, then set it to between 1 and 3am if (change_mode_time> 23) { change_mode_time =random (1, 4); } //set the new clock mode clock_mode =random(0, NUM_DISPLAY_MODES + 1); //pick new random clock mode}//dislpay menu to change the clock settingsvoid setup_menu() { char* set_modes[] ={ "Rndom", "24 Hr","Set", "Brght", "Exit"}; if (ampm ==0) { set_modes[1] =("12 Hr"); } byte setting_mode =0; byte next_setting_mode; byte firstrun =1; //loop waiting for button (timeout after 35 loops to return to mode X) for(int count=0; count <35; count++) { //if user hits button, change the clock_mode if(buttonA.uniquePress() || firstrun ==1){ count =0; cls(); if (firstrun ==0) { setting_mode++; } if (setting_mode> NUM_SETTINGS_MODES) { setting_mode =0; } //print arrown and current clock_mode name on line one and print next clock_mode name on line two char str_top[9]; strcpy (str_top, set_modes[setting_mode]); next_setting_mode =setting_mode + 1; if (next_setting_mode> NUM_SETTINGS_MODES) { next_setting_mode =0; } byte i =0; while(str_top[i]) { putnormalchar(i*6, 0, str_top[i]); i++; } firstrun =0; } vertraging(50); } //pick the mode switch(setting_mode){ case 0:set_random(); pauze; case 1:set_ampm(); pauze; case 2:set_time(); pauze; case 3:set_intensity(); pauze; case 4://exit menu break; } //change the clock from mode 6 (settings) back to the one it was in before clock_mode=old_mode;}//toggle random mode - pick a different clock mode every few hoursvoid set_random(){ cls(); char text_a[9] ="Off"; char text_b[9] ="On"; byte i =0; //if random mode is on, turn it off if (random_mode){ //turn random mode off random_mode =0; //print a message on the display while(text_a[i]) { putnormalchar((i*6), 0, text_a[i]); i++; } } else { //turn randome mode on. random_mode =1; //set hour mode will change set_next_random(); //print a message on the display while(text_b[i]) { putnormalchar((i*6), 0, text_b[i]); i++; } } delay(1500); //leave the message up for a second or so}//set 12 or 24 hour clockvoid set_ampm() { // AM/PM or 24 hour clock mode - flip the bit (makes 0 into 1, or 1 into 0 for ampm mode) ampm =(ampm ^ 1); cls();}//change screen intensityintensityvoid set_intensity() { cls(); byte i =0; char text[7] ="Bright"; while(text[i]) { puttinychar((i*4)+4, 0, text[i]); i++; } //wait for button input while (!buttonA.uniquePress()) { levelbar (0,6,(intensity*2)+2,2); //display the intensity level as a bar while (buttonB.isPressed()) { if(intensity ==15) { intensity =0; cls (); } else { intensity++; } //print the new value i =0; while(text[i]) { puttinychar((i*4)+4, 0, text[i]); i++; } //display the intensity level as a bar levelbar (0,6,(intensity*2)+2,2); //change the brightness setting on the displays for (byte address =0; address <4; address++) { lc.setIntensity(address, intensity); } delay(150); } }}// display a horizontal bar on the screen at offset xposr by ypos with height and width of xbar, ybarvoid levelbar (byte xpos, byte ypos, byte xbar, byte ybar) { for (byte x =0; x  
LibrariesArduino
Geen voorbeeld (alleen downloaden).

Schema's


Productieproces

  1. LED-sequencer
  2. Koekoeksklok
  3. MATLAB - Matrix
  4. Mini Boss Battle
  5. Hoofdklok
  6. Berlijnse klok
  7. Analoge stijl LED POV-klok
  8. LED-matrix + bewegingssensor deurdisplay [Arduino Holiday]
  9. 8x LED-verlichting door geluid
  10. Arduino Quadruped
  11. Hot Glue LED Matrix Lamp