基础配置
- 数据库:Mysql
- 服务器:Linux
- 后端:php
- 前端:html,css,echar
- 开发板:esp8266
- 传感器:温湿度传感器,型号不会看
成品演示
esp8266把传感器的数据上传到服务器, 手机上访问网址就能看到当前的温度湿度。
流程图
流程图应该挺详细了。
接口设计
简单安全考虑,增加一个密钥验证, 防止被恶意写入乱七八糟数据;
接口:http://zxyoyo.com/sky/iot123.php
传输方式:GET
参数:
token:"123abc" //安全参数,随意设置
temp: 22.6 //温度,浮点数
humi: 46.9 //湿度,浮点数
maker: 123 // 程序的id,随意设置,用于区分不同设备
php接口代码
<?php
//设置编码为UTF-8,以避免中文乱码
header('Content-Type:text/plain;charset=utf-8');
//验证--- token,温度,湿度,设备id
$token = $_GET['token'];
$temp = $_GET['temp'];
$humi = $_GET['humi'];
$maker = $_GET['maker'];
$mytoken = "123abc";//固定的token
// 判断是否为空
if(empty($token)||empty($temp)||empty($humi) || empty($maker)){
die("-null-");
}
// token 校验
if($token != $mytoken){
die("token error!");
}
// 导入数据库连接配置信息
//示例:$link=mysqli_connect("localhost","root","123456","database_name")or die ('Error connecting to MySQL server.');
include __DIR__.'/../con_mysql.php';
// 编写sql 插入数据到 表中
$sql = "INSERT INTO iot_th_one(temp,humi,maker) VALUES ("
."'".$temp."',"
."'".$humi."',"
."'".$maker."');";
// 执行sql
$rowresult = mysqli_query($link, $sql);
$result= "";
if($rowresult){
//保存到数据库成功
$result = "ok";
}else{
// 保存到数据库失败
$result = "add error";
}
//关闭数据库连接
mysqli_close($link);
// 返回结果
die($result);
?>
Arduino程序设计
主要是用到wifi库,http网络请求库
// 导入dht库,用于传感器的库
#include <DHT.h>
//连接多个wifi
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
//网络请求
#include <ESP8266HTTPClient.h>
// 定义一个dht对象,5是GPIO5,具体看开发板
DHT dht(5, DHT11);
ESP8266WiFiMulti wifiMulti; //创建一个ESP8266WiFiMulti对象
//创建 HTTPClient 对象
HTTPClient httpClient;
WiFiClient wifiClient;
//上传数据的接口
String api = "http://zxyoyo.com/sky/iot123.php";
void setup() {
// put your setup code here, to run once:
//开启串口监视器
Serial.begin(9600);
//初始化dht传感器
dht.begin();
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
// 通过 addAP函数存储 wifi 名称,wifi密码
wifiMulti.addAP("00QAQ", "00QAQ123!");
wifiMulti.addAP("00qaq", "00qaq123!");
Serial.println("Please wait, Connecting");
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
if(i>10) Serial.println("\n");
//print(i++);
}
//连接wifi成功后,输出连接成功信息
Serial.println("\n");
Serial.print("connected to ");
Serial.println(WiFi.SSID());
Serial.print("IP address: \t");
Serial.println(WiFi.localIP());
//添加api的校验信息
api += "?token=123abc";
//添加api的设备信息
api += "&maker=esp8266";
}
void loop() {
// put your main code here, to run repeatedly:
//延迟10s 打印
delay(10000);
// 获取摄氏温度
float temp = dht.readTemperature();
// 获取空气湿度
float humi = dht.readHumidity();
// 判断读取到的数据
if(isnan(temp)){
//没有读取到摄氏温度
Serial.println("failed to read temp");
temp = 8266.0;
}else {
//读取到摄氏温度,打印
Serial.print("Read temp = ");
Serial.println(temp);
}
if(isnan(humi)){
//没有读取空气湿度
Serial.println("failed to read humi");
humi = 8266.0;
}else {
//读取空气湿度,打印
Serial.print("Read humi = ");
Serial.println(humi);
}
//如果温度或者湿度有一个有读数,上传数据
if(temp != 8266.0 || humi != 8266.0){
uploadData(temp,humi);
}else{
Serial.println("read data failed");
}
}
//上传数据到服务器
void uploadData(float temp, float humi){
String tempUrl = api +"&temp=";
tempUrl += temp;
tempUrl += "&humi=";
tempUrl += humi;
httpClient.begin(wifiClient,tempUrl);
//启动连接并发送http请求
int code = httpClient.GET();
if(code == HTTP_CODE_OK){
String resp = httpClient.getString();
Serial.print("Server resp: ");
Serial.println(resp);
}else{
Serial.println("request server error");
Serial.print("code=");Serial.println(code);
Serial.println(tempUrl);
Serial.println(httpClient.errorToString(code).c_str());
}
}
前端设计
访问接口
http://zxyoyo.com/skx/iot1.php
基本的html,css代码,使用echar设计图表,不用额外接口获取数据了,直接用php方便多了。
<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="shortcut icon" href="./favicon.ico">
<link href="./assets/css/iot1.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>温湿度</title>
<script src="./assets/js/echarts.min.js"></script>
</head>
<!--
0摄氏度以下:16e6fb,26cbfd
一般天气20-30;47a8fb
高温黄色预警信号:连续三天温度达到35℃; f7bb13
高温橙色预警信号:当日气温达到37℃; ff5d3a
高温红色预警信号:当日温度达到40℃。 ff0b0b
-->
<body>
<!-- 获取数据 -->
<?php
// 导入数据库连接配置信息
//示例:$link=mysqli_connect("localhost","root","123456","database_name")or die ('Error connecting to MySQL server.');
include __DIR__.'/../con_mysql.php';
$maker = "deviceid";
//获取最新的 温度湿度数据
$curTemp = 1.23;//当前温度
$curHumi = 1.23;//当前湿度
$updateTime = '';//更新时间
$sql = "SELECT * from iot_th_one WHERE maker='".$maker."' order by id desc limit 1;";
$rowresult = mysqli_query($link, $sql);
if (!$rowresult) {
printf("Error: %s\n", mysqli_error($link));
mysqli_close($link);
echo 'error';
}
if($rowresult->num_rows > 0){
$row = mysqli_fetch_assoc($rowresult);
if($row['id']>0){
mysqli_close($link);
$curHumi = $row['humi'];
$curTemp = $row['temp'];
$updateTime = $row['createtime'];
//小数点后一位
if(strpos($curTemp,'.') !== false){
$curTemp = number_format($curTemp,1);
}
}
mysqli_close($link);
}else{
mysqli_close($link);
}
?>
<div style="position: relative;color: #107bff;">
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style=""></div>
<div id="content" style="" >当前温度:<?php echo $curTemp;?>,
当前湿度:<?php echo $curHumi;?><br>
数据更新时间: <?php echo $updateTime;?><br>
<a style="text-decoration: none;" href="./iot1.php">点击更新</a></div>
</div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
series: [
{
type: 'gauge',
min: -20,
max: 60,
axisLine: {
lineStyle: {
width: 20,
color: [
[1,new echarts.graphic.LinearGradient(0,0,1,0,[
{offset: 0,color: '#26cbfd'},
{offset: 0.1,color: '#16e6fb'},
{offset: 0.375,color: '#47a8fb'},
{offset: 0.7125,color: '#f7bb13'},
{offset: 1,color: '#ff0b0b'},
])]
]
}
},
pointer: {
itemStyle: {
color: 'auto'
}
},
axisTick: {
distance: -20,
length: 8,
lineStyle: {
color: '#fff',
width: 2
}
},
splitLine: {
distance: -30,
length: 30,
lineStyle: {
color: '#fff',
width: 4
}
},
axisLabel: {
color: 'auto',
distance: 22,
fontSize: 14
},
detail: {
valueAnimation: true,
formatter: '{value} ℃',
color: 'auto',
fontSize: 20
},
data: [
{
value: <?php echo $curTemp;?>,
name: <?php echo "'湿度:".$curHumi."'";?>
}
]
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
总结
感谢您阅读到最后。做个东西的灵感来源是之前在某宝买了一个电子温度湿度显示,在小米的app能看到实时数据,其实还是很方便的。自己动手做一个,几乎把所学都用到了(c 写arduino,php写接口,html写页面展示,Mysql存储数据),很是满意,后面继续完善。共勉!
|