基于STM32的智能鞋柜设计与实现--“臭臭没了”

 Hello,大家好,我是阿金,本文仅供参考,提供一些建议。如有不对,还请指正。谢谢~

随着5G网络的迅速普及,“万物联网”的时代指日可待。针对传统鞋柜及目前市场上现有的智能鞋柜功能单一,鞋子护理效果不理想的问题,本文设计了一款以STM32F103ZET6为主控芯片,同时具有温湿度检测、杀菌除臭、APP端控制、触摸屏控制和语音交互等多种功能的智能鞋柜系统。该鞋柜主要应用场景为平常百姓家中,采用PVC发泡板所制作的模型,经济环保。

       该系统主要分为下位机和上位机两个部分。下位机可通过点击触摸屏或唤醒语音助手来控制智能鞋柜的杀菌除臭、弹出鞋柜门或座椅等功能;上位机APP端可通过WiFi与之相连,实时检测鞋柜内部的温湿度值的同时也能控制鞋柜,已达到方便用户控制鞋柜的目的。测试结果表明,该系统的功能特性较为稳定,操作简便,具有较高的实用价值。

一、基于STM32的智能鞋柜设计实现的功能主要有以下几个方面:

(1)开发基于温湿度检测的除湿除臭系统。采用DHT11温湿度检测模块,实时采集智能鞋柜内部的温湿度数据,并通过STM32F103ZET6主控芯片预先设置好的程序来判断是否需要运行循环风调节系统。将活性炭吸附棉装置于通风口处,用以除臭。除湿除臭系统主要用以保持鞋柜内部环境为恒温恒湿状态,达到延长鞋子使用寿命的效果。

(2)开发基于紫外线灯光照射的杀菌系统。本系统采用紫外线LED灯带照射模块。根据鞋柜内部情况安置相对合适的紫外线led灯带。该杀菌系统可以由用户来调节每次启动后运行的时长,或者也可通过手机APP开启或关闭该功能。

(3)手机APP上位机。设计Android Studio上位机的界面,其中包括鞋柜控制情况、温湿度显示信息、鞋柜用户身份信息。通过串口来实现对智能鞋柜的整体控制。

(4)触摸屏。DHT11温湿度检测模块检测到的数据也会实时显示到触摸屏上,同时显示RTC实时时钟。最先设计的界面较为简洁,以实现按下触屏屏的按键块即可控制鞋柜功能开关为主。

(5)人机交互。采用启英泰伦的CI-B03GS01S语音模块,依托平台上的资源来开发属于自己的鞋柜唤醒词及功能命令词,最终实现语音交互来控制鞋柜上的各种功能模块。

二、系统结构图

三、主要技术路线 

 四、APP上位机

 

代码:字节型协议传输,发送具体指令,控制鞋柜各种功能模块的开关。

        //自动填写按钮事件
        btnSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //自动填写服务器固定的IP地址跟端口号
                edGateIp.setText("10.10.100.254");
                edGateSn.setText("8899");
            }
        });

        //连接服务器按钮事件
        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //容错机制
                //取出文本框内容,用来判断输入框是否为空
                String ip = edGateIp.getText().toString();
                String sn = edGateSn.getText().toString();

                tempdisp.setText(Float.toString(25));
                humdisp.setText(Float.toString(62));

                if ((ip == null || ip.length() == 0) && (sn == null || sn.length() == 0))
                    Toast.makeText(yemian.this, "IP地址、端口号不能为空", Toast.LENGTH_SHORT).show();
                else if (ip == null || ip.length() == 0)
                    Toast.makeText(yemian.this, "IP地址不能为空", Toast.LENGTH_SHORT).show();
                else if (sn == null || sn.length() == 0)
                    Toast.makeText(yemian.this, "端口号不能为空", Toast.LENGTH_SHORT).show();
                else {
                    //判断服务器连接状态
                    if (isConnected != true) {
                        //创建一条新的Socket连接
                        new ConnectThread(0).start();
                        btnLogin.setText("断开连接");
                        startTimer();
                        //按钮文字改变
                        //页面消息
                        Toast.makeText(yemian.this, "服务器连接成功!", Toast.LENGTH_SHORT).show();
                    } else {
                       //按钮按下的时候已在连接情况下,服务器断开连接
                        if (socket != null) {
                            try {
                                //退出服务器
                                socket.close();
                                //服务器状态改为空
                                socket = null;
                                //服务器连接转态改为空
                                isConnected = false;
                                //读数据线程不执行
                                RD = false;

                                btnLogin.setText("连接服务器");

                                //页面文字显示
                                Toast.makeText(yemian.this, "与服务器断开连接!", Toast.LENGTH_SHORT).show();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        });

        //消息处理机制
        messageHandler = new Handler() { // 等待socket连接成功
            @Override
            public void handleMessage(android.os.Message msgMessage){
                String sendString = "";
                String receiveString = "";

                switch (msgMessage.what) {
                    case 0:
                        break;
                    case 1:
                        receiveString = "服务器端发送:" + msgMessage.obj.toString() + "\n";
                        byte[] readbuffer = (byte[]) msgMessage.obj;
                        byte[] pattendata = {0x44, 0x5a, 0x4c};
                        List<Integer> start = CommonMethod.indexOf(readbuffer, pattendata);
                        System.out.println("ceshi"+start.toString());

                        for (int a = 0; a < start.size(); a++) {
                            List<Byte> data = new ArrayList<Byte>();

                            for (int b = 0; b < readbuffer[start.get(a) + 3] + 5; b++) {

                                data.add(readbuffer[start.get(a) + b]);
                            }
                            //System.out.println(data.toString());
                            if (data.get(4) == (byte)0x03) {

                                // 准备数据
                                byte[] tmptemp = new byte[]{data.get(11), data.get(12), data.get(13), data.get(14)};
                                float tmpfloat = ByteArrayConvert.getFloat(tmptemp, 0);                         tempdisp.setText(Float.toString(tmpfloat));
                                byte[] humtemp = new byte[]{data.get(19), data.get(20), data.get(21), data.get(22)};
                                float humfloat = ByteArrayConvert.getFloat(humtemp, 0);                           humdisp.setText(Float.toString(humfloat));
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        };

 五、下位机

#include "show.h"
#include "lcd.h"  
#include "text.h"	
#include "touch.h" 
#include "dht11.h"
#include "delay.h"
#include "led.h" 		 	 
#include "relay.h"
 //加载键盘控制界面
//x,y:界面起始坐标
void py_load_ui(u16 x,u16 y)
{
	POINT_COLOR=RED;
	
	//画矩形	
	LCD_DrawRectangle(x,y,x+300,y+500);  
	//画线    
	LCD_DrawLine(x,y+100,x+300,y+100);  //横1
	LCD_DrawLine(x,y+200,x+300,y+200);	//横2
	LCD_DrawLine(x,y+300,x+300,y+300);	//横3
	LCD_DrawLine(x,y+400,x+300,y+400);	//横4
    LCD_DrawLine(x+150,y,x+150,y+500);	//竖
	//在指定区域内填充单个颜色   
LCD_Fill(x+2,y+2,x+148,y+98,WHITE);//控制 Left1
    LCD_Fill(x+152,y+2,x+298,y+98,WHITE);//控制 Right1
	
    LCD_Fill(x+2,y+102,x+148,y+198,WHITE);//控制 Left2 
    LCD_Fill(x+152,y+102,x+298,y+198,WHITE);//控制 Right2 
    LCD_Fill(x+2,y+202,x+148,y+298,WHITE);//控制 Left3 
    LCD_Fill(x+152,y+202,x+298,y+298,WHITE);//控制 Right3
LCD_Fill(x+2,y+302,x+148,y+398,WHITE);//控制 Left3 
    LCD_Fill(x+152,y+302,x+298,y+398,WHITE);//控制 Right3
LCD_Fill(x+2,y+402,x+148,y+498,WHITE);//控制 Left3 
    LCD_Fill(x+152,y+402,x+298,y+498,WHITE);//控制 Right3
	
	
	//显示字符串  
	POINT_COLOR=BLACK;
	LCD_ShowString(x+51,y+38,lcddev.width,lcddev.height,24,"Left1");  
	LCD_ShowString(x+183,y+38,lcddev.width,lcddev.height,24,"Right1"); 
		LCD_ShowString(x+51,y+138,lcddev.width,lcddev.height,24,"Left2");      
	LCD_ShowString(x+183,y+138,lcddev.width,lcddev.height,24,"Right2");   
	LCD_ShowString(x+51,y+238,lcddev.width,lcddev.height,24,"Left3");      
	LCD_ShowString(x+183,y+238,lcddev.width,lcddev.height,24,"Right3");
	POINT_COLOR=RED;       				    	 
	Show_Font(200,20,(u8 *)"智",24,0);
	Show_Font(225,20,(u8 *)"能",24,0);
	Show_Font(250,20,(u8 *)"鞋",24,0);
	Show_Font(275,20,(u8 *)"柜",24,0);
	POINT_COLOR=BLACK;  
	Show_Str(30,60,200,16,"温度为:",16,0);	
	Show_Str(120,60,200,16,"℃",16,0);
	Show_Str(30,90,200,16,"湿度为:",16,0);
	Show_Str(120,90,200,16,"%",16,0);
	Show_Font(150,540,(u8 *)"座",24,0);
	Show_Font(175,540,(u8 *)"椅",24,0);
	Show_Font(285,540,(u8 *)"风",24,0);
	Show_Font(310,540,(u8 *)"扇",24,0);
	Show_Font(150,640,(u8 *)"杀",24,0);
	Show_Font(175,640,(u8 *)"菌",24,0);
	Show_Font(285,640,(u8 *)"消",24,0);
	Show_Font(310,640,(u8 *)"毒",24,0);
	}
//按键状态设置
//x,y:键盘坐标
//key:键值(0~8)
//sta:状态,0,松开;1,按下;
void py_key_staset(u16 x,u16 y,u8 keyx,u8 sta)
{                  
    u16 i=keyx/2,j=keyx%2;
	if(keyx>10)
		return;
	if(sta && keyx != 1)
		LCD_Fill(x+j*150+1,y+i*100+1,x+j*150+149,y+i*100+99,GREEN);
	else if(keyx != 1)
	LCD_Fill(x+j*150+1,y+i*100+1,x+j*150+149,y+i*100+99,WHITE);
	POINT_COLOR=BLACK;
    	LCD_ShowString(x+51,y+38,lcddev.width,lcddev.height,24,"Left1");  
	LCD_ShowString(x+183,y+38,lcddev.width,lcddev.height,24,"Right1"); 
	LCD_ShowString(x+51,y+138,lcddev.width,lcddev.height,24,"Left2");      
	LCD_ShowString(x+183,y+138,lcddev.width,lcddev.height,24,"Right2");   
	LCD_ShowString(x+51,y+238,lcddev.width,lcddev.height,24,"Left3");      
	LCD_ShowString(x+183,y+238,lcddev.width,lcddev.height,24,"Right3");
	Show_Font(150,540,(u8 *)"座",24,0);
	Show_Font(175,540,(u8 *)"椅",24,0);
	Show_Font(285,540,(u8 *)"风",24,0);
	Show_Font(310,540,(u8 *)"扇",24,0);
	Show_Font(150,640,(u8 *)"杀",24,0);
	Show_Font(175,640,(u8 *)"菌",24,0);
	Show_Font(285,640,(u8 *)"消",24,0);
	Show_Font(310,640,(u8 *)"毒",24,0);
}
//得到触摸屏的输入
//x,y:键盘坐标
//返回值:按键键值(1~9有效;0,无效)
u8 py_get_keynum(u16 x,u16 y)
{
	u16 i,j;
	static u8 key_x=0;//0,没有任何按键按下;1~4,1~4号按键按下
	u8 key=0;
	tp_dev.scan(0);                  
	if(tp_dev.sta&TP_PRES_DOWN) //触摸屏被按下
	{       
			for(i=0;i<5;i++)
			{
					for(j=0;j<2;j++)
					{
							if(tp_dev.x[0]<(x+j*150+150)&&tp_dev.x[0]>(x+j*150)&&tp_dev.y[0]<(y+i*100+100)&&tp_dev.y[0]>(y+i*100)) //决定每一块区域所代表的值
							{       
									key=i*2+j+1;         
									break;                           
							}
					}
					if(key)
					{          
							if(key_x==key)
								key=0;
							else
							{
									py_key_staset(x,y,key_x-1,0);
									key_x=key;
									py_key_staset(x,y,key_x-1,1);	//决定哪一块区域发生按键捕获
							}
							break;
					}
			}  
	}
	else if(key_x)  //每次从0开始 不记录上次的状态
	{
		py_key_staset(x,y,key_x-1,0);
		key_x=0;
	}
    return key;
}
void show(void)
{
	u8 key;
	u8 t=0;			    
	u8 temperature;  	    
	u8 humidity;
	py_load_ui(100,200); 
	while(1)
	{
		key=py_get_keynum(100,200);
		if(t%10==0)			//每1000ms读取一次
		{									  
			DHT11_Read_Data(&temperature,&humidity);	//读取温湿度值					    
			LCD_ShowNum(30+60,60,temperature,2,16);//显示温度	   		LCD_ShowNum(30+60,90,humidity,2,16);//显示湿度	
			if(temperature > 30 | humidity > 60 )
			{
				key = 8;
			}
		}				   
		delay_ms(100);
		t++;
		if(t==20)
		{
			t=0;
		}
			switch(key)
		{
			case 1  : LED0	 =	!LED0;break;//鞋柜 (左一) 
			case 2  : LED1   =	!LED1;break;//鞋柜 (右一)
			case 3  : LED0	 =	!LED0;break;//鞋柜 (左二)
			case 4  : LED1	 =	!LED1;break;//鞋柜 (右二)
			case 5  : LED0	 =	!LED0;break;//鞋柜 (左三)
			case 6  : LED1	 =	!LED1;break;//鞋柜 (右三)
			case 7  : RELAY1 =	!RELAY1;break;//座椅  			      case 8  : RELAY2 =	!RELAY2;break;//风扇  两个
			case 9  : RELAY3 =	!RELAY3;break;//杀菌  灯带
			case 10 : RELAY4 =	!RELAY4;break;//烘干  			}		
	}
}

 

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值