Índice:

Matriz RGB LED: 5 etapas
Matriz RGB LED: 5 etapas

Vídeo: Matriz RGB LED: 5 etapas

Vídeo: Matriz RGB LED: 5 etapas
Vídeo: matriz de led básica de 7x5 con PIC generando una letra mediante corrimiento de bit 2024, Julho
Anonim
Image
Image
Design de Hardware
Design de Hardware

Pesquise instrutível e você encontrará muitos projetos de matriz de LED. Nenhum deles era exatamente o que eu queria, que era explorar as interações de design de hardware e software para produzir algo e produzir o produto final em um PCB elegante com um driver que me permite desenhar na "tela de LED" usando alto nível construções (por exemplo, desenhar uma linha em oposição a definir pixels específicos). Esta parte foi importante para mim, já que muitos dos drivers de matriz de LED são básicos e não fornecem muito em termos de criação de imagem ou animação de maneira programática. Isso não significa que você não pode criar imagens e animações com os outros drivers, apenas que você teria que fazer um trabalho mais repetitivo de projeto para projeto.

Então, comecei a realizar minha visão. O primeiro passo foi projetar o hardware. Este foi provavelmente o mais desafiador para mim, pois minha formação é mais software. Novamente, havia muitos designs pré-fabricados e certamente os usei como inspiração, mas queria aprender fazendo, então criei um protótipo de uma matriz 4x4 em uma placa de ensaio. Aprendi muito com esse processo, pois minhas primeiras iterações não funcionaram. Mas fiz um design de hardware que funcionou, o que me permitiu começar a desenvolver um driver.

Escolhi o Arduino como minha plataforma de driver porque ele está amplamente disponível e tem muitas referências online. Embora a experiência de carreira tenha me permitido obter uma versão funcional de um driver de forma mais eficiente do que meus esforços de hardware, ainda havia muitas iterações enquanto otimizava o desempenho do driver para o microcontrolador ATMega e desenvolvia uma API de programação de que gostava.

Este Instructable documenta o design e alguns aprendizados importantes do meu projeto. Mais informações sobre este projeto podem ser encontradas em meu site aqui, incluindo kits completos que você pode comprar para construir sua própria matriz de LED RGB.

Etapa 1: Design de Hardware

O objetivo principal do meu design de hardware era criar uma série de LEDs RGB que eu pudesse programar, mas também não queria gastar muito dinheiro. A abordagem que decidi foi usar registradores de deslocamento 74HC595 para controlar os LEDs. A fim de minimizar o número de registradores de deslocamento necessários, organizei os LEDs RGB em um layout de matriz onde os ânodos comuns foram amarrados em linhas e os terminais de cátodo vermelho, verde e azul foram amarrados juntos em colunas. Para a matriz 4x4, o diagrama de circuito se parecia com o diagrama de circuito anexado.

Uma coisa que você notará imediatamente é que, dado o circuito da matriz, existem algumas configurações de iluminação por LED que não podem ser feitas com todos os LEDs desejados ligados ao mesmo tempo. Por exemplo, a matriz não pode acender simultaneamente dois LEDs que são diagonais um do outro porque alimentar as linhas e colunas fará com que os dois LEDs opostos acendam na diagonal perpendicular aos LEDs desejados. Para contornar isso, usaremos a multiplexação para examinar cada linha. Existem muitos recursos na web que cobrem a técnica de multiplexação, não vou tentar replicá-los aqui.

Como estou usando LEDs de ânodo comuns, isso significa que as linhas fornecem energia positiva e as colunas afundam no solo. A boa notícia é que os registradores de deslocamento 74HC595 podem fornecer e drenar energia, mas a má notícia é que eles têm um limite para a quantidade de energia que podem fornecer ou drenar. Os pinos individuais do 74HC595 têm um consumo máximo de corrente de 70 mA, mas é melhor manter menos de 20 mA. As cores individuais em nossos LEDs RGB têm, cada uma, cerca de 20 mA. Isso significa que o 74HC595 não pode alimentar diretamente uma linha inteira de LEDs se eu desejar ligá-los todos.

Portanto, em vez de alimentar a linha diretamente, o 74HC595 irá, em vez disso, acionar um transistor para cada linha, e o transistor ligará ou desligará a corrente que alimenta a linha. Como o projeto está usando LEDs de ânodo comum, o transistor de comutação será PNP. Se estivéssemos usando um LED de cátodo comum, o transistor de comutação seria NPN. Observe que, ao usar um transistor PNP para conduzir uma linha, a configuração do registrador de deslocamento para ligá-lo agora torna-se baixa, pois um transistor PNP precisa de uma voltagem negativa entre o emissor e a base para ser ligado, o que permitirá que a corrente positiva flua para o fileira.

Uma outra coisa a se considerar é o layout de bits desejado dos registradores de deslocamento. Ou seja, entre os registradores de deslocamento, quais bits controlam quais linhas ou colunas na matriz. O design que enviei é onde o primeiro bit, ou "bit mais significativo", enviado para os registradores de deslocamento em cadeia controlam a coluna do elemento vermelho de LEDs, o segundo bit controlou o elemento verde da primeira coluna, o terceiro bit controla os da primeira coluna elemento azul, o quarto bit controla o elemento vermelho da segunda coluna, … este padrão é repetido nas colunas da esquerda para a direita. Em seguida, o próximo bit enviado controla a última linha ou inferior, o próximo da penúltima linha, … isso é repetido até o último bit enviado, ou "bit menos significativo", controla a primeira linha ou superior na matriz.

Finalmente, eu precisava determinar quais resistores eu usaria para cada um dos LEDs no LED RGB. Embora você possa usar a fórmula padrão que combina a tensão direta e a corrente desejada para calcular o resistor necessário, descobri que definir a corrente de cada LED para 20 miliamperes resultou em uma cor esbranquiçada quando todos os LEDs vermelho, verde e azul estavam ligados. Então comecei a olhar para ele. Muito vermelho no branco significava aumentar os ohms do resistor do LED vermelho para reduzir a corrente. Eu repeti a troca de resistores de ohms diferentes até que encontrei uma combinação que produziu uma cor branca que eu senti que era a certa. A combinação final foi 180 Ω para o LED vermelho, 220 Ω para o LED verde e 100 Ω para o LED azul.

Etapa 2: construção de hardware - placa de ensaio

Construção de ferragens - placa de ensaio
Construção de ferragens - placa de ensaio
Construção de Hardware - Placa de Pão
Construção de Hardware - Placa de Pão

A primeira fase do construtor de hardware foi o breadboarding. Aqui fiz uma matriz 4x4 com os LEDs RGB. Essa matriz exigiria 16 bits para controlar, 12 para as colunas RGB e 4 para cada linha. Dois registradores de deslocamento 74HC595 podem lidar com tudo. Primeiro, pesquisei e projetei um circuito que pensei que funcionaria, depois o construí na placa de ensaio.

Provavelmente, o maior desafio da construção do breadboard foi gerenciar todos os fios. Peguei um kit de arame pré-formado para placas de ensaio, mas mesmo assim era um pouco pesado. Um truque que achei útil foi criar uma "porta" para conexão com a placa Arduino. Ou seja, em vez de conectar os pinos no Arduino diretamente aos vários pinos IC na placa de ensaio, dedique algumas linhas na placa de ensaio para ser o ponto de conexão para o Arduino e, em seguida, conecte os pinos de identificação relevantes a essas linhas. Para este projeto, você só precisa de cinco conexões com o Arduino: + 5V, terra, dados, relógio e trava.

Assim que a construção do breadboard foi concluída, eu precisei testá-la. No entanto, sem algum tipo de driver para enviar os sinais corretos aos registradores de deslocamento, não consegui testar se o layout do hardware funcionava.

Etapa 3: Design do software do driver

Image
Image

Dada a minha própria experiência profissional com desenvolvimento de software, essa foi a parte do projeto que provavelmente eu estava mais clara sobre o caminho a seguir. Eu pesquisei muitos dos outros drivers de matriz de LED baseados em Arduino. Embora certamente haja bons drivers disponíveis, nenhum tinha o design que eu queria. Meus objetivos de design do driver eram:

  • Fornece uma API de alto nível para poder criar imagens e animações de maneira programática. A maioria dos drivers que vi estavam mais focados em imagens codificadas. Além disso, como sou um programador C ++ profissional, eu queria usar um bom design orientado a objetos para implementar e gerenciar as atividades de desenho para a matriz de LED.
  • Use uma abordagem de buffer duplo para gerenciar a imagem na tela. Um buffer é o que é desenhado programaticamente, enquanto o outro representa o estado dos pixels da matriz em qualquer momento. A vantagem dessa abordagem é que você não precisa renderizar completamente a próxima atualização de quadro da tela entre os ciclos de atualização da multiplexação.
  • Use o PWM para permitir mais do que as sete cores primitivas que um RGB pode renderizar por meio de combinações simples dos elementos vermelho, verde e azul.
  • Escreva o driver de forma que ele "simplesmente funcione" com matrizes de LED RGB de tamanhos diferentes que seguem minha abordagem geral de design de matriz. Observe que, embora meu design de hardware use registradores de deslocamento 74HC595, espero que meu driver funcione com qualquer mecanismo liga / desliga de estilo de registrador de deslocamento que seja disposto usando um layout de bits semelhante ao meu design de hardware. Por exemplo, eu esperaria que meu driver trabalhasse com um projeto de hardware que usasse chips DM13A para controlar as colunas e um chip 74HC595 para controlar as linhas.

Se você quiser ir direto para o código do driver, pode encontrá-lo no GitHub aqui.

A primeira iteração do meu driver foi um pouco uma curva de aprendizado sobre os recursos da plataforma Arduino. A limitação mais óbvia é a RAM, que é de 2K bytes para o Arduino Uno e o Nano. O uso de objetos C ++ em tal cenário freqüentemente não é recomendado devido à sobrecarga de memória dos objetos. No entanto, achei que, se feito da maneira certa, o benefício dos objetos em C ++ superasse seu custo (em RAM).

O segundo grande desafio foi descobrir como implementar a modulação de largura de pulso por meio dos registradores de deslocamento para que eu pudesse gerar mais do que as sete cores primitivas do LED RGB. Tendo programado por muitos anos em plataformas Linux, eu estava acostumado a usar construções como threads para gerenciar processos que exigem um tempo consistente. O tempo da operação de atualização do registro de deslocamento acaba sendo muito crítico ao fazer um driver para uma matriz de LED que usa multiplexação. A razão é que, embora a multiplexação esteja acontecendo tão rápido que seus olhos não podem ver os LEDs individuais piscando, seus olhos podem perceber diferenças no tempo total agregado em que qualquer um dos LEDs está ligado. Se uma linha de LEDs ficar constantemente acesa por um longo período de tempo do que as outras, ela parecerá mais brilhante durante a multiplexação. Isso pode levar a um brilho irregular na matriz ou estroboscópio periódico da matriz como um todo (isso ocorre quando um ciclo de atualização leva mais tempo do que os outros).

Como eu precisava de um mecanismo de temporização consistente para fazer com que as atualizações de registro de deslocamento fossem consentidas, mas o Arduino não oferece suporte formalmente a thread, tive que criar meu próprio mecanismo semelhante a thread. Minha primeira iteração foi simplesmente criar um cronômetro de loop que dependesse da função loop () do Arduino e dispararia uma ação quando um certo período de tempo tivesse decorrido desde a última vez que a ação foi disparada. Esta é uma forma de "multitarefa cooperativa". Parece bom, mas na prática provou ser inconsistente quando a taxa de disparo foi medida em microssegundos. A razão para isso é que, se eu tivesse dois desses temporizadores de loop em funcionamento, uma de suas ações frequentemente demorava tempo suficiente para fazer com que a segunda ação fosse acionada mais tarde do que o desejado.

Descobri que a solução para esse problema é usar o mecanismo de interrupção de relógio nativo do Arduino. Esse mecanismo permite que você execute um pequeno trecho de código em intervalos muito consistentes. Portanto, projetei o código do driver em torno do elemento de design de usar uma interrupção de relógio para acionar o código para enviar os registradores de deslocamento da matriz a próxima atualização no ciclo multiplex. Para fazer isso e permitir que ocorram atualizações na imagem da tela para não interferir com um despejo ativo para os registradores de deslocamento (algo que chamaríamos de "condição de corrida"), usei uma abordagem de ter buffers gêmeos para os bits do registrador de deslocamento, um para escrever e um para ler. Quando o usuário está atualizando a imagem da matriz, essas operações ocorrem no buffer de gravação. Quando essas operações são concluídas, as interrupções são temporariamente suspensas (isso significa que a interrupção do relógio não pode ser acionada) e o buffer de gravação é trocado pelo buffer de leitura anterior e não é o novo buffer de leitura, então os interpretadores são reativados. Então, quando a interrupção do relógio dispara indicando que é hora de enviar a próxima configuração de bit para os registradores de deslocamento, essa informação é lida do buffer de leitura atual. Dessa forma, nenhuma gravação ocorre em um buffer que pode estar sendo lido durante uma interrupção do clock, o que pode corromper as informações enviadas para os registradores de deslocamento.

Projetar o resto do driver foi um caso relativamente simples de design orientado a objetos. Por exemplo, criei um objeto para gerenciar a imagem do bit de registro de deslocamento para qualquer estado de tela. Ao encapsular o código pertencente ao gerenciamento de imagem de bits, a criação da abordagem de buffers gêmeos mencionada anteriormente foi um exercício direto. Mas eu não escrevi este Instructable para exaltar as virtudes do design orientado a objetos. Outro elemento de design inclui o conceito de um Glifo e uma imagem RGB. Um Glyph é uma construção de imagem básica que não possui informações de cor inatas. Você pode pensar nisso como uma imagem em preto e branco. Quando o glifo é desenhado na tela de LED, informações de cor são fornecidas para indicar como os pixels "brancos" devem ser coloridos. Uma imagem RGB é uma imagem em que cada pixel tem suas próprias informações de cor.

Eu encorajo você a revisar os exemplos de esboço do Arduino e revisar a documentação do cabeçalho do driver para se familiarizar com como usar o driver para criar imagens e animações em uma matriz RGB LED.

Etapa 4: LED Ghosting

LED Ghosting
LED Ghosting
LED Ghosting
LED Ghosting

Em uma matriz de LED, "fantasma" é o fenômeno de um LED na matriz brilhando quando não é desejado, geralmente um nível muito reduzido. Meu design de hardware original era suscetível a fantasmas, principalmente na última linha. A causa disso é devido a duas coisas: os transistores não desligam imediatamente e a capacitância parasita nos LEDs RGB.

Conforme examinamos as linhas, devido ao fato de que os transistores não desligam imediatamente, a linha anterior no ciclo de varredura ainda está parcialmente energizada quando a próxima linha é ligada. Se uma determinada coluna que estava desligada na linha anterior for ligada novamente quando a nova linha for energizada, o LED dessa coluna na linha anterior acenderá por um curto período enquanto o transistor de comutação da linha anterior ainda está no processo de girar desligado. O que faz com que o transistor demore bastante para desligar é a saturação na base do transistor. Isso faz com que o caminho coletor-emissor do transistor continue a conduzir quando a corrente é removida da base, pelo menos até que a saturação se dissipe. Dado que nosso ciclo de atualização de multiplexação faz com que as linhas sejam ativadas propositadamente por um período de tempo medido em microssegundos, a quantidade de tempo que o transistor saturado da linha anterior permanece condutor pode ser uma fração perceptível disso. Como resultado, seu olho pode perceber por uma pequena quantidade de tempo que o LED da linha anterior fica ligado.

Para corrigir o problema de saturação do transistor, um diodo Schottky pode ser adicionado ao transistor entre a base e o coletor para causar uma pequena corrente de retorno à base quando o transistor estiver ligado, evitando que o transistor fique saturado. Isso, por sua vez, fará com que o transistor desligue mais rapidamente quando a corrente for removida da base. Consulte este artigo para obter uma explicação detalhada desse efeito. Como você pode ver na imagem desta seção, sem o diodo o fantasma é bastante perceptível, mas adicionar o diodo ao circuito para cada linha remove significativamente o fantasma.

LEDs RGB são suscetíveis a outro fenômeno chamado capacitância parasita. A causa raiz disso é o fato de que cada um dos três LEDs coloridos na unidade de LED RGB tem tensões diretas diferentes. Essa diferença nas tensões diretas pode causar o efeito da capacitância elétrica entre cada uma das cores individuais do LED. Uma vez que uma carga elétrica é criada na unidade de LED quando ligada, quando a energia é removida, a capacitância parasita precisa ser descarregada. Se aquela coluna de LED estiver ligada para alimentação de outra linha, a carga parasita será descarregada através do LED dessa coluna e fará com que ele brilhe brevemente. Este efeito é bem explicado neste artigo. A solução é adicionar um caminho de descarga para essa carga parasita diferente do próprio LED e, em seguida, dar ao LED tempo para descarregar antes que a coluna seja energizada novamente. No projeto do meu hardware, isso é feito adicionando um resistor a cada linha de alimentação que conecta a força ao aterramento. Isso fará com que mais corrente seja consumida com a linha alimentada, mas fornece um caminho de descarga para a capacitância parasita quando a linha não está energizada.

É importante notar, no entanto, que na prática eu acho o efeito da capacitância parasita quase imperceptível (se você procurar por ele, poderá encontrá-lo), e por isso considero a adição desse resistor extra opcional. O efeito do tempo de desaceleração para transistores saturados é muito mais forte e perceptível. No entanto, se você inspecionar as três fotos fornecidas nesta seção, poderá ver que os resistores removem completamente qualquer fantasma que ainda ocorra além dos tempos lentos de desligamento do transistor.

Etapa 5: Fabricação final e próximas etapas

Image
Image

A fase final deste projeto foi para mim criar uma placa de circuito impresso (PCB). Usei o programa de código aberto Fritzing para projetar meu PCB. Embora houvesse muitas tarefas repetitivas para realizar o layout de 100 LEDs em uma placa 10x10, na verdade eu achei essa fase do projeto estranhamente satisfatória. Descobrir como cada caminho elétrico seria disposto foi como um quebra-cabeça, e resolvê-lo criou uma sensação de realização. Como não fui configurado para fabricar as placas de circuito, usei um dos muitos recursos online que fazem pequenas execuções de placas de circuito impresso personalizadas. Soldar as peças foi bastante simples, já que meu projeto utilizou todas as peças através do orifício.

No momento em que escrevo este Instructable, tenho os seguintes planos para meus projetos RGB LED Matrix:

  1. Continue a melhorar o driver na camada API para habilitar mais funcionalidade de alto nível para o programador, principalmente a rolagem de texto.
  2. Crie designs de matriz maiores, como 16x16 ou até 16x32.
  3. Explore o uso de MOSFETs em vez de BJTs para a comutação de energia da linha
  4. Explore o uso de drivers de corrente constante DM13As em vez de 74HC595s para a troca de coluna
  5. Crie drivers para outras plataformas de microcontrole, como Teensy, ODROID C2 ou Raspberry Pi.

Observe que tanto o design de hardware quanto o driver foram lançados sob a licença de código aberto GPL v3 neste repositório GitHub. Além disso, mesmo que os fabricantes de PCB façam "pequenas execuções" do meu projeto de PCB, ainda recebo muito mais do que pessoalmente preciso. Portanto, estou vendendo kits completos para meus vários designs de matriz de LED RGB (PCB e todas as peças incluídas) no meu site aqui.

Recomendado: