上一次实现了esp8266和服务器的简单交互,这次就利用刚刚实现的功能做一个小玩具
功能
是这样的,我打算实现一个判断有没有人进入我的房间的小玩具,如果有人进入我的房间,那么就通过qq给我发送一封邮件提醒我
原理
通过超声波传感器HC-SR04和esp8266连接,然后把接收到的距离信息通过esp8266给服务器发送过去,
这里esp8266和服务器的1314端口建立tcp连接,然后服务器通过一个python程序接收这些消息,然后根据距离的大小判断是否有人经过我的房门,如果距离变动较大,则给我发送一封邮件提醒
代码
esp8266端:
1:发送消息请求的代码
#include <ESP8266WiFi.h>
#define Trig D3
#define Echo D4
const char* ssid = "huawei1203";//wifi名称
const char* password = "123456789";//wifi密码
const char* host="47.102.159.133";
WiFiServer server(80);//开启80端口
void setup() {
pinMode(Trig,OUTPUT);//超声波
pinMode(Echo,INPUT);
Serial.begin(115200);//开启串口监视器
delay(10);
Serial.print("Connecting to");
Serial.println(ssid);
WiFi.begin(ssid, password);//使用名称和密码链接wifi
while (WiFi.status() != WL_CONNECTED) {//如果连接成功跳出循环
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();//开启服务器
Serial.println("Server started");
// Print the IP address
Serial.println(WiFi.localIP());//输出板子的ip
}
int value=0;
void loop() {
// put your main code here, to run repeatedly:
Serial.print("Connecting to");
Serial.println(host);
WiFiClient client;//tcp连接
const int httpPort=1314;//端口号
if(!client.connect(host,httpPort)){//连接失败
Serial.println("connection failed");
Serial.println(WiFi.localIP());
return;
}
//向服务器发送请求
// client.print("HelloServer!");
float lengths=get_length();
String string=String(lengths);
client.print(string);
Serial.println(string);
//读取返回值
while(client.available()){
String line=client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
delay(5000);
}
2:传感器获取距离的代码
float get_length(){
float cm; //距离变量
float temp; //
//给Trig发送一个低高低的短时间脉冲,触发测距
digitalWrite(Trig, LOW); //给Trig发送一个低电平
delayMicroseconds(2); //等待 2微妙
digitalWrite(Trig,HIGH); //给Trig发送一个高电平
temp = float(pulseIn(Echo, HIGH)); //存储回波等待时间,
//pulseIn函数会等待引脚变为HIGH,开始计算时间,再等待变为LOW并停止计时
//返回脉冲的长度
//声速是:340m/1s 换算成 34000cm / 1000000μs => 34 / 1000
//因为发送到接收,实际是相同距离走了2回,所以要除以2
//距离(厘米) = (回波时间 * (34 / 1000)) / 2
//简化后的计算公式为 (回波时间 * 17)/ 1000
cm = (temp * 17 )/1000; //把回波时间换算成cm
return cm;
}
python程序
import threading
import socket
import smtplib
import time
from email.mime.text import MIMEText
from email.utils import formataddr
my_sender='这里写右键服务端的邮箱地址,需要自己打开有相当smtp和pop服务'
my_pass = '这里写邮箱官方提供的16位授权码'
# 发送邮件的函数
def mail(to,value,title):
ret=True
try:
msg=MIMEText(str(value),'plain','utf-8')
msg['From']=formataddr(["Room",my_sender])
msg['To']=formataddr(["Admin",to])
msg['Subject']=str(title)
server=smtplib.SMTP_SSL("smtp.qq.com", 465)
server.login(my_sender, my_pass)
server.sendmail(my_sender,[to,],msg.as_string())
server.quit()
except Exception:
ret=False
return ret
encoding = 'utf-8'
BUFSIZE = 1024
#读取端口消息的函数
class Reader(threading.Thread):
def __init__(self, client):
threading.Thread.__init__(self)
self.client = client
def run(self):
while True:
data = self.client.recv(BUFSIZE)##接收端口的消息
if (data):
string = bytes.decode(data, encoding)##转换字符串
print(string)
if(float(string)<100):##如果接受到的数字小于100,则发送邮件
str1="Length:"+string+"Some One In You Room!"
self.client.send(str1.encode())
maile=mail("你的qq号@qq.com",str1,"Waing!")
if(maile):
print("OK!")
else:
print("no!")
else:
break
# print("close:", self.client.getpeername())
##建立链接
class Listener(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self)
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(("0.0.0.0", port))
self.sock.listen(0)
def run(self):
print("listener started")
while True:
client, cltadd = self.sock.accept()
Reader(client).start()
# client.send("hello you!".encode())
cltadd = cltadd
# print("accept a connect")
lst = Listener(1314) # create a listen thread
lst.start() # then start
接线:在这里插入图片描述
分别上传代码后看下效果:
刚启动时
成功打开硬件之后:前面不稳定的数据是由于我移动传感器导致
我们用手挡一下传感器:
可以看到接收到了5cm左右的一个消息,这时收到了邮件,多收的那些邮件是我打字时不小心遮挡导致的