提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
想要弄一个用电器识别装置,识别完了之后将结果发送到网页端进行显示,ESP32自带的WiFi可以实现将识别数据传输到云服务器的MySQL上,最后在服务器上搭建的网页端读取MySQL数据显示出来
其实这个完全可以用MQTT开源服务器来做,我主要是之前租了个腾讯云的服务器不用可惜了,刚好学学网页制作
一、ESP32传输数据到MySQL
本人用的Arduino IDE写的ESP32程序,代码比较简单一些,ESP-IDF应该基本差不多,首先是用Arduino IDE安装ESP32的库,在Arduino的首选项-附加开发板管理网址输入下面地址 (速度可能会有些慢,最好把科学上网配置好),在库管理里搜索ESP32
https://www.arduino.cn/package_esp32_index.json
然后在开发板里选择相应的ESP32开发板,下面是ESP32的程序
#include <WiFi.h>
#include <WiFiClient.h>
#include <Wire.h>
const char *ssid = "xxxxxx";
const char *password = "xxxxxxx";
const char *host = "你的服务器地址";//注意是公网地址
const int port = 端口;
int lasti = 0;//从串口接受来的数据
void setup()
{
Serial.begin(115200);
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 with IP address:");
Serial.println(WiFi.localIP());
}
void loop()
{
String Load_status="YYNNNNY";//定义的七个用电器状态,Y表示开启,N表示关闭
delay(1000);
Serial.print("connecting to");
Serial.print(host);
WiFiClient client;
//判断是否连接上服务器
if (!client.connect(host, port))
{
Serial.println("connection failed");
return;
}
client.print(Load_status); //发送数据
}
Arduino的ESP32库把socket连接的函数都封装好了,所以连接服务器时不用写socket,只需要只要服务器的公网地址和你设置的接收数据的端口就行了
下面是服务器段接收数据,使用Python编写的接受数据并保存到MySQL的程序,用到了pymysql,是Python连接MySQL的一个库
import socket
import datetime
import pymysql
# 建立一个服务端
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 以下设置解决ctrl+c退出后端口号占用问题
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('服务器的内网IP',8090)) #绑定要监听的地址(内网ip)和端口
server.listen(5) #开始监听 表示可以使用五个链接排队
#打开数据库连接
mysql_conn = pymysql.connect(user="xxxx",password="xxxxx",host="localhost",database="xxxxx",port=3306)
#获取游标
while True:# conn就是客户端链接过来而在服务端为期生成的一个链接实例
conn,addr = server.accept() #等待链接,多个链接的时候就会出现问题,其实返回了两个值
print(conn, addr)
try:
data = conn.recv(1024) #接收数据
if data:
print('Time:',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
de_data=data.decode()
print('recive:',de_data) #打印接收到的数据
count =0
//将数据保存到MySQL
while (count<7):
if de_data[count]=="Y":
cursor=mysql_conn.cursor()
m_count=count+1
cursor.execute("""UPDATE load2 set sta=1 where id=%s""",m_count)
#提交到数据库执行
mysql_conn.commit()
print('第',m_count,'个用电器数据修改成功')
count=count+1
cursor.close()#先关闭游标
elif de_data[count]=="N":
cursor=mysql_conn.cursor()
m_count=count+1
cursor.execute("""UPDATE load2 set sta=0 where id=%s""",m_count)
#提交到数据库执行
mysql_conn.commit()
print('第',m_count,'个用电器数据修改成功')
count=count+1
cursor.close()#先关闭游标
except ConnectionResetError as e:
print('关闭了正在占线的链接!')
break
# conn.close()
//按Ctrl+C结束程序
写好程序之后将程序上传到云服务器,用Python运行下
注意: 服务器一般自带的都是Python2.7,必要要用Python3编译运行,具体的云服务器安装Python可以看下面这个
cd到你到Python程序上传的文件夹,运行
python3 server.py
下面是编译运行后的结果,成功接受到了ESP32发送来的数据
下面是MySQL中存储的用电器状态
二、读取MySQL数据并在网页上显示
1.PHP读取MySQL数据
这里必须用PHP(世界上最好的语言)来读取MySQL中的数据
PHP 5 及以上版本建议使用以下方式连接 MySQL
- MySQLi extension (“i” 意为 improved)
- PDO (PHP Data Objects)
必须吐槽一下:网上一些教程还用的mysql_connect、mysql_close,这都是多少年前的标准了<无语>
代码如下:
<?php
$servername = "localhost";
$username = "xxxx";
$password = "xxxxxxx";
$dbname = "Load_status";
// 创建连接
$conn = mysqli_connect($servername, $username, $password,$dbname);
// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "SELECT sta FROM load2 WHERE id=1";//选取保存在MySQL里用电器1的状态
$result = mysqli_query($conn, $sql);//用mysqli_query获取你想要的数据
while($row = mysqli_fetch_row($result)) {//将获取到数据用数组保存起来
if($row[0]==1)
{
$jus='open';
echo $jus;//如果用电器开着的话就输出open字符串(主要是配合我改CSS的className)
}else{
$jus='close';
echo $jus;//关闭就输出close字符串
}
}
mysqli_close($conn);
?>
2.修改网页端显示状态
我用了7个按钮来表示用电器,通过XMLHttpRequest使用php来调取服务器MySQL的数据
主要逻辑就是php调取MySQL数据后,返回一个XMLRespondText,判断是open还是close,然后改变按钮的class
<button class="open">
<button class=''close'>
JavaScript相关代码
var xhr = new XMLHttpRequest();
xhr.open("GET","GetStatus7.php",false);//这里每一个按钮都用了一个php文件来调取,这是按钮7的
xhr.send(null);
console.log(xhr.responseText);
if(xhr.responseText=='open')
{
var b7_status =document.getElementById("b7")//获取button
b7_status.className='open'//将button的class 改为open
}else if(xhr.responseText=='close')
{
var b7_status =document.getElementById("b7")
b7_status.className='close'
}