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