Ledsticker: Meu primeiro projeto holístico de SW + HW

Traduções: en
20/02/2021

Era julho de 2019. Eu estava fazendo aula de Laboratório de Sistemas Embarcados e tinha que fazer um projeto final de minha escolha. Eu tive a ideia de fazer uma espécie de Guitar Hero usando um teclado como entrada, uma matriz de LED 8x8 para mostrar as notas e alto-falantes para tocar o som das notas. O problema era que a faculdade não disponibilizava matriz de LED nem alto-falantes, então eu decidi comprá-los, com a desculpa de que eu usaria eles depois para os meus projetos pessoais também.

Esse projeto deu certo, e o resultado pode ser visto no YouTube. Mas tendo finalizado ele, eu comecei a pensar o que eu iria fazer com a matriz de LED. Eventualmente, eu tive uma ideia que era tão legal que não tinha como não fazer.

Eu gostava de grudar adesivos que achasse legais na tampa do meu notebook, e eu tinha muitos deles, mas se você parar para pensar, adesivos não são tão interessantes. Então e se eu usasse a matriz de LED como um adesivo? Eu poderia grudá-la na tampa do notebook e conectá-la à porta USB tanto para fornecer energia quanto permitir que ela pudesse ser controlada. Eu seria capaz de programar qualquer coisa que eu quisesse que fosse mostrada na matriz.

Prototipagem

O primeiro passo para tornar isso realidade era construir um protótipo. Eu já tinha o módulo da matriz de LED, mas ele recebia os dados através de um barramento SPI ao invés do USB que eu queria usar. Eu comecei a procurar na internet por um circuito que convertesse USB para SPI e encontrei o CI MCP2210. Eu comprei alguns deles, mas também comprei sua versão em placa de desenvolvimento, com o CI na placa pronto para uso, para que o processo de prototipagem inicial fosse mais fácil.

Então eu procurei por um programa que implementasse a interface com o MCP2210 e encontrei MCP2210-Library. Eu comecei a escrever o meu próprio programa para inicializar o CI responsável por controlar a matriz de LED, o MAX7219, (presente no módulo de matriz de LED) através da chamada das funções dessa biblioteca para enviar os dados SPI através do USB (os quais o MCP2210 depois encaminhava através do barramento SPI para o MAX7219).

Nesse ponto eu tinha o mínimo necessário para verificar a viabilidade do projeto: os componentes de hardware necessários nos próprios módulos prontos para uso e um software mínimo capaz de interagir com os CIs e desenhar um padrão fixo na matriz de LED. Eu conectei o módulo USB-para-SPI no computador e módulo da matriz de LED e rodei o meu programa:

Módulos de USB-para-SPI e da matriz de LED conectados. Alguns LEDs estão ligados mostrando que está funcionando.

Tendo confirmado que o projeto de fato era viável, eu comecei a avançar nos passos necessários para torná-lo usável ao usuário final. A primeira coisa era tornar simples o controle da matriz de LED para os propósitos do projeto. Foi nesse ponto que eu defini o conceito de adesivo, que é central ao projeto.

Adesivos

Eu queria que fosse possível mostrar três coisas diferentes na matriz de LED:

  • Uma "imagem" estática, ou seja, ligar um padrão estático de LEDs.
  • Uma "imagem" animada, ou seja, mostrar uma sequência de padrões, cada um depois de um certo atraso
  • Uma "imagem" animada mas que fosse gerada dinamicamente da saída de um programa, para que eu pudesse mostrar uma simulação do Jogo da Vida, por exemplo.

Para permitir os dois primeiros casos de uso, eu defini o conceito de um adesivo estático. Ele consiste em um arquivo de texto contendo uma sequência de comandos que determinam o que é mostrado na matriz. Existem comandos para ligar e desligar pixels individuais, colunas ou linhas inteiras, ou a tela inteira, também para atualizar a tela, etc.

Para possibilitar o terceiro caso de uso, eu defini o adesivo dinâmico, que é qualquer programa, programado em qualquer linguagem, que escreve esses comandos de adesivo em sua saída. Dessa forma, uma linguagem de programação pode ser usada para gerar um adesivo mais complexo e dinâmico.

A ideia portanto é que o usuário executaria o programa ledsticker e passaria como parâmetro um adesivo estático ou dinâmico. Se fosse estático, os comandos seriam lidos e a matriz de LED atualizada de acordo. Se fosse dinâmico, ele seria executado e sua saída usada como um adesivo estático da mesma forma.

Para que tudo isso funcionasse, eu precisava tanto definir os comandos dos adesivos, como também implementar a leitura desses comandos pelo meu programa. Como um exemplo dos comandos, o mais simples é on R C, que liga o LED da linha R e coluna C.

Finalmente, para confirmar que esses comandos eram o suficiente, e também por diversão, eu implementei alguns adesivos: um único quadro com a cara do Creeper, um Tetris animado, e uma simulação gerada dinamicamente do Jogo da Vida.

Hardware

Nesse ponto eu já tinha o software totalmente operacional, então eu queria começar a avançar no lado do hardware. Eu estava usando módulos separados para a matriz de LED e para o USB-para-SPI, mas o objetivo mesmo era ter isso tudo em uma única e pequena placa de circuito impresso (PCB), para que fosse conveniente anexá-la à tampa do notebook.

Mas antes de começar a fazer a PCB, eu precisava ter certeza sobre o circuito. Eu tinha dois módulos separados que eu sabia que funcionavam, então eu usei eles como referência e li os datasheets do MAX7219 e do MCP2210 para criar o esquemático do circuito no KiCad.

Ao final, meu esquemático ficou com os dois CIs principais, MAX7219 e MCP2210, além de outros componentes passivos necessários para o funcionamento deles (resistores, capacitores e um cristal), bem como a matriz de LED e um conector USB mini.

O símbolo de esquemático (e footprint) da matriz de LED (modelo 1088AS) em especial eu precisei criar por contra própria, já que ele não existia. Eu segui a série de introdução ao KiCad da DigiKey para isso.

Com o circuito decidido, eu soldei todos os componentes e conexões em uma placa universal (teria sido mais fácil usar uma protoboard, mas eu não tinha uma boa) para testar. A parte mais difícil foi que o MCP2210 é um dispositivo de montagem superficial (SMD), e SMDs não são feitos para serem soldados em uma placa universal. O que eu fiz foi comprar uma PCB adaptadora de SMD com o tamanho correto de pinos para que eu conseguisse soldar o CI nela e soldá-la na minha placa. Tudo isso ficou assim:

Placa protótipo para o Ledsticker. Todos os componentes e conexões estão soldados.

Depois de testar essa placa com alguns adesivos e concluir que estava funcionando bem, a última coisa que restava era fazer a PCB.

PCB

Eu nunca tinha feito uma PCB, e a ideia de finalmente aprender a fazer uma foi uma das coisas que me motivou a fazer esse projeto para começo de conversa.

Eu aprendi praticamente tudo seguindo a série de introdução ao KiCad da DigiKey que eu já mencionei. Há muitos passos diferentes em fazer uma PCB, mas eles não chegam a ser difíceis, só trabalhosos às vezes. Posicionar os componentes de uma forma compacta tendo em mente as ligações que precisariam ser feitas foi bastante complicado, mas foi um desafio divertido.

Depois que finalizei o projeto no KiCad, eu encomendei a PCB da OSHPark. Depois de 3 longos meses esperando (por conta de demoras no transporte de navio devido à pandemia), a placa finalmente chegou.

Depois de tanto tempo esperando pela placa, eu não perdi tempo para soldar. Peguei todos os componentes e soldei tudo no mesmo dia. Aqui estão todos os componentes junto com a PCB:

PCB customizada para o Ledsticker no topo. Todos os componentes que serão soldados em baixo.

Metade do caminho (era o que eu pensava):

PCB com apenas alguns dos componentes soldados.

Soldar os componentes SMD (MCP2210 e o conector USB mini) foi muito mais difícil do que o restante. O conector USB mini em particular foi praticamente impossível. Os contatos na PCB para os seus 5 pinos eram praticamente do mesmo tamanho que os pinos do conector em si, e não eram muito acessíveis para o ferro de solda. Mas depois de múltiplas tentativas, eu finalmente consegui. Aqui está a placa final:

PCB com todos os componentes soldados.

Nem preciso dizer que foi incrível ver minha própria PCB. Tem algo mágico em segurar algo que você mesmo projetou, que escrever software nunca poderia proporcionar. Ver o circuito todo muito bem organizado na PCB também deu uma impressão muito mais robusta e profissional (veja de novo a placa de prototipagem como comparação...).

Resultados

Com tudo finalmente pronto, a placa e o programa, era hora de brincar. O gif seguinte mostra tanto a linha de comando usada para carregar o adesivo quanto a placa sendo atualizada. Três adesivos são carregados em sequência. Primeiro uma cara de Creeper estática, depois uma animação de Tetris, e finalmente uma simulação do Jogo da Vida gerada por um programa em python "em tempo real" [1]:

GIF mostrando a linha de comando e a placa com os LEDs atualizando simultaneamente. Três adesivos são mostrados em sequência.

E isso marca o projeto como concluído! Calma, mas e a parte de grudar a placa na tampa do notebook? Bom, quando eu comecei esse projeto, eu tinha essa intenção por um motivo social: conforme eu andasse com o meu notebook pela universidade, pessoas iriam me perguntar sobre ele, então eu teria uma desculpa para ter conversas nerds sobre a placa e seria um ótimo começador de conversas. Mas com a pandemia, eu sempre estou em casa, então fazer isso não só seria inútil como aí nem mesmo eu veria a placa. E é por isso que eu estou adiando a anexação para depois que eu voltar a frequentar espaços públicos de novo. Mas só para dar uma ideia de como ficaria, eu grudei ela com fita adesiva só para essa foto:

Tampa do notebook com adesivos comuns cobrindo a maior parte e o Ledsticker no meio mostrando o adesivo de cara de Creeper.

Conclusão

Esse foi de longe meu projeto preferido. Realmente foi um projeto holístico, onde eu projetei tanto o software quanto o hardware e precisei pensar em muitos aspectos diferentes. No lado do software eu precisei criar comandos para prover uma boa interface com o usuário além de implementar o programa como um todo (a não ser pela comunicação com o MCP2210). No lado do hardware eu investiguei datasheets para projetar o circuito, organizei tudo para ser compacto e fiz minha primeira PCB!

Se você achou o projeto interessante, eu te convido a fazer sua própria placa ledsticker e criar seus próprios adesivos! Tudo é aberto. Você pode encontrar o programa de linha de comando junto com informações detalhadas sobre ele em ledsticker. O esquemático da placa junto com a descrição do hardware podem ser encontrados em ledsticker-hw. Você também pode encomendar a PCB diretamente da OSHPark caso queira (eu não vou receber nada por isso). Ah, e se você fizer a placa ou um adesivo, eu adoraria saber! 😃 (Você pode encontrar meu email na página Sobre).

Ledsticker with a Glider sticker. The Glider is walking diagonally on loop.
[1]Não é realmente em tempo real. O programa do adesivo dinâmico é executado o mais rápido possível, preenchendo o buffer de entrada do ledsticker, que é então consumido quadro a quadro muito mais lentamente, dependendo do FPS que foi configurado.