先說(shuō)說(shuō)硬件環(huán)境,使用的是STM32F4DISCO(自帶加速度)+Si4703+LCD5110。軟件設(shè)計(jì)上,雖然應(yīng)用的核心功能是收音機(jī)了,但是和大部分的應(yīng)用相似,沒(méi)有良好的用戶交互界面,使用體驗(yàn)是要大打折扣的。所以下面的文字大部分都集中在用戶交互設(shè)計(jì)上。
首先是控制部分,加速度計(jì)可以提供上下左右4個(gè)方向的控制,在應(yīng)用中給音量增減和電臺(tái)下上切臺(tái)使用。由于敲擊功能沒(méi)有實(shí)現(xiàn),因此電臺(tái)的開(kāi)關(guān)交給了開(kāi)發(fā)板上的用戶按鍵。用戶按鍵原計(jì)劃使用callback來(lái)實(shí)現(xiàn)功能,但是測(cè)試木有成功啊。不過(guò)既然加速度值也是用polling的話,那不如按鍵也一起好了。掃描使用最原始的方式,掃描到以后,延時(shí)10ms,然后再判斷是否按下。加速度計(jì)在使用時(shí),也存在類(lèi)似的抖動(dòng),因此也使用了相同的邏輯來(lái)消抖。同時(shí),通過(guò)測(cè)試,給定了一個(gè)加速度計(jì)傾轉(zhuǎn)的閾值:g=0.3,也就是說(shuō)當(dāng)某個(gè)方向(不含z)的g大于0.3,表示有用戶動(dòng)作發(fā)生。
接下來(lái)就是顯示界面了。整個(gè)5110有6行高度為8的字符可用,每行84個(gè)點(diǎn)。應(yīng)用要顯示的核心內(nèi)容是電臺(tái)頻率和音量,內(nèi)容不多,因此可以適當(dāng)放大。最終頻率選擇了12*24的字體,占用3行,又不會(huì)把整行撐滿;音量做了以模擬的bar顯示,用豎條|||||||的多少表示音量的打下,占用兩行;這樣還多出一行,用來(lái)顯示一個(gè)固定字符串“PY FM Radio”。
整體界面如下圖所示:
事先用其他方式確定了若干個(gè)本地效果較好的電臺(tái),放到了radiolist中。當(dāng)發(fā)現(xiàn)有左右手勢(shì)的時(shí)候,取出radiolist中的下一個(gè)電臺(tái)頻率值,發(fā)送給Si4703,并更新顯示界面,電臺(tái)頻率是繞圈改變的,也就是說(shuō)到了radiolist的最后一個(gè),下一次就回到了第一個(gè)。當(dāng)發(fā)現(xiàn)有上下手勢(shì)時(shí),對(duì)volume進(jìn)行響應(yīng)的改變,并發(fā)送給Si4703,并更新顯示界面。音量最大15,最小0(表示靜音)。當(dāng)發(fā)現(xiàn)有用戶按鍵動(dòng)作時(shí),在開(kāi)關(guān)狀態(tài)之間切換。關(guān)閉時(shí),清除屏幕,關(guān)閉Si4703;開(kāi)機(jī)時(shí),正常顯示,F(xiàn)M工作。
視頻演示:
說(shuō)明:
設(shè)計(jì)過(guò)程中發(fā)現(xiàn)了浮點(diǎn)數(shù)運(yùn)算的精度問(wèn)題。比如頻率99.6Mhz,在list當(dāng)中是存成996的,顯示的時(shí)候,通過(guò)運(yùn)算channel=str(996/10),將電臺(tái)轉(zhuǎn)為浮點(diǎn)字符串99.6。前期調(diào)試的時(shí)候,用的電臺(tái)較少,沒(méi)有問(wèn)題。后面把所有電臺(tái)都加上時(shí),發(fā)現(xiàn)有些電臺(tái),比如890,做了除法運(yùn)算以后,變成了89.0001,導(dǎo)致顯示行方向溢出。最后通過(guò)字符串截取的方式取到自己想要的長(zhǎng)度。python似乎沒(méi)有printf?
目前還有一些小問(wèn)題,比如加速度識(shí)別的抖動(dòng)有時(shí)候還會(huì)出現(xiàn),音量有時(shí)候會(huì)有跳變等等。最后通過(guò)視頻看下具體效果吧。
詳細(xì)的制作講解和main.py見(jiàn)附件內(nèi)容。