之前的《Android Things創(chuàng)客DIY第三課-Android Things入門配件包開發(fā)案例教程-數(shù)碼管顯示》中猛铅,介紹了如何使用Android Things控制1位數(shù)碼管顯示镐牺。本文先對之前的1位數(shù)碼管做一個回顧烹骨,再介紹4位數(shù)碼管顯示原理和動手實踐過程。
根據(jù)之前的介紹拂玻,我們知道酬凳,1位數(shù)碼管是通過8個GPIO控制8個顯示段的顯示尚蝌,達到顯示不同數(shù)字的目的的。1位的8段數(shù)碼管磕蒲,相當(dāng)于8個獨立的LED發(fā)光二極管留潦。每個獨立的發(fā)光二極管都有正極(陽)和負極(陰)兩根引腳。
所謂共陽辣往,就是把這8個發(fā)光二極管的正極(陽)連接在一起兔院,接入到電源正極,通過GPIO分別控制每個發(fā)光管的負極站削,達到控制顯示的目的坊萝。
所謂共陰,就是把這8個發(fā)光二極管的負極(陰)連接在一起钻哩,接入到GND上屹堰,通過GPIO分別控制每個發(fā)光管的正極,達到控制現(xiàn)實的目的街氢。
入門配件包中提供的1位數(shù)碼管是“1位共陰”的數(shù)碼管扯键,所以在之前的例子中,我們是將共陰腳接在GND上珊肃,將8段的腳分別接在8個GPIO上荣刑,控制8個段的GPIO為高電平時該段顯示,為低電平時該段不顯示伦乔。
4位數(shù)碼管顯示的物料準備
1. 樹莓派3B開發(fā)板 或 NXP Pico i.MX7D開發(fā)板
2. 1KΩ電阻8個(入門配件包中藍色電阻)
3. 4位數(shù)碼管
4. 透明熱縮管
5. 面包板
6. 杜邦線12根(公-母)
如需購買入門配件包厉亏,可訪問:淘寶(https://item.taobao.com/item.htm?id=564226570619)?或?微店(https://weidian.com/item.html?itemID=2238998104)
了解4位數(shù)碼管的顯示原理
如前文所述,1位數(shù)碼管的顯示需要8個GPIO烈和,那么控制4位數(shù)碼管爱只,是不是需要4*8=32個GPIO呢?什么樣的開發(fā)板會提供那么多GPIO???
答案當(dāng)然是否定的招刹。我們說過數(shù)碼管每段有正極(陽)和負極(陰)恬试,如前面所述窝趣,我們將1位共陰數(shù)碼管的共陰腳接在GND上,那么如果我們將共陰腳接在另一個GPIO上呢训柴?通過這個GPIO哑舒,我們就可以控制這一位數(shù)碼管是否顯示。那么對于4位數(shù)碼管幻馁,我們就可以通過4個GPIO選擇我們要顯示4位中的哪一位洗鸵。
通過這種方式,我們只需要4+8個GPIO仗嗦,就可以控制4位數(shù)碼管的每一位依次顯示了:
1. 設(shè)置第一位數(shù)字要顯示哪些段
2. 通過GPIO控制第一位數(shù)字顯示
3. 持續(xù)一段時間
4. 關(guān)閉第一位數(shù)字的顯示
5. 設(shè)置第二位數(shù)字要顯示哪些段
6. 通過GPIO控制第二位數(shù)字顯示
……如此周而復(fù)始
那么如何實現(xiàn)4位數(shù)字同時顯示呢膘滨?其實只要上面依次顯示的刷新速度足夠快,人眼看到的就是同時顯示的效果了儒将。
動手實踐
入門配件包中提供的4位數(shù)碼管是”4位共陽“數(shù)碼管吏祸,即控制4位數(shù)字某位是否顯示的引腳接入正極(陽)——也就是高電平時該位顯示;控制數(shù)字中某段是否顯示的引腳接入負極(陰)——也就是低電平時該段顯示钩蚊。
可以按上圖的原理贡翘,使用面包板進行接線,先將4位數(shù)碼管插在面包板上砰逻,將數(shù)碼管的各段對應(yīng)的引腳鸣驱,通過電阻引出,再接到開發(fā)板上蝠咆。將每位數(shù)字的引腳踊东,通過面包板接到開發(fā)板對應(yīng)的引腳上。連接效果如下圖所示:
接下來刚操,我們就可以通過程序控制數(shù)碼管的顯示了闸翅。代碼同樣可以從Github上下載:https://github.com/sysolve/androidthings-digitalDisplay
案例代碼已升級到Android Things?Developer Preview 7版本,注意開發(fā)板系統(tǒng)與代碼版本一致菊霜。
代碼中的FourDigitalActivity.java即為控制4位數(shù)碼管顯示的程序坚冀,運行前需要將AndroidManifest.xml中FourDigitalActivity的啟動設(shè)置注釋取消,并將MainActivity的啟動設(shè)置注銷掉鉴逞。
程序分析
首先记某,我們對控制數(shù)字的各個段的GPIO進行定義,即digital[0]~digital[7]构捡;對控制數(shù)碼管4位數(shù)字是否顯示的GPIO進行定義液南,即showDigital[0]~showDigital[3]。
初始化時勾徽,我們讓所有段滑凉、所有數(shù)字都不現(xiàn)實,因為是4位共陽數(shù)碼管,我們將所有段對應(yīng)的GPIO置為高電平譬涡,Gpio.DIRECTION_OUT_INITIALLY_HIGH闪幽;將各位數(shù)字是否顯示的GPIO設(shè)置低電平啥辨,Gpio.DIRECTION_OUT_INITIALLY_LOW涡匀。
初始化完成后,我們先依次顯示每位數(shù)字的每個段進行一下測試溉知,即代碼中調(diào)用testDigitalSegment()方法陨瘩。具體代碼不再貼出,邏輯摘要如下:
for-each showDigital[d]? ? ? ? ? ? //循環(huán)每一位數(shù)字
? ? ? showDigital[d].setValue(true);? ?//控制這一位數(shù)字顯示(置高電平)
? ? ? for-each digital[i]? ? ? ? //循環(huán)數(shù)字的每一段
? ? ? ? ? ? ? digital[i].setValue(false);? ? ? ? ? ? //控制這一段顯示(置低電平)
? ? ? ? ? ? ? Thread.sleep(200);? ? ? ? ? ? ? ? ? ? //持續(xù)200ms
? ? ? ? ? ? ? digital[i].setValue(true);? ? ? ? ? ? ? //關(guān)閉這一段顯示(置高電平)
? ? ? showDigital[d].setValue(false);? ? //控制這一位數(shù)字不顯示(置低電平)
這樣级乍,我們就能依次看到各位數(shù)字的各段依次顯示的效果了:https://github.com/sysolve/androidthings-digitalDisplay#testdigitalsegment
每段都顯示完成后舌劳,接下來依次顯示數(shù)字。
首先我們要定義0-9這10個數(shù)字對應(yīng)數(shù)碼管各段顯示的真值表玫荣,真值表與1位數(shù)碼管顯示的例子相同甚淡,即數(shù)字8顯示的真值表為7段都為true,只有最后個點為false捅厂。
因為我們用的4為數(shù)碼管是共陽的數(shù)碼管贯卦,低電平時對應(yīng)段才顯示,我已在使用真值表中的值時焙贷,需要先取反。接下來我們來看testDisplayDigital()方法辙芍,邏輯如下:
for i = -1 to 10? ? //依次顯示0-9的數(shù)字,為-1時不現(xiàn)實
? ? ? ? for-each showDigital[d]? ? //遍歷每一位數(shù)字庶灿,即依次在各位數(shù)碼管上顯示數(shù)字
? ? ? ? ? ? ? ? ?displayDigital(i);? ? //調(diào)用displayDigital(i)方法,設(shè)置顯示數(shù)字i
? ? ? ? ? ? ? ? ?showDigital[d].setValue(true);? ? //設(shè)置指定位的數(shù)碼管顯示
? ? ? ? ? ? ? ? ?Thread.sleep(500);? ? //持續(xù)500ms
? ? ? ? ? ? ? ? ?showDigital[d].setValue(false);? ? //設(shè)置指定位的數(shù)碼管不顯示
在displayDigital()方法中吃衅,我們從真值表中獲得指定數(shù)字d各段是否顯示往踢,并循環(huán)設(shè)置GPIO捐晶,注意菲语,設(shè)置GPIO時要先取反惑灵。
這樣我們就能看到0~9的數(shù)字山上,依次在數(shù)碼管的各位上顯示出來:https://github.com/sysolve/androidthings-digitalDisplay#testdisplaydigital
最后,我們來看看如何通過4位數(shù)碼管顯示4位數(shù)字英支,我們來做個自動累加計數(shù)器,并將計數(shù)器的數(shù)值顯示在數(shù)碼管上。
//自動計數(shù)
autoIncNumber();//將自動計數(shù)的數(shù)值顯示在4位數(shù)碼管上
display4Digitals();
autoIncNumber()每隔1秒調(diào)用一次楞黄,即每秒計數(shù)+1,并將計數(shù)器值轉(zhuǎn)換成4位數(shù)字分別存放在digitalForDisplay[]數(shù)組中鬼廓。
display4Digitals()方法是一個持續(xù)掃描數(shù)碼管的各個數(shù)位致盟,并將計數(shù)器值的對應(yīng)位顯示在對應(yīng)的數(shù)碼管對應(yīng)位上的方法。
while (true)? ? ? //持續(xù)刷新顯示
? ? ? ? ? ? for-each showDigital[d]? ? ? ? ?? //依次在每位數(shù)碼管上顯示 ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ?//先設(shè)置顯示的數(shù)碼管段
? ? ? ? ? ? ? ? ? ? ?displayDigital(digitalForDisplay[d]);? ? ? ? ? ? ? ? ? ? ?//設(shè)置對應(yīng)的數(shù)碼管位開啟顯示
? ? ? ? ? ? ? ? ? ? ?showDigital[d].setValue(true);? ? ? ? ? ? ? ? ? ? ?Thread.sleep(2);? ? ? ? ? ?//掃描時間越短馏锡,數(shù)字顯示的閃爍感越弱,如將數(shù)值改大杯道,則會看到各個數(shù)字位依次顯示的效果
? ? ? ? ? ? ? ? ? ? ?//設(shè)置對應(yīng)的數(shù)碼管位關(guān)閉顯示
? ? ? ? ? ? ? ? ? ? ?showDigital[d].setValue(false);
這樣,我們就完成了數(shù)碼管顯示4位數(shù)字:https://github.com/sysolve/androidthings-digitalDisplay#display4digitals
寫在后面
1. 數(shù)碼管可以顯示小數(shù)點萎庭,感興趣的朋友昧港,可以嘗試一下用4位數(shù)碼管顯示小數(shù)擎椰。
2. 4位數(shù)碼管顯示時创肥,會發(fā)現(xiàn)亮度忽亮忽暗的情況,這是因為Android并非實時系統(tǒng)巩搏,顯示延時并不精確,而掃描各位數(shù)字顯示時贯底,時間長短直接影響顯示亮度撒强。
3. 占用過多GPIO,樹莓派3B一共有13個GPIO飘哨,NXP Pico iMX7D只有12個,而這個4位數(shù)碼管就用掉了12個GPIO!
4. 本案例只是為了講解4位數(shù)碼管的原理芽隆,通常在實際使用中统屈,我們會使用專門的控制芯片去控制數(shù)碼管的顯示牙躺,由專用芯片實現(xiàn)數(shù)碼管各位的掃描顯示。通常只需要2~3個GPIO進行數(shù)據(jù)通訊孽拷,主控板將要顯示的內(nèi)容發(fā)送給數(shù)碼管控制芯片即可,具體的掃描顯示過程由專用芯片完成思犁,專用芯片中的實時系統(tǒng)保證顯示的效果更穩(wěn)定。在《Android Things創(chuàng)客DIY第五課-硬件開發(fā)案例教程-PWM調(diào)色-觸摸開關(guān)-數(shù)碼管顯示-OLED顯示》中介紹的帶冒號4位數(shù)碼管,就是通過專用芯片控制數(shù)碼管顯示的棉磨。