为 16x2 lcd keypad shield 使用 yakindu 状态图工具创建数字手表。
我将向您展示如何使用yakindu statechart tools创建数字手表并在使用 lcd keypad shield 的 arduino 上运行。
数字手表的原始模型取自大卫哈雷尔。他之前发表过一篇关于“状态机和状态图的传统形式的广泛扩展”的论文。在论文中,他以数字手表为例进行了研究。我以此为灵感,使用yakindu statechart tools (一种用于创建状态机图形模型并使用它生成 c/c++ 代码的工具)重建了手表,并在 arduino 上让它重新焕发生机。
数字手表的工作原理
让我们从定义数字手表应该如何工作开始。
基本上,它是一个具有不同模式的可配置手表。主要是显示当前时间,但还有一些其他功能。作为输入,您有一个开/关、一个模式和一个设置按钮。此外,还可以打开和关闭灯。
使用模式按钮,您可以区分模式并激活/禁用时钟功能:
显示时间(时钟)
显示日期(日期)
设置闹钟(闹钟 1、闹钟 2)
启用/禁用铃声(设置铃声)
使用秒表(秒表)
在菜单中,您可以使用开/关按钮来配置模式。设置按钮允许您设置时间 - 例如时钟或闹钟。秒表可以通过使用开灯和关灯按钮来控制 - 启动和停止。您还可以使用集成的计圈器。
此外,还有一个钟声,每时每刻都在响起,并且集成了一个可控的背光。不过在第一步,我没有将它们连接到 arduino。
状态机
我不想详细解释这个例子。这不是因为它太复杂,它只是有点太大了。不过我会尝试解释它具体如何工作的基本思想。通过查看模型或下载并模拟它。状态机的某些部分在子区域中汇总,例如设置的时间区域。这样就可以确保状态机的可读性。
该模型共分为两部分 - 图形和文本。
在文本部分,将定义事件、变量等。
在图形部分 - 状态图 - 指定了模型的逻辑执行。
要创建满足指定行为的状态机,需要一些输入事件,这些事件可以在模型中使用:onoff 、set 、mode 、light和light_r。在定义部分中使用了一个内部事件,它每 100 毫秒递增一次时间值:
every 100 ms / time += 1
基于 100 毫秒步长,当前时间将以hh:mm:ss格式计算:
display.first = (time / 36000) % 24;
display.second = (time / 600) % 60;
display.third = (time / 10) % 60;
每次调用状态机时,这些值将通过使用updatelcd操作连接到 lcd 显示器:
display.updatelcd(display.first, display.second, display.third, display.text)
状态机的基本执行已在“数字手表的工作原理”部分中定义。在该工具中,我使用了一些“特殊”建模元素,如compositestate 、history 、sub-diagrams 、exitnodes等。
lcd 键盘屏蔽
lcd keypad shield 对于需要一个可视化屏幕和一些按钮作为输入的简单项目来说非常酷 - 一个典型的简单 hmi(人机界面)。lcd keypad shield 包含五个用户按钮和一个用于重置的按钮。五个按钮一起连接到 arduino 的 a0 引脚。它们中的每一个都连接到一个分压器,可以区分按钮。
您可以使用analogread(0) 来查找特定值,这当然可能因制造商而异。这个简单的项目在 lcd 上显示当前值:
#include
#include
liquidcrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
lcd.begin(16, 2);
lcd.setcursor(0,0);
lcd.write(measured value);
}
void loop() {
lcd.setcursor(0,1);
lcd.print( );
lcd.setcursor(0,1);
lcd.print(analogread(0));
delay(200);
}
这些是我的测量结果:
无:1023
选择:640
左:411
下降:257
上:100
右:0
使用这些阈值可以读取按钮:
#define none 0
#define select 1
#define left 2
#define down 3
#define up 4
#define right 5
static int readbutton() {
int result = 0;
result = analogread(0);
if (result < 50) {
return right;
}
if (result < 150) {
return up;
}
if (result < 300) {
return down;
}
if (result raise_mode();
break;
}
case left: {
statemachine->getsci_button()->raise_set();
break;
}
case down: {
statemachine->getsci_button()->raise_light();
break;
}
case up: {
statemachine->getsci_button()->raise_light_r();
break;
}
case right: {
statemachine->getsci_button()->raise_onoff();
break;
}
default: {
break;
}
}
}
}
连接
主程序使用三个部分:
状态机
计时器
显示处理程序(典型的 lcd.print(...))
digitalwatch* statemachine = new digitalwatch();
cpptimerinterface* timer_sct = new cpptimerinterface();
displayhandler* displayhandler = new displayhandler();
状态机使用显示处理程序并获得一个计时器,该计时器将被更新以控制定时事件。之后,状态机被初始化并进入。
void setup() {
statemachine->setsci_display_ocb(displayhandler);
statemachine->settimer(timer_sct);
statemachine->init();
statemachine->enter();
}
循环做了三件事:
引发输入事件
计算经过时间并更新计时器
调用状态机
long current_time = 0;
long last_cycle_time = 0;
void loop() {
raiseevents();
last_cycle_time = current_time;
current_time = millis();
timer_sct->updateactivetimer(statemachine,
current_time - last_cycle_time);
statemachine->runcycle();
}
添加示例
将示例添加到正在运行的 ide 中:
文件 -》 新建 -》 示例 -》 yakindu 状态图示例 -》 下一步 -》 arduino - 数字手表 (c++)
LED1202 LED驱动器实现更多自主可能性
如何准确测量瞬态电压扰动
jlink和串口的区别
一文解析布隆过滤器设计原理
直流电子负载应用
如何使用YAKINDU Statechart Tools创建数字手表
振弦采集模块参数配置工具VMTool 的使用
【虹科新品】HK-MR340系列:用于确定肿瘤的大小和位置
DEKRA德凯新建静安电磁兼容和射频实验室为客户提供专业化服务
碳化硅MOSFET与Si MOSFET的比较
押注2nm!英特尔26亿抢单下一代 EUV光刻机,台积电三星决战2025!
疫情防控新设备可5秒杀死病毒
外部SDI/HDMI信号如何使用NDI传输技术输入电脑进行推流
中频点焊机保养常识_中频点焊机保养流程
PCB电路中的电磁兼容设计应该怎样设计
三个主流软件提取寄生参数比较
科大讯飞将带来一场人工智能盛宴
Socket 940是什么
特瑞仕半导体推出超小型1mm、高速LDO电压调整器XC622
LED结温及其降低方法