Índice:

Relógio digital no Arduino usando uma máquina de estados finitos: 6 etapas
Relógio digital no Arduino usando uma máquina de estados finitos: 6 etapas

Vídeo: Relógio digital no Arduino usando uma máquina de estados finitos: 6 etapas

Vídeo: Relógio digital no Arduino usando uma máquina de estados finitos: 6 etapas
Vídeo: FAÇA UMA MÁQUINA DE ESTADOS FINITOS COM ARDUINO | Curso de Arduino #245 2024, Novembro
Anonim
Relógio digital no Arduino usando uma máquina de estados finitos
Relógio digital no Arduino usando uma máquina de estados finitos

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

Image
Image

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

Escudo do teclado LCD
Escudo do teclado LCD

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

Interface da máquina de estado
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!

Recomendado: