分享

《一种基于数码管/按键的人际交互界面设计模式》

 guitarhua 2018-01-22
《一种基于数码管/按键的人际交互界面设计模式》
在2018年的今天,因为智能手机的的极大普及,各种触摸显示屏大量出现在我们的身边。可是作为最古老的人机交互界面,数码管/按键依然在21世纪的现实生活中大量使用,因为其简单易用,稳定可靠,成本低廉。作为一个从业8年的嵌入式开发人员,虽然也经常做自带可触摸显示屏的嵌入式系统,包括linux和android,但是数码管/按键作为一种常用的人机交互界面,还是不断在日常的开发流程中重复使用。因为不是所以系统都需要一块5~10寸的可触摸显示屏,在一些小型控制系统中,选用触摸屏和数码管/按键两种方案,成本相差几十上百倍。如果不是一定要高端大气上档次的设计风格,那能省就省,这是开发人员的良心,不要故意为了卖弄技术而加大产品的成本和技术难度。

好了,闲话到此结束吧!下面进入今天的正题。先用一个问题来引出今天的主题吧?
如果产品经理决定用6个数码管和两个按键来进行人机交互界面的设计。
1.需要显示工作时间(以分钟表示,最高99),工作温度(以4位表示,最后一位为0.1摄氏度)
2.还必须输入不同的参数到系统(MCU)中,参数大约有20个左右,有正有负。
3.必须明确区分显示机器各种不同的状态或模式,比如运行模式,待机模式,设置模式,以及错误模式。

各位朋友都能想出什么好方法来呢?也许八仙过海,各有神通吧!也不卖关子了,在这里把我个人根据经验总结出来的一个设计模式展现给大家。也许叫设计模式有点大了,但是它确实解决了我遇到过的所有需用通过数码管/按键来进行人机交互的各种需求。

可显示的数码管就这么六个,可输入的部件也就两个按键。首先来说显示输出部分,因为系统有那么多的数据和参数需要显示并明确区分不同的模式。如果通过直接写数码管,再驱动数码管显示不同的数值和模式,就必须创建大量的条件判断分支,结构会很复杂。因此我就在想有没有更好的设计方式,联想到LCD驱动芯片工作模式,一般都是有一个显存,显存中的一个或几个字节分别对应一个像素点,程序即使处理再复杂的图形运算,也不需要直接调用不同的驱动函数进行输出,而只需把运算处理后的整个图形或图元分解成一个个的像素点数值,然后写入到显存中的这些像素点对应的字节地址中即可,然后显卡中的图形输出单元就会按照一定频率自动进行输出刷新。如此以来,大量减少了图形驱动显示方面的难度和需要处理的繁琐的细节。在linux中,这种显示输出模式叫帧缓存(frambuffer)驱动输出。

对了,就是这样的,我们可以把一个数码管联想成一个像素点,一个像素点有 亮度,红,绿,蓝,4种参数值,而一个数码管也有8个笔画(A,B,C,D,E,F,G,H),每个笔画有亮与灭两种状态,刚好可以对应成一个8位的unsigned char型值。因此我们也可以把一个数码管对应成一个像素点,多个数码管就用一个数组unsigned char[n]来表示。因此根据我们的设计要求,便有了如下示意图

数码管<--->定时刷新模块<--->显存<--->需要显示输出的客户模块

但是如果我们把数码管再想象成高级一点的显示器,为了满足我们的设计要求,它还必须可以闪烁显示,闪烁又有多种模式,1.全部笔画闪烁 2.单笔画闪烁 3.多笔画跳跃显示(比如先显示D,再显示G,最后显示A,然后依次循环显示,可用来代表一种工作状态), 而且可以是一个数码管单独闪烁,或者多个数码管一起闪烁。
上面只讲了数码管的显示输出功能,还可以配合按键显示输入值,方便用户对系统参数进行调整。这里开始结合按键来讲解相关的输入模式了。
首先,点击按键时要知道此时修改的哪个参数值和跟随按键的输入数值是多少。因此我们可以规划2位数码管来显示不同的设置代码,不同的设置代码代表不同的参数。剩下4位数码管显示该参数的实际数值。
其次,我们规划一个按键作为循环移动数码管的功能,因为6个数码管中我们只能同时修改某一位,选中的该位数码管进行闪烁,以显示其被选中,然后通过另一个按键来修改它的数值。这里就说到另一个按键的功能了,就是数值修改功能,比如说我们把它设定为加功能,按一下数值加一,因此能从0加到9,但是到9后就不能在继续加了,那我们则让它返回到0,因此由可以继续加了,只要能循环修改数值就行了。
最后,数值修改完了我们要怎么确认保存呢,只有这么两个按键,都已经分配了独一无二的功能了,也不能再进行功能复用了。但是别忘了,我们至少还有两个2虚拟按键。虚拟按键?说的也太神了吧?咋又来了2个虚拟按键呢??下面听我慢慢说来,首先必须要说的是刚才我们讨论的按键功能都是做个单独一个按键来讨论的,但是别忘了,我们还可以两个按键同时按。还能这么玩???嘿嘿,其实在很多系统中都有使用这种模式来作为一个隐藏功能,比如说当两键同时按下时进入设置模式,因为有些系统的设置是不想做的太方便而让人随便进行修改一样,就如同在进入设置前需要输入密码一样。就像防误触功能,尽管我们有时不小心会触碰到按键,但是同时误触碰到两个按键的概率就要大大降低了。

因为每个数码管都对应显存数组中的一个单元,当我们通过按键进行修改时,只需要对显存中该数码管的对应单元进行加减就行了,不需要立马对实际数值修改。一次性全部修改完后再统一更新保存到对于的该参数变量中。

哎...讲着虚拟按键又差点跑远了,刚才只讲了一个,还有一个呢?那我们反过来想,我们进入设置模式后,怎么退出设置模式呢?已经没有实体按键供我们驱使了,是不是有点抓狂了呢?其实解决办法还是有的,而且那种东西,对于每个活着的人都无时不刻不在享受着它?难道是空气??哈哈,玩笑开大了!其实那个不容易想到的变量就是时间。哈哈哈,是不是有点搞?!但是时间这个变量在控制系统中的妙用是非常多的,我们设计人员在做很多设计决策时一定要第一时间想到这个变量。比如在我们这个系统里,要退出设置模式非常简单,只需要在按键没有操作后的10秒退出设置模式就行了。专业点可是这么形容,在无按键操作10s后退出设置模式,或者说10s设置超时退出。

按键这边说得差不多了,我们还得回过头了将数码管这个部件,主要是数码管在我们系统中是最复杂的工作部件了。因为要支持这么多的功能,不复杂才怪呢?好了,基本工作原理也说得差不多了,下面来设计我们的显存单元结构。刚才只列举了一个最简单的结构,就是一给unsigned char数组,但是数码管其实还有好多精彩的玩法,我们也在这次设计中一块包含。如下所示,我设计一个unsigned int32 数组,需要这么大的单元结构吗?每个数码管用4个字节来表示,不是跟普通TFT LCD的ARGB模式差不多了吗?嘿嘿,其实也差不多了很多?你也千万别小看数码管这东西。
unsigned int32 digitrons[6]
为了兼容上次我们设计的显存单元结构,我们保持显存单元的低8位功能不变,还是代表数码管显示的段码,但不是啥时都会使用,是根据更高字节的数值位来决定,使用段码直接驱动输出还是进行BCD解码。

bit 7~0 段码,在需要时可使用这个字节直接驱动输出,可显示任意笔画或组合字段。
bit 15~8 其中11~8 4位代表该数码管数值的BCD码,能显示从0~9,A~F,涵盖了10进制和16进制的全部数值。
    12位为解码模式位,为0时进行BCD解码,为1时不解码,直接段码输出,实际段码为bit7~0。
    14~13两位代表闪烁模式,00时不闪烁,01时全字段闪烁,10时小数点闪烁,11暂时未定义
    15位代表小数点,为1时显示小数点字段,为0时不显示小数点。
bit 16 代表当前数码管处于设置修改状态,可配合数值修改按键进行数值修改。
bit 17 代表当前数码管是否为符号位,符号有两种,正或者负,为1时有效。
bit 18 当bit17为1时,bit18作为实际的符号位值,为0时代表正,为1时代表负。

备注:BCD解码模式,因为从0~9,A~B按数码管段码格式编码,可以用一个15位的数字来表示
unsigned char segment[15]={};
当处于BCD解码模式时,我们不需要在bit7~0直接赋值实际段码,只需要在bit11~8中,写入要显示的实际数值的BCD码,1就写1,2就写2,3就写3,直到F,在定时刷新模块里面,当bit12为1时,只需把bit11~8代入到上面的段码数组segment[]中作为序号即可取出对应段码,就免去了调用函数写入段码的工作,而变成了由刷新模块进行解码。
比如说我要让第3位数码管中显示9,只需要digitrons[2]=0x000300;即可完成工作,剩下的琐碎就由刷新模块去处理了,我就是大爷了,我只要有需求,直接按照上面规定的格式往digitrons[]数组中丢数据就行了,这叫极大的解放了程序员的生产力。只要能用BCD解码的尽量用解码模式,除非是解码模式满足不了的特殊显示要求,那就需要用到直接段码输出了。
一图胜千言,下面再用个示意图来表示上面说的一大堆废话,即按键/数码管输入原理。

数码管<--->定时刷新模块<--->显存<--->实际参数变量
                |
                |
              按键    
通过上面讲解的输入模式,可以非常方便快速的进行千位数范围内的任意数值输入。假如原先数值是999,要修改成-999,如果我们按照有些系统中的输入模式,当按住按键时对数值进行整体加减,从999变成-999,需要1999次减法,如果按照1秒钟10次按键扫描处理的话,需要按键3分多钟,即使不怕按键容易老化损坏,也怕使用客户的手指头都要麻木了。当然也有某些系统设计了按键加速功能,但是那个很不容易控制,一不小心就按过了头。但是在我们这个设计模式中,只需要在符号位按一下按键就可以从999变成-999了。从-999~999千位数范围内的任意数值输入,最多需要按键9×3+1=28次。







    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多