上篇文章,通過(guò)狀態(tài)機(jī)編程,實(shí)現(xiàn)了全自動(dòng)洗衣機(jī)的邏輯控制,并通過(guò)串口打印的方式顯示各個(gè)狀態(tài)。
本篇,為了更加直觀的感受狀態(tài)機(jī)的運(yùn)行,使用0.96寸OLED來(lái)顯示各個(gè)狀態(tài),并搭配對(duì)應(yīng)的動(dòng)態(tài)圖標(biāo)來(lái)體現(xiàn)洗衣機(jī)工作的各個(gè)狀態(tài)。
1 OLED圖片顯示
為了能方便的在OLED上顯示文字和圖片,可以借助一些圖形庫(kù)來(lái)幫我們顯示,這里使用的是U8g2圖形庫(kù)。
1.1 U8g2庫(kù)移植
U8g2庫(kù)在STM32上的移植,之前的文章已經(jīng)介紹過(guò),具體的移植過(guò)程可以參考這篇:
移植成功后,可以使用測(cè)試?yán)舔?yàn)證U8g2庫(kù)的顯示效果。
![pYYBAGKeImaAbklYAAES8Ep9QH8703.png](https://file.elecfans.com/web2/M00/47/BB/pYYBAGKeImaAbklYAAES8Ep9QH8703.png)
1.2 圖片顯示
圖片相比較文字,可以展示更加豐富的內(nèi)容,因此本篇通過(guò)簡(jiǎn)單的單色圖片來(lái)展示洗衣機(jī)的工作狀態(tài)。
U8g2庫(kù)顯示圖片,可以使用u8g2_DrawXBM函數(shù),需要先將圖片轉(zhuǎn)為數(shù)組。
可以使用這個(gè)在線網(wǎng)頁(yè)來(lái)進(jìn)行圖片數(shù)據(jù)的轉(zhuǎn)換:https://tools.clz.me/image-to-bitmap-array
這里可以使用自己喜歡的圖片,進(jìn)行展示,比如我選取了不同水量的洗衣機(jī)圖標(biāo)來(lái)顯示洗衣機(jī)的當(dāng)前水量,使用多張圖片的交替顯示產(chǎn)生洗衣機(jī)在清洗的動(dòng)畫效果。
![poYBAGMXWIeALw-DAABSGg7iq9s098.png](https://file.elecfans.com/web2/M00/67/50/poYBAGMXWIeALw-DAABSGg7iq9s098.png)
2 更多狀態(tài)輸出
OLED屏幕要想顯示洗衣機(jī)的工作狀態(tài),就需要獲取狀態(tài)機(jī)的具體工作狀態(tài)。這里自定義了一些展示需要用到的數(shù)據(jù),組成一個(gè)結(jié)構(gòu)體,狀態(tài)機(jī)在運(yùn)行過(guò)程中,對(duì)各個(gè)成員變量進(jìn)行修改,然后OLED端獲取這些數(shù)據(jù),再進(jìn)行展示。
typedef struct
{
WASHER_STATUS washerStatus; /*洗衣機(jī)的工作狀態(tài)*/
int targetWaterLevel; /*洗衣機(jī)的目標(biāo)水位*/
int targetWashTimes; /*洗衣機(jī)的目標(biāo)清洗次數(shù)*/
int remainingTime; /*洗衣機(jī)的剩余工作時(shí)間(暫未使用)*/
int curWaterLevel; /*洗衣機(jī)當(dāng)前的水位*/
bool hasNewData; /*是否有新的數(shù)據(jù)(用于告訴OLED是否刷新顯示)*/
}WASHER_OUTPUT_DATA;
對(duì)于OLED的展示邏輯,這里是在狀態(tài)機(jī)的每個(gè)循環(huán)結(jié)束后,調(diào)用下面的程序邏輯進(jìn)行展示:
void show_washer_status(WASHER_OUTPUT_DATA washerOutPutData)
{
if (washerOutPutData.hasNewData)
{
WASHER_STATUS s = washerOutPutData.washerStatus;
printf("u8g2 get status:%d(%s)\r\n", s, washer_status_name[s]);
switch(s)
{
case WS_INIT: showWasherInit(&u8g2, washerOutPutData); break;
case WS_IDLE: showWasherIdle(&u8g2, washerOutPutData); break;
case WS_ADD_WATER: showWasherAddWater(&u8g2, washerOutPutData); break;
case WS_WASH: showWasherWash(&u8g2, washerOutPutData); break;
case WS_DRAIN_WATER: showWasherDrainWater(&u8g2, washerOutPutData); break;
case WS_SPIN_DRY: showWasherSpinDry(&u8g2, washerOutPutData); break;
case WS_PAUSE: showWasherPause(&u8g2, washerOutPutData); break;
case WS_DONE: showWasherDone(&u8g2, washerOutPutData); break;
default: break;
}
}
}
當(dāng)此輪狀態(tài)循環(huán)有新的數(shù)據(jù)產(chǎn)生時(shí),則根據(jù)狀態(tài)機(jī)的主狀態(tài),分別顯示對(duì)應(yīng)狀態(tài)下的圖片或動(dòng)畫。
比如加水狀態(tài),會(huì)根據(jù)當(dāng)前加的水位,不斷更新圖片展示的水位:
void drawCurWaterLevel(u8g2_t *u8g2, int level)
{
switch(level)
{
case 0: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_0); break;
case 1: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_1); break;
case 2: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_2); break;
case 3: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_3); break;
case 4: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_4); break;
case 5: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_5); break;
case 6: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_6); break;
case 7: u8g2_DrawXBM(u8g2,64, 16, 48, 48, pic_water_7); break;
default: break;
}
}
void showWasherAddWater(u8g2_t *u8g2, WASHER_OUTPUT_DATA data)
{
char strStatus[14] = "AddWater";
u8g2_ClearBuffer(u8g2);
u8g2_SetFont(u8g2,u8g2_font_ncenB10_tr);
u8g2_DrawStr(u8g2,0,15,strStatus);
drawCurWaterLevel(u8g2, data.curWaterLevel);
u8g2_SendBuffer(u8g2);
}
?對(duì)于主程序的結(jié)構(gòu),和上篇一樣,只是增加了OLED的顯示:
int main(void)
{
delay_init(); //延時(shí)函數(shù)初始化
LED_Init(); //初始化與LED連接的硬件接口
oled_init();
KEY_Init();
uart_init(115200);
TIM3_Int_Init(500-1,7200-1); //調(diào)用定時(shí)器使得50ms產(chǎn)生一個(gè)中斷
printf("hello\r\n");
while(1)
{
washer_run_loop();
WASHER_OUTPUT_DATA data = get_washer_output_data();
show_washer_status(data);
delay_ms(100);
}
}
在狀態(tài)機(jī)每運(yùn)行一個(gè)循環(huán),獲取一下具體的狀態(tài)數(shù)據(jù),然后使用OLED將具體的狀態(tài)數(shù)據(jù)展示出來(lái)。
3 具體演示
再來(lái)對(duì)比看下這個(gè)狀態(tài)圖,實(shí)驗(yàn)測(cè)試狀態(tài)機(jī)的執(zhí)行。
![pYYBAGMWC8CAUAu0AADA8uwfW3c243.png](https://file.elecfans.com/web2/M00/67/B4/pYYBAGMWC8CAUAu0AADA8uwfW3c243.png)
正常的洗衣流程
不考慮暫停這個(gè)狀態(tài),洗衣機(jī)上點(diǎn)開始后,依次經(jīng)歷空閑、加水、清洗、排水、甩干這幾個(gè)流程即結(jié)束,若清洗計(jì)數(shù)設(shè)置了不知1次,則加水、清洗、排水這3個(gè)動(dòng)作會(huì)循環(huán)執(zhí)行對(duì)應(yīng)的次數(shù)。
洗衣流程中暫停再繼續(xù)
在洗衣機(jī)的運(yùn)行狀態(tài):加水、清洗、排水、甩干,通過(guò)暫停按鈕,可以暫停這些狀態(tài)的執(zhí)行,此時(shí)狀態(tài)機(jī)會(huì)運(yùn)行于暫停模式,再按繼續(xù)(暫停/繼續(xù)的一個(gè)按鈕),則會(huì)繼續(xù)執(zhí)行洗衣工作。
暫停后修改水量或次數(shù)后再繼續(xù)
在洗衣過(guò)程中,如果想要修改洗衣的水量或次數(shù),可以先通過(guò)暫停鍵來(lái)暫停洗衣機(jī)的運(yùn)行,然后通過(guò)水位或次數(shù)按鈕,使?fàn)顟B(tài)機(jī)從暫停狀態(tài)先切換到空閑狀態(tài),進(jìn)行水位或次數(shù)的調(diào)整后,再繼續(xù),即會(huì)按照新的設(shè)置參數(shù)繼續(xù)運(yùn)行洗衣程序。
比如本來(lái)的清洗水位是3,清洗次數(shù)是1,在第一次清洗的加水時(shí)按下暫停,再將清洗參數(shù)進(jìn)行修改,比如水位設(shè)為5,次數(shù)設(shè)為2,再繼續(xù)后,會(huì)再次進(jìn)入加水狀態(tài),并將水位補(bǔ)到5后,繼續(xù)清洗,并清洗2遍結(jié)束。
注:本狀態(tài)機(jī)還有繼續(xù)優(yōu)化的空間,比如:
水量只會(huì)補(bǔ)加,多了此輪清洗不會(huì)排出。比如先設(shè)置的水位是5,在加到3個(gè)時(shí)候,暫停并修改為2,再繼續(xù)后,判斷大于目標(biāo)水位則會(huì)直接開始清洗,不會(huì)先由水位3再排水到水位2再清洗
任何清洗狀態(tài)(加水、清洗、排水)按下暫停調(diào)整水位后,再繼續(xù),都會(huì)默認(rèn)跳到加水重新新的清洗循環(huán),如果是在排水狀態(tài),調(diào)整了水位后,此次的水還沒(méi)有排位,就又重新加水開始洗,不太合理
以上3種測(cè)試方式的演示效果,可以再對(duì)比看下演示視頻:
https://www.bilibili.com/video/BV1xT411E7pY
![poYBAGMXWbmAIDfmAAsqoUkF_GU573.png](https://file.elecfans.com/web2/M00/67/50/poYBAGMXWbmAIDfmAAsqoUkF_GU573.png)
4 總結(jié)
本篇在上篇全自動(dòng)洗衣機(jī)的狀態(tài)機(jī)編程實(shí)例的基礎(chǔ)上,增加了OLED來(lái)更新直觀的展示洗衣機(jī)的工作狀態(tài),并通過(guò)3種測(cè)試場(chǎng)景來(lái)展示洗衣機(jī)工作狀態(tài)機(jī)的執(zhí)行。
-
STM32
+關(guān)注
關(guān)注
2273文章
10926瀏覽量
357767 -
洗衣機(jī)
+關(guān)注
關(guān)注
13文章
680瀏覽量
43441 -
狀態(tài)機(jī)
+關(guān)注
關(guān)注
2文章
492瀏覽量
27674
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
FPGA設(shè)計(jì)洗衣機(jī)
跪求畢業(yè)設(shè)計(jì):全自動(dòng)洗衣機(jī)系統(tǒng)設(shè)計(jì)?。?!
跪求 全自動(dòng)洗衣機(jī)系統(tǒng) proteus仿真?。?!
洗衣機(jī)為什么能自動(dòng)運(yùn)行呢
如何去實(shí)現(xiàn)一種基于單片機(jī)的全自動(dòng)洗衣機(jī)模擬系統(tǒng)設(shè)計(jì)
基于單片機(jī)SPMC75的模擬全自動(dòng)洗衣機(jī)的設(shè)計(jì)
全自動(dòng)洗衣機(jī)控制電路
全自動(dòng)洗衣機(jī)
全自動(dòng)洗衣機(jī)程序
半自動(dòng)洗衣機(jī)改全自動(dòng)教程
基于STM32單片機(jī)的全自動(dòng)洗衣機(jī)
STM32狀態(tài)機(jī)編程實(shí)例——全自動(dòng)洗衣機(jī)(上)
![<b class='flag-5'>STM32</b><b class='flag-5'>狀態(tài)機(jī)</b><b class='flag-5'>編程</b><b class='flag-5'>實(shí)例</b>——<b class='flag-5'>全自動(dòng)</b><b class='flag-5'>洗衣機(jī)</b>(上)](https://file.elecfans.com//web2/M00/67/1B/poYBAGMWDNWARU5KAACFza_1ZuU350.png)
評(píng)論