0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32状态机编程实例——全自动洗衣机(下)

码农爱学习 来源:码农爱学习 作者:码农爱学习 2022-09-07 08:47 次阅读

上篇文章,通过状态机编程,实现了全自动洗衣机的逻辑控制,并通过串口打印的方式显示各个状态。

本篇,为了更加直观的感受状态机的运行,使用0.96寸OLED来显示各个状态,并搭配对应的动态图标来体现洗衣机工作的各个状态。

1 OLED图片显示

为了能方便的在OLED上显示文字和图片,可以借助一些图形库来帮我们显示,这里使用的是U8g2图形库。

1.1 U8g2库移植

U8g2库在STM32上的移植,之前的文章已经介绍过,具体的移植过程可以参考这篇:

移植成功后,可以使用测试例程验证U8g2库的显示效果。

pYYBAGKeImaAbklYAAES8Ep9QH8703.png

1.2 图片显示

图片相比较文字,可以展示更加丰富的内容,因此本篇通过简单的单色图片来展示洗衣机的工作状态。

U8g2库显示图片,可以使用u8g2_DrawXBM函数,需要先将图片转为数组。

可以使用这个在线网页来进行图片数据的转换:https://tools.clz.me/image-to-bitmap-array

这里可以使用自己喜欢的图片,进行展示,比如我选取了不同水量的洗衣机图标来显示洗衣机的当前水量,使用多张图片的交替显示产生洗衣机在清洗的动画效果。

poYBAGMXWIeALw-DAABSGg7iq9s098.png

2 更多状态输出

OLED屏幕要想显示洗衣机的工作状态,就需要获取状态机的具体工作状态。这里自定义了一些展示需要用到的数据,组成一个结构体,状态机在运行过程中,对各个成员变量进行修改,然后OLED端获取这些数据,再进行展示。

typedef struct
{
	WASHER_STATUS washerStatus; /*洗衣机的工作状态*/
	int targetWaterLevel;       /*洗衣机的目标水位*/
	int targetWashTimes;        /*洗衣机的目标清洗次数*/
	int remainingTime;          /*洗衣机的剩余工作时间(暂未使用)*/
	int curWaterLevel;          /*洗衣机当前的水位*/
	bool hasNewData;            /*是否有新的数据(用于告诉OLED是否刷新显示)*/
}WASHER_OUTPUT_DATA;

对于OLED的展示逻辑,这里是在状态机的每个循环结束后,调用下面的程序逻辑进行展示:

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;
		}
	}
}

当此轮状态循环有新的数据产生时,则根据状态机的主状态,分别显示对应状态下的图片或动画。

比如加水状态,会根据当前加的水位,不断更新图片展示的水位:

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);
}

​对于主程序的结构,和上篇一样,只是增加了OLED的显示:

int main(void)
{	
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	//初始化与LED连接的硬件接口
	oled_init();
	
	KEY_Init();
	uart_init(115200);
	TIM3_Int_Init(500-1,7200-1); //调用定时器使得50ms产生一个中断

	printf("hello\r\n");
	
	while(1)
	{
		washer_run_loop();
		
		WASHER_OUTPUT_DATA data = get_washer_output_data();
		
		show_washer_status(data);
		
		delay_ms(100);
	}
}

在状态机每运行一个循环,获取一下具体的状态数据,然后使用OLED将具体的状态数据展示出来。

3 具体演示

再来对比看下这个状态图,实验测试状态机的执行。

pYYBAGMWC8CAUAu0AADA8uwfW3c243.png

正常的洗衣流程

不考虑暂停这个状态,洗衣机上点开始后,依次经历空闲、加水、清洗、排水、甩干这几个流程即结束,若清洗计数设置了不知1次,则加水、清洗、排水这3个动作会循环执行对应的次数。

洗衣流程中暂停再继续

在洗衣机的运行状态:加水、清洗、排水、甩干,通过暂停按钮,可以暂停这些状态的执行,此时状态机会运行于暂停模式,再按继续(暂停/继续的一个按钮),则会继续执行洗衣工作。

暂停后修改水量或次数后再继续

在洗衣过程中,如果想要修改洗衣的水量或次数,可以先通过暂停键来暂停洗衣机的运行,然后通过水位或次数按钮,使状态机从暂停状态先切换到空闲状态,进行水位或次数的调整后,再继续,即会按照新的设置参数继续运行洗衣程序。

比如本来的清洗水位是3,清洗次数是1,在第一次清洗的加水时按下暂停,再将清洗参数进行修改,比如水位设为5,次数设为2,再继续后,会再次进入加水状态,并将水位补到5后,继续清洗,并清洗2遍结束。

注:本状态机还有继续优化的空间,比如:

水量只会补加,多了此轮清洗不会排出。比如先设置的水位是5,在加到3个时候,暂停并修改为2,再继续后,判断大于目标水位则会直接开始清洗,不会先由水位3再排水到水位2再清洗

任何清洗状态(加水、清洗、排水)按下暂停调整水位后,再继续,都会默认跳到加水重新新的清洗循环,如果是在排水状态,调整了水位后,此次的水还没有排位,就又重新加水开始洗,不太合理

以上3种测试方式的演示效果,可以再对比看下演示视频

https://www.bilibili.com/video/BV1xT411E7pY

poYBAGMXWbmAIDfmAAsqoUkF_GU573.png

4 总结

本篇在上篇全自动洗衣机的状态机编程实例的基础上,增加了OLED来更新直观的展示洗衣机的工作状态,并通过3种测试场景来展示洗衣机工作状态机的执行。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2239

    文章

    10668

    浏览量

    348677
  • 洗衣机
    +关注

    关注

    11

    文章

    671

    浏览量

    42533
  • 状态机
    +关注

    关注

    2

    文章

    485

    浏览量

    27158
收藏 人收藏

    评论

    相关推荐

    FPGA设计洗衣机

    本帖最后由 eehome 于 2013-1-5 09:59 编辑 设计一个全自动洗衣机控制器,它具有三阀门分别是冷水、 设计一个全自动洗衣机控制器,它具有三阀门分别是冷水、 设计
    发表于 05-04 20:35

    跪求毕业设计:全自动洗衣机系统设计!!!

    急需!!!全自动洗衣机系统设计与研究
    发表于 04-29 23:38

    跪求 全自动洗衣机系统 proteus仿真!!!

    本人做毕业设计 全自动洗衣机系统研究与设计跪请各位帮忙!!!
    发表于 05-01 18:50

    Proteus + C51全自动洗衣机

    本帖最后由 依然Dirk 于 2015-1-21 15:34 编辑 Proteus + C51全自动洗衣机
    发表于 01-21 15:31

    全自动洗衣机原理与维修资料

    给大家分享全自动洗衣机原理与维修资料。
    发表于 03-17 20:34

    全自动洗衣机

    单片全自动洗衣机
    发表于 04-12 13:11

    转: 全自动洗衣机控制系统

    全自动洗衣机控制系统
    发表于 08-03 16:55

    基于单片全自动洗衣机控制系统设计

    基于单片全自动洗衣机控制系统设计
    发表于 05-01 14:23

    洗衣机为什么能自动运行呢

    知识点:全自动洗衣机、程序、计算机如今,洗衣机已经进入千家万户,人们再也不用面对一大堆脏衣服发愁了,只要把脏衣服、洗衣粉放到洗衣机里,接通电
    发表于 09-02 06:52

    怎样去设计一种基于单片全自动洗衣机模拟系统

    具体实现功能:模拟全自动洗衣机工作过程,以电机替代洗衣机电机。可以显示洗衣机工作的状态(进水、浸泡、洗衣
    发表于 11-25 06:27

    如何去实现一种基于单片全自动洗衣机模拟系统设计

    基于单片全自动洗衣机模拟系统实现的功能是什么?如何去实现一种基于单片全自动洗衣机模拟系统
    发表于 01-17 08:13

    如何去实现一种基于单片全自动洗衣机仿真设计

    资料下载地址-1063(百度网盘):点击下载摘 要全自动洗衣机就是将洗衣的全过程(泡浸-洗涤-漂洗-脱水)预先设定好N个程序,洗衣时选择其中一个程序,打开水龙头和启动
    发表于 02-23 07:19

    51单片全自动洗衣机控制系统代码分享

    51单片全自动洗衣机控制系统代码
    发表于 09-26 07:33

    全自动洗衣机程序

    全自动洗衣机程序全自动洗衣机程序全自动洗衣机程序
    发表于 05-19 16:40 24次下载

    STM32状态机编程实例——全自动洗衣机(上)

    本篇实现了一款全自动洗衣机的基础洗衣控制流程,可实现不同水位与清洗次数的设置,以及任务的暂停与继续。此外,通过对之前按键状态机的进一步优化修改,实现了按键
    的头像 发表于 09-06 08:47 1758次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>状态机</b><b class='flag-5'>编程</b><b class='flag-5'>实例</b>——<b class='flag-5'>全自动</b><b class='flag-5'>洗衣机</b>(上)