首页 技术服务 智能显示屏 Smart Display RS485 进阶实例

Smart Display RS485 进阶实例

一、前言

前一篇关于 SmartDispaly RS485的技术文章『SmartDisplay RS485入门』已经对RS485与 Modbus协议进行初步介绍,本篇将进一步以多页面的实例来介绍几个常用的技巧,同时说明相关的SmartDisplay规格与技术,包括:

  • 如何利用按钮widget进行换页。
  • 换页后的widget数据更新。
  • 以蜂鸣器发出不同长短的声音。
  • Graph widget的使用方法。

二、 准备材料

  • 具备RS485接口的SmartDisplay 。此处使用的是3.5” SmartDisplay。
  • Arduino (Uno 或Mega2560)。
  • Arduino 的RS485 扩充板 (Link to DFRobot)
  • 可变电阻。

三、 接线方式

  • 可变电阻:Vcc接5V, GND 接GND, 输出接到 Arduino A0。
  • RS485扩充板的A接到SmartDisplay RS485+。
  • RS485扩充板的B接到SmartDisplay RS485-。

四、 范例内容

这个项目包含三个页面,各页面可以利用按钮对象进行切换。各页面的内容与功能如下:

第一页:
右方有一个到下一页的按钮,下方则有一个调整屏幕亮度的Horizontal Slider。预视图如下:

范例内容 - 第一页

第二页:
左边按钮回前一页,右边按钮到下一页,以及下方三个按钮可以分别发出短、中、长三种不同长度的蜂鸣声。

范例内容 - 第二页

第三页:
左边按钮回前一页,同时以可变电阻模拟模拟输入,将结果显示在Graph widget上:

范例内容 - 第三页

由于本范例中使用了RS485扩充板,在开始进行编程前请透过函式库管理员进行下载函式库:

由于本范例中使用了RS485扩充板,在开始进行编程前请透过函式库管理员进行下载函式库

五、 建立页面内容

首先以GUI Builder建立页面内容。其中各页面的 Text widget可以直接填入文字,就不必在程序中写入:

建立页面内容 - 1

详细的 widget 内容如下表所示:

建立页面内容 - 2

您可以根据现有材料选择SmartDisplay型号,并使用不同widget制作不同的外观,唯一要注意的是每一页的 widget ID与Type必须和程序中的写法一致,所以为了避免复杂化,建议还是根据此表的 widget ID和type 建立您的页面内容。

接下来就要进入程序部分。

六、 范例解说

1. Include 檔

下载 ModebusMaster 函式库后,记得要加入 #include:

范例解说 - Include 文件 - 1

另外我们也把一些 SmartDisplay 相关的常数放在 SmartDisplayModbus.h 中以方便管理,也要包含进来。

2. Widget ID与缓存器的转换

在前一篇的介绍文章中曾说明 widget ID 的缓存器地址换算方式如下:

范例解说 - Widget ID与缓存器的转换 - 1

但这个表格是针对早期每页最多只有10个widgets的情况下制定。现在每一页的 widget 已经可以增加到最多 64 个。这个表格在前10个 widget 仍然适用,但超过10个以后就必须调整到新的缓存器区块,因此我们定义了下列巨集:

范例解说 - Widget ID与缓存器的转换 - 2

为了方便使用,我们定义了根据 widget ID 来进行读写的函式,在函式中进行转换:

Explanation - (2) Widget ID to Register Conversion - 3范例解说 - Widget ID与缓存器的转换 - 3

3. Widget ID 与 GUI 设计

在前面使用 GUI Builder 设计页面内容时曾提到 widget ID 必须保持一致,因此程序中定义了 widget ID常数如下:

范例解说 - Widget ID 与 GUI 设计 - 1

利用这些常数定义可以帮助我们记忆widget的类别,同时便于对照到实际的页面设计。日后若GUI设计上有进行修改,也记得要对这些数值进行比对,以免产生错误。

4. 蜂鸣器

韧体实现蜂鸣器发声方式是以计数器延迟一段时间后送出0/1讯号给蜂鸣器发出声音,并以其他计数器来控制声音启动与关闭的时间。为了发出声音,我们必须写入四个缓存器,包括:

范例解说 - 蜂鸣器 - 1

为了调整声音长度,我们制作一个传入SMARTDISPLAY_BUZZER_HIGH参数的函式进行发音:

范例解说 - 蜂鸣器 - 2

SMARTDISPLAY_BUZZER_ACTIVE 必须与前一次写入的值不一样时才会进行发声,所以在此函式内以 static 式存在,并且在每次呼叫前进行反向处理。

最后在页面处理函式中就可以根据按钮状态发出不同长度的声音了:

范例解说 - 蜂鸣器 - 3

5. 换页机制

换页前必须先进入 CONFIG_MODE。设定到新页面后,再设为 DISPLAY_MODE。在切换页面后,SmartDisplay会重载新页面所有的 widgets。为了避免在SmartDisplay加载动作完成前进行读写,我们通常会增加一个延迟时间稍作等待。这个延迟长度与页面复杂度有关,若实际操作时发现换页后有异常现象,可以试着延长时间看看。

范例解说 - 换页机制 - 1

换页之后新页面的 widgets的内容都是默认值,因此我们建立一个流程来进行换页、记录 widgets及回复 widgets的数值。

首先定义页面处理的函式指标,方便我们建立页面表格,并且为每一页指定一个处理函式:

范例解说 - 换页机制 - 2

并且建立页面表格:

范例解说 - 换页机制 - 3

常数MAX_WIDGETS_PER_PAGE 定义了每一页要记录数值的 widgets数量。若日后增加了widget数,记得同步更新些值。

最后在 loop() 进行处理:

范例解说 - 换页机制 - 4

当发现目前页面_curPage不等于下个页面_nextPage时,就将换页旗标 newPage 设为 true,这样在页面处理函式知道需要进行初始化。以 Page0 为例:

范例解说 - 换页机制 - 5

若传入的 init 为 true 表示刚进入页面,我们就将 WIDGET_P0_BUTTON_NEXT 的值设为0,这是因为刚换到新页的按钮默认值为 0,我们希望只有在刚按下时(此时读到的值为由0变1)才会执行特定指令(这里为换到PAGE_1),因此要重新设定(因为先前可能已经按下变成1了)。

Slider 刚加载时的初值也是0,但是先前可能已经修改过亮度,因此要恢复成目前的亮度值 _brightness。

其他时候(init 为 false)则根据 widget 的是否有变化进行相对的处置,最后再把所有 widget的值都存起来,供下次处理时参考。

至于下一页_nextPage的设定,是利用下列函式:

范例解说 - 换页机制 - 6

页面处理函式除了第一次外每次都会检查 widgets内容。当检查到按钮由0变1时就呼叫此函式提出换页需求:

范例解说 - 换页机制 - 7

6. 绘图对象(Graph Widget)

Graph widget可以将写入的数值以绘图的方式呈现。这里使用一个可变电阻接到 A0 模拟成模拟输入,以Graphic widget显示数据的变化。由于 Arduino 的模拟输入范围为 0-1023,而 Graph widget 的接受范围则为 0-100,因此要使用 map() 进行范围调整。

Graph widget被设计成当数值改变时才会更新画面,若想要呈现定时更新的效果,就得使用一些小技巧:定时更新检查数值,若发现新的值与上次读取的值相同时,就稍微加以变化(加1或减1),这样就可以产生定时更新的动态效果。

范例解说 - 绘图对象(Graph Widget) - 1

七、 结语

以上就是对这次范例程序的说明,希望能让读者有进一步的认识。此范例也可以做为日后项目的初始框架,缩短一些开发时间。完整的程序可以在下列网址下载: Modbus-MultiPageOperation on GitHub.

若对 RS485 / Modbus 比较不熟悉的话,也可以参考前一篇的说明: SmartDisplay RS485 Introduction.

回分类页
go top
close