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.

O módulo TM1637

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

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

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

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(); } } }