Que o Arduino pode ser utilizado para uma infinidade de coisas já sabemos, mas que tal gerar sinais de vídeo? O Arduino consegue? A resposta é sim, e isso é feito utilizando-se a biblioteca TVout escrita por Myles Metzer, que torna fácil mostrar caracteres, e nem tão fácil assim, figuras. A página da biblioteca, que contém tutorias e informações está disponível aqui.
Utilizando a biblioteca TVout é possível gerar sinais PAL ou NTSC, lembre-se que o padrão no Brasil é o PAL, à resolução de 128×96 pixels em preto e branco, não é nehum Full HD com milhões de cores, porém é mais do que suficiente para entreter qualquer hobista, além disso, a conexão é entre Arduino e TV é muito simples e rápida de se fazer.
Essa biblioteca é usada no hackvision , que é uma placa vídeo game baseada em Arduino, e no video game shield.
Material Necessário:
1 Placa Arduino(Mega, UNO, Nano… tanto faz).
1 Resistor de 1kΩ(marrom,preto, vermelho).
1 Resistor de 470Ω(amarelo,violeta, marrom).
1 Conector RCA fêmea(retirei o meu de sucata, porém ao invés disso, um cabo RCA pode ser cortado e usado ).
Protoboard.
Jumpers.
Sim, para mostrar vídeo em sua TV usando um Arduino é necessário apenas isso, componentes que podem ser encontrados em qualquer loja de eletrônica.
Montagem
A montagem, como dito é muito simples. O esquemático pode ser visto na figura abaixo:
Na figura não está muito claro,por causa do design do conector, mas os resistores devem ser ligados ao pino no centro do conector enquanto a “casca” externa do conector deve ser conectada ao terra (ground) do Arduino.
As conexões podem variar dependendo da placa Arduino utilizada, nos modelos Uno, Nano, Decimila e Duemilanove baseados no microcontrolador Atmega328 as conexões são como na figura acima. As imagens abaixo foram retiradas do msgs dias dos namorados da biblioteca e mostram a ligação para cada Modelo.
Como pode ser visto na figura abaixo, as conexões mudam para o Arduino Mega que possui um microcontrolador diferente, o Atmega1280 ou 2560 e para o presente dia dos namorados ideias, que é uma placa baseada em Arduino e usa o Atmega644 ou 1284, e é utilizada no projeto https://dragaosemchama.com/cacau-show-presente-para-namorada/ que visa impressoras 3D caseiras e replicantes.
https://dragaosemchama.com/como-amarrar-o-namorado/
Download e instalação da biblioteca
Primeiro é necessário baixar a biblioteca TVout no msgs dias dos namorados da mesma ou aqui. Depois de baixar a biblioteca instale a na IDE do Arduino, extraindo os arquivos baixados na pasta “libraries” onde estiver instalado sua IDE do Arduino.
Depois de terminada a instalação, estamos prontos para utilizar as funções disponíveis na biblioteca e mostrar algo em uma TV.
Código
O código a seguir mostra alguns bitmapss na TV, você pode criar suas próprias imagens para mostrar na tela, os arquivos met.h e invader.h foram criados por mim e devem ser baixados aqui, caso você queira adicioná-los ao seu código.
O resolução utilizada no código é 120×96 pixels, sendo o ponto 0,0 o canto superior esquerdo da televisão, você pode exibir o texto ou uma imagem em um ponto específico, se orientando a partir desse ponto.
#include <TVout.h> #include <fontALL.h> #include "met.h" #include "invader.h" TVout TV; void setup() { TV.begin(PAL,120,96); TV.select_font(font6x8); TV.println(0,40,"Arduino e TV com a\nbiblioteca TVout\n"); TV.delay(2500); TV.clear_screen(); TV.println(0,40,"Desenhando Imagens:"); TV.delay(1500); TV.clear_screen(); TV.bitmap(18,0,met); TV.delay(10000); for(int i=0;i<90;i++){ TV.clear_screen(); TV.bitmap(i,0,invader); TV.delay(100); } for(int i=90;i>0;i--){ TV.clear_screen(); TV.bitmap(i,0,invader); TV.delay(100); } TV.clear_screen(); TV.print(9,44,"Dragao sem Chama"); TV.delay(2000); } void loop() { }
Baixe o código e os arquivos .h aqui.
Me perdoem pela qualidade ruim do vídeo, foi que deu pra conseguir.
*ATENÇÃO* O vídeo contém padrões com luzes piscantes, então se você possui algum problema de saúde relacionado a esses padrões, recomendo que não assista.
Como mostrar seus próprios bitmaps
Para mostrar suas imagens bitmap você deve:
1- Em um programa de edição de imagens( o bom e velho paint serve), redimensione a imagem que se quer exibir para um tamanho menor que a resolução de 128×90 pixels. Salve a imagem como Bitmap monocromático. Abaixo um exemplo:
2- Baixe o programa Image2Code, ele serve para transformar as imagens bitmap em código.
3- Abra o Image2Code e selecione a imagem que você editou e transformou em bitmap, depois selecione a terceira opção da esquerda para a direita.
A opção “Invert Image”, se ativada, trocará as cores da sua imagem, então vai depender do que você quer mostrar, por exemplo, o space invader no vídeo não foi invertido já que ele é “branco no preto”. Caso a imagem estivesse sido invertida, ia ficar algo “preto no preto”, então pense um pouco antes para saber se sua imagem precisa ter as cores invertidas.
4- Deixe a opção C Array Writer e clique em “Convert”. Um arquivo do bloco de notas será aberto como na imagem:
5- Apague:
- Os ‘{‘ e ‘}’, use a ferramenta substituir, em editar. Substitua-os(opção ‘Substituir tudo’) por nada ‘ ‘(deixe como está ou coloque um espaço).
- A última vírgula do arquivo.
6- Agora crie um arquivo cpp, pode ser no bloco de notas, com o seguinte código, substituindo os ‘link’ pelo nome que desejar, porém é melhor, para evitar bagunça, colocar o nome da imagem.
#include "link.h" PROGMEM const unsigned char link[] = { 90,90, 0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x03,0xFF,0xC0,0x07,0xFF,0xFC,0x00,0x00,0x00,0x00, 0x00,0x00,0x03,0xFF,0xC0,0x07,0xFF,0xFC,0x00,0x00,0x00,0x00, 0x00,0x00,0x03,0xFF,0xC0,0x07,0xFF,0xFC,0x00,0x00,0x00,0x00, 0x00,0x00,0x03,0xFF,0xC0,0x07,0xFF,0xFC,0x00,0x00,0x00,0x00, 0x00,0x00,0x03,0xFF,0xC0,0x07,0xFF,0xFC,0x00,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xC0,0x00,0x00,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xC0,0x00,0x00,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xC0,0x00,0x00,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xC0,0x00,0x00,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xC0,0x00,0x00,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xF0,0x3F,0xFF,0xFF,0x03,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xF0,0x3F,0xFF,0xFF,0x03,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xF0,0x3F,0xFF,0xFF,0x03,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xF0,0x3F,0xFF,0xFF,0x03,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xF0,0x3F,0xFF,0xFF,0x03,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xF0,0x3F,0xFF,0xFF,0x03,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7E,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x7C,0x00,0x3E,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x7F,0xF0,0x3E,0x00,0x1F,0x03,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xF0,0x3E,0x00,0x1F,0x03,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xF0,0x3E,0x00,0x1F,0x03,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xF0,0x3E,0x00,0x1F,0x03,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xF0,0x3E,0x00,0x1F,0x03,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xF0,0x3E,0x00,0x1F,0x03,0xFF,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFE,0x00,0x00, 0x03,0xE0,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFE,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x00,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x00,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x00,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x00,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x00,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x00,0x00,0x1F,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x1F,0xFF,0xF0,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00, 0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00 };
Salve como “nomedaimagem.cpp” selecionando a opção “todos os arquivos”.
7- Novamente no boloco de notas, crie um arquivo com o seguinte conteúdo, substituindo ‘LINK’ e ‘link’ pelo nome que você colocou no arquivo anterior.
# include # ifndef LINK_H # define LINK_H extern const unsigned char link[]; #endif
E salve como “nomedaimagem.h”, lembrando de selecionar a opção “todos os arquivos”.
8 – Por fim, coloque esses arquivos na pasta do seu código e use-os como:
TV.bitmap(x,y,Bitmap);
Onde x e y são as coordenadas onde se quer inserir a imagem, e ‘link’ deve ser substituído pelo nome que você deu aos seus arquivos.
Exemplo:
TV.bitmap(20,0,link);
Qualquer dúvida, deixe nos comentários.
É isso pessoal! Idéias? que tal implementar algum tipo de jogo? Visor de gráficos? muita coisa bacana pode ser feita com esse esquema. Até outro post o/.
ola nao consgui passar minha programaçao, comos seria uma programaçao completa dps de ter feito tudo isso ? obg
Cara, faça upload simples como qualquer outro sketch.
Está faltando o nome das bibliotecas incluidas nos códigos
Pronto! Acho que alguma coisa aconteceu com o plugin que usamos para postar códigos. Veja que você tambem pode baixar o projeto no link abaixo do código.
cara ñ tá dando certo …:( ve o q pode ser.os erros são estes:
tv2.ino: In function ‘void setup()’:
tv2.ino:9:12: error: ‘PAL’ was not declared in this scope
tv2.ino:10:25: error: invalid conversion from ‘const unsigned char*’ to ‘uint8_t {aka unsigned char}’ [-fpermissive]
In file included from tv2.ino:1:0:
C:\Users\Mauricio\Documents\Arduino\libraries\TVout/TVout.h:103:7: error: initializing argument 1 of ‘void TVout::select_font(uint8_t)’ [-fpermissive]
void select_font(uint8_t f);
^
tv2.ino:11:6: error: ‘class TVout’ has no member named ‘println’
tv2.ino:14:6: error: ‘class TVout’ has no member named ‘println’
Olá Mauricio, você copiou a biblioteca certinho?
Tentou gravar algum dos exemplos que já vem na biblioteca?
Robson! percebi que mudei o nome do arquivo…..sem querer adicionei uma letra “t” no final (não me pergunte como!!!) Agora deu certinho,muito legal; vlw pelo Post mano!!!
Opa! Quem bom que deu certo! Volte mais vezes :)
Fala aew galera, eu ainda não testei Pq no momento estou sem pc mas planejo fazer um game bem da hora, um rpg com a visão de 45 graus estilo the legend of zelda se alguém quiser ajudar ou compartilhar conhecimentos me envie um email wattafukbr@gmail.com.
Galera, eu gostaria de inserir um valor de inclinação medida por um acelerômetro no canto inferior da tela mas mixando a imagem de uma câmera de forma que eu apenas acrescente a informação que quero na imagem da câmera sacaram? É possível fazer isso?
Tem como ter uma resolução com mais pixels tipo 240×192.
Isso é uma pergunta.
Alguém sabe se da para aumentar a resolução?
Boa tarde, gostei do site, minha pergunta e se consigo colorir os pixel, sera q e possível?
Infelizmente com essa biblitoeca não é possivel Cleiton, pra isso é necessário escrever valores analogicos no sinal da tv, o atmega sozinho não faz isso, são necessarios um conversor adc e outra biblioteca
O que acontece se colocarmos dois resistores com o mesmo valor em vez de um de 1k e outro de 470?
Grato!
Olá Pedro. Pode ser que mude a cor ou o brilho da imagem. Mas eu não recomendo mudar os resistores sem antes ter certeza do que está fazendo. Esses resistores são super comuns e podem ser encontrados em qualquer loja de eletrônica.
Tem como você mostrar como é feita a conexão do rca com os resistores. Vi outros projetos,mas não estou entendendo como é feita a soldagem e não sei qual é o rca utilizado (poderia mandar uma foto)?
OI Kyra
Desculpa, o cabo rca tem dois fios. Você tem que descobrir qual dos dois é o do sinal e qual é o GND, geralemente o GND parece uma malha (ou trança) e o outro tem a capinha de borracha.
O GND é super importante e deve ser conectado, caso você use um conector RCA em vez de cortar um cabo, o GND é a parte mais externa do conector enquanto o sinal fica no centro.
O cabo que eu usei era igual a esse, eu cortei na metade:
https://cdn.sparkfun.com/assets/f/c/9/7/4/5113df13ce395f0f7e000000.jpg
Qualquer dúvida só perguntar aqui novamente.
Não tá dando nenhum erro no código,mas não tá aparecendo nada na Tv. Tem que usar algum canal específico ou em AV?
Oi Kyra
Sim, a TV deve estar no AV
Oi Robson,
Parabéns, excelente matéria.
Em 2019 estava procurando sobre como gerar imagens a partir do Arduino, e o seu artigo/vídeo foi o primeiro que encontrei, falando sobre a biblioteca TVOut e a montagem do respectivo hardware.
Hoje consigo desenvolver meus próprios jogos de videogame utilizando a TVOut e outras bibliotecas.
Obrigado.