4095 LEDs e tudo-tudo-tudoSurpreendentemente, o controlador ATmega328, subjacente ao Arduino Uno, lida com a saída da imagem em um monitor. Tudo acabou sendo um console de bolso (pesando vários quilos), no qual um jogo baseado em Space Invaders foi costurado. Os planos de criar outra coisa, porque resta muita memória livre.
Abaixo do recorte, você pode ler sobre como essa tela é organizada e como pode ser controlada.
Às vezes, em vez de encontrar
computadores antigos na coleção , eu os construo a partir de
materiais improvisados .
Desta vez, eu queria fazer algo compacto com uma resolução no nível de consoles e computadores do início dos anos 80. É verdade que a tela de 64x64 pixels não chega ao Atari 2600, mas em até 64 pixels a mais que a tela do Nokia 3310, onde também havia jogos. Portanto, deveria ter sido suficiente com uma margem pelo menos para um jogo confortável de tetris ou pong.
Além da tela, consegui uma placa compatível com o Arduino Uno e comecei a pensar em como voar com todas essas coisas.
A Adafruit vende esses displays e você pode encontrar
exemplos de seu uso em seu site. Há também um link para a
biblioteca para trabalhar com eles. A biblioteca suporta o Arduino Uno e o Arduino Mega.
Esta biblioteca organiza a memória de vídeo, onde armazena cores de pixel. O programa do usuário repõe esses pixels e a imagem é exibida no manipulador de interrupção do timer. Com telas pequenas, isso funciona bem, mas no meu caso esse método não é bom. Mesmo que meio byte seja alocado para cada pixel (um bit por R, G, B e um extra), para uma matriz de 64x64, serão necessários 2 kilobytes de memória. E isso é tudo o que o ATmega328P possui. Você pode, é claro, usar um processador mais poderoso, mas esse não é o caminho dos Jedi.
Afinal, quem nos obriga a armazenar todas as linhas da tela de uma só vez? Você pode recalcular cada linha antes de exibi-la. Para gráficos primitivos de vários sprites, esses cálculos não devem demorar muito, portanto, tudo deve funcionar.
Era na
floresta de uma escola de informática de verão, era muito preguiçoso para procurar documentação sobre microcircuitos e rastrear o quadro para entender o que estava conectado. Portanto, selecionei o algoritmo para trabalhar com a exibição nas bibliotecas baixadas anteriormente:
- Defina o endereço da linha de saída nas entradas do visor
- Preencha a matriz com as cores dos pixels do sprite que se cruzam com a linha atual.
- Mudamos todos os pixels em um registro de mudança, que controla os LEDs
- Clicamos nos dados recebidos e os enviamos para as saídas dos registros
Como resultado, uma matriz com um tamanho de apenas quatro linhas da tela é selecionada para a memória de vídeo. Por que quatro? Isso ocorre porque, ao mesmo tempo, enviamos os dados em duas linhas - porque a matriz possui dois grupos de entradas: R1 / G1 / B1 e R2 / G2 / B2. Eles controlam duas linhas espaçadas 16 pixels.
Mas então por que não duas linhas, mas quatro? Acontece que a matriz 64x64 consiste em duas matrizes 32x64 independentes. Seria possível conectar saídas de processador separadas a cada uma, mas o ATmega328 não possui o suficiente. Felizmente, um fabricante atencioso forneceu a cascata dessas matrizes - a saída do registro de turno de um pode ser conectada à entrada do outro. Em seguida, obtemos a matriz lógica 32x128, exibida fisicamente como 64x64. Ou seja, em cada fase, precisamos inserir duas linhas de 128 pixels nos registros - e são 4 linhas da tela física.

Fizemos um protótipo do console durante a escola de informática de verão. O primeiro jogo foi algo remotamente parecido com o
Space Invaders .
Na realidade, os LEDs realmente queimaram seus olhos. É improvável que você possa ajustar o brilho usando o PWM - o ATmega não tem velocidade suficiente. Precisamos usar algum tipo de ARM ou FPGA.
A versão final que desenhei em uma caixa de madeira. A tela é protegida por plexiglass lixado. Devido à dispersão da luz, os olhos não ficam mais cansados, mas agora é mais difícil gravar o trabalho do console no vídeo - toda a imagem fica embaçada.
O programa inteiro usa 1101 bytes (53%) de RAM e 6432 (19%) bytes de ROM. Ainda há espaço para fazer vários jogos e menus para sua seleção.
Referências- Fontes do projeto: github.com/Dovgalyuk/BackspaceInvaders
- Descrição da matriz no adafruit: learn.adafruit.com/32x16-32x32-rgb-led-matrix
- Biblioteca de gerenciamento de matrizes Adafruit : github.com/adafruit/RGB-matrix-Panel
- Biblioteca Adafruit para desenhar primitivas gráficas: github.com/adafruit/Adafruit-GFX-Library
- Um projeto semelhante em um processador mais poderoso: learn.adafruit.com/ledgames-beaglebone-black-64x64-led-game/overview
- O artigo é sobre como gerenciar uma tela menor: geektimes.ru/post/275548