Componentes eletrônicos, Hobby, Microcontroladores, Projetos, Tutorial

Display de 4 dígitos TM1637 no Arduino

Neste post, são mostrados como usar no Arduino o módulo TM1637, um display com quatro dígitos de sete segmentos e três exemplos de projetos.

O chip TM1637

É um circuito integrado que faz o controle de acionamento de display de LEDs de anodo comum. Possui uma varredura de teclado com um circuito de identificação aprimorada com chaves anti-interferência. Também tem um MCU (unidade microcontroladora), que integra a interface do teclado de varredura, a trava de dados e o acionamento de LEDs.

chip TM1637 no módulo
O chip TM1637 no módulo usado para o Arduino.

O módulo TM1637

Disaplay Tm1637 DESTAQUE

São necessários apenas 4 fios para fazer a conexão, sendo 2 de alimentação. Sem este módulo, seriam necessários 12 fios para ligar os 4 dígitos de 7 segmentos ao Arduino.

  • CLK: O terminal para o sinal de clock do módulo.
  • DIO: Entrada e saída de dados. 

Outros parâmetros do módulo TM1637.

  • Faixa de tensão de operação: 3,3 V a 5 V.
  • Corrente de consumo: 80 mA.
  • Faixa de temperatura de operação: -10°C a 80ºC.

Para usar este display, você deve baixar a biblioteca que está neste link.

Projetos com TM1637

Relógio de tempo real

TM1637 com RTC e Arduino
O esquemático do projeto.

Além do TM1637, este projeto usa o módulo RTC DS3231SN. Já escrevi um post sobre este componente, cujo link está abaixo.

Tutorial de Arduino (Parte 10)Clique aqui

Para este projeto, é recomendável abaixar a biblioteca RTClib.h. Esta é mais fácil de entender do que a biblioteca mostrada no post sobre o módulo DS3231SN. O link está aqui. O algoritmo abaixo foi baseado no exemplo fornecido ao abaixar o RTClib.h.

#include "RTClib.h"
#include <TM1637Display.h>

// Define os pinos de conexão para o módulo TM1637.
#define CLK 2
#define DIO 3

//Inicialização do RTC e do display.
RTC_DS3231 rtc;
TM1637Display display = TM1637Display(CLK, DIO);

//Para mostrar os dias da semana  
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//Variável para mostrar no display.
int displayshow;

void setup () {
  Serial.begin(9600);
//Ajusta o brilho no display.
  display.setBrightness(0x0f);
  
//Avisa se o RTC não estiver ligado.
  if (! rtc.begin()) { 
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

//Se a bateria do RTC acabar. Imprime o aviso na janela Serial. 
  if (rtc.lostPower()) { 
    Serial.println("RTC lost power, let's set the time!");
    //Coloca a data (DATE) e a hora (TIME) no momento em que o algoritmo for 
    //compilado.
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // Por exemplo, para determinar 21 de Janeiro de 2014 e 3 da manhã, deve 
    //escrever no rtc.adjust.
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {
    DateTime now = rtc.now();
    //Imprime na janela Serial a data, o dia da semana e a hora, incluindo 
    //os segundos.
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    //Mostra minutos e segundos no módulo TM1637. Pega os minutos, 
    //multiplica por 100 e adiciona os segundos para aparecer no display.
    displayshow=(now.minute()*100)+now.second();
    //Esta função serve para mostrar o valor de displayshow com 2 pontos no 
    //meio. O segundo argumento entre parênteses são os 2 pontos e o false 
    //serve para não colocar zeros nos dígitos não usados.
    display.showNumberDecEx(displayshow,0b11100000,false);
    //Se o minuto for menor que 10, deve ser posto um zero na frente.
    if(now.minute()<10){ 
      //Nesta função, o primeiro argumento é o número que deve ser mostrado, 
      //o segundo é a quantidade de dígitos que deve ser modificado e o 
      //terceiro é a posição no display de 1 até 4. 
      display.showNumberDec(0,0,1);
      //Deve usar novemente para não desaparecer quando mostrar o zero 
      //adicional.
      display.showNumberDec(displayshow,0b11100000,false);
    }

    //Mostra horas e minutos no módulo TM1637.
    /*displayshow=(now.hour()*100)+now.minute();
    display.showNumberDecEx(displayshow,0b11100000,false);
    //Se a hora for menor que 10, deve ser posto um zero na frente.
    if(now.hour()<10){
      display.showNumberDec(0,0,1);
      display.showNumberDec(displayshow,0b11100000,false);
    }*/
    Serial.println();
    delay(1000);
}

Contador regressivo

Neste projeto, o display faz a contagem regressiva até 0. Quando chegar no zero, o buzzer liga. Um botão ajusta o tempo para cima, outro para baixo e outro dá início a contagem regressiva.

O transistor N é um BJT BC548. Por quê eu não liguei diretamente o buzzer no Arduino? Se ligar diretamente, o buzzer vai fazer um pequeno zumbido quando a entrada digital estiver no nível baixo. Quando a saída digital do Arduino estiver ligada na base do transistor com um resistor de 200 Ω, o transistor age como chave e o buzzer não emitirá som quando estiver no nível baixo.

#include <TM1637Display.h> //INCLUSÃO DE BIBLIOTECA

#define DIO 2 //PINO DIGITAL UTILIZADO PELO DIO
#define CLK 3 //PINO DIGITAL UTILIZADO PELO CLK

TM1637Display display(CLK, DIO);

int buzzer=8;
int plus_button=5;
int minus_button=6;
int number;
int start_button;

void setup() {
  pinMode(4,INPUT);
  pinMode(buzzer,OUTPUT);
  display.setBrightness(0x0f);
  Serial.begin(9600);
}

void loop() {
//Neste caso, apenas dois argumentos é o suficiente.
  display.showNumberDec(number,false);
  start_button=digitalRead(4);
  if(digitalRead(plus_button)==LOW){
    number++;
  }
  if(digitalRead(minus_button)==LOW){
    number--;
  }
  if(start_button != 1){
    while(number>0){
      number--;
      display.showNumberDec(number,false);
      delay(1000);  
      if(number==0){
          digitalWrite(buzzer,HIGH);
      }else{
          digitalWrite(buzzer,LOW);  
      }
    }
  }
}

Teclado com senha

senha de 4 dígitos

Você digita no teclado matricial 4×4 uma senha de 4 dígitos, que aparecem no display. Se a senha for correta, o LED verde acende. Caso contrário, o vermelho acende. O código abaixo.

#include <Keypad.h>
#include <TM1637Display.h>

#define CLK 2
#define DIO 3

const char keys[4][4]={
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

const byte pinslines[4]={11,10,9,8};
const byte pinsrows[4]={7,6,5,4};

Keypad matrix = Keypad(makeKeymap(keys),pinslines,pinsrows,4,4);

TM1637Display display(CLK, DIO);

int RedLed=12;
int GreenLed=13;

// Armazena a senha que o usuário vai usar.
char data[] = "    ";
// Esta variável indica a posição do dígito no display.
int sequenceNum = 0;

// Esta função atualiza o display para mostrar a senha atual.
void updateDisplay() {
  //Array que limpa o display.
  uint8_t displayData[] = { 0, 0, 0, 0 };
  //Loop sobre cada caractere no código.
  for (int i = 0; i < (sizeof(data) / sizeof(data[0])); i++) { 
  //Faz com que os números aparecam no display, se apertar de 0 a 9.
  if (data[i] >= '0' && data[i] <= '9') {
      displayData[i] = display.encodeDigit((int)data[i] - 48);
    }
    // Se apertar *, limpa o display e começa de novo.
    else if (data[i] == '*') {
      memset(data, 0, sizeof(data));
      sequenceNum = 0;
    }
    //Se apertar o caractere #, aparece duas linhas paralelas. 
    else if (data[i] == '#') {
      displayData[i] = 0b00001001;
    }
    else if(data[i] == 'A'){
      displayData[i] = 0b11110111;
    }
    else if(data[i] == 'B'){
      displayData[i] = 0b01111100;
    }
    else if(data[i] == 'C'){
      displayData[i] = 0b00111001;
    }
    else if(data[i] == 'D'){
      displayData[i] = 0b01011110;
    }
  }
  //Passa o vetor de dados para exibir no display.
  display.setSegments(displayData);
}

// Função que faz os valores piscarem no display.
void flashDisplay() {
  // Define um array vazio. Todos os LEDs apagados.
  uint8_t OFF[] = { 0, 0, 0, 0 };
  // Alterna entre mostrar o valor e apagar os LEDs.
  for (int i = 0; i < 4; i++) {
    delay(250);
    display.setSegments(OFF);
    delay(250);
    updateDisplay();
  }
}
void setup() {
  Serial.begin(9600);
  //Determina o brilho do display.
  display.setBrightness(4);
  pinMode(RedLed,OUTPUT);
  pinMode(GreenLed,OUTPUT);
}

void loop() {
  char key = matrix.getKey();
  if (key) {
    // Log it to the serial output
    Serial.println(key);
    // Coloca a tecla pressionada na atual posição na sequência da senha.
    data[sequenceNum] = key;
    // Acrescenta o contador +1.
    sequenceNum++;
    // Atualiza o display para exibir a sequência atual.
    updateDisplay();
    // Se os 4 dígitos já foram pressionados.
    if (sequenceNum == 4) {
      Serial.print(F("Code entered: "));
      // Mostra a senha na janela Serial.
      Serial.println(data);
      // Toma a decisão baseada na senha digitada.
      if (strcmp(data, "123A") == 0) {  //Escreva a senha aqui. A senha //mostrada é 123A.
        digitalWrite(RedLed,LOW);
        digitalWrite(GreenLed,HIGH);
        delay(2000);
        digitalWrite(RedLed,LOW);
        digitalWrite(GreenLed,LOW);
      }else{
        digitalWrite(RedLed,HIGH);
        digitalWrite(GreenLed,LOW);
        delay(2000);
        flashDisplay();
        digitalWrite(RedLed,LOW);
        digitalWrite(GreenLed,LOW);
      }
      // Limpa o array de dados.
      memset(data, 0, sizeof(data));
      sequenceNum = 0;
      // Atualiza o display.
      updateDisplay();
 }
  }
}

About Pedro Ney Stroski

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *