基于无线传输的温湿度采集系统上位机开发

运行环境
Linux系统,Python语言
实现功能
从单片机串口接收采集到的温度和湿度,将数据存到数据库中,并实时显示在折线图上。
使用软件
Pycharm
使用python库
数据库层:pymysql
数据可视化层:matplotlib
串口通信层:pyserial

实现流程
在这里插入图片描述

串口通信模块

串口所在位置:"/dev/ttyUSB0"
波特率:9600
超时时间:timeout=None,由于是实时监测,所以将timeout设置为None,只有数据传输过来的时候才执行后面程序。
传输字节:bytesize=8

import random
import serial
import time
from Humiture1.WriteData import Mysqlclass


class Serailset:

    def __init__(self):
        self.mc=Mysqlclass()
        self.ser=serial.Serial("/dev/ttyUSB0",9600,timeout=None,bytesize=8)//初始化配置
	
	#关闭串口
    def close(self):
        self.ser.close()
	
	#读取串口数据,每次读取一行
    def read(self):
        return self.ser.readline()


if __name__ == '__main__':
    ser=Serailset()
    print(ser.insertMysql())
ser.close()

数据库层
使用pymysql模块与数据库进行交互,将数据库操作封装成一个类,方便操作。

import pymysql as mysql
import time
import random

#连接数据库
db_config = {
    'host':'localhost',
    'user':'root',
    'passwd':'',
    'db':'Data',
    'port':3306,
    'charset':'utf8'
}

class Mysqlclass:
	
	#初始化,连接数据库,创建游标
    def __init__(self):
        try:
            self.db_config=db_config
            self.conn=mysql.connect(**self.db_config)
            self.cur=self.conn.cursor()
        except Exception as e:
            print("连接数据库失败")
        else:
            print("连接数据库成功")
	
	#关闭连接,关闭游标
    def close(self):
        self.cur.close()
        self.conn.close()



    #往A数据表存入数据
    def insertsql_A(self,list):
        li=[]
        li.append(tuple(list))
        insert_sql='INSERT INTO humitures_A(measuring_time,temperature,humidity) VALUES (%s,%s,%s)'
        self.cur.executemany(insert_sql,li)
        last_id_A=int(self.cur.lastrowid)
        self.conn.commit()
        return last_id_A

#往B数据表存入数据
    def insertsql_B(self, list):
        li = []
        li.append(tuple(list))
        insert_sql = 'INSERT INTO humitures_B(measuring_time,temperature,humidity) VALUES (%s,%s,%s)'
        self.cur.executemany(insert_sql, li)
        last_id_B=int(self.cur.lastrowid)
        self.conn.commit()
        return last_id_B

	#读取数据表中最大行,方便访问最新插入的数据
    def read_maxcount(self,site):
        self.cur.execute('select count(*) from humitures_%s' %(site))
        return self.cur.fetchall()[0][0]


    #读取数据
    def readData_A(self,after):
        time.sleep(0.5)
        self.cur.execute('select * from humitures_A where id between %s and %s' %(after-10,after))
        self.conn.commit()
        return self.cur.fetchall()


    def readData_B(self,after):
        time.sleep(0.5)
        self.cur.execute('select * from humitures_B where id between %s and %s' %(after-10,after))
        self.conn.commit()
        return self.cur.fetchall()

数据可视化

import matplotlib.pyplot as plt
from Humiture1.WriteData import Mysqlclass
import numpy as np
import time

class PictureShow:
    
    def __init__(self):
        self.mc = Mysqlclass()
        self.fig = plt.figure()
        plt.ion()

    def showA(self,last_id_A):
        ax1=plt.subplot(211)   #实现多幅图创建
        plt.grid(True)
        after=last_id_A
        tuple=self.mc.readData_A(after)
        x1_datelist = [str(i[1])[11:] for i in tuple]
        y1_tmplist=[i[2] for i in tuple]
        y2_humlist=[i[3] for i in tuple]
    

        ax1.plot(x1_datelist,y1_tmplist,c='red')
        ax1.set_title("Site_A_Temperature")
        ax1.set_ylabel('Temperature(C)', fontsize=16)
        ax2=ax1.twinx()       #绑定ax1和ax2实现双Y轴折线图
        ax2.plot(x1_datelist, y2_humlist, c='blue')
        ax2.set_xlabel('Time(s)', fontsize=16)
        ax2.set_ylabel('humiture(%)', fontsize=16)


    def showB(self,last_id_B):
        ax3=plt.subplot(212)
        plt.grid(True)
        after = last_id_B
        tuple=self.mc.readData_B(after)

        x2_datelist = [str(i[1])[11:] for i in tuple]
        y3_tmplist = [i[2] for i in tuple]
        y4_humlist = [i[3] for i in tuple]

        ax3.plot(x2_datelist, y3_tmplist, c='red')
        ax3.set_title("Site_B_Temperature")
        ax3.set_ylabel('Temperature(C)', fontsize=16)

        ax4 = ax3.twinx()
        ax4.plot(x2_datelist, y4_humlist, c='blue')
        ax4.set_xlabel('Time(s)', fontsize=16)
        ax4.set_ylabel('humiture(%)', fontsize=16)
        self.fig.autofmt_xdate()


    def showWindow(self,last_id_A,last_id_B):
        plt.clf()  # 清除画布
        self.showA(last_id_A)
        self.showB(last_id_B)
        plt.pause(0.001)


主操作
从串口中读取数据,判断A、B两地的数据,A地的信息存入数据库中的A数据表,B地的信息存入数据库中B地的数据表。每插入一条信息折线图模块从数据库中读取一条最新插入的数据,在折线图上进行显式。

import time
from Humiture1.WriteData import Mysqlclass
from Humiture1.showpicture import PictureShow
from Humiture1.Serailset import Serailset

class Manager:
    def __init__(self):
        self.mc=Mysqlclass()
        self.ps=PictureShow()
        self.ser=Serailset()
	

    def insertMysqlandshow(self):
        while True:
            infotuple = []
            info = str(self.ser.read())
            date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            infotuple.append(date)
            infotuple.append(info[8:10])
            infotuple.append(info[15:17])
            last_id_A = int(self.mc.read_maxcount("A"))
            last_id_B = int(self.mc.read_maxcount("B"))
            if info[2] == "A":
                self.mc.insertsql_A(infotuple)
                self.ps.showWindow(last_id_A, last_id_B)
                print(info)
            elif info[2] == "B":
                self.mc.insertsql_B(infotuple)
                self.ps.showWindow(last_id_A, last_id_B)
                print(info)


if __name__ == '__main__':
    mg=Manager()
    mg.insertMysqlandshow()


猜你喜欢

转载自blog.csdn.net/mashaokang1314/article/details/84024585
今日推荐