Índice:
Vídeo: Relógio digital no Arduino usando uma máquina de estados finitos: 6 etapas
2025 Autor: John Day | [email protected]. Última modificação: 2025-01-13 06:58
Olá, vou mostrar a vocês como um relógio digital pode ser criado com YAKINDU Statechart Tools e executado em um Arduino, que usa um teclado de teclado LCD.
O modelo original do relógio digital foi tirado de David Harel. Ele publicou um artigo sobre o
"[…] ampla extensão do formalismo convencional de máquinas de estado e diagramas de estado."
Neste artigo, ele usou o exemplo do relógio digital para sua pesquisa. Eu o usei como inspiração e reconstruí o relógio com YAKINDU Statechart Tools (uma ferramenta para criar modelos gráficos de máquinas de estado e gerar código C / C ++ com ele) e o trouxe de volta à vida em um Arduino.
Suprimentos
Hardware:
- Arduino Uno ou Mega
- Escudo do teclado LCD
Programas:
- YAKINDU Statechart Tools
- Eclipse C ++ IDE para Arduino
Etapa 1: Como funciona o relógio digital
Vamos começar definindo como o relógio digital deve funcionar. Você se lembra desses … digamos … relógios digitais "super legais" que todo mundo tinha nos anos 90? Um cronômetro integrado, alarmes diferentes e seu bipe irritante a cada hora. Se não, dê uma olhada: relógio digital dos anos 90.
Basicamente, é um relógio configurável com diferentes modos. Principalmente, a hora atual será exibida, mas existem alguns outros recursos. Como entrada, você tem um botão liga / desliga, um modo e um botão de configuração. Além disso, você pode ligar e desligar a luz. Com o botão de modo, você pode distinguir entre os modos e ativar / desativar os recursos do relógio:
- Exibir a hora (relógio)
- Exibir a data (data)
- Defina o alarme (Alarme 1, Alarme 2)
- Ativar / desativar campainha (Definir campainha)
- Use o cronômetro (cronômetro)
Dentro dos menus, você pode usar o botão liga / desliga para configurar o modo. O botão definir permite que você defina a hora - por exemplo, para o relógio ou os alarmes. O cronômetro pode ser controlado - iniciado e interrompido - usando o botão light on e light off. Você também pode usar um contador de voltas integrado
Além disso, há um carrilhão, que toca a cada hora, e uma luz de fundo controlável integrada. Na primeira etapa, não os conectei ao Arduino.
Etapa 2: a máquina de estado
Não quero entrar em muitos detalhes para a explicação deste exemplo. Não é porque é muito complexo, é apenas um pouco grande. Vou tentar explicar a ideia básica de como funciona. A execução deve ser autoexplicativa, basta dar uma olhada no modelo ou fazer o download e simular. Algumas partes da máquina de estado são somadas em sub-regiões, como a região de tempo definida. Com isso, a legibilidade da máquina de estado deve ser garantida.
O modelo é dividido em duas partes - uma gráfica e uma textual. Na parte textual serão definidos os eventos, variáveis, etc. Na parte gráfica - o diagrama de estado - a execução lógica do modelo é especificada. Para criar uma máquina de estado que atenda ao comportamento especificado, alguns eventos de entrada são necessários, os quais podem ser usados no modelo: onoff, set, mode, light e light_r. Na seção de definição, um evento interno é usado, o que aumenta o valor de tempo a cada 100 ms:
a cada 100 ms / tempo + = 1
Com base nas etapas de 100 ms, o tempo atual será calculado no formato HH: MM: SS:
display.first = (tempo / 36000)% 24;
display.second = (tempo / 600)% 60; display.terceiro = (tempo / 10)% 60;
Os valores serão conectados ao display LCD usando a operação updateLCD toda vez que a máquina de estado for chamada:
display.updateLCD (display.first, display.second, display.third, display.text)
A execução básica da máquina de estados já está definida na seção Como funciona o Digital Watch. Dentro da ferramenta, usei alguns elementos de modelagem "especiais" como CompositeState, History, Subdiagrams, ExitNodes, etc. Uma descrição detalhada pode ser encontrada no Guia do Usuário.
Etapa 3: escudo do teclado LCD
O escudo do teclado LCD é muito bom para projetos simples, que requerem uma tela para visualização e alguns botões como entrada - uma típica e simples IHM (Interface Homem-Máquina). O escudo do teclado LCD contém cinco botões do usuário e outro para reinicialização. Os cinco botões juntos são conectados ao pino A0 do Arduino. Cada um deles está conectado a um divisor de tensão, que permite distinguir entre os botões.
Você pode usar analogRead (0) para encontrar os valores específicos, que podem, é claro, diferir de acordo com o fabricante. Este projeto simples exibe o valor atual no LCD:
#include "Arduino.h"
#include "LiquidCrystal.h" LiquidCrystal lcd (8, 9, 4, 5, 6, 7); configuração vazia () {lcd.begin (16, 2); lcd.setCursor (0, 0); lcd.write ("Valor medido"); } void loop () {lcd.setCursor (0, 1); lcd.print (""); lcd.setCursor (0, 1); lcd.print (analogRead (0)); atraso (200); }
Estes são os meus resultados medidos:
- Nenhum: 1023
- Selecione: 640
- Esquerda: 411
- Down: 257
- Até: 100
- Certo: 0
Com esses limites, é possível ler os botões:
#define NONE 0 # define SELECT 1 #define LEFT 2 #define DOWN 3 #define UP 4 #define RIGHT 5 static int readButton () {int result = 0; resultado = analogRead (0); if (resultado <50) {return RIGHT; } if (resultado <150) {return UP; } if (resultado <300) {return DOWN; } if (resultado <550) {return LEFT; } if (resultado <850) {return SELECT; } return NONE; }
Etapa 4: interface da máquina de estado
O código C ++ gerado da máquina de estado fornece interfaces, que devem ser implementadas para controlar a máquina de estado. O primeiro passo é conectar os eventos de entrada com as teclas do escudo do teclado. Já mostrei como ler os botões, mas para fazer a interface deles com a máquina de estado, é necessário eliminar os botões - caso contrário, os eventos seriam disparados várias vezes, o que resulta em um comportamento imprevisível. O conceito de debouncing de software não é novo. Você pode dar uma olhada na documentação do Arduino.
Em minha implementação, detectei uma borda descendente (liberando o botão). Eu li o valor do botão, esperei 80 ms (obtive melhores resultados com 80 em vez de 50), salvei o resultado e li o novo valor. Se o resultado antigo não for NENHUM (não pressionado) e o novo resultado for NENHUM, eu sei que o botão foi pressionado antes e agora foi liberado. Então, eu aumento o evento de entrada correspondente da máquina de estado.
int oldState = NONE; estático void raiseEvents () {int buttonPressed = readButton (); atraso (80); oldState = buttonPressed; if (oldState! = NONE && readButton () == NONE) {switch (oldState) {case SELECT: {stateMachine-> getSCI_Button () -> raise_mode (); pausa; } case LEFT: {stateMachine-> getSCI_Button () -> raise_set (); pausa; } case DOWN: {stateMachine-> getSCI_Button () -> raise_light (); pausa; } case UP: {stateMachine-> getSCI_Button () -> raise_light_r (); pausa; } case RIGHT: {stateMachine-> getSCI_Button () -> raise_onoff (); pausa; } padrão: {break; }}}}
Etapa 5: conectando as coisas
O programa principal usa três partes:
- A máquina de estado
- Um cronômetro
- Um manipulador de exibição (típico lcd.print (…))
DigitalWatch * stateMachine = new DigitalWatch (); CPPTimerInterface * timer_sct = new CPPTimerInterface (); DisplayHandler * displayHandler = new DisplayHandler ();
A máquina de estado usa um manipulador de display e tem um cronômetro, que será atualizado para controlar os eventos cronometrados. Depois disso, a máquina de estado é inicializada e inserida.
void setup () {stateMachine-> setSCI_Display_OCB (displayHandler); stateMachine-> setTimer (timer_sct); stateMachine-> init (); stateMachine-> enter (); }O loop faz três coisas:
- Aumentar eventos de entrada
- Calcule o tempo decorrido e atualize o cronômetro
- Ligue para a máquina de estado
long current_time = 0; long last_cycle_time = 0; loop void () {raiseEvents (); last_cycle_time = current_time; current_time = millis (); timer_sct-> updateActiveTimer (stateMachine, current_time - last_cycle_time); stateMachine-> runCycle (); }
Etapa 6: obtenha o exemplo
É isso. Provavelmente, não mencionei todos os detalhes da implementação, mas você pode dar uma olhada no exemplo ou deixar um comentário.
Adicione o exemplo a um IDE em execução com: Arquivo -> Novo -> Exemplo -> Exemplos de gráfico de estado YAKINDU -> Próximo -> Arduino - Relógio digital (C ++)
> Você pode baixar o IDE aqui <<
Você pode começar com um teste de 30 dias. Depois, você deve obter uma licença, que é gratuita para uso não comercial!