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

Cubo LED RGB 8x8x8

Componentes e suprimentos

RGB Diffused Common Anode
× 512
DM13A LED Driver
× 12
74HC138 Decodificação de 3 a 8 linhas
× 1
IRF9640 P-Channel MOSFET
× 8
Arduino UNO
Você também pode criar uma versão breadboard com apenas um ATmega328, cristal de 16 MHz, 2 x 22pf capacitores
× 1
Fonte de alimentação chaveada Digilent 5V 2.5A
× 1
Resistor 10k ohm
× 8
Resistor 1k ohm
× 8
Resistor 100 ohm
× 8

Aplicativos e serviços online

Arduino IDE

Sobre este projeto





Vídeo





Construir


Esta construção foi inspirada no cubo Kevin Darrah RGB.

Olhando para a constituição de Kevin, sua paciência não deve ter limites - infelizmente a minha tem.

Decidi substituir os 24 registradores de deslocamento, 192 transistores e 640 resistores por 12 drivers de LED DM13a (cerca de US $ 1 cada no eBay).

O próprio cubo foi construído como Kevin descreve no seguinte vídeo:

Assim que o cubo foi feito, criei uma placa de circuito impresso usando o método Toner para conter os chips do driver DM13A e o próprio cubo. Em vez de pagar o custo de uma placa feita comercialmente com chapeamento através do orifício, decidi fazer o cabeamento manual de cada conexão de LED ao pino DM13A apropriado usando um fio wire-wrap. Os arquivos Eagle incluídos contêm a versão com fio manual e também uma versão com roteamento automático (não testada).

O microprocessador e a placa de ânodo também contêm um MSGEQ7 - Equalizador Gráfico de Sete Bandas e um pré-amplificador de microfone que pretendo experimentar no futuro. No momento, eles não são usados. Se você quiser usar uma placa UNO ou Nano comercial, tudo o que você precisa é o decodificador 74HC138 de 3 a 8 linhas e os 8 MOSFETs de canal P e resistores associados. Você pode simplesmente conectá-los a alguma protoplaca, se desejar.

A fonte de alimentação de 5 V 20 W foi comprada no eBay. Fiz a caixa em pinho revestido de 40 mm x 9 mm.

Eu adicionei algumas animações ao software de cubo de Kevin, mas ele basicamente permanece inalterado.





Conclusão


Você deve conseguir comprar LEDs RGB difusos de ânodo comum 600 x 5mm no eBay por cerca de US $ 30. Mesmo depois de simplificar a eletrônica, a construção do cubo consumia muito tempo, mas no final das contas, recompensadora.

Código

  • Cube_8x8x8_V1.ino
Cube_8x8x8_V1.ino C / C ++
 / * O 8x8x8 RGB LED Cubeby John Bradnambaseado no trabalho de Kevin DarrahLatestV12 04/17 / 2013Notas de lançamento:V11- Corrigido bug com temporização BAM- Movido a configuração do pino em branco para ISR, então os pinos estão mortos até que sejam gravados na operação V12 bitwise para definir pins LOW estava incorreto deve ser PORTx &=~ (1 < // Biblioteca SPI usado para registrar dados para os registradores de deslocamento # define LATCH_PIN 2 // pode usar qualquer pino que você deseja travar os registradores de deslocamento # define BLANK_PIN 4 // mesmo, pode usar qualquer pino que desejar para isso, apenas certifique-se de puxar por a 1k a 5V # define DATA_PIN 11 // usado pelo SPI, deve ser o pino 11 # define CLOCK_PIN 13 // usado pelo SPI, deve ser 13 # define LAYER_A 5 // 74138 A Input # define LAYER_B 6 // 74138 A Input # define LAYER_C 7 // 74138 A Input # define SWITCH_PGM 10 // PB2 # define SWITCH_SEQ 9 // PB1 # define CUBE_SIZE 8 // Número de colunas, linhas ou níveis no cubo # define CUBE_MAX (CUBE_SIZE - 1) // Cubo máximo em dex # define LEDS_PER_LEVEL (CUBE_SIZE * CUBE_SIZE) // Número de LEDS por nível // *** variáveis ​​*** variáveis ​​*** variáveis ​​*** variáveis ​​*** variáveis ​​*** variáveis ​​*** variáveis ​​*** variáveis // Essas variáveis ​​são usadas por multiplexação e código de modulação de ângulo de bit // É assim que o brilho de cada LED é armazenado, // Cada LED só precisa de um 'bit' para saber se deve estar LIGADO ou DESLIGADO, então 64 bytes você 512 bits =512 LEDs // Como estamos modulando os LEDs, usando resolução de 4 bits, cada cor tem 4 matrizes contendo 64 bits cada byte red0 [LEDS_PER_LEVEL], red1 [LEDS_PER_LEVEL], red2 [LEDS_PER_LEVEL], red3 [LEDS_PER_LEVEL]; byte azul0 [LEDS_PER_LEVEL], azul1 [LEDS_PER_LEVEL], azul2 [LEDS_PER_LEVEL], azul3 [LEDS_PER_LEVEL]; byte verde0 [LEDS_PER_LEVEL], verde1 [LEDS_PER_LEVEL], verde2 [LEDS_PER_LEVEL], verde3 [LEDS_PER_LEVEL], verde3 [LEDS_PER_LEVEL] notará quanto mais resolução; mais de seu precioso nível de RAMint =0; // mantém o controle de qual nível estamos transferindo dados paraint anodeLevel =0; // isso aumenta através dos níveis de ânodoint BAM_Bit , BAM_Contador =0; // Variáveis ​​de modulação de ângulo de bit para controlar as coisasint animation =0; // Mantém o controle da animação no loop principal // **** configuração **** configuração **** configuração **** configuração **** configuração **** configuração **** configuração **** configuração **** configuração **** configuração **** configuração **** configuração **** configuraçãovoid configuração () {SPI.setBitOrder (MSBFIRST); // Bit Mais Significativo Primeiro SPI.setDataMode (SPI_MODE0); // Modo 0 borda ascendente dos dados, mantenha o clock baixo SPI.setClockDivider (SPI_CLOCK_DIV2); // Execute os dados em 16 MHz / 2 - 8 MHz //Serial.begin(115200);// se precisar? noInterrupts (); // elimina as interrupções até que todos estejam configurados // Usamos o Timer 1 para atualizar o cubo TCCR1A =B00000000; // Registre A todos os 0s, já que não estamos alternando nenhum pino TCCR1B =B00001011; // bit 3 definido para colocar no modo CTC, irá chamar uma interrupção em um contador de correspondência // bits 0 e 1 são definidos para dividir o relógio por 64, então 16MHz / 64 =250kHz TIMSK1 =B00000010; // bit 1 definido para chamar a interrupção em um OCR1A corresponde a OCR1A =30; // você pode brincar com isso, mas eu defini para 30, o que significa:// nosso relógio funciona a 250kHz, que é 1 / 250kHz =4us // com OCR1A definido para 30, isso significa que a interrupção será chamada a cada ( 30 + 1) x4us =124us, // o que dá uma frequência multiplex de cerca de 8 kHz // finalmente configurar o pinMode das saídas (LATCH_PIN, OUTPUT); // Latch pinMode (DATA_PIN, OUTPUT); // MOSI DATA pinMode (CLOCK_PIN, OUTPUT); // PinMode do relógio SPI (LAYER_A, OUTPUT); // 74138 PinMode de entrada A (LAYER_B, OUTPUT); // 74138 PinMode de entrada B (LAYER_C, OUTPUT); // 74138 Entrada C digitalWrite (LAYER_A, LOW); digitalWrite (LAYER_B, LOW); digitalWrite (LAYER_C, LOW); pinMode (SWITCH_PGM, INPUT); // Chave PGM 1 / PGM 2 pinMode (SWITCH_SEQ, INPUT); // Chave SEQ / COLOR // pinMode (BLANK_PIN, OUTPUT); // Habilitar saída importante para fazer isso por último, então os LEDs fazem não pisca na inicialização do SPI.begin (); // inicia a biblioteca SPI interrupts (); // deixe o show começar, isso permite o início da multiplexação} // *** start loop *** start loop *** loop inicial *** loop inicial *** loop inicial *** loop inicial *** loop inicial *** loop inicial *** iniciar loopvoid loop () {// Cada animação localizada em uma sub-rotina // Para controlar um LED, você simplesmente:// LED (nível que você deseja 0-CUBE_MAX, linha que deseja 0-CUBE_MAX, coluna que deseja 0-CUBE_MAX, brilho vermelho 0-15, brilho verde 0-15, brilho azul 0-15); if (digitalRead (SWITCH_PGM) ==HIGH) test_leds (); else {clean (); animação =animação + 1; switch (animação) {case 1:rainVersionTwo (20); pausa; caso 2:pasta (10); pausa; caso 3:sinwaveTwo (15); pausa; caso 4:randomColor (10); pausa; caso 5:wipe_out (10); pausa; caso 6:bouncyvTwo (15); pausa; caso 7:color_wheelTWO (10); pausa; caso 8:harlem_shake (); pausa; caso 9:ondulações (10); pausa; caso 10:animação =0; pausa; }}} // **** LED Rotina **** LED Rotina **** LED Rotina **** LED Routinevoid LED (nível interno, linha interna, coluna interna, byte vermelho, byte verde, byte azul) { // É aqui que tudo começa // Esta rotina é como os LEDs são atualizados, com as entradas para a localização do LED e seus níveis de brilho RG e B // Primeiro, verifique e certifique-se de que nada foi além dos limites, apenas fixe as coisas em ou 0 ou 7 para localização e 0 ou 15 para nível de brilho =restrição (nível, 0, CUBE_MAX); linha =restrição (linha, 0, CUBE_MAX); coluna =restrição (coluna, 0, CUBE_MAX); vermelho =restrição (vermelho, 0, 15); verde =restrição (verde, 0, 15); azul =restrição (azul, 0, 15); // Existem (CUBE_SIZE * CUBE_SIZE * CUBE_SIZE) LEDs no cubo, então quando gravamos no nível 2, coluna 5, linha 4, isso precisa ser convertido em um número de 0 a (CUBE_SIZE * CUBE_SIZE * CUBE_SIZE) - 1 // Os LEDs de primeiro nível estão primeiro na sequência, depois no segundo nível, depois no terceiro e assim por diante // Para um cubo 4 x 4 x 4, o (nível * (4 * 4)) é o que indexa o local de início do nível, então o nível 0 são LEDs 0 - 15, o nível 1 são LEDs 16 - 31 e assim por diante // se você olhou para baixo no cubo e olhou apenas para o nível inferior // 00 01 02 03 // 04 05 06 07 / / 08 09 10 11 // 12 13 14 15 // Para um cubo de 8 x 8 x 8 o (nível * (8 * 8)) é o que indica o local de início do nível, então o nível 0 são LEDs 0 - 63, nível 1 são LEDs 64 - 127 e assim por diante // se você olhou para baixo no cubo, e apenas olhou para o nível inferior // 00 01 02 03 04 05 06 07 // 08 09 10 11 12 13 14 15 // 16 17 18 19 20 21 22 23 // 24 25 26 27 28 29 30 31 // 32 33 34 35 36 37 38 39 // 40 41 42 43 44 45 46 47 // 48 49 50 51 52 53 54 55 // 56 57 5 8 59 60 61 62 63 // Então, se você incrementou o nível, o canto superior direito da grade acima começaria em (CUBE_SIZE * CUBE_SIZE) // A razão para fazer isso, é para que você não precise memorizar um número para cada LED, permitindo que você use nível, linha, coluna // Agora, que tal dividir por 8 aí? //... bem, temos 8 bits por byte e 64 bytes na memória para todos os 512 bits necessários para cada LED, então // dividimos o número que acabamos de encontrar por 8 e pegamos o inteiro dele, então sabemos qual byte esse bit está localizado // confuso? está tudo bem, vamos dar um exemplo, se quiséssemos escrever do LED para o último LED no cubo, escreveríamos 7, 7, 7 // dando (7 * 64) + (7 * 8) =7 =511, que está certo, mas agora vamos dividi-lo por 8, 511/8 =63,875, e pegar o int dele, obtemos 63, // este é o último byte na matriz, o que está certo, pois este é o último LED // Obtém o LED número 0 - 511 int wholebyte =(nível * LEDS_PER_LEVEL) + (linha * CUBE_SIZE) + coluna; // Pega o índice no array. Cada localização indexada contém um byte ou 8 bits; int whichbyte =int (wholebyte / 8); int whichbit =(wholebyte &7); // Tudo isso fará sentido em um segundo // Esta é a resolução de cor de 4 bits, então cada cor contém matrizes de x4 64 bytes, explicação abaixo:bitWrite (red0 [whichbyte], whichbit, bitRead (red, 0)); bitWrite (red1 [whichbyte], whichbit, bitRead (red, 1)); bitWrite (red2 [whichbyte], whichbit, bitRead (red, 2)); bitWrite (red3 [whichbyte], whichbit, bitRead (red, 3)); bitWrite (green0 [whichbyte], whichbit, bitRead (green, 0)); bitWrite (green1 [whichbyte], whichbit, bitRead (green, 1)); bitWrite (green2 [whichbyte], whichbit, bitRead (green, 2)); bitWrite (green3 [whichbyte], whichbit, bitRead (green, 3)); bitWrite (blue0 [whichbyte], whichbit, bitRead (blue, 0)); bitWrite (blue1 [whichbyte], whichbit, bitRead (blue, 1)); bitWrite (blue2 [whichbyte], whichbit, bitRead (blue, 2)); bitWrite (blue3 [whichbyte], whichbit, bitRead (blue, 3)); // Você está mais confuso agora? Você não deveria estar! Está começando a fazer sentido agora. Observe como cada linha é um bitWrite, que é, // bitWrite (o byte que você deseja escrever, o bit do byte a escrever e o 0 ou 1 que deseja escrever) // Isso significa que o 'whichbyte' é o byte de 0-63 em que o bit corresponde ao LED de 0-511 // Faz sentido agora por que fizemos isso? pegando um valor de 0-511 e convertendo-o em um valor de 0-63, já que cada LED representa um bit em // um array de 64 bytes. // Então a próxima linha é qual bit 'wholebyte- (8 * whichbyte)' // Isso está simplesmente pegando o valor do LED de 0-511 e subtraindo-o do BYTE seu bit foi localizado em tempos 8 // Pense nisso, byte 63 conterá LEDs de 504 a 511, então se você pegou 505- (8 * 63), você obtém um 1, o que significa que // o LED número 505 está localizado no bit 1 do byte 63 na matriz // é aquele isto? Não, você ainda tem que fazer o bitRead do brilho 0-15 que você está tentando escrever, // se você escreveu um 15 para VERMELHO, todas as 4 matrizes para aquele LED teriam um 1 para aquele bit, o que significa que ele estará ligado 100% // É por isso que as quatro matrizes leem 0-4 do valor inserido para VERMELHO, VERDE e AZUL // espero que tudo isso faça algum sentido?} // *** MultiPlex BAM *** MultiPlex BAM ** * MultiPlex BAM *** MultiPlex BAM *** MultiPlex BAM *** MultiPlex BAM *** MultiPlex BAMISR (TIMER1_COMPA_vect) {// Esta rotina é chamada em segundo plano automaticamente na frequência definida por OCR1A // Neste código, eu configurei OCR1A a 30, então isso é chamado a cada 124us, dando a cada nível no cubo 124us do tempo ON // Existem 8 níveis, então temos um brilho máximo de 1/8, já que o nível deve desligar antes que o próximo nível seja ligado // A frequência da multiplexação é então 124us * 8 =992us, ou 1 / 992us =cerca de 1kHz PORTD | =1 < =CUBE_SIZE) {fx =CUBE_MAX; fxm =-1; } pausa; caso 1:fy =fy + fym; if (fy <0) {fy =0; fym =1; } if (fy> =CUBE_SIZE) {fy =CUBE_MAX; fym =-1; } pausa; caso 2:fz =fz + fzm; if (fz <0) {fz =0; fzm =1; } if (fz> =CUBE_SIZE) {fz =CUBE_MAX; fzm =-1; } pausa; } switch (random (3)) {case 0:ftx =ftx + ftxm; if (ftx <0) {ftx =0; ftxm =1; } if (ftx> =CUBE_SIZE) {ftx =CUBE_MAX; ftxm =-1; } pausa; caso 1:fty =fty + ftym; if (fty <0) {fty =0; ftym =1; } if (fty> =CUBE_SIZE) {fty =CUBE_MAX; ftym =-1; } pausa; caso 2:ftz =ftz + ftzm; if (ftz <0) {ftz =0; ftzm =1; } if (ftz> =CUBE_SIZE) {ftz =CUBE_MAX; ftzm =-1; } pausa; }} // while clean ();} // wipeout // **** rainVersionTwo **** rainVersionTwo **** rainVersionTwo **** rainVersionTwo **** rainVersionTwovoid rainVersionTwo (int runtimeInSeconds) {int x [LEDS_PER_LEVEL ], y [LEDS_PER_LEVEL], z [LEDS_PER_LEVEL], ledcolor; int xx [LEDS_PER_LEVEL], yy [LEDS_PER_LEVEL], zz [LEDS_PER_LEVEL], xold [LEDS_PER_LEVEL], yold [LEDS_PER_LEVEL], zold [LEDS_PER_LEVEL]; para (int addr =0; addr  =200 &&ledcolor <300) {for (int addr =0; addr  =300 &&ledcolor <400) {} if (ledcolor> =500 &&ledcolor <600) {} ledcolor ++; if (ledcolor> =300) ledcolor =0; para (int addr =0; addr  

Esquemas

eagle_files_WfqPEUP7Mp.zip

Processo de manufatura

  1. Alarme de planta de alerta de sede
  2. Cubo LED 5x5x5
  3. Word Clock italiano
  4. Medidor Sigfox kWh
  5. Arduino RGB Color Mixer
  6. Monitor de temperatura Bluetooth
  7. DMX RGB LED externo
  8. Bloqueio controlado por gestos
  9. Uma entrada analógica isolada para Arduino
  10. Meça seu tempo de reação