Código
código Arduino
// ********************************************* ***********************************************//// MATRIX CLOCK // Adrian Jones, março de 2014 //// - permite rolagem da esquerda para a direita e de cima para baixo //// ********************* *************************************************** ****************** // # include // biblioteca I2C-WIRE # include // Biblioteca RTC // define registros max7219 e de controlo de pinos # definir max7219_reg_noop 0x00 # definir max7219_reg_digit0 0x01 # definir max7219_reg_digit1 0x02 # definir max7219_reg_digit2 0x03 # definir max7219_reg_digit3 0x04 # definir max7219_reg_digit4 0x05 # definir max7219_reg_digit5 0x06 # definir max7219_reg_digit6 0x07 # definir max7219_reg_digit7 0x08 # definir max7219_reg_decodeMode 0x09 # definir max7219_reg_intensity 0x0A # definir max7219_reg_scanLimit 0x0b # define max7219_reg_shutdown 0x0c # define max7219_reg_displayTest 0x0f # define dataIn 12 // DIN # define carga 10 // CS # define relógio 11 // CLKchar alphanum [] [8] ={{0x00,0x00,0x00,0x00,0x00,0x00 , 0x00,0x00}, // hex em branco 20 de dezembro de 32 {0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10}, //! 33 {0x00,0x28,0x28,0x28,0x00,0x00,0x00,0x00}, // "34 {0x00,0x28,0x7C, 0x28,0x7C, 0x28,0x00,0x00}, // # 35 {0x10,0x38, 0x50,0x38,0x14,0x54,0x38,0x10}, // $ {0x41,0xA2,0x44,0x08,0x10,0x22,0x45,0x82}, //% {0x38,0x44,0x44,0x38,0x50,0x4A, 0x44,0x3A}, // &{0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00}, // '{0x30,0x40,0x80,0x80,0x80,0x80,0x40,0x30}, // ( 40 {0xC0,0x20,0x10,0x10,0x10,0x10,0x20,0xC0}, //) {0x28,0x10,0xAA, 0x54,0xAA, 0x10,0x28,0x00}, // * {0x00,0x10,0x10, 0x10,0xFE, 0x10,0x10,0x10}, // + {0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x10}, //, {0x00,0x00,0x00,0x00,0x7E, 0x00,0x00, 0x00}, // - {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18}, //. {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}, // / {0x7E , 0xC1,0xA1,0x91,0x89,0x85,0x83,0x7E}, // 0 {0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x7C}, // 1 {0x38,0x44,0x82,0x04,0x18 , 0x20,0x40,0xFE}, // 2 50 {0x7C, 0x82,0x02,0x3C, 0x02,0x02,0x82,0x7C}, // 3 {0x08,0x18,0x28,0x48,0xFE, 0x08,0x08,0x08} , // 4 {0xFE, 0x80,0xF8,0x04,0x02,0x82,0x44,0x38}, // 5 {0x38,0x44,0x80,0xB8,0xC4 , 0x82,0x44,0x38}, // 6 {0xFE, 0x02,0x04,0x08,0x10,0x20,0x20,0x20}, // 7 {0x7C, 0x82,0x82,0x7C, 0x82,0x82,0x82,0x7C}, // 8 {0x7C, 0x82,0x82,0x7E, 0x02,0x82,0x44,0x38}, // 9 {0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00}, //:{0x00,0x00, 0x18,0x18,0x00,0x18,0x18,0x30}, //; {0x00,0x10,0x20,0x40,0x80,0x40,0x20,0x10}, // <60 {0x00,0x00,0x00,0x7E, 0x00,0x7E, 0x00,0x00}, // ={0x00,0x80,0x40, 0x20,0x10,0x20,0x40,0x80}, //> {0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20}, //? {0x7E, 0x81,0x99,0xA1,0xA1,0x9E, 0x80,0x7E}, // @ {0x3C, 0x42,0x81,0x81,0xFF, 0x81,0x81,0x81}, // A {0xFC, 0x82,0x81,0xFE , 0x81,0x81,0x82,0xFC}, // B {0x3C, 0x42,0x81,0x80,0x80,0x81,0x42,0x3C}, // C {0xFC, 0x82,0x81,0x81,0x81,0x81,0x82,0xFC }, // D {0xFE, 0x80,0x80,0xFC, 0x80,0x80,0x80,0xFE}, // E {0xFE, 0x80,0x80,0xFC, 0x80,0x80,0x80,0x80}, // F 70 {0x3C , 0x42,0x81,0x80,0x87,0x81,0x42,0x3C}, // G {0x81,0x81,0x81,0xFF, 0x81,0x81,0x81,0x81}, // H {0xFE, 0x10,0x10,0x10,0x10 , 0x10,0x10,0xFE}, // I {0xFF, 0x08,0x08,0x08,0x08,0x88,0x88,0x70}, // J {0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x84}, // K {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE}, // L {0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81}, // M {0x81,0xC1, 0xA1,0x91,0x89,0x85,0x83,0x81}, // N {0x3C, 0x42,0x81,0x81,0x81,0x81,0x42,0x3C}, // O {0xFC, 0x82,0x81,0x82,0xFC, 0x80, 0x80,0x80}, // P 80 {0x3C, 0x42,0x81,0x81,0x81,0x85,0x42,0x3D}, // Q {0xFC, 0x82,0x81,0x82,0xFC, 0x84,0x82,0x81}, // R {0x3C, 0x42,0x81,0x40,0x3E, 0x81,0x42,0x3C}, // S {0xFE, 0x10,0x10,0x10,0x10,0x10,0x1 0,0x10}, // T {0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38}, // U {0x82,0x82,0x82,0x82,0x82,0x44,0x28,0x10}, // V {0x81,0x81,0x81,0x81,0x99,0xA5,0xC3,0x81}, // W {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81}, // X {0x82,0x44,0x28,0x10 , 0x10,0x10,0x10,0x10}, // Y {0xFF, 0x02,0x04,0x08,0x10,0x20,0x40,0xFF}, // Z 90 {0xE0,0x80,0x80,0x80,0x80,0x80,0x80, 0xE0}, // [{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}, // {0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x07}, //] {0xE0, 0xA0,0xE0,0xA0,0xAA, 0x15,0x15,0x11}, // am (codificado como '^' {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E}, // _ {0x10,0x08, 0x00,0x00,0x00,0x00,0x00,0x00}, // '{0x00,0x00,0x38,0x04,0x3C, 0x44,0x48,0x34}, // um {0x00,0x40,0x40,0x40,0x78,0x44, 0x44,0x38}, // b {0x00,0x00,0x18,0x24,0x40,0x40,0x24,0x18}, // c {0x00,0x04,0x04,0x04,0x3C, 0x44,0x44,0x38}, // d 100 {0x00,0x00,0x38,0x44,0x7C, 0x40,0x44,0x38}, // e {0x00,0x18,0x20,0x20,0x78,0x20,0x20,0x20}, // f {0x00,0x38,0x44, 0x44,0x38,0x04,0x44,0x38}, // g {0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44}, // h {0x0 0,0x00,0x40,0x00,0x40,0x40,0x40,0x40}, // i {0x00,0x08,0x00,0x08,0x08,0x08,0x48,0x30}, // j {0x00,0x40,0x40,0x48, 0x50,0x60,0x50,0x48}, // k {0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x20}, // l {0x00,0x00,0x00,0x28,0x54,0x44,0x44,0x44} , // m {0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44}, // n 110 {0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x38}, // o {0x00, 0x00,0x70,0x48,0x48,0x70,0x40,0x40}, // p {0x00,0x00,0x30,0x48,0x48,0x38,0x08,0x08}, // q {0x00,0x00,0x00,0x30,0x48, 0x40,0x40,0x40}, // r {0x00,0x30,0x48,0x40,0x30,0x08,0x48,0x30}, // s {0x00,0x20,0x70,0x20,0x20,0x20,0x28,0x10}, / / t {0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x38}, // u {0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10}, // v {0x00,0x00,0x82 , 0x82,0x82,0x92,0x54,0x28}, // w {0x00,0x00,0x84,0x48,0x30,0x30,0x48,0x84}, // x 120 {0x00,0x48,0x48,0x48,0x38,0x08, 0x48,0x30}, // y {0x00,0x00,0x00,0x7C, 0x08,0x10,0x20,0x7C}, // z {0x00,0x30,0x40,0x40,0x80,0x40,0x40,0x30}, // { {0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20}, // | {0x00,0x60,0x10,0x10,0x08,0x10,0x10,0x60}, //} {0xE0,0xA0,0xE0,0x80,0x8A, 0x15,0x15,0x11} // códigos pm como '~' Hex 7E, dezembro 126}; // define a operação RTCRTC_DS1307 RTC; // Módulo Tiny RTC (DS1307) (SDA - A4, SCL - A5) // codificador rotativo, interruptor e controle de LED # define enc_PinA 2 // codificador A para o pino 2 (interrupção 0) # define enc_PinB 4 // codificador B para pino 4 # define enc_Switch 3 // chave do codificador para pino 3 (interrupção 1) #define mode_Pin 8 // LED de modo pino # define min_Pin 9 // minuto LED pinunsigned char enc_A, enc_B, enc_A_prev =0; static boolean rotating =false; booleano estático no sentido horário =falso; booleano estático updateFlag =falso; modo int estático =0; // 0 - nada, 1 - hora definido, 2 - min definido // define as strings de exibição # define max_array_size 100char ac [max_array_size] ={}; byte rc [8] ={}; String display_message =""; int arraylen; // parâmetros operacionais # define delay_line 75 // ms entre os deslocamentos de linha # define delay_char 400 // ms entre caracteres # define delay_mess 500 // ms entre mensagens # define cblanks 1 // número de linhas em branco entre caracteres # define eblanks 0 // número de linhas em branco adicionais (acima de 8) no final da mensagem // exibe featuresstatic boolean top2bottom =false; // direção de exibição (de cima para baixo ou da direita para a esquerda estática booleana hour24 =false; // exibição de 24 horas? static boolean charHI =true; // realça toda a caracteristica booleana doSerial =true; // saída serial? // *** *************************************************** ************************************//// Configuração inicial//****** *************************************************** ********************************** // void setup () {Wire.begin (); Serial.begin ( 57600); if (doSerial) Serial.print ("MATRIX Clock - Adrian Jones, Mar. 2014"); // pinos de controle de matriz de LED 8x8 pinMode (dataIn, OUTPUT); pinMode (clock, OUTPUT); pinMode (carregar, OUTPUT ); initMatrix (); // inicializar matriz de LED // pinos de LED pinMode (mode_Pin, OUTPUT); // pino de modo digitalWrite (mode_Pin, 1); pinMode (min_Pin, OUTPUT); // pino de minuto digitalWrite (min_Pin, 1); // pinMode de controle do codificador (enc_PinA, INPUT_PULLUP); digitalWrite (enc_PinA, HIGH); // pino codificador rotativo A pinMode (enc_PinB, INPUT_PULLUP); digitalWrite (enc_PinB, HIGH); // rotativo pino B do codificador pinMode (enc_Switch, INPUT_PULLUP); digitalWrite (enc_Switch, HIGH); // chave do codificador attachInterrupt (0, rotEncoder, CHANGE); // configuração de tempo attachInterrupt (1, swEncoder, CHANGE); // minutos / horas // RTC RTC.begin (); if (! RTC.isrunning ()) {RTC.adjust (DateTime (__ DATE__, __TIME__)); if (doSerial) Serial.println ("(redefinição RTC)"); } else {if (doSerial) Serial.println ("(RTC em execução)"); }} // ********************************************* *********************************************//// Main Loop / / ************************************************** ***************************************** // void loop () {DateTime now =RTC.now (); // show_time_and_date (agora); // exibe o tempo display_message =createMessage (now); arraylen =initDisplayString (display_message); if (updateFlag) {show_time_and_date (agora); updateFlag =false; } enquanto (girando) {atraso (1); // debounce adjTime (agora, sentido horário); show_time_and_date (RTC.now ()); display_message =createMessage (agora); arraylen =initDisplayString (display_message); atraso (1); girando =falso; // Redefine o sinalizador de interrupção de volta para falso} delay (5); for (int i =0; i <(arraylen-7); i ++) {// percorre a matriz de mensagens, avançando um byte por vez para (int j =1; j <9; j ++) {maxSingle (j, ac [i + 8-j]); } // linha 1 obtém ac [i + 8], linha 2 obtém ac [i + 7] etc ... linha 8 obtém ac [i + 0] if (i% (8 + cblanks) ==0) {/ / quando há um caractere completo no display ... if (charHI) maxSingle (max7219_reg_intensity, 0x01); // ... aumenta o brilho e interrompe temporariamente newDelay (delay_char); } else {// brilho normal maxSingle (max7219_reg_intensity, 0x00); newDelay (delay_line); }} if (mode ==0) newDelay (delay_mess);} // ******************************** *************************************************** / /// INTERRUPT ROUTINES // ******************************************** **************************************** //// function rotEncoder ():ISR chamado quando o codificador rotatedvoid rotEncoder () {delay (1); enc_A =digitalRead (enc_PinA); enc_B =digitalRead (enc_PinB); if (! enc_A &&enc_A_prev) {// mudança de estado no sentido horário =(! enc_A &&enc_B)? verdadeiro falso; if (modo! =0) rotativo =verdadeiro; } enc_A_prev =enc_A; // Armazena o valor de A para a próxima vez} // função swEncoder ():ISR chamado quando o botão do codificador pushvoid swEncoder () {delay (1); if (digitalRead (enc_Switch)! =LOW) return; // se a chave for pressionada delay (1); // debounce if (digitalRead (enc_Switch)! =LOW) return; // se a chave ainda estiver pressionada mode ++; modo =modo% 3; // modo de incremento digitalWrite (mode_Pin,! (mode ==1)); // LED de ajuste de hora digitalWrite (min_Pin,! (mode ==2)); // ajuste de minuto LED updateFlag =true;} // ************************************** **********************************************//// ROTINAS DE OPERAÇÃO // ************************************************ *********************************** //// função newDelayvoid newDelay (int dly) {for (int z =1; z =25) adj_hrs =1; } else {// decrementar if (adj_hrs ==0) adj_hrs =24; if (- adj_hrs <=0) adj_hrs =24; } RTC.adjust (DateTime (now.year (), now.month (), now.day (), adj_hrs, now.minute (), now.second ())); } if (mode ==2) {// ajusta os minutos int adj_mins =now.minute (); if (dir) {if (++ adj_mins> =60) adj_mins =0; } else {if (- adj_mins <0) adj_mins =59; } RTC.adjust (DateTime (now.year (), now.month (), now.day (), now.hour (), adj_mins, now.second ())); }} // função rotChar (char):para caractere char, transpõe os bits 90 graus. (parte superior - inferior ==> esquerda - direita) // e armazena os resultados em rc [0] - rc [7] .byte rotChar (char inLetter) {int ind =int (inLetter) - 0x20; para (int col =0; col <8; col ++) {máscara de byte =0x01 <<(7-col); for (int row =0; row <8; row ++) {bitWrite (rc [col], 7-row, (alphanum [ind] [row] &mask)); }}} // função show_time_and_date:imprime string de tempo &bytesvoid show_time_and_date (DateTime datetime) {if (doSerial) {int minutes =datetime.minute (); horas int =datetime.hour (); if (horas ==0) horas =24; segundos inteiros =datetime.second (); char delim ='/'; char dend =''; String te ="Data / hora atual:"; te =te + datetime.year () + delim + datetime.month () + delim + datetime.day () + dend; Serial.print (te); if (horas <10) Serial.print (0); Serial.print (horas, DEC); Serial.print (":"); if (minutos <10) Serial.print (0); Serial.print (minutos, DEC); Serial.print (":"); if (segundos <10) Serial.print (0); Serial.print (segundos, DEC); Serial.println (""); }} String createMessage (DateTime datetime) {String new_mess =""; int hr =datetime.hour ()% 24; se (hr ==0) hr =24; int mn =datetime.minute (); if (mode ==0) {// Modo normal if (hour24) {new_mess + =hr; } else {new_mess + =(hr> 12)? h - 12:h; } new_mess + =':'; if (mn <10) new_mess + ='0'; nova_mensagem + =mn; if (! hour24) new_mess + =(hr> 12)? "~":"^"; } if (mode ==1) {// Ajustando horas new_mess + =hr; } if (mode ==2) {// Ajustando os minutos if (mn <10) new_mess + ='0'; nova_mensagem + =mn; } return new_mess;} // função initDisplayString ():cria um array de string de mensagem com espaços em branco entre os caracteres e no final initDisplayString (String message) {int x =0; for (int y =0; y > 1); // coloca dados digitalWrite (load, HIGH);} // função putByte ():carrega dados para a matriz, MSB para LSB void putByte (dados de byte) {byte i =8; máscara de bytes; while (i> 0) {// MSB para máscara LSB =0x01 <<(i - 1); // cria bitmask digitalWrite (clock, LOW); // marque if (data &mask) {// escolha o bit digitalWrite (dataIn, HIGH); // envie 1} else {digitalWrite (dataIn, LOW); // envie 0} digitalWrite (clock, HIGH); // tock --i; // mover para o bit menor}}