Nesse post veremos como montar um Placar de Truco portátil com Arduino. Os materiais necessários para montagem desse projeto são de fácil acesso e a programação apresenta vários conceitos fundamentais para quem deseja se aprofundar no Arduino. O placar pode ser montado em uma protoboard ou você pode criar uma placa de circuito impresso compacta a partir do design fornecido.
Materiais Necessários
Para montagem desse projeto vamos precisar dos seguintes materiais:
- Arduino Nano / Uno / Pro Mini
- Display OLED 0.91″ 128×32
- Botões Tácteis (Push Buttons)
- Conector de Bateria 9V
- Bateria 9V
- Protoboard
- Jumpers
Circuito Eletrônico
Para montagem do projeto você deve conectar:
- Pino VCC do Display no 5V do Arduino
- Pino GND do Display no GND do Arduino
- Pino SDA do Display na porta A4 do Arduino
- Pino SCL do Display na porta A5 do Arduino
- Pino GND do Arduino em um dos terminais de cada um dos Push Buttons
- Terminal remanescente de cada um dos Push Buttons em uma porta digital do Arduino
- Pino VIN do Arduino no positivo da bateria de 9V
- Pino GND do Arduino no negativo da bateria de 9V
Arduino | Display | Bateria | Botão 1 | Botão 2 | Botão 3 |
---|---|---|---|---|---|
5V | VCC | ||||
GND | GND | Negativo | Terminal 1 | Terminal 1 | Terminal 1 |
A4 | SDA | ||||
A5 | SCL | ||||
D7 | Terminal 2 | ||||
D5 | Terminal 2 | ||||
D3 | Terminal 2 | ||||
VIN | Positivo |
Código do Placar de Truco
Nesse projeto, precisaremos usar a biblioteca Adafruit SSD1306 para controlar o display OLED. Ela pode ser facilmente instalada pela gerenciador de bibliotecas da IDE do Arduino conforme a imagem abaixo.
Logo no início do código, temos as definições dos parâmetros relativos a montagem do projeto:
// Portas------------ #define Botao1 7 #define Botao2 5 #define BotaoTruco 3 // ------------------ // Delay-------------- #define atraso 2000 #define debounce 500 // ------------------- // Parâmetros do Display---- #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 32 #define OLED_RESET 4 #define OLED_ADDRESS 0x3C // -------------------------
Em Portas, temos os pinos do Arduino onde estão conectados os Push Buttons, nesse caso usamos os pinos 3, 5 e 7 mas você pode utilizar qualquer um dos pinos digitais.
Em Delay, definimos o tempo de debounce em milissegundos que, por padrão, está definido como 500 (meio segundo). Caso enfrente problemas com registro duplicado ao apertar os botões, aumente gradualmente esse valor até que o problema seja sanado. Para maiores detalhes sobre o uso de Push Buttons com o Arduino acesse o post “Debounce, o que é e como resolver via software“.
Os Parâmetros do Display já estão configurados para um display OLED 128×32. Caso deseje utilizar um display de 128×64 faça as alterações necessárias de acordo com as especificações do fabricante.
void setup() { // Define o padrão das portas onde os botões estão conectados como HIGH pinMode( Botao1, INPUT_PULLUP); pinMode( Botao2, INPUT_PULLUP); pinMode( BotaoTruco, INPUT_PULLUP); // Configura o Display OLED OLED.begin( SSD1306_SWITCHCAPVCC, OLED_ADDRESS); OLED.setTextColor( WHITE); OLED.clearDisplay(); tela_inicial(); //Exibe tela inicial }
No início da função setup, definimos as portas do Arduino onde os botões estão conectados como entrada mantida em estado alto por padrão. Para entender melhor o uso de entradas pull-up no Arduino confira o nosso post “Entendendo o pull-up e pull-down no Arduino“. Logo em seguida inicializamos o display OLED e chamamos a função tela_inicial, que exibe uma animação de boas-vindas com o nome do projeto.
void loop() { // Jogo Normal if( pontos[0] < 11 && pontos[1] < 11) rodadas(); // Equipe 1 Venceu if( pontos[0] >= 12) vencedor( 1); // Equipe 2 Venceu if( pontos[1] >= 12) vencedor( 2); // Equipe 1 com 11 pontos if( pontos[0] == 11 && pontos[1] < 11) mao_de_onze( 1); // Equipe 2 com 11 pontos if( pontos[1] == 11 && pontos[0] < 11) mao_de_onze( 2); // Ambas as equipes com 11 pontos if( pontos[1] == 11 && pontos[0] == 11) ambas_com_onze(); }
Na função loop, checamos constantemente a pontuação de cada equipe para saber o estado atual do jogo. De acordo com o momento em que o jogo se encontra, a função apropriada é chamada.
O código completo está disponível abaixo, assim como neste arquivo para download. Para saber como carregar o código no Arduino acesse o nosso post “Primeiros passos com Arduino“.
//Bibliotecas---------------- #include <Wire.h> #include <Adafruit_SSD1306.h> //--------------------------- //Portas------------- #define Botao1 7 #define Botao2 5 #define BotaoTruco 3 //------------------- //Delay--------------- #define atraso 2000 #define debounce 500 //-------------------- //Parâmetros do Display----- #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 32 #define OLED_RESET 4 #define OLED_ADDRESS 0x3C //-------------------------- //Protótipos das Funções---------- void truco(); void placar(); void rodadas(); void nova_partida(); void tela_inicial(); int obter_resposta(); void ambas_com_onze(); void vencedor(int champ); void mao_de_onze(int equipe_onze); //-------------------------------- //Variáveis Globais-------------------- bool EstadoAtual_1 = HIGH; bool EstadoAtual_3 = HIGH; bool EstadoAtual_Truco = HIGH; bool EstadoAnterior_1 = HIGH; bool EstadoAnterior_2 = HIGH; bool EstadoAnterior_Truco = HIGH; unsigned short int resposta; unsigned short int tentos = 0; unsigned short int pontos[2] = { 0, 0}; //------------------------------------- //Instancia o display OLED-------------------------------------------- Adafruit_SSD1306 OLED(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { //Define o padrão das portas onde os botões estão conectados como HIGH pinMode(Botao1, INPUT_PULLUP); pinMode(Botao2, INPUT_PULLUP); pinMode(BotaoTruco, INPUT_PULLUP); //Configura o Display OLED OLED.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS); OLED.setTextColor(WHITE); OLED.clearDisplay(); tela_inicial(); //Exibe tela inicial } void loop() { //Jogo Normal if(pontos[0] < 11 && pontos[1] < 11) rodadas(); //Equipe 1 Venceu if(pontos[0] >= 12) vencedor(1); //Equipe 2 Venceu if(pontos[1] >= 12) vencedor(2); //Equipe 1 com 11 pontos if(pontos[0] == 11 && pontos[1] < 11) mao_de_onze(1); //Equipe 2 com 11 pontos if(pontos[1] == 11 && pontos[0] < 11) mao_de_onze(2); //Ambas as equipes com 11 pontos if(pontos[1] == 11 && pontos[0] == 11) ambas_com_onze(); } void placar() { OLED.clearDisplay(); //Limpa a tela OLED.setTextSize(1); //Define o tamanho da fonte OLED.setCursor(2,7); //Posiciona o cursor OLED.print("Equipe 1--> "); //Define o texto a ser exibido OLED.setCursor(77,7); OLED.print(pontos[0]); OLED.setCursor(2, 16); OLED.print("Equipe 2--> "); OLED.setCursor(77, 16); OLED.print(pontos[1]); OLED.display(); //Mostra na tela o texto definido } int obter_resposta() { while(true) { //Lendo o estado dos pinos onde os botões estão conectados EstadoAtual_1 = digitalRead(Botao1); EstadoAtual_3 = digitalRead(Botao2); EstadoAtual_Truco = digitalRead(BotaoTruco); if(!EstadoAtual_1 && EstadoAnterior_1) //O botão 1 está apertado { EstadoAnterior_1 = EstadoAtual_1; delay(debounce); //Evita que sejam registrados toques duplicados return 1; //Função retorna o botão pressionado break; //Sai do laço While } if(!EstadoAtual_3 && EstadoAnterior_2) //O botão 2 está apertado { EstadoAnterior_2 = EstadoAtual_3; delay(debounce); return 2; break; } if(!EstadoAtual_Truco && EstadoAnterior_Truco) //O botão de truco está apertado { EstadoAnterior_Truco = EstadoAtual_Truco; delay(debounce); return 3; break; } EstadoAnterior_1 = EstadoAtual_1; EstadoAnterior_2 = EstadoAtual_3; EstadoAnterior_Truco = EstadoAtual_Truco; } } void rodadas() { //Nenhuma equipe com 11 ou vencedora while(pontos[0] < 11 && pontos[1] < 11) { placar(); //Exibe o placar atual resposta = obter_resposta(); //Espera o botão pressionado pelo usuário if(resposta == 3) truco(); //A jogada está trucada else pontos[resposta-1] ++; //Atualiza o placar } } void truco() { tentos += 3; //Exibe quanto vale a rodada OLED.clearDisplay(); OLED.setTextSize(2); switch(tentos) { case 3: OLED.setCursor(3,8); OLED.print(" TRUCO! "); break; case 6: OLED.setCursor(0,8); OLED.print(" SEIS! "); break; case 9: OLED.setCursor(0,8); OLED.print(" NOVE! "); break; case 12: OLED.setCursor(0,8); OLED.print(" DOZE! "); break; } OLED.display(); delay(1000); //Desconsidera o botão de truco sendo apertado depois de se pedir 12 if(tentos > 12) tentos = 12; //Pergunta quem venceu a rodada trucada OLED.clearDisplay(); OLED.setTextSize(1); OLED.setCursor(0,7); OLED.print(" Quem Venceu? "); OLED.setCursor(0,16); OLED.print(" 1)Eq. 1 2)Eq. 2 "); OLED.display(); resposta = obter_resposta(); if(resposta == 3) truco(); else { pontos[resposta-1] += tentos; placar(); delay(atraso); } tentos = 0; } void mao_de_onze(int equipe_onze) { int outra_equipe; if(equipe_onze == 1) outra_equipe = 2; else outra_equipe = 1; //Pergunta se a equipe com 11 deseja jogar a rodada OLED.clearDisplay(); OLED.setTextSize(1); OLED.setCursor(0,7); OLED.print(" Mao de Onze "); OLED.setCursor(0,16); OLED.print(" 1)Aceita 2)Corre "); OLED.display(); resposta = obter_resposta(); //Rodada foi aceita if(resposta == 1) { //Pergunta quem venceu a rodada OLED.clearDisplay(); OLED.setTextSize(1); OLED.setCursor(0,7); OLED.print(" Quem Venceu? "); OLED.setCursor(0,16); OLED.print(" 1)Eq. 1 2)Eq. 2 "); OLED.display(); resposta = obter_resposta(); if(resposta == equipe_onze) pontos[equipe_onze-1] += 3; if(resposta == outra_equipe) { pontos[outra_equipe-1] += 3; placar(); delay(atraso); } } //Rodada não foi aceita else if(resposta == 2) { pontos[outra_equipe-1]++; //Equipe em desvantagem recebe um ponto placar(); delay(atraso); } } void ambas_com_onze() { //Pergunta qual equipe venceu a rodada final OLED.clearDisplay(); OLED.setTextSize(1); OLED.setCursor(0,7); OLED.print(" Ambas com Onze "); OLED.display(); delay(atraso); OLED.clearDisplay(); OLED.setTextSize(1); OLED.setCursor(0,7); OLED.print(" Quem Venceu? "); OLED.setCursor(0,16); OLED.print(" 1)Eq. 1 2)Eq. 2 "); OLED.display(); resposta = obter_resposta(); if(resposta == 1) pontos[0]++; if(resposta == 2) pontos[1]++; } void vencedor(int champ) { //Exibe a equipe vencedora for(int i = 0; i < 4; i++) { OLED.clearDisplay(); OLED.setTextSize(1); OLED.setCursor(0,7); OLED.print(" O Jogo Acabou! "); OLED.setCursor(0,16); OLED.print(" "); OLED.display(); delay(atraso/2); OLED.setCursor(0,16); OLED.print(" Equipe Venceu! "); OLED.setCursor(60,16); OLED.print(champ); OLED.display(); delay(atraso); } OLED.clearDisplay(); while(true) { OLED.setCursor(0,7); OLED.println(" Italo "); OLED.setCursor(0,15); OLED.println(" Coelho "); OLED.display(); delay(10000); } } void tela_inicial() //Animação Incial { OLED.setTextSize(1); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println("---------------------"); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" ------------------- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" ----------------- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" --------------- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" ------------- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" ------------- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" --------- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" --------- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" ----- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" --- "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,15); OLED.println(" - "); OLED.display(); delay(50); OLED.clearDisplay(); OLED.setCursor(0,7); OLED.println(" Placar de Truco "); OLED.setCursor(0,15); OLED.println(" "); OLED.display(); delay(50); OLED.clearDisplay(); }
Placa de circuito impresso
Para confeccionar o Placar de Truco em forma de placa de circuito impresso, vamos utilizar como microcontrolador o Arduino Pro Mini de 5V e uma placa de Fenolite de 5 cm x 5 cm.
Para saber como fazer upload do código no Arduino Pro Mini você pode conferir o post “Programando uma Placa Pro Mini com Arduino Uno” ou “Programando o Arduino Pro Mini com Cabo Conversor USB TTL“.
Você pode fazer o download do design da PCB. Acesse o nosso post “Confecção de PCB de formar caseira“ para instruções em como produzir a sua própria placa em casa.
Funcionamento do Placar de Truco com Arduino:
A interface do placar é composta por três botões que denominaremos, da esquerda para a direita, de botão Um, Dois e Três. Durante o jogo os botões Um e Dois adicionam um ponto a suas respectivas equipes enquanto o botão Três é usado para trucar e pedir seis, nove ou doze. Quando aparecem perguntas na tela, o botão Um corresponde à resposta afirmativa enquanto o botão Dois indica resposta negativa.
Gostou desse projeto? Não se esqueça de deixar um comentário nos contando o que achou.
Boa TArde. Preciso de um código. Poderia me ajudar? Fazer negócio?