运行环境
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()