您现在的位置是:首页 >技术交流 >【逗老师的无线电】MMDVM串口屏相关开发网站首页技术交流
【逗老师的无线电】MMDVM串口屏相关开发
哎呀呀,终于研究通透了MMDVM的串口屏相关了。
一、Nextion和陶晶驰串口屏
MMDVM默认对接的是Nextion屏幕。但是有人跟我说,NXT的屏幕和国内陶晶驰的屏幕就是一个东西,只不过ROM不一样。
至于Nextion和陶晶驰到底背后有啥PY关系,我们就不管了。但是我就知道,虽然HMI文档不能跨品牌直接打开,但这俩设计软件几乎长一样,手工画图移植GitHub上的工程就行
NXT和TJC的设计软件资源
1、陶晶驰wiki:
http://wiki2.tjc1688.com/start/index.html
2、陶晶驰设计软件-USART HMI
http://wiki2.tjc1688.com/start/download_ide.html
3、NXT设计软件NextionEditor
https://nextion.tech/nextion-editor/
二、MMDVM与串口屏通信原理
学画串口屏之前,先别急,我们先搞明白MMDVM与串口屏的通信原理
1、指令发送
MMDVM在运行过程中,会通过串口向串口屏幕发送对应的指令。包括文本更新指令和屏幕切换指令
1.1、文本更新指令
如上图所示,在编辑HMI文件的时候,我们可以看到页面的文本框的编号t0 t1 txxx,MMDVM通过串口向屏幕发送指令,即可更新文本框中的文本内容。
这些编号与MMDVM的Nextion Display模块的各个字段名称一一对应。这些字段名称的含义在两个地方可以找到:
- 基础字段:https://github.com/g4klx/MMDVMHost/blob/master/Nextion.cpp
Nextion.cpp中可以看到原始传递给Nextion的字段内容 - 扩展字段:需要使用NextionDriverhttps://github.com/on7lds/NextionDriver
扩展字段扩充了包括CPU温度、磁盘、位置等等字段的信息。
例如,需要更新TX发送频率,MMDVM会向屏幕发送指令
t32.txt="439.600Mhz"
屏幕上t32文本框则会显示MMDVM发送过来的文本内容,如下图所示
1.2、页面切换
串口屏幕一般情况下会具备如下几个页面,包括主页面,DMR、YSF等各种制式的通信页面。
在需要切换页面的时候,MMDVM会通过串口发送下述命令。
注意,这些页面名称基本写死了,所以在自定义屏幕HMI的时候,需要创建相同名称的页面,但是无所谓页面ID,MMDVM并不会以ID进行page更新指令。
page MMDVM
page DMR
1.3、隐藏指令
在后面开发HMI工程,以及参考GitHub上的各种工程时,发现除了上面两种显性指令以外,MMDVM还具有几个隐性指令
1.3.1、S0触控热区刷新指令
每次更新完成任意指令之后,MMDVM一定会在当前页面点击一次S0触控热区,关于触控热区,属于串口屏上一个透明的触摸按钮。所以对于需要在串口屏上进行数据处理的动作,可以写在S0的触摸动作里。
1.3.2、MMDVM.status.val状态码
在page MMDVM页面,有一个status变量,此变量很有意思,存储的是MMDVM更新状态代码。MMDVM在更新不同的字段内容之后,会将代码赋予不同的值。例如64代表刚刚更新过的是DMR TS1的呼号,72代表刚刚更新过DMR TS2的呼号
page MMDVM的status状态码在https://github.com/g4klx/MMDVMHost/blob/master/Nextion.cpp里面声明的
关于上述两个隐藏指令的功能,后面讲到HMI工程开发的时候会具体说明。
2、触控回传
支持触摸操作的串口屏幕,在触摸动作发生之后,会按照配置通过串口发送相应指令。如下图所示
如果使用NextionDriver,其会侦听串口,并在侦听到指令之后执行相应的动作。
关于NextionDriver可以响应的串口指令如下:
Sending commands from the display
例如上图的2A FB 02 FF FF FF
对应的动作即为显示UserDB更新时间
3、串口屏硬件连接方式
如果不使用NextionDriver,MMDVM直连串口屏,有两种方式:
- 通过树莓派板载串口直接与串口屏通信
- 通过双工或者单工热点版的NXT接口进行通信
由于安装双工热点版之后占用了树莓派上唯一的一个板载异步串口,所以在使用热点板的情况下,只能选择第二种方式进行通信。
两种通信方式的主要区别是,使用树莓派板载串口,可以使用115200波特率高刷通信(),使用modem串口,只能以9600波特率通信。
如果使用NextionDriver,MMDVM侧选择使用dev/ttyNextionDriver这个虚拟串口,NextionDriver选择实际使用的物理串口。
4、NextionDriver扩展摸扩的作用
4.1、NextionDriver介绍
可能很多朋友有误会,认为使用串口屏一定要安装NextionDriver驱动。其实不是的
如前文所说,NextionDriver的主要功能和特点是:
- MMDVM不再直接选择物理串口,而是选择/dev/ttyNextionDriver这个虚拟串口
- /dev/ttyNextionDriver虚拟串口接收来自MMDVM的串口指令,经过处理后发送给物理串口
- NextionDriver可以处理和扩展来自MMDVM的串口指令,例如添加DMR Alisa,Location,CPU TEMP这些原本MMDVM没有的字段
- NextionDriver可以侦听来自触摸屏的触控指令。
不装该项目也行,不是必选,但是有些字段不传递
4.2、NextionDriver GitHub传送门
https://github.com/on7lds/NextionDriver
https://on7lds.net/42/
4.3、安装NextionDrive
https://github.com/on7lds/NextionDriverInstaller
4.4、配置NextionDriver
NextionDriver的参数本身也位于 MMDVM 配置文件的额外部分 [NextionDriver]中(MMDVM.ini 或 PiStar 上的 /etc/mmdvmhost)
配置字段含义参考https://github.com/on7lds/NextionDriver/blob/master/README-options.md
三、参考GitHub上几个经典NXT屏幕工程
1、MMDVM项目中的NXT基础工程
关注其中的Nextion_ON7LDS和Nextion.cpp
https://github.com/g4klx/MMDVMHost
https://github.com/g4klx/MMDVMHost/blob/master/Nextion.cpp
Nextion.cpp中可以看到原始传递给Nextion的字段内容
L3 Layout模式下传递的字段说明:
https://github.com/g4klx/MMDVMHost/blob/master/Nextion_ON7LDS/README-L3
关于L2和L3两个布局的区别,L2传递字体、颜色各种信息,强约束屏幕布局。L3只传递文本内容,自定义屏幕建议使用L3的布局字段进行开发。
2、ON7LDS的扩展项目
https://github.com/on7lds/NextionDriver/tree/master/Nextion
这几个HMI工程很具有参考意义
四、串口屏幕程序设计
1、陶晶驰wiki:
后面有关于代码的问题,可以先去看官方wiki,上面啥都有
http://wiki2.tjc1688.com/start/index.html
2、创建工程
后文的教程,可以参考逗老师最近创建的一个工程文件
示例MMDVM串口屏HMI工程文件
3、MMDVM主页
page MMDVM为待机界面,名称一定要是"MMDVM"
4、DMR页面和YSF页面
名称一定要是DMR和YSF
5、进阶操作1-呼号历史记录显示
以YSF页面为例
前文所说,MMDVM在更新任意一条指令之后,都会去点击一下S0按钮,所以我们可以在S0的点击动作里面去写一些复杂操作。
同时,还记的前面说的MMDVM.status这个全局变量么,MMDVM.status=84的时候,代表刚刚更新过的是YSF通联的相关字段。
所以,如果想记录通联历史,在当S0被按下且MMDVM.status=84的时候,把当前YSF页面需要存储的字段,赋值给下面的txbis文本上,并以此循环赋值,是不是就可以实现历史记录保存功能了呢
if(MMDVM.status.val==84)
{
if(t0bis1.txt!=t0.txt)
{
if(t0bis1.txt!="")
{
t0bis7.txt=t0bis6.txt
t2bis7.txt=t2bis6.txt
t200bis7.txt=t200bis6.txt
t0bis6.txt=t0bis5.txt
t2bis6.txt=t2bis5.txt
t200bis6.txt=t200bis5.txt
t0bis5.txt=t0bis4.txt
t2bis5.txt=t2bis4.txt
t200bis5.txt=t200bis4.txt
t0bis4.txt=t0bis3.txt
t2bis4.txt=t2bis3.txt
t200bis4.txt=t200bis3.txt
t0bis3.txt=t0bis2.txt
t2bis3.txt=t2bis2.txt
t200bis3.txt=t200bis2.txt
t0bis2.txt=t0bis1.txt
t2bis2.txt=t2bis1.txt
t200bis2.txt=t200bis1.txt
}
t0bis1.txt=t0.txt
t2bis1.txt=t2.txt
t200bis1.txt=t200.txt
}
}