- Materiais requisitados:
- Pré-requisitos:
- Diagrama de circuito:
- Programação para despertador:
- Simulação:
- Trabalhando com Despertador Digital usando PIC16F877A:
A revolução digital iniciada em 1950 transforma todas as estruturas eletrônicas mecânicas e analógicas existentes em computadores digitais. Como o crescimento da eletrônica digital foi exponencial, hoje é quase impossível para uma pessoa resistir ao uso de qualquer equipamento eletrônico. A começar pelo despertador que acorda e pela torradeira que serve o pequeno-almoço, tudo é uma contribuição da electrónica digital. Pensando em tudo isso, é realmente emocionante programar nossas próprias coisas que podem fazer tarefas simples, mas úteis, como o Despertador que iremos construir neste projeto com o Microcontrolador PIC. Anteriormente, construímos um despertador com outros microcontroladores:
- Raspberry Pi Alarm Clock usando RTC Module DS1307
- Relógio digital baseado em Arduino com alarme
- Despertador usando microcontrolador ATmega32
Este despertador terá um display LCD 16x2 que exibirá a hora atual e a hora definida. Usaremos alguns botões para definir a hora do alarme sempre que necessário. A hora atual será mantida no controle usando o módulo RTC DS3231 e usaremos a comunicação IIC para obter esses valores do módulo RTC. Já aprendemos sobre o módulo RTC e como fazer a interface com o PIC. Portanto, é recomendável ler esse tutorial, iremos pular a maioria das informações abordadas nesse tutorial.
Materiais requisitados:
- Tábua de pão - 2Nos
- PIC16F877A
- Fonte de alimentação 5V - Módulo de alimentação
- Cristal de 20 MHz
- Capacitor 33pf - 2Nos
- Módulo DS3231 RTC
- Módulo de exibição 16 * 2 LCD
- 10K POT
- Resistor de 10k e 1k
- Botões de pressão - 5Nos
- Buzzer
- Fios de conexão
Pré-requisitos:
Este projeto requer que você conheça alguns fundamentos sobre o microcontrolador PIC e como programá-lo. Usaremos GPIOs, display LCD e módulo RTC para este projeto. Portanto, é melhor aprender a usar esses módulos de antemão. Os links a seguir irão ajudá-lo a aprender o mesmo
- Escrevendo seu primeiro programa com Microcontrolador PIC
- Interface LCD com PIC
- Comunicação I2C usando PIC
- Interface DS3231 RTC com PIC
Diagrama de circuito:
O diagrama de circuito para este projeto de despertador baseado em PIC é mostrado abaixo, o qual foi criado usando o software proteus. O também será usado para simulação mais adiante neste projeto.
Os cinco botões funcionarão como uma entrada para definir o alarme para o tempo necessário. Assim, uma extremidade de todos os botões de pressão são conectadas ao aterramento e as outras extremidades são conectadas ao pino PORTB, um resistor pull-up interno será usado nesses pinos para evitar que os pinos flutuem. O Buzzer atuará como uma saída e nos dará um bipe quando o alarme for acionado e conectado ao pino PORT S. A hora atual é sempre mantida no controle pelo módulo DS3231 RTC do qual o PIC recebe os dados através do barramento I2C, de forma que os pinos SCL e SDA do módulo RTC sejam conectados ao SCL e ao pino SDA do controlador PIC. Um display LCD está conectado ao PORTD do PIC, que é usado para exibir a hora atual e a hora definida. Saiba mais sobre como usar o módulo DS3231 RTC com PIC aqui.
O circuito completo pode ser construído sobre uma placa de ensaio. Como existem algumas dezenas de fios para conectar, então tenha paciência e certifique-se de que as conexões estão corretas. Minha configuração de hardware parecia algo assim abaixo, uma vez que eu terminei com as conexões
Usei um módulo de placa de ensaio e um adaptador de 12 V para alimentar o módulo. Esta é minha fonte de tensão de alimentação de + 5V. Além disso, preciso usar duas placas de ensaio para manter o circuito limpo. Você também pode soldar todo o circuito em uma placa de desempenho se estiver procurando fazer um projeto mais robusto.
Programação para despertador:
O programa PIC completo para este projeto Alarm Clock pode ser encontrado na parte inferior desta página. Este projeto também requer três bibliotecas para usar LCD, I2C e RTC com PIC. O código completo com os arquivos de cabeçalho pode ser baixado do arquivo ZIP aqui e pode ser aberto no MPLABX após a extração. Mais abaixo, estou apenas explicando o arquivo c principal como pequenos trechos. Você pode recorrer aos tutoriais mencionados acima se quiser saber como funcionam os arquivos de cabeçalho.
Antes de entrar no programa principal, temos que definir os pinos que usamos com nomes mais significativos. Desta forma, será fácil utilizá-los durante a programação. Os pinos definidos em nosso programa são mostrados abaixo
// Defina os pinos do LCD #define RS RD2 // Reinicialize o pino do LCD #define EN RD3 // Habilite o pino do LCD #define D4 RD4 // Bit de dados 0 do LCD #define D5 RD5 // Bit de dados 1 do LCD #define D6 RD6 // Bit de dados 2 do LCD # define D7 RD7 // Bit de dados 3 do LCD // Definir botões #define MB RB1 // O botão do meio # define LB RB0 // botão esquerdo # define RB RB2 // botão direito # define UB RB3 // Botão superior # define BB RB4 // Botão inferior // Define Buzz # define BUZZ RD1 // Buzzer está conectado ao RD1
Dentro da função principal , começamos declarando os pinos de entrada e saída. Em nosso projeto, o PORTB é usado para botões que são um dispositivo de entrada, então definimos seus pinos como entradas e PORTD é usado para LCD e buzzer, então definimos seus pinos como saída. Além disso, um pino nunca deve ser deixado flutuando, o que significa que os pinos de E / S devem sempre ser conectados ao aterramento ou à tensão de + 5V. Em nosso caso, para os botões de pressão, os pinos não serão conectados a nada quando o botão não for pressionado, então usamos um resistor pull-up interno que define o pino como alto quando não está em uso. Isso é feito usando os registros de controle conforme mostrado abaixo
TRISD = 0x00; // Faça os pinos da Porta D como saída para interface LCD TRISB = 0xFF; // Os switches são declarados como pinos de entrada OPTION_REG = 0b00000000; // Habilita o resistor pull up na porta B para switches BUZZ = 0; // Turn of buzzer
Como temos o arquivo de cabeçalho LCD e I2C vinculados ao programa principal, podemos iniciar a inicialização do LCD chamando uma função simples. O mesmo pode ser feito para a inicialização I2C. Aqui estamos iniciando a comunicação I2C em 100kHz já que o módulo RTC trabalha com 100kHz.
Lcd_Start (); // Inicializa o módulo LCD I2C_Initialize (100); // Inicializa I2C Master com clock de 100KHz
A função abaixo é usada para definir a hora e a data no módulo RTC, uma vez que a hora e a data são definidas, remova esta linha. Caso contrário, cada vez que você iniciar o programa, a hora e a data serão definidas novamente e novamente
// Remova a linha abaixo assim que a hora e a data forem definidas pela primeira vez. Set_Time_Date (); // definir hora e data no módulo RTC
Para indicar que o programa está inicializando, exibimos uma pequena tela de introdução que exibe o nome do projeto e o nome do site conforme mostrado abaixo
// Fornece uma mensagem de introdução no LCD Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("Despertador"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __delay_ms (1500);
Em seguida dentro da enquanto ciclo precisamos ler a hora e data atual do módulo RTC, isto pode ser feito por apenas chamando a seguir a função.
Update_Current_Date_Time (); // Leia a data e hora atuais do módulo RTC
Chamar a função acima atualizará as variáveis seg, min e hora com o valor atual. Para exibi-los na tela LCD , temos que dividi-los em caracteres individuais usando o código abaixo.
// Dividir em char para exibir no lcd char sec_0 = sec% 10; char sec_1 = (seg / 10); char min_0 = min% 10; char min_1 = min / 10; char hora_0 = hora% 10; char hora_1 = hora / 10;
A seguir, atualizamos os valores na tela LCD. A hora atual será exibida na primeira linha e a hora definida em que o alarme deve ser disparado é exibida na segunda linha. O código que faz o mesmo é mostrado abaixo.
// Exibe a hora atual na tela LCD Lcd_Clear (); Lcd_Set_Cursor (1, 1); Lcd_Print_String ("HORA:"); Lcd_Print_Char (hora_1 + '0'); Lcd_Print_Char (hora_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (min_1 + '0'); Lcd_Print_Char (min_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (sec_1 + '0'); Lcd_Print_Char (sec_0 + '0'); // Mostra a data na tela LCD Lcd_Set_Cursor (2, 1); Lcd_Print_String ("Alarme:"); Lcd_Print_Char (alarme_val + '0'); Lcd_Print_Char (alarme_val + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (alarm_val + '0 '); Lcd_Print_Char (alarme_val + '0');
Agora, exibimos a hora e definimos a hora no LCD, temos que verificar se o usuário está tentando definir a hora do alarme. Para fazer isso, o usuário deve pressionar o botão do meio, então vamos verificar se o botão do meio está pressionado e alternar uma variável para entrar no modo de definição de alarme. O mesmo botão será pressionado novamente para confirmar que os valores estão configurados e, nesse caso, temos que sair do modo de configuração do alarme. Portanto, usamos a linha de código abaixo para alterar o status da variável set_alarm .
// Use o botão do meio para verificar se o alarme deve ser definido if (MB == 0 && set_alarm == 0) {// Se o botão do meio for pressionado e o alarme não estiver ativado while (! MB); // Espere até que o botão seja liberado set_alarm = 1; // inicia a configuração do valor do alarme } if (MB == 0 && set_alarm == 1) {// Se o botão do meio for pressionado e o alarme não for desligado while (! MB); // Espere até que o botão seja liberado set_alarm = 0; // pare de definir o valor do alarme }
Se o usuário pressionou o botão do meio, significa que ele está tentando definir a hora do alarme. Neste caso, o programa entra no modo de definição de alarme usando o código acima. Dentro do modo de definição de alarme, se o usuário pressionar o botão esquerdo ou direito, isso significa que devemos mover o cursor para a esquerda ou direita. Para fazer isso simplesmente aumentamos ou diminuímos o valor da posição em que o cursor deve ser colocado
if (LB == 0) {// Se o botão esquerdo for pressionado enquanto (! LB); // Espere até que o botão seja liberado pos--; // Em seguida, mova o cursor para a esquerda } if (RB == 0) {// Se o botão direito for pressionado enquanto (! RB); // Espere até que o botão seja liberado pos ++; // Mova o cursor para a direita }
Ao usar um botão com um microcontrolador ou microprocessador, há um problema comum a ser resolvido. Este problema é denominado switch bouncing. Quando o botão é pressionado, ele pode gerar pulsos ruidosos para o MCU / MPU, o que pode falsificar o MCU para várias entradas. Esse problema pode ser resolvido adicionando um capacitor na chave ou usando uma função de atraso assim que o botão pressionado for detectado. Este tipo de solução é denominado de-bouncing. Aqui temos usado um enquanto loop para manter o programa no lugar até que o botão é liberado. Esta não é a melhor solução de eliminação de saltos, mas para nós funcionará perfeitamente.
enquanto (! RB);
Semelhante ao botão esquerdo e direito, também temos os botões superior e inferior que podem ser usados para aumentar ou diminuir o valor da hora do alarme. O código para fazer o mesmo é mostrado abaixo. Observe que cada caractere do tempo de alarme definido é endereçado pelo valor de índice da matriz. Assim, podemos acessar facilmente o caractere necessário cujos valores devem ser alterados.
if (UB == 0) {// Se o botão superior for pressionado enquanto (! UB); // Espere até que o botão seja liberado alarm_val ++; // Aumente o valor do caractere específico } if (BB == 0) {// Se o botão inferior for pressionado enquanto (! UB); // Espere até que o botão seja liberado alarm_val--; // Diminua esse valor char específico }
Assim que a hora do alarme for definida, o usuário pressionará o botão do meio novamente. Então podemos começar a comparar a hora atual com a hora definida. A comparação verifica se cada caractere da hora atual é igual ao caractere da hora definida. Se os valores forem iguais, disparamos o alarme definindo a variável trigger_alarm , caso contrário, apenas comparamos até que fique igual.
// O alarme IF está definido Verifique se o valor definido é igual ao valor atual if (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // Liga o gatilho se o valor corresponder
Se o alarme estiver definido, temos que tocar a campainha para alertar o usuário sobre o alarme. Isso pode ser feito simplesmente alternando a campainha em um intervalo regular, conforme mostrado abaixo.
if (trigger_alarm) {// Se o alarme for disparado // Beep the buzzer BUZZ = 1; __delay_ms (500); BUZZ = 0; __delay_ms (500); }
Simulação:
Este programa também pode ser simulado usando o software proteus. Apenas recrie o circuito mostrado acima e carregue o arquivo hex no PIC. O código hexadecimal para este projeto pode ser encontrado no arquivo ZIP que está vinculado aqui. Uma captura de tela tirada durante a simulação é mostrada abaixo
A simulação se torna muito útil quando você está tentando adicionar novos recursos ao projeto. Você também pode usar o módulo depurador I2C para verificar quais dados estão entrando e saindo pelo barramento I2C. Você pode tentar pressionar os botões e também definir a hora do alarme. Quando a hora definida for igual à hora atual, a campainha soará alto.
Trabalhando com Despertador Digital usando PIC16F877A:
Construa o circuito na placa de ensaio, obtenha o código do link de download e compile-o usando o compilador MplabX e XC8. Se você baixou o código do arquivo ZIP fornecido aqui, não deverá ter problemas para compilá-lo, pois os arquivos de cabeçalho já estão anexados.
Depois de compilar, carregue o programa em seu hardware usando o programador PicKit3. A conexão para conectar o programador pickit ao PIC IC também é mostrada no diagrama de circuito. Depois que o programa for carregado, você deverá ver a tela de introdução e, em seguida, a hora exibida, você pode usar os botões de pressão para definir a hora do alarme. A configuração do meu hardware quando ligado é a seguinte.
Quando a hora do alarme coincidir com a hora atual, a campainha começará a soar para alertar o usuário. O trabalho completo pode ser conferido no vídeo abaixo. O projeto tem uma infinidade de opções para se basear. O módulo RTC pode controlar qualquer hora e data, para que você possa executar uma tarefa agendada a qualquer hora / data necessária. Você também pode conectar um aparelho CA como um ventilador ou luz e programá-lo para LIGAR ou DESLIGAR quando necessário. Ainda há muito mais que você pode desenvolver neste projeto. Deixe-me saber qual ideia vem à sua mente como um upgrade para este projeto e terei o prazer de ouvir de você.
Espero que você tenha entendido o projeto e aprendido algo útil com o processo. Se você tiver alguma dúvida neste projeto use a seção de comentários para postá-los ou use os fóruns para qualquer ajuda técnica.
O código PIC completo com arquivos de cabeçalho pode ser encontrado aqui