前言:

这是大四上学期做的物联网实验,总共4个实验,这是第4个,也是最难的一个,当然大部分程序是我的老师编写的,我只是跟着实验指导书做出来的,希望可以帮到大家。

1. 系统工作原理

温湿度感知节点(Client),实时采集温湿度数据,然后通过WiFi模块,以TCP协议
将采集数据实时无线传输给服务端(Server);服务端将接收到的温湿度数据存于数据库
中;用户终端(User)从服务端获取实时采集和历史数据,用以监测、分析、查询等应
用。

2. 系统 设计

用户应用程序界面如图所示。

服务器界面:

使用串口助手看数据:
如果不写服务器程序和用户应用程序,也可以使用串口助手来观察数据

操作方法如下:

  1. 打开串口调试工具SSCOM,如下图所示。
  2. 实验以开发板作为客户端(Client),以电脑作为服务器端(Server)。所以,在SSCOM中,端口号选择TCPServer,服务器IP(本地IP)、端口设置与main函数中的一致。
  3. 按下SSCOM“侦听”按钮,若系统显示“已连接”,表明开发板已经建立了与服务器端的TCP连接,则可以看到温湿度的实时监测数据,。

终端设备:
主要用到的元器件有:
STM32F103C8T6、ESP8266、DHT11、DS18B20、ST-LINK下载器、方口数据线

3. 程序编写

STM32部分源码:
这部分代码太多了,只给出主函数的代码。

#include "filelib.h"int main(void)
{char *sendtxt = (char*)malloc(48);strcpy(P_data.wifi_ssid,"XIAOCHUN");          //设置连接WiFi名称strcpy(P_data.wifi_psd,"3118003167");         //设置连接WiFi密码strcpy(P_data.wifi_ip,"192.168.43.217");      //设置连接服务器IPstrcpy(P_data.wifi_port,"12345");              //设置连接服务器端口ESP8266_Init ();                                 //初始化ESP8266DHT11_GPIO_Config();DS18B20_Init();macESP8266_CH_ENABLE();                          //使能ESP8266ESP8266_AT_Test();                               //检测ESP8266的AT是否启动(若10次测试失败,则结束程序运行)ESP8266_Net_Mode_Choose(STA);                    //设置wifi模块为STA模式//连接wifiwhile (!ESP8266_JoinAP(P_data.wifi_ssid, P_data.wifi_psd))
{//连接wifi失败,重连
}   ESP8266_Enable_MultipleId(DISABLE);             //关闭WiFi多连接//连接到远程服务器while (!ESP8266_Link_Server(enumTCP, P_data.wifi_ip, P_data.wifi_port, Single_ID_0))
{//连接服务器失败,重连}while (!ESP8266_UnvarnishSend()) ;                     //开启穿透模式while(1){Delay_ms(1500);                                        //每隔1500ms获取一次温湿度//Dev_data.temp = readtemp();                     //获取温度Dev_data.temp =DS18B20_GetTemperture();sprintf(sendtxt,"%s%.2f%s","温度:",Dev_data.temp,"℃");ESP8266_SendString ( ENABLE,sendtxt,0, Single_ID_0 );    //发送温度值到服务器Dev_data.humi = Get_Humi_Value();                       //获取湿度sprintf(sendtxt,"%s%u%s","湿度:",Dev_data.humi,"%RH");ESP8266_SendString ( ENABLE,sendtxt,0, Single_ID_0 );    //发送温度值到服务器
//      ESP8266_SendString ( ENABLE, "Welcome!\r\n", 0, Single_ID_0 );    //发送湿度值到服务器}
}

服务器源码:

#define _CRT_SECURE_NO_WARNINGS#if defined(_WIN32) || defined(_WIN64)  //为了支持windows平台上的编译
#include <windows.h>
#endif#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<winsock.h>
#include "mysql.h"  //该文件在…\mysql-8.0.18-winx64\include下#pragma comment(lib,"ws2_32.lib")using namespace std;
void initialization();
int main() {//以下是MySQL数据库操作程序 MYSQL mysql, * sock; //声明MySQL的句柄 const char* host = "localhost"; //数据库服务器IP const char* user = "root"; //连接MySQL的用户名 const char* passwd = "123456"; //连接MySQL的用户密码const char* db = "iotdatabase"; //连接数据库的名字unsigned int port = 3306; //这是MySQL的服务器的端口,如果没有修改过的话就是3306const char* unix_socket = NULL; //unix_socket这是unix下的,在Windows下把它设置为NULL unsigned long client_flag = 0; //这个参数一般为0 char query_str[200]; //MySQL命令字符串  mysql_init(&mysql); //连接数据库之前必须使用初始化函数进行初始化 //连接MySQL  if ((sock = mysql_real_connect(&mysql, host, user, passwd, db, port, NULL,0 )) == NULL)  //unix_socket  client_flag{cout << "连接mysql失败" << endl;exit(1); //exit(0);正常的关闭所有程序; exit(1):有错误的关闭所有程序}//以下是Socket通信服务端程序 int recv_len = 0; //定义长度变量 int len = 0;//定义服务端套接字,接受请求套接字SOCKET s_server;SOCKET s_accept;//服务端地址客户端地址SOCKADDR_IN server_addr;SOCKADDR_IN accept_addr;//initialization();//填充服务端信息server_addr.sin_family = AF_INET;            //协议簇类型:TCP/IP–IPv4server_addr.sin_addr.S_un.S_addr = inet_addr("192.168.43.217");        //服务器IP 192.168.43.217server_addr.sin_port = htons(12345);         //服务器端口//初始化套接字 WORD w_req = MAKEWORD(2, 2); //版本号 WSADATA wsadata;int err;err = WSAStartup(w_req, &wsadata); //初始化套接字if (err != 0) {WSACleanup(); //中止套接字 }//创建套接字s_server = socket(AF_INET, SOCK_STREAM, 0);  //SOCK_STREAM—TCP流//SOCK_DGRAM—UDP数据报;SOCK_RAW—原始套接字 if (bind(s_server, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {WSACleanup();cout << "失败" << endl;}else {cout << "套接字绑定成功!" << endl;cout << "IP:192.168.43.217" << endl;cout << "端口:12345" << endl;}//设置套接字为监听状态if (listen(s_server, SOMAXCONN) < 0) {cout << "设置监听状态失败!" << endl;WSACleanup();}else {cout << "设置监听状态成功!" << endl;}cout << "服务端正在监听连接,请稍候...." << endl;//接受连接请求len = sizeof(SOCKADDR);s_accept = accept(s_server, (SOCKADDR*)&accept_addr, &len);if (s_accept == SOCKET_ERROR) {cout << "连接失败!" << endl;WSACleanup(); //释放DLL资源return 0;}cout << "连接建立,准备接受数据" << endl;//接收数据while (1) {char recv_buf[100] = { "\0" };    //定义接受缓冲区,并赋初值Nullrecv_len = recv(s_accept, recv_buf, 100, 0);      //接收数据长度if (recv_len < 0) {cout << "接受失败!" << endl;break;}else {//获取温湿度数据 数据格式:温度数据 + 湿度数据 #char* p1 = NULL;char* p2 = NULL;char* p3 = NULL;//分割字符串安全函数,这个函数将剩余的字符串存储在buf变量中,而不是静态变量中,从而保证了安全性。//char *strtok_s( char *strToken, const char *strDelimit, char **buf);string tempData = strtok_s(recv_buf, "+", &p2);string humiData = strtok_s(p2, "#", &p3);//获取采集时间char str[50];SYSTEMTIME st;       //系统时间变量GetLocalTime(&st);  //获得系统时间sprintf(str, "%u-%u-%u %u:%u:%u",st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);string datetimeDA = str;     //将采集时间转换为字符串 //拼接MYSQL查询命令字符串string sql = "insert into acquisitiondata(tempData,humiData,datetimeDA) values ('" + tempData + "','" + humiData + "','" + datetimeDA + "')";strcpy_s(query_str, sql.c_str()); //将采集的温湿度插入MySQL数据表acquisitiondatamysql_real_query(&mysql, query_str, strlen(query_str));  //执行由query_str指向的SQL查询cout << "将采集的温湿度插入MySQL数据表acquisitiondata" << endl;}}//关闭服务端套接字closesocket(s_server);closesocket(s_accept);//释放DLL资源WSACleanup();return 0;
}void initialization() {//初始化套接字库WORD w_req = MAKEWORD(2, 2);//版本号WSADATA wsadata;int err;err = WSAStartup(w_req, &wsadata);if (err != 0) {cout << "初始化套接字库失败!" << endl;}else {cout << "初始化套接字库成功!" << endl;}//检测版本号if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {cout << "套接字库版本号不符!" << endl;WSACleanup();}else {cout << "套接字库版本正确!" << endl;}
}

用户程序源码:

using System.Windows;
using MySql.Data.MySqlClient;
using System.Data;
using System.Linq;
using System.Threading;namespace UserApp
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();   //窗体界面定义初始化string connectionString = "server=localhost;port=3306;database=iotdatabase;charset=utf8;user id=root;password=123456;pooling=false;";//MySQL数据库连接字符串MySqlConnection conn = new MySqlConnection(connectionString); //连接MySQL数据库conn.Open();                     //打开连接DataTable dt = new DataTable(); //定义数据表string sqlstring = "SELECT * from acquisitiondata where numRecord = (SELECT max(numRecord)FROM acquisitiondata)"; //查询实时数据命令字符串MySqlCommand cmd = new MySqlCommand //定义MySQLCommand对象{Connection = conn,CommandText = sqlstring,CommandType = CommandType.Text};SynchronizationContext _syncContext = SynchronizationContext.Current;Thread LogThread = new Thread(new ThreadStart(DoService)); //定义线程LogThread.IsBackground = true; //设置线程为后台线程LogThread.Start(); //开启线程void DoService(){while (true){MySqlDataAdapter da = new MySqlDataAdapter(cmd); //获取实时数据da.Fill(dt); //将数据填充到数据表dtDataRow dr_last = dt.AsEnumerable().Last();_syncContext.Post(SetTextBox1, dr_last[1].ToString()); //通过线程更新txBoxTemp_syncContext.Post(SetTextBox2, dr_last[2].ToString()); //通过线程更新txBoxHumi_syncContext.Post(SetTextBox3, dr_last[3].ToString()); //通过线程更新txBoxTimeThread.Sleep(1000);}}void SetTextBox1(object text){txBoxTemp.Text = text.ToString(); //更新txBoxTemp}void SetTextBox2(object text){txBoxHumi.Text = text.ToString(); //更新txBoxHumi}void SetTextBox3(object text){txBoxTime.Text = text.ToString(); //更新txBoxTime}}private void Button_Click(object sender, RoutedEventArgs e){//查询按钮string connectionString = "server=localhost;port=3306;database=iotdatabase;charset=utf8;user id = root; password = 123456; pooling = false; ";MySqlConnection conn = new MySqlConnection(connectionString);  //连接MySQL数据库conn.Open();                                                  //打开连接DataTable dt = new DataTable();                                //定义数据表string sqlstring = "SELECT * FROM acquisitiondata;";          //查询所有记录命令字符串MySqlCommand cmd = new MySqlCommand();                        //定义MySQLCommand对象cmd.Connection = conn;cmd.CommandText = sqlstring;cmd.CommandType = CommandType.Text;MySqlDataAdapter da = new MySqlDataAdapter(cmd);da.Fill(dt);                                                   //将数据填充到数据表dtdataGridViewTH.ItemsSource = dt.DefaultView;                 //dataGridViewTH绑定数据表dtconn.Close();                                                //关闭数据库连接}private void BtnClear_Click_1(object sender, RoutedEventArgs e){//清空按钮string connectionString = "server=localhost;port=3306;database=iotdatabase;charset=utf8;user id = root; password = 123456; pooling = false; ";MySqlConnection conn = new MySqlConnection(connectionString);  //连接MySQL数据库conn.Open();                                                  //打开连接DataTable dt = new DataTable();                                //定义数据表                                                         string sqlstring = "TRUNCATE acquisitiondata;"; //TRUNCATE TABLE 删除表中的所有行,而不记录单个行删除操作MySqlCommand cmd = new MySqlCommand();                        //定义MySQLCommand对象cmd.Connection = conn;cmd.CommandText = sqlstring;cmd.CommandType = CommandType.Text;MySqlDataAdapter da = new MySqlDataAdapter(cmd);da.Fill(dt);                                                   //将数据填充到数据表dtdataGridViewTH.ItemsSource = dt.DefaultView;                 //dataGridViewTH绑定数据表dtconn.Close();                                                //关闭数据库连接}private void txBoxTime_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e){//采集时间框}private void TextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e){//温度数据框}private void txBoxHumi_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e){//湿度数据款框}}
}

最后:
需要资料的可以自行下载。下载链接
下载操作:

物联网实验-温湿度实时监测系统相关推荐

  1. 智慧茶厂:茶叶温湿度远程监测系统

    茶是中国人生活中必不可少的东西.随着技术进步与产业发展,制茶工艺也从传统手工制造迈向自动化生产,提供更高的产能和品质.茶叶生产.保存.运输都和温湿度息息相关,不同的口感与味道也影响到不同茶叶的价格.因 ...

  2. 工业物联网案例:船舶航行安全实时监测系统

    对于航运公司来说,如何对船舶以及进行安全及时和高效的管理是一个难题.传统的管理模式依赖有经验的员工进行巡查巡检,无法实时掌握船舶航行的有关信息,从而影响到决策的制定与实施. 船舶航行安全实时监测系统, ...

  3. 工业物联网解决方案:地下水实时监测系统

    随着物联网通信技术的发展以及国家水资源管理的加强,要求建设地下水实时监测系统,通过对地下水各要素数据采集,实现地下水资源的实时监测.展示.预警,及时掌握水资源的变化信息,为地下水资源的开发和保护提供科 ...

  4. 智慧工地安全施工实时监测系统解决方案

     背景介绍 随着经济的发展,混凝土搅拌车数量有很大增长,但是其超速.超载等原因造成了很多交通事故,给交通安全带来隐患,也给企业造成损失,严重影响了和谐城市建设的进程. 中国电子科技集团第52研究所经过 ...

  5. 基于改进YOLOv7&OpenCV的行人过马路速度与交通灯实时监测系统(源码&教程)

    1.研究背景 横穿马路的行人运动速度太快.太慢或者突变都可能影响驾驶者的判断,从而导致交通事故.车载辅助系统应能够在交通路口为驾驶者提供异常行人的速度预判信息.文献[1-2]通过对不同红绿灯情形进行建 ...

  6. 基于STC89C52单片机的粮仓温湿度无线监测系统简易设计

    任务书,以及相关资料见附件,下载查看. 任务概述, 设计一个基于单片机的粮仓温湿度无线监测系统.该系统包括:单片机.无线通信模块.温湿度传感器模块.按键模块.显示模块等. 1.基本功能 (1)本设计以 ...

  7. 实战 | 基于OpenCV的停车场空余车位实时监测系统(详细步骤 + 源码)

    导  读 本文主要介绍如何使用Python和OpenCV实现一个停车场空余车位实时监测系统,并包含详细步骤和源码. 背景介绍 介绍实现步骤之前,先来看看测试视频(小型停车场实时监控画面): ,时长00 ...

  8. 单片机+DHT11的温湿度采集监测系统,LCD1602显示,带报警功能,C代码、原理图和Proteus仿真

    设计要求 1.设计一个基于51单片机和DHT11传感器的温湿度监测系统: 2.传感器DHT11实现对环境温湿度参数的准确测量,单片机对数据进行分析和处理: 3.用户可根据需要,通过按键自主调节温湿度上 ...

  9. 4)lsof linux命令,***Linux命令实时监测系统(top,htop,iotop,lsof,tcpdump,netstat,vmstat,iostat)...

    摘要:本文总结了8个非常实用的Linux命令行性能监测工具,这些命令支持所有的Linux系统,不仅可以用于监控系统,还可以发现导致性能问题的原因所在. 对每个系统/网络管理员来说,每天监测Linux系 ...

最新文章

  1. 数据结构与算法:15 树
  2. CUDA简易安装教程
  3. zabbix—安装agent客户端(linux版)
  4. 电信用户流失预测案例(2)(特征工程)
  5. SqlServer2005/2008下sysproperties无效的解决办法
  6. FFmpeg中的日志以及avio实现对文件的读写功能
  7. mysql中下杠怎么打_怎么打字母下方的短横杠?,下横杠怎么打
  8. 三星Galaxy Note10系列国内发布会官宣:8月21日见!
  9. 第二届大数据世界论坛 聚焦行业需求
  10. UML基础: 统一建模语言简介
  11. java io图_JAVA IO流结构图
  12. CenterNet++ | CenterNet携手CornerNet终于杀回来了,实时高精度检测值得拥有!
  13. windows server 2003产生的 Minidmp蓝屏文件分析求助
  14. xampp mysql关机意外_xampp运行MySQL shutdown unexpectedly解决方法
  15. android lottie大小,android-Lottie动画填充
  16. word编辑公式并编号
  17. 设计师都在用这几个免费素材网站,赶紧马住
  18. mysql数据库的单引号用法_数据库SQL语句单引号、双引号的用法
  19. 前端js常用剪贴板(复制粘贴)操作和应用,以及navigator.clipboard新粘贴板API使用
  20. What is china

热门文章

  1. 腾讯、网易云、字节跳动面试点总结—AMS在Android起到什么作用?
  2. Django开发个人博客网站——1、开发环境
  3. hbuilder基座_3图标基座的禅宗
  4. java基础入门篇(1)
  5. 作为一名IT狗,天天加班,快变秃子了,我决定去植发……
  6. arduino ps2摇杆程序_Arduino技巧之PS2摇杆实验
  7. OCR -上传图片 自动识别文字并填充
  8. iOS 切换到后台任务执行
  9. 简练软考知识点整理-云大物移智区加
  10. 程序设计思维与实践 CSP-M4