Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Mini LED Matrix Clock

Componentes e suprimentos

Arduino Nano R3
× 1
Maxim Integrated DS3231M - ± 5ppm, I2C Real-Time Clock
× 1
Botão de pressão, momentâneo
× 2
Módulo de matriz LED 32x8
× 1

Ferramentas e máquinas necessárias

Ferro de soldar (genérico)

Aplicativos e serviços online

Arduino IDE

Sobre este projeto




Na página "Projetos LED do Nick" encontrei o projeto do relógio que mostra a hora em 4 matrizes com 8x8 leds. Ele construiu o relógio com matrizes da loja "ICStation" que vende kits DIY de painel de módulo de matriz.

Com uma mudança mínima no código, eu fiz meu relógio com o módulo de matriz de pontos MAX7219 icrocontroller display quatro-em-um que é completamente dobrado e é muito mais barato. Eu comprei no AliExpress.

O relógio tem muitos recursos:

- Modo básico com dígitos grandes

- Modo slide onde os dígitos entram e saem da tela

- Pequenos dígitos com modo de segundos

- Tempo escrito em palavras, por exemplo “Doze e dez”

- Exibição de data

- opção 12/24 horas

- Opção de brilho

- Opção de modo de relógio aleatório que muda o modo de exibição a cada poucas horas.

- Menus acionados por botão para configuração e seleção de exibição.



Como você pode ver no circuito, exceto matrizes, precisamos de uma placa arduino, um módulo de relógio em tempo real e dois botões de pressão para configurações. Você pode baixar bibliotecas e código modificado nos links abaixo.

Código

  • código
  • Bibliotecas
código Arduino
 / ********************************************** ************************* Mini Clock v1.0, Jul 2014 por Nick HallDistribuído sob os termos da GPL.Para ajuda sobre como construir o relógio veja meu blog:http://123led.wordpress.com/Testado no IDE v1.6.5 ***************************** ********************************************/// incluir bibliotecas:#include "LedControl.h" #include  // Biblioteca de fontes # include  // DS1307 clock # include "RTClib.h" // DS1307 clock # include  // Biblioteca de botões por Alexander Brevig // Configuração da matriz de LED // o pino 12 está conectado ao DataIn no display // o pino 11 está conectado ao CLK no display // o pino 10 está conectado a LOAD no displayLedControl lc =LedControl (12, 11, 10, 4); // define os 3 pinos como 12, 11 e 10 e, em seguida, define 4 exibições (o máximo é 8 exibições) // variáveis ​​globais em bytes de intensidade =7; // Intensidade / brilho padrão (0-15) byte clock_mode =0; // Modo de relógio padrão. Padrão =0 (basic_mode) bool random_mode =0; // Definir modo aleatório - altera o tipo de exibição a cada poucas horas. Padrão =0 (desligado) byte old_mode =clock_mode; // Armazena o modo de relógio anterior, então se formos para a data ou qualquer outra coisa, sabemos para qual modo voltar after.bool ampm =0; // Defina o tempo de 12 ou 24 horas. 0 =24 horas. 1 =12 hourbyte change_mode_time =0; // Mantém a hora em que o modo do relógio será alterado em seguida se estiver no modo aleatório.unsigned long delaytime =500; // Sempre esperamos um pouco entre as atualizações do displayint rtc [7]; // Mantém o outputchar do relógio em tempo real dias [7] [4] ={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // array de dias - usado nos modos slide, basic_mode e jumble (o DS1307 gera de 1 a 7 valores para o dia da semana) char daysfull [7] [9] ={"Sunday", "Monday", "Tuesday", "Wed "," Quinta-feira "," sexta-feira "," sábado "}; sufixo char [4] [3] ={" st "," nd "," rd "," th "}; // array de sufixo de data, usado nos modos slide, basic_mode e jumble. e, g, 1st 2nd ... // define constantes # define NUM_DISPLAY_MODES 3 // Modos de exibição de número (conting zero como o primeiro modo) #define NUM_SETTINGS_MODES 4 // Modos de configuração de número =6 (conting zero como o primeiro modo) # define SLIDE_DELAY 20 // O tempo em milissegundos para o efeito de slide por personagem no modo slide. Faça isso mais alto para um efeito mais lento # define cls clear_display // Clear displayRTC_DS1307 ds1307; // Cria objectButton RTC buttonA =Button (2, BUTTON_PULLUP); // Configuração do botão A (usando a biblioteca de botões) Botão buttonB =Button (3, BUTTON_PULLUP); // Botão de configuração B (usando a biblioteca de botões) void setup () {digitalWrite (2, HIGH); // liga o resistor pullup para o botão no pino 2 digitalWrite (3, HIGH); // liga o resistor pullup para o botão no pino 3 digitalWrite (4, HIGH); // liga o resistor pullup para o botão no pino 4 Serial.begin (9600); // inicia o serial // inicializa os 4 painéis da matriz // já definimos o número de dispositivos quando criamos o LedControl int devices =lc.getDeviceCount (); // temos que inicializar todos os dispositivos em um loop para (int endereço =0; endereço  =0 &&x <=7) {endereço =3; } if (x> =8 &&x <=15) {address =2; x =x - 8; } if (x> =16 &&x <=23) {address =1; x =x - 16; } if (x> =24 &&x <=31) {address =0; x =x - 24; } if (val ==1) {lc.setLed (endereço, y, x, verdadeiro); } else {lc.setLed (endereço, y, x, falso); }} // limpar a telavoid clear_display () {para (endereço de byte =0; endereço <4; endereço ++) {lc.clearDisplay (endereço); }} // desvanece o downvoid da tela fade_down () {// desvanece da intensidade global para 1 para (byte i =intensidade; i> 0; i--) {para (endereço de byte =0; endereço <4; endereço ++) {lc .setIntensity (endereço, i); } atraso (30); // mude isso para mudar a velocidade do fade down} clear_display (); // limpa a exibição completamente (desligada) // redefine a intenção para o valor global para (endereço de byte =0; endereço <4; endereço ++) {lc.setIntensity (endereço, intensidade); }} // liga o teste do led e exibe o número da versão do softwarevoid printver () {byte i =0; char ver_a [9] ="Vers 1.0"; char ver_b [9] ="Olá!"; // teste todos os leds. for (byte x =0; x <=31; x ++) {for (byte y =0; y <=7; y ++) {plot (x, y, 1); }} atraso (500); fade_down (); while (ver_a [i]) {puttinychar ((i * 4), 1, ver_a [i]); atraso (35); i ++; } atraso (700); fade_down (); i =0; while (ver_b [i]) {puttinychar ((i * 4), 1, ver_b [i]); atraso (35); i ++; } atraso (700); fade_down ();} // puttinychar // Copia um glifo de 3x5 caracteres da estrutura de dados myfont para exibir a memória, com seu canto superior esquerdo na coordenada fornecida // Isso não é otimizado e simplesmente usa plot () para desenhar cada ponto.void puttinychar (byte x, byte y, caractere c) {pontos de byte; if (c> ='A' &&c <='Z' || (c> ='a' &&c <='z')) {c &=0x1F; // A-Z mapeia para 1-26} else if (c> ='0' &&c <='9') {c =(c - '0') + 32; } else if (c =='') {c =0; // espaço} else if (c =='.') {c =27; // ponto final} else if (c ==':') {c =28; // dois pontos} else if (c =='\' ') {c =29; // aspas simples} else if (c =='!') {c =30; // aspas simples} else if (c =='?') {c =31; // aspas simples} para (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); senão plot (x + col, y + linha, 0); }}} void putnormalchar (byte x, byte y, char c) {pontos de byte; // if (c> ='A' &&c <='Z' || (c> ='a' &&c <='z')) {// c &=0x1F; // A-Z mapeia para 1-26 //} if (c> ='A' &&c <='Z') {c &=0x1F; // A-Z mapeia para 1-26} else if (c> ='a' &&c <='z') {c =(c - 'a') + 41; // A-Z mapeia para 41-67} else if (c> ='0' &&c <='9') {c =(c - '0') + 31; } else if (c =='') {c =0; // espaço} else if (c =='.') {c =27; // ponto final} else if (c =='\' ') {c =28; // aspas simples} else if (c ==':') {c =29; // seta do seletor clock_mode} else if (c =='>') {c =30; // seta do seletor clock_mode} else if (c> =-80 &&c <=-67) {c * =-1; } para (char col =0; col <5; col ++) {dots =pgm_read_byte_near (&myfont [c] [col]); for (char row =0; row <7; row ++) {// verifique as coordenadas estão na tela antes de tentar plotar // if ((x> =0) &&(x <=31) &&(y> =0) &&(y <=7)) {if (pontos &(64>> linha)) {// apenas 7 linhas. plot (x + col, y + linha, 1); } else {plot (x + col, y + row, 0); } //}}}} // small_mode // mostra a hora em pequenos caracteres 3x5 com segundos displayvoid small_mode () {char textchar [8]; // os 16 caracteres no byte de exibição min =100; // min byte secs =rtc [0]; // segundos byte old_secs =secs; // mantém o valor dos segundos antigos - da última vez que os segundos foram atualizados o display - usado para verificar se os segundos mudaram cls (); // executa o loop principal do relógio contanto que run_mode retorne verdadeiro while (run_mode ()) {get_time (); // verificar se o botão foi pressionado if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); Retorna; } // se os segundos mudaram, atualize-os no visor secs =rtc [0]; if (secs! =old_secs) {// secs char buffer [3]; itoa (segundos, buffer, 10); // corrige - caso contrário, se num tiver zero à esquerda, por exemplo, "03" segundos, ele cobre isso para caracteres com espaço "3". if (s <10) {buffer [1] =buffer [0]; buffer [0] ='0'; } puttinychar (20, 1, ':'); // segundos, dois pontos puttinychar (24, 1, buffer [0]); // segundos puttinychar (28, 1, buffer [1]); // segundos old_secs =secs; } // se o minuto muda, muda o tempo if (mins! =rtc [1]) {// redefine para comparação na próxima vez mins =rtc [1]; byte horas =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } // byte dow =rtc [3]; // o DS1307 produz 0 - 6 onde 0 =Domingo0 - 6 onde 0 =Domingo. // byte date =rtc [4]; // definir caracteres char buffer [3]; itoa (horas, buffer, 10); // corrige - caso contrário, se num tiver zero à esquerda, por exemplo, "03" horas, ele cobre isso para caracteres com espaço "3". if (horas <10) {buffer [1] =buffer [0]; // se estivermos no modo de 12 horas, deixe em branco o zero à esquerda. if (ampm) {buffer [0] =''; } else {buffer [0] ='0'; }} // definir horas chars textchar [0] =buffer [0]; textchar [1] =buffer [1]; textchar [2] =':'; itoa (minutos, buffer, 10); if (min <10) {buffer [1] =buffer [0]; buffer [0] ='0'; } // definir caracteres de minutos textchar [3] =buffer [0]; textchar [4] =buffer [1]; // faz segundos textchar [5] =':'; buffer [3]; segs =rtc [0]; itoa (segundos, buffer, 10); // corrige - caso contrário, se num tiver zero à esquerda, por exemplo, "03" segundos, ele cobre isso para caracteres com espaço "3". if (s <10) {buffer [1] =buffer [0]; buffer [0] ='0'; } // definir segundos textchar [6] =buffer [0]; textchar [7] =buffer [1]; byte x =0; byte y =0; // imprime cada caractere para (byte x =0; x <6; x ++) {puttinychar (x * 4, 1, textchar [x]); }} atraso (50); } fade_down ();} // basic_mode () // mostra a hora em 5x7 charactersvoid basic_mode () {cls (); buffer char [3]; // para que a conversão de int em char transforme os valores rtc em caracteres, podemos imprimir na tela byte offset =0; // usado para compensar a posição x dos dígitos e centralizar a exibição quando estamos no modo de 12 horas e o relógio mostra apenas 3 dígitos. por exemplo. 3:21 byte x, y; // usado para desenhar uma caixa transparente sobre o lado esquerdo "1" do visor quando rolamos de 12h59 -> 1h00 no modo de 12 horas. // faz conversão de 12/24 horas se ampm definido para 1 byte horas =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } // faz a conversão de deslocamento if (ampm &&hours <10) {offset =2; } // define o próximo minuto em que mostramos a data em // set_next_date (); // defina inicialmente os minutos com o valor 100 - então nunca será igual a rtc [1] no primeiro loop do relógio, o que significa que desenhamos a exibição do relógio quando inserimos a função byte secs =100; byte min =100; contagem interna =0; // executa o loop principal do relógio, desde que run_mode retorne verdadeiro enquanto (run_mode ()) {// obtém a hora do chip do relógio get_time (); // verificar se o botão foi pressionado if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); Retorna; } // verifique se é hora de exibir a data automaticamente // check_show_date (); // desenha o piscar:como se os segundos tivessem mudado. if (secs! =rtc [0]) {// atualizar segundos com o novo valor secs =rtc [0]; // desenhar:plot (15 - deslocamento, 2, 1); // gráfico do ponto superior (15 - deslocamento, 5, 1); // contagem do ponto inferior =400; } // se a contagem acabou, desligue o:if (count ==0) {plot (15 - offset, 2, 0); // gráfico do ponto superior (15 - deslocamento, 5, 0); // ponto inferior} else {contagem--; } // desenha novamente a exibição se o botão for pressionado ou se os minutos! =rtc [1] ou seja, se o tempo mudou em relação ao que armazenamos em minutos, (também acionado na primeira entrada da função quando os minutos são 100) if (minutos! =rtc [1]) {// atualiza minutos e horas com os novos valores mins =rtc [1]; horas =rtc [2]; // ajusta as horas de ampm definidas para o modo de 12 horas if (hours> 12) {hours =hours - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } itoa (horas, buffer, 10); // se horas <10, o número, por exemplo "3" horas, ele cobre isso para caracteres com espaço "3" que não queremos if (horas <10) {buffer [1] =buffer [0]; buffer [0] ='0'; } // imprimir horas // se estivermos no modo de 12 horas e horas <10, não imprimir o zero à esquerda e definir o deslocamento para centralizar a exibição com 3 dígitos. if (ampm &&hours <10) {offset =2; // se a hora for 1h, apague todo o display, pois o deslocamento muda neste momento e precisamos apagar as 12h59 antigas if ((hours ==1 &&mins ==0)) {cls (); }} else {// else sem deslocamento e horas de impressão dezenas de dígitos offset =0; // se a hora for 10h00, apague todo o display, pois o deslocamento muda neste momento e precisamos apagar as antigas 9h59 if (hours ==10 &&mins ==0) {cls (); } putnormalchar (1, 0, buffer [0]); } // imprime as horas com um dígito putnormalchar (7 - deslocamento, 0, buffer [1]); // imprime minutos // adiciona zero à esquerda se minutos <10 itoa (minutos, buffer, 10); if (min <10) {buffer [1] =buffer [0]; buffer [0] ='0'; } // imprime minutos de dezenas e unidades de dígitos putnormalchar (19 - deslocamento, 0, buffer [0]); putnormalchar (25 - deslocamento, 0, buffer [1]); }} fade_down ();} // como basic_mode, mas com slide effectvoid slide () {byte digits_old [4] ={99, 99, 99, 99}; // valores antigos nos quais armazenamos o tempo. Defina como algo que nunca corresponderá ao tempo inicialmente, então todos os dígitos são desenhados quando o modo inicia byte digits_new [4]; // o tempo dos novos dígitos deslizará para revelar o byte digits_x_pos [4] ={25, 19, 7, 1}; // x pos para o qual desenhar cada dígito em char old_char [2]; // usado quando usamos itoa para transpor o dígito atual (tipo byte) em um char para passar para a função de animação char new_char [2]; // usado quando usamos itoa para transpor o novo dígito (tipo byte) em um caractere para passar para a função de animação // old_chars - armazena os caracteres de 5 dias e sufixo de data no display. por exemplo. "mon" e "st". Nós os alimentamos na animação do slide como o caractere atual quando esses caracteres são atualizados. // Nós os enviamos inicialmente como A, que são usados ​​quando o clocl entra no modo e nenhum último caractere é armazenado. // char old_chars [6] ="AAAAA"; // plotar os dois pontos do relógio no visor cls (); putnormalchar (13, 0, ':'); byte old_secs =rtc [0]; // armazena segundos em old_secs. Comparamos os segundos e os segundos antigos. Quando eles são diferentes, redesenhamos o display // executa o loop principal do relógio, desde que run_mode retorne verdadeiro while (run_mode ()) {get_time (); // verificar se o botão foi pressionado if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); Retorna; } // se os segundos mudaram, atualize a exibição if (rtc [0]! =old_secs) {old_secs =rtc [0]; // faz conversão de 12/24 horas se ampm definido para 1 byte horas =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } // dividir toda a data e hora em dígitos individuais - colocar em digits_new array // rtc [0] =segundos // array pos e dígito armazenados // digits_new [0] =(rtc [0]% 10); // 0 - segundos uns // digits_new [1] =((rtc [0] / 10)% 10); // 1 - dezenas de segundos // rtc [1] =minutos digits_new [0] =(rtc [1]% 10); // 2 - minutos uns digits_new [1] =((rtc [1] / 10)% 10); // 3 - minutos dezenas // rtc [2] =horas digits_new [2] =(horas% 10); // 4 horas uns digits_new [3] =((horas / 10)% 10); // dezenas de 5 horas // rtc [4] =data // digits_new [6] =(rtc [4]% 10); // 6 - data uns // digits_new [7] =((rtc [4] / 10)% 10); // 7 - dezenas de datas // desenha a tela inicial de todos os caracteres. Depois disso, apenas desenharemos as alterações. // compare os dígitos de 0 a 3 (minutos e horas) para (byte i =0; i <=3; i ++) {// veja se o dígito mudou ... if (digits_old [i]! =digits_new [i]) {// executa a sequência de animação de 9 etapas para cada um por vez para (byte seq =0; seq <=8; seq ++) {// converte dígito em string itoa (digits_old [i], old_char, 10); itoa (digits_new [i], new_char, 10); // se definido para o modo de 12 horas e estamos no dígito 2 (modo de dezenas de horas), verifique se isso é zero. Se for, deixe em branco para obtermos 14h00 e não 14h00 if (ampm &&i ==3) {if (digits_new [3] ==0) {new_char [0] =''; } if (digits_old [3] ==0) {old_char [0] =''; }} // desenha o quadro de animação para cada slide de dígito (digits_x_pos [i], 0, seq, old_char [0], new_char [0]); atraso (SLIDE_DELAY); }}} / * // compare o dígito de data 6 (uns) e (7) dezenas - se algum desses mudar, precisaremos atualizar a linha de data. Comparamos as dezenas de datas, digamos, 31 de janeiro -> 01 de fevereiro, então os dígitos não mudam se ((digits_old [6]! =Digits_new [6]) || (digits_old [7]! =Digits_new [7])) { // altera o dia mostrado. O loop abaixo passa por cada um dos 3 caracteres, por exemplo, "MON" for (byte day_char =0; day_char <=2; day_char ++) {// execute a sequência do anim para cada caractere para (byte seq =0; seq <=8; seq ++) {// o dia (0 - 6 ) Leia este número na matriz de dias char. o número dos segundos na matriz 0-2 obtém os 3 caracteres do nome do dia, por ex. m o n slideanim (6 * day_char, 8, seq, old_chars [day_char], days [rtc [3]] [day_char]); // 6 x day_char nos dá x pos para o atraso de char (SLIDE_DELAY); } // salve os caracteres antigos na matriz old_chars na matriz pos 0-2. Usaremos isso na próxima vez que mudarmos o dia e alimentarmos a animação como o caractere atual. O char atualizado é alimentado como o novo char. old_chars [day_char] =days [rtc [3]] [day_char]; } // mude o dígito das dezenas da data (se necessário) e o dígito da unidade. (os dígitos da data irão sempre mudar, mas colocar isso no loop 'if' torna o código um pouco mais claro.) 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]); atraso (SLIDE_DELAY); }}} // imprime o sufixo do dia "nd" "rd" "th" etc. Primeiro calcule o sufixo de 2 letras da data - por exemplo, st, nd, rd, th byte s =3; // a pos para ler nossa matriz de sufixo. byte data =rtc [4]; if (data ==1 || data ==21 || data ==31) {s =0; } else if (data ==2 || data ==22) {s =1; } else if (data ==3 || data ==23) {s =2; } for (byte suffix_char =0; suffix_char <=1; suffix_char ++) {for (byte seq =0; seq <=8; seq ++) {slideanim ((sufixo_char * 6) + 36,8, seq, old_chars [sufixo_char + 3 ], sufixo [s] [sufixo_char]); // passamos o array old_char char como o char atual e o array de sufixo como o novo char delay (SLIDE_DELAY); } // salve o caractere suffic na matriz de chars antiga na matriz pos 3 e 5. Usaremos esses chars na próxima vez que mudarmos o sufixo e alimentá-lo para a animação como o caractere atual. O char atualizado é alimentado como o novo char. old_chars [sufixo_char + 3] =sufixo [s] [sufixo_char]; }} // fim da linha de data * / // salvar a matriz de dígitos até o antigo para comparação próximo loop para (byte i =0; i <=3; i ++) {digits_old [i] =digits_new [i]; }} // secs / oldsecs} // while loop fade_down ();} // chamado pelo slide // desenha a animação de um char deslizando e o outro deslizando. Existem 8 etapas na animação, chamamos a função para desenhar uma das etapas de 0-7 // as entradas são são char xey, sequência de quadros de animação (0-7) e os caracteres atuais e novos sendo desenhados.void slideanim (byte x, byte y, sequência de bytes, caractere atual_c, caractere novo_c) {// Para deslizar um caractere desligado e outro ligado, precisamos de 9 etapas ou quadros em sequência ... // seq # 0123456 <-rows of the display // | ||||||| // seq0 0123456 START - todas as linhas do display 0-6 mostram os caracteres atuais linhas 0-6 // seq1 012345 char atual desce uma linha no display. Vemos apenas suas linhas 0-5. Existem nas posições de exibição 1-6. Há uma linha em branco inserida no topo // seq2 6 01234 char atual desce 2 linhas. agora vemos apenas as linhas 0-4 nas linhas 2-6 do display. A linha 1 do visor está em branco. A linha 0 mostra a linha 6 do novo char // seq3 56 0123 // seq4 456 012 meio antigo / meio novo char // seq5 3456 01 // seq6 23456 0 // seq7 123456 // seq8 0123456 END - todas as linhas mostram o novo char // de cima, podemos ver ... // currentchar executa 0-6, depois 0-5 e então 0-4 até 0. A posição Y inicial aumenta em 1 linha a cada vez. // novo char executa 6, depois 5-6, depois 4-6 e depois 3-6. a posição inicial Y aumenta em 1 carreira de cada vez. // se o número da sequência for menor que 7, precisamos desenhar o caractere atual if (sequence <7) {byte dots; // if (current_c> ='A' &&|| (current_c> ='a' &¤t_c <='z')) {// current_c &=0x1F; // A-Z mapeia para 1-26 //} if (current_c> ='A' &¤t_c <='Z') {current_c &=0x1F; // A-Z mapeia para 1-26} else if (current_c> ='a' &¤t_c <='z') {current_c =(current_c - 'a') + 41; // A-Z mapeia para 41-67} else if (current_c> ='0' &¤t_c <='9') {current_c =(current_c - '0') + 31; } else if (current_c =='') {current_c =0; // espaço} else if (current_c =='.') {current_c =27; // ponto final} else if (current_c =='\' ') {current_c =28; // aspas simples} else if (current_c ==':') {current_c =29; // dois pontos} else if (current_c =='>') {current_c =30; // seta do seletor de clock_mode} byte curr_char_row_max =7 - sequência; // o número máximo de linhas a serem desenhadas é 6 - número de sequência byte start_y =sequence; // posição y para começar - é o mesmo que o número da sequência. Nós aumentamos cada loop // plotamos cada linha até o máximo da linha (calculado a partir do número de sequência) para (byte curr_char_row =0; curr_char_row <=curr_char_row_max; curr_char_row ++) {for (byte col =0; col <5; col ++) {pontos =pgm_read_byte_near (&myfont [current_c] [col]); if (dots &(64>> curr_char_row)) plot (x + col, y + start_y, 1); // plotado em outro plot (x + col, y + start_y, 0); // outro gráfico liderou} start_y ++; // adiciona um a y para que desenhemos a próxima linha um abaixo}} // desenhe uma linha em branco entre os caracteres se a sequência estiver entre 1 e 7. Se não fizermos isso, obteremos os restos dos caracteres atuais última posição deixada no display if (seqüência> =1 &&seqüência <=8) {for (byte col =0; col <5; col ++) {plot (x + col, y + (seqüência - 1), 0); // a posição y para desenhar a linha é equivalente ao número da sequência - 1}} // se a sequência estiver acima de 2, também precisamos começar a desenhar o novo caractere if (sequência> =2) {// trabalhar o byte do caractere pontos; // if (new_c> ='A' &&new_c <='Z' || (new_c> ='a' &&new_c <='z')) {// new_c &=0x1F; // A-Z mapeia para 1-26 //} if (new_c> ='A' &&new_c <='Z') {new_c &=0x1F; // A-Z mapeia para 1-26} else if (new_c> ='a' &&new_c <='z') {new_c =(new_c - 'a') + 41; // A-Z mapeia para 41-67} else if (new_c> ='0' &&new_c <='9') {new_c =(new_c - '0') + 31; } else if (new_c =='') {new_c =0; // espaço} else if (new_c =='.') {new_c =27; // ponto final} else if (new_c =='\' ') {new_c =28; // aspas simples} else if (new_c ==':') {new_c =29; // seta do seletor clock_mode} else if (new_c =='>') {new_c =30; // seta do seletor de clock_mode} byte newcharrowmin =6 - (seqüência - 2); // minimumm row num to draw for new char - isso gera uma saída de 6 a 0 quando alimentado com os números de sequência 2-8. Esta é a linha mínima a ser desenhada para o novo byte de caractere start_y =0; // posição y para começar - é o mesmo que o número da sequência. nós aumentamos cada linha // plotamos cada linha a partir do mínimo de linha (calculado pelo número de sequência) até 6 para (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); // plotado em outro plot (x + col, y + start_y, 0); // então plotar o led off} start_y ++; // adicionar um a y para desenhar a próxima linha um abaixo}}} // imprimir um relógio usando palavras em vez de númerosvoid word_clock () {cls (); números char [19] [10] ={"um", "dois", "três", "quatro", "cinco", "seis", "sete", "oito", "nove", "dez", "onze", "doze", "treze", "quatorze", "quinze", "dezesseis", "dezessete", "dezoito", "dezenove"}; char numberstens [5] [7] ={"dez", "vinte", "trinta", "quarenta", "cinquenta"}; // potencialmente 3 linhas para exibir char str_a [8]; char str_b [8]; char str_c [8]; // byte horas_y, minutos_y; // horas e minutos e posições para horas e minutos linhas byte horas =rtc [2]; if (horas> 12) {horas =horas - ampm * 12; } if (horas <1) {horas =horas + ampm * 12; } consiga tempo(); // obtém a hora do chip de relógio byte old_mins =100; // armazena minutos em old_mins. Comparamos os minutos e os minutos antigos e quando eles são diferentes, redesenhamos a exibição. Defina como 100 inicialmente para que a exibição seja desenhada quando o modo iniciar. byte minutos; // executa o loop principal do relógio desde que run_mode retorne verdadeiro while (run_mode ()) {// verifique se o botão foi pressionado if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); } consiga tempo(); // obtém a hora do chip do relógio mins =rtc [1]; // obter os minutos // se os minutos forem diferentes de old_mins - redesenhar a exibição if (minutos! =old_mins) {// atualizar old_mins com o valor atual dos minutos old_mins =mins; // redefine para comparação na próxima vez mins =rtc [1]; horas =rtc [2]; // transforma as horas no formato de 12 horas if (hours> 12) {hours =hours - 12; } if (horas ==0) {horas =12; } // divide o valor dos minutos em dois dígitos separados int minsdigit =rtc [1]% 10; byte mindigito =(rtc [1] / 10)% 10; // se min <=10, então a linha superior deve indicar "mindigti passado" e a linha inferior indicará horas if (min <10) {strcpy (str_a, numbers [minsdigit - 1]); strcpy (str_b, "PASSADO"); strcpy (str_c, números [horas - 1]); } // se mins =10, não posso usar minsdigit como acima, então um caso especial para imprimir 10 / n horas. if (min ==10) {strcpy (str_a, números [9]); strcpy (str_b, "PASSADO"); strcpy (str_c, números [horas - 1]); } // se o tempo não estiver na hora - ou seja, ambos os dígitos dos minutos não são zero, // então faça a primeira linha ler "horas" e as 2 e 3ª linhas lerem "minstens" "minutos", por exemplo "três / n vinte / n um" else if (minutos digitados! =0 &&minutos dígitos! =0) {strcpy (str_a, números [horas - 1]); // se minutos são adolescentes, use adolescentes da matriz de números para a 2ª linha, por exemplo, "quinze" // if (min> =11 &&min <=19) {if (min <=19) {strcpy (str_b, número [min - 1]); } else {strcpy (str_b, numberstens [mindigitten - 1]); strcpy (str_c, números [mindígitos - 1]); }} // se o dígito do minuto for zero, não o imprima. leia leia "horas" "minstens", por exemplo "três / n vinte" else if (minsdigitten! =0 &&minsdigit ==0) {strcpy (str_a, numbers [hours - 1]); strcpy (str_b, numberstens [mindigitten - 1]); strcpy (str_c, ""); } // se ambos os minutos são zero, ou seja, está na hora, a linha superior mostra "horas" e a linha inferior mostra "horas" else if (minsdigitten ==0 &&minsdigit ==0) {strcpy (str_a, números [horas - 1]); strcpy (str_b, "O'CLOCK"); strcpy (str_c, ""); }} // tempo de término do worknig // executa em um loop // imprime uma linha de "doze" bytes len =0; enquanto (str_a [len]) {len ++; }; // obtém o comprimento do byte da mensagem offset_top =(31 - ((len - 1) * 4)) / 2; // // traçar o byte da linha de horas i =0; while (str_a [i]) {puttinychar ((i * 4) + offset_top, 1, str_a [i]); i ++; } // segure a tela, mas verifique se há pressionamentos de botão int counter =1000; while (counter> 0) {// verificar se o botão foi pressionado if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); } atraso (1); balcão--; } fade_down (); // imprime a linha b len =0; enquanto (str_b [len]) {len ++; }; // obtém o comprimento da mensagem offset_top =(31 - ((len - 1) * 4)) / 2; i =0; while (str_b [i]) {puttinychar ((i * 4) + offset_top, 1, str_b [i]); i ++; } // mantém a tela, mas verifica se há pressionamentos de botão counter =1000; while (contador> 0) {if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); } atraso (1); balcão--; } fade_down (); // imprime a linha c se houver. len =0; enquanto (str_c [len]) {len ++; }; // obtém o comprimento da mensagem offset_top =(31 - ((len - 1) * 4)) / 2; i =0; while (str_c [i]) {puttinychar ((i * 4) + offset_top, 1, str_c [i]); i ++; } contador =1000; while (counter> 0) {// verificar se o botão foi pressionado if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); } atraso (1); balcão--; } fade_down (); // mantenha o visor em branco, mas verifique se o botão foi pressionado antes de iniciar novamente. contador =1000; while (counter> 0) {// verificar se o botão foi pressionado if (buttonA.uniquePress ()) {switch_mode (); Retorna; } if (buttonB.uniquePress ()) {display_date (); } atraso (1); balcão--; }} fade_down ();} /// mensagem de rolagem - não usada no momento - muito lenta.void scroll () {char message [] ={"Hello There"}; cls (); byte p =6; // pos atual em string byte chara [] ={0, 1, 2, 3, 4, 5}; // caracteres da string int x [] ={0, 6, 12, 18, 24, 30}; // xpos para cada byte de caractere y =0; // y pos // clear_buffer (); while (mensagem [p]! ='\ 0') {// desenha todos os 6 caracteres para (byte c =0; c <6; c ++) {putnormalchar (x [c], y, mensagem [chara [c]] ); // desenha uma linha de pixels desligada após cada caractere, caso contrário, as lacunas entre os caracteres têm pixels deixados neles do caractere anterior para (byte yy =0; yy <8; yy ++) {plot (x [c] + 5, aa, 0); } // tira um de cada posição dos caracteres x [c] =x [c] - 1; } // redefine um caractere se ele saiu da tela para (byte i =0; i <=5; i ++) {if (x [i] <-5) {x [i] =31; chara [i] =p; p ++; }}}} // display_date - imprime o dia da semana, data e mês com um cursor piscando effectvoid display_date () {cls (); // leia a data do byte DS1307 dow =rtc [3]; // dia da semana 0 =domingo byte date =rtc [4]; byte mês =rtc [5] - 1; // array de nomes de meses a serem impressos no display. Alguns são abreviados, pois temos apenas 8 caracteres para brincar com os char monthnames [12] [9] ={"janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho" , "Agosto", "setembro", "outubro", "novembro", "dezembro"}; // imprime o nome do dia // obtém o comprimento do texto em pixels, dessa forma podemos centralizá-lo na exibição divindin os pixels restantes b2 e usando isso como um byte de deslocamento len =0; while (dias cheios [dow] [len]) {len ++; }; deslocamento de byte =(31 - ((len-1) * 4)) / 2; // nosso deslocamento para centralizar o texto // imprime o nome int i =0; while (daysfull [dow] [i]) {puttinychar ((i * 4) + offset, 1, daysfull [dow] [i]); i ++; } atraso (1000); fade_down (); cls (); // imprime numerais de data char buffer [3]; itoa (data, buffer, 10); deslocamento =10; // deslocar para o texto central se 3 caracteres - por exemplo 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]); atraso (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 ++; } atraso (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; } atraso (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. return 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; } atraso (50); } //pick the mode switch(setting_mode){ case 0:set_random(); pausa; case 1:set_ampm(); pausa; case 2:set_time(); pausa; case 3:set_intensity(); pausa; 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
 Sem visualização (somente download). 

Esquemas


Processo de manufatura

  1. Sequenciador de LED
  2. Relógio de cuco
  3. MATLAB - Matriz
  4. Batalha do Mini Boss
  5. Relógio mestre
  6. Relógio de Berlim
  7. Relógio POV de LED estilo analógico
  8. Matriz LED + Display da porta do sensor de movimento [Arduino Holiday]
  9. Iluminação LED 8x por som
  10. Arduino Quadruped