该项目具有检测室内环境数据和发送电子邮件、开灯按钮、体感照明屏等功能。经过不断的踩坑学习,初代简易智能家居中控系统已经完成,大部分功能已经完成,但是有些功能WIO终端没有实现。一方面是因为代码量太大,会给WIO终端带来很大的“压力”;另一方面,我的技术还不够,还得继续学习,寻找解决方案。首先介绍一下我最初的想法:WIO终端是一款高度集成的开发板。它配备了液晶显示屏、三个按钮、一个五向开关、麦克风、扬声器、加速度传感器、红外发射器等,甚至可以与树莓派和Jetsonnano结合使用。作为家居的“大脑”,这些硬件非常实用。因此,在智能家居的中控系统中,我选择WIO终端作为这个系统的核心。未来,家里应该有一个智能管家。这个智能管家就是我现在做的简单版。有了它,您就可以在家中获取准确实时的温度、湿度、光照强度等数据。不仅如此,它还像一个“万能”遥控器,可以帮助你控制家中的电器。当然,它应该像智能音箱一样,能够理解我们给它的指令并响应我们!提前准备在这个项目的过程中,我第一次使用了开发板WIO终端:不知为何,在WIO终端上使用grow-temperature湿度压力气体传感器时,接收不到数据,只好转身实现:使用Django搭建一个简单的数据中心(基于Grove——温度湿度压力气体传感器)重回正轨,实现数据展示的主要功能:使用WIO终端通过HTTP请求获取并显示传感器实时数据下一步就是完善其他三个功能,我主要通过python实现完善系统功能前面我简单提到了一些WIO终端上没有实现的功能的原因,具体原因我没有细说。毕竟刚开始做,所以打算先实现功能。至于实现方式,我想在二代系统中改进一下通过WIO端子输出状态我要表达的状态是读取可配置按钮的状态(是否按下按钮)和麦克风的数据(数据也可以代表状态)对于WIO终端来说,简单的输出这些数据还是比较简单的补充setup()中的管脚定义:pinMode(WIO_MIC,INPUT);pinMode(WIO_KEY_A,INPUT_PULLUP);pinMode(WIO_KEY_B,INPUT_PULLUP);pinMode(WIO_KEY_C,INPUT_PULLUP);补充loop()中的if条件语句:intval_first=analogRead(WIO_MIC);intval_next=analogRead(WIO_MIC);if(abs(val_first-val_next)>=100){Serial.println("sendmessage!");}if(digitalRead(WIO_KEY_A)==LOW){Serial.println("AKeypressed");}if(digitalRead(WIO_KEY_B)==LOW){Serial.println("BKeypressed");}if(digitalRead(WIO_KEY_C)==LOW){Serial.println("CKeypressed");}当WIO终端连接PC时,PC会读取串口的数据,并在读取相应的输出时采取相应的动作至此,我们已经完成了关于Arduino的所有代码。整理一下代码,分享给大家。#include#include#include"LIS3DHTR.h"#include"Free_Fonts.h"#include"TFT_eSPI.h"TFT_eSPItft;LIS3DHTRlis;WiFiClientclient;constchar*ssid="YourWiFiaccount";constchar*password="YourWiFipassword";constchar*server="192.168.1.102";//ServerURLStringdata;floataccelerator_readings[3];voidsetup(){//Initializeserialandwaitforporttoopen:Serial.begin(115200);delay(100);pinMode(WIO_MIC,INPUT);pinMode(WIO_KEY_A,INPUT_PULLUP);pinMode(WIO_KEY_B,INPUT_PULLUP);pinMode(WIO_KEY_C,INPUT_PULLUP);lis.begin(Wire1);lis.setOutputDataRate(LIS3DHTR_DATARATE_25HZ);lis.setFullScaleRange(LIS3DHTR_RANGE_2G);floatx_raw=lis.getAccelerationX();floaty_raw=lis.getAccelerationY();floatz_raw=lis.getAccelerationZ();accelerator_readings[0]=x_raw;//storex-axisreadingsaccelerator_readings[1]=y_raw;//storey-axisreadingsaccelerator_readings[2]=z_raw;//storez-axisreadings//Serial.print("AttemptingtoconnecttoSSID:");//Serial.println(ssid);WiFi.begin(ssid,password);tft.begin();tft.setRotation(3);tft.fillScreen(TFT_BLACK);tft.setFreeFont(FMB12);tft.setCursor((320-tft.textWidth("ConnectingtoWi-Fi.."))/2,120);tft.print("ConnectingtoWi-Fi..");//attempttoconnecttoWifinetwork:while(WiFi.status()!=WL_CONNECTED){//Serial.print(".");//wait1secondforre-tryingdelay(1000);}//Serial.print("Connectedto");//Serial.println(ssid);tft.fillScreen(TFT_BLACK);tft.setCursor((320-tft.textWidth("Connected!"))/2,120);tft.print("Connected!");getFirstData();}voidloop(){intval_first=analogRead(WIO_MIC);floatx_raw=lis.getAccelerationX();floaty_raw=lis.getAccelerationY();floatz_raw=lis.getAccelerationZ();intval_next=analogRead(WIO_MIC);if(abs(val_first-val_next)>=100){Serial.println("sendmessage!");}if(digitalRead(WIO_KEY_A)==LOW){Serial.println("AKeypressed");}if(digitalRead(WIO_KEY_B)==LOW){Serial.println("BKeypressed");}if(digitalRead(WIO_KEY_C)==LOW){Serial.println("CKeypressed");}if(abs(accelerator_readings[0]-x_raw)>=0.1&&abs(accelerator_readings[1]-y_raw)>=0.1&&abs(accelerator_readings[2]-z_raw)>=0.1){//TurningontheLCDbacklightdigitalWrite(LCD_BACKLIGHT,HIGH);getFirstData();delay(3000);getLastData();delay(3000);}else{//TurningofftheLCDbacklightdigitalWrite(LCD_BACKLIGHT,LOW);delay(500);}for(uint8_ti=0;iaccelerator_readings[i]=0.0;//thisisusedtoremovethefirstreadvariable}accelerator_readings[0]=x_raw;//storex-axisreadingsaccelerator_readings[1]=y_raw;//storey-axisreadingsaccelerator_readings[2]=z_raw;//storez-axisreadings}voidgetFirstData(){//Serial.println("\nStartingconnectiontoserver...");if(!client.connect(server,9000)){//Serial.println("Connectionfailed!");tft.fillScreen(TFT_BLACK);tft.setCursor((320-tft.textWidth("Connectionfailed!"))/2,120);tft.print("Connectionfailed!");}else{//Serial.println("Connectedtoserver!");//MakeaHTTPrequest:StringpostRequest=(String)("GET")+"/HTTP/1.1\r\n"+"Connection:close\r\n\r\n";//Serial.println(postRequest);client.print(postRequest);while(client.connected()){Stringline=client.readStringUntil('\n');if(line=="\r"){//Serial.println("headersreceived");break;}}while(client.available()){Stringline=client.readStringUntil('\r');data=line;}//Serial.println(data);client.stop();//Serial.println("closingconnection");}//ArduinoJsontoparsedata,plesaecheckArduinoJsonformoreinfoconstsize_tcapacity=JSON_OBJECT_SIZE(5)+100;DynamicJsonDocumentdoc(capacity);deserializeJson(doc,data);floattemperature=doc["temperature"];floatpressure=doc["pressure"];floathumidity=doc["humidity"];//-----------------LCD---------------------tft.setFreeFont(FF17);tft.setTextColor(tft.color565(224,225,232));tft.drawString("CurrentDataAtHome",20,10);tft.fillRoundRect(10,45,300,55,5,tft.color565(40,40,86));tft.fillRoundRect(10,105,300,55,5,tft.color565(40,40,86));tft.fillRoundRect(10,165,300,55,5,tft.color565(40,40,86));tft.setFreeFont(FM9);tft.drawString("temperature:",75,50);tft.drawString("pressure:",75,110);tft.drawString("humidity:",75,170);tft.setFreeFont(FMB12);tft.setTextColor(TFT_RED);tft.drawFloat(temperature,2,140,75);tft.setTextColor(tft.color565(224,225,232));tft.drawFloat(pressure,2,140,135);tft.setTextColor(TFT_GREEN);tft.drawFloat(humidity,2,140,195);tft.drawString("℃",210,75);tft.drawString("KPa",210,135);tft.drawString("%",210,195);}voidgetLastData(){//Serial.println("\nStartingconnectiontoserver...");if(!client.connect(server,9000)){//Serial.println("Connectionfailed!");tft.fillScreen(TFT_BLACK);tft.setCursor((320-tft.textWidth("Connectionfailed!"))/2,120);tft.print("Connectionfailed!");}else{//Serial.println("Connectedtoserver!");//MakeaHTTPrequest:StringpostRequest=(String)("GET")+"/HTTP/1.1\r\n"+"Connection:close\r\n\r\n";//Serial.println(postRequest);client.print(postRequest);while(client.connected()){Stringline=client.readStringUntil('\n');if(line=="\r"){//Serial.println("headersreceived");break;}}while(client.available()){Stringline=client.readStringUntil('\r');data=line;}//Serial.println(data);client.stop();//Serial.println("closingconnection");}//ArduinoJsontoparsedata,plesaecheckArduinoJsonformoreinfoconstsize_tcapacity=JSON_OBJECT_SIZE(5)+100;DynamicJsonDocumentdoc(capacity);deserializeJson(doc,data);floathumidity=doc["humidity"];floatgas=doc["gas"];StringupdataTime=doc["updataTime"];//-----------------LCD---------------------tft.setFreeFont(FF17);tft.setTextColor(tft.color565(224,225,232));tft.drawString("CurrentDataAtHome",20,10);tft.fillRoundRect(10,45,300,55,5,tft.color565(40,40,86));tft.fillRoundRect(10,105,300,55,5,tft.color565(40,40,86));tft.fillRoundRect(10,165,300,55,5,tft.color565(40,40,86));tft.setFreeFont(FM9);tft.drawString("humidity:",75,50);tft.drawString("gas:",75,110);tft.drawString("updataTime:",75,170);tft.setFreeFont(FMB12);tft.setTextColor(TFT_RED);tft.drawFloat(humidity,2,140,75);tft.setTextColor(tft.color565(224,225,232));tft.drawFloat(gas,2,140,135);tft.setTextColor(TFT_GREEN);tft.drawString(updataTime,30,195);tft.drawString("%",210,75);tft.drawString("Kohms",210,135);}上传成功后,打开串口监视器:接下来我们来看看Python的具体实现使用Python读取串口数据并做出相应决策web端增加了保存数据的功能因为我需要发送邮件,所以我先将传感器接收到的数据存储在一个TXT文本文件中。发送邮件时,我可以直接发送这个文本文件在视图中在py中:defindex(request):datas=getDatas()content={'temperature':datas[0],'pressure':datas[1],'humidity':datas[2],'gas':datas[3],'updataTime':datas[4],}jsonData=json.dumps(content)withopen("D:\TemperatureHumidityPressureGasData.txt","w")asfp:fp.write(jsonData)returnHttpResponse(jsonData)主要变化是:withopen("D:\TemperatureHumidityPressureGasData.txt","w")asfp:fp.write(jsonData)文件存放路径可以修改为自己的路径打开文本文件,看能否保存成功:通过红外模块控制小夜灯小夜灯可以遥控控制:因为WIO终端没有红外解码功能,所以我又买了一个红外模块,编解码合二为一。当然,我还需要一个usb-ttl串口转换器:其实这个想法很简单。读取遥控器对应按键发送的数据,然后用红外模块发送出去可以使用串口调试助手进行解码,更方便:串行端口发送它接收到的任何内容。收货时最好找个比较暗的地方多试几次以下是我收集的每个密钥应该发送的数据(十六进制):开灯send_data='FDFD3003534B003417013B02650026001E002700D90926008A004002C317260000002100FFFFFFFF01222222221111111112112222212211134546F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005760022DFDF'提亮send_data='FDFD30035247003416013A026600270020002700D90925008A00410200002100FFFFFFFFFFFFFFFF012222222211111112211122211222111345F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008763F6DDFDF'调光send_data='FDFD3003534B003416013C02630027001F002700DA0925008B003D02C417240000002000FFFFFFFF01222222221111111211112221222211134546F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002763F2EDFDF'要发送红外线,只需再添加两行:send_data=bytes.fromhex(send_data)#先编码,再发送infrared_ser.write(send_data)通过语音控制PC发送邮件语音不是真正的语音识别。当WIO终端识别到环境音频信号有波动时,会发送“sendmessage!”到串口,PC读取后发送邮件说话时,音频信号会有明显的波动:发送电子邮件并不难。我把它封装成一个方法,当时可以直接调用importsmtplibfromemail.mime.textimportMIMETextfromemail.mime.multipartimportMIMEMultipartfromemail.headerimportHeaderdefsend():#第三方SMTP服务mail_host="smtp.qq.com"#设置服务器mail_user=""#用户名mail_pass=""#口令sender=''receivers=['']#接收邮件,可设置为你的QQ邮箱或者其他邮箱#创建一个带附件的实例message=MIMEMultipart()message['From']=Header("WioTerimal",'utf-8')message['To']=Header("温湿度、大气压力、可燃气体检测数据",'utf-8')subject='当前温湿度、大气压力、可燃气体检测数据'message['Subject']=Header(subject,'utf-8')#邮件正文内容message.attach(MIMEText('温湿度、大气压力、可燃气体检测数据','plain','utf-8'))#构造附件,传送当前目录下的test.txt文件att=MIMEText(open('D:\TemperatureHumidityPressureGasData.txt','rb').read(),'base64','utf-8')att["Content-Type"]='application/octet-stream'#这里的filename可以任意写,写什么名字,邮件中显示什么名字att["Content-Disposition"]='attachment;filename="TemperatureHumidityPressureGasData.txt"'message.attach(att)server=smtplib.SMTP_SSL(mail_host,465)#SMTP协议默认端口是25server.set_debuglevel(1)server.login(mail_user,mail_pass)try:server.sendmail(sender,receivers,message.as_string())print("邮件发送成功")exceptsmtplib.SMTPException:print("Error:无法发送邮件")此处的发送者和接收者可以编写自己的电子邮件。尝试发送电子邮件进行测试:预览此TXT文件:通过语音合成回复用户Windows系统下,可以直接调用系统的语音包:importwin32com.clientspeaker=win32com.client.Dispatch("SAPI.SpVoice")text="输入要语音合成的内容"speaker.Speak(text)完整的程序代码中的串口需要改成自己的串口:Com14是WIO终端开发板Com15是红外模块Com19是seeeduinov42开发板每次插上后,可能会因为电脑上的USB接口不够,导致串口发生变化。我买了一个USB扩展坞importserialimportreimportsmtplibfromemail.mime.textimportMIMETextfromemail.mime.multipartimportMIMEMultipartfromemail.headerimportHeaderimportwin32com.clientspeaker=win32com.client.Dispatch("SAPI.SpVoice")defsend():#第三方SMTP服务mail_host="smtp.qq.com"#设置服务器mail_user="2733821739@qq.com"#用户名mail_pass=""#口令sender='2733821739@qq.com'receivers=['2733821739@qq.com']#接收邮件,可设置为你的QQ邮箱或者其他邮箱#创建一个带附件的实例message=MIMEMultipart()message['From']=Header("WioTerimal",'utf-8')message['To']=Header("温湿度、大气压力、可燃气体检测数据",'utf-8')subject='当前温湿度、大气压力、可燃气体检测数据'message['Subject']=Header(subject,'utf-8')#邮件正文内容message.attach(MIMEText('温湿度、大气压力、可燃气体检测数据','plain','utf-8'))#构造附件,传送当前目录下的test.txt文件att=MIMEText(open('D:\TemperatureHumidityPressureGasData.txt','rb').read(),'base64','utf-8')att["Content-Type"]='application/octet-stream'#这里的filename可以任意写,写什么名字,邮件中显示什么名字att["Content-Disposition"]='attachment;filename="TemperatureHumidityPressureGasData.txt"'message.attach(att)server=smtplib.SMTP_SSL(mail_host,465)#SMTP协议默认端口是25server.set_debuglevel(1)server.login(mail_user,mail_pass)try:server.sendmail(sender,receivers,message.as_string())print("邮件发送成功")speaker=win32com.client.Dispatch("SAPI.SpVoice")text="Messagesentsuccessfully"speaker.Speak(text)exceptsmtplib.SMTPException:print("Error:无法发送邮件")infrared_ser=serial.Serial('COM10',9600,timeout=0.2)Wio_terminal=serial.Serial('COM14',115200,timeout=0.2)#接收返回的信息whileTrue:strs=Wio_terminal.readline().decode('utf-8')ifstrs.strip()!='':print(strs)if(re.match(r"C",strs)):send_data='FDFD3003534B003417013B02650026001E002700D90926008A004002C317260000002100FFFFFFFF01222222221111111112112222212211134546F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005760022DFDF'send_data=bytes.fromhex(send_data)infrared_ser.write(send_data)text="OKexecuted"speaker.Speak(text)elif(re.match(r"B",strs)):send_data='FDFD30035247003416013A026600270020002700D90925008A00410200002100FFFFFFFFFFFFFFFF012222222211111112211122211222111345F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008763F6DDFDF'send_data=bytes.fromhex(send_data)infrared_ser.write(send_data)text="Brightnessup"speaker.Speak(text)elif(re.match(r"A",strs)):send_data='FDFD3003534B003416013C02630027001F002700DA0925008B003D02C417240000002000FFFFFFFF01222222221111111211112221222211134546F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002763F2EDFDF'send_data=bytes.fromhex(send_data)infrared_ser.write(send_data)text="Brightnessdown"speaker.Speak(text)elif(re.match(r"send",strs)):try:send()except:text="Failedtosendmail.Pleasetryagainlater"speaker.Speak(text)infrared_ser.close()Wio_terminal.close()未来的想法目前的系统只是一个非常简单的第一代版本。往后我们可能会考虑使用云平台存储传感器采集的温度、湿度、光照强度、紫外线强度等数据,制作一个APP,让用户出门在外就可以知道家里的情况。如果您对此项目有任何想法、意见或问题,请在下方留言。以上内容翻译自网络,原作者:WanNiu,如涉及侵权,可联系删除。