Python学习之道-串口编程TEMI880温箱控制
Python学习之道-串口编程&TEMI880温箱控制
- 一、环境准备
- 安装pyserial库
- pyserial库常用函数介绍
- 参考例程
- 二、开发实践
- 1、实践项目
- 2、协议介绍
- 2.1 一般的指令格式:
- 2.2 举例:
- 2.3 协议命令
- 3、串口测试
- 4、温箱串口控制类实现
PS:自己学习Python已经断断续续有1年了,之前没有写博客的习惯,前段日子去图书馆借阅了《程序员的自我修养》,觉得应该养成写博客的习惯,将自己学习的过程记录下来,方便自己也方便大家,记录自己学习历程和思路,后面回顾也方便易上手。最主要的是方面自己查找 哈哈
从大一开始接触单片机开发,串口使用了8年了,之前做上位机开发时大多使用MFC/C#/LabVIEW等,比较杂。现在学习用Python进行串口编程,相信效率会高不少。
一、环境准备
参照网上的教程,消息吸收。
安装pyserial库
https://github.com/pyserial/pyserial
pip install pyserial
PS D:\python> pip install pyserial
Collecting pyserialDownloading https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl (193kB)100% |████████████████████████████████| 194kB 613kB/s
Installing collected packages: pyserial
Successfully installed pyserial-3.4
PS D:\python>
pyserial库常用函数介绍
serial.Serial(portx, bps, timeout = waitTime)
serial = serial.Serial(‘COM1’, 115200) 打开COM1并设置波特率为115200,COM1只适用于Windows
serial = serial.Serial(‘/dev/ttyS0’, 115200) 打开/dev/ttyS0并设置波特率为115200, 只适用于Linux
print serial .portstr 能看到第一个串口的标识
serial .write(“hello”) 往串口里面写数据
serial .close() 关闭serial 表示的串口
serial .open() 打开串口
data = serial .read(num) 读num个字符
data = serial .readline() 读一行数据,以/n结束,要是没有/n就一直读,阻塞。
serial .baudrate = 9600 设置波特率
print serial 可查看当前串口的状态信息
serial .isOpen() 当前串口是否已经打开
serial.inWaiting() 判断当前接收的数据
serial.flushInput() 清除输入缓冲区数据
serial.flushOutput() 中止当前输出并清除输出缓冲区数据
参考例程
#!/usr/bin/python
# coding=UTF-8import serial###################################################
#
# 功 能: 将接收到的数据已hex显示
# 参 数: 串口接受到的数据
# 返 回: 转换后的数据
#
###################################################def hexshow(data):hex_data = ''hLen = len(data)for i in xrange(hLen):hvol = ord(data[i])hhex = '%02x' % hvolhex_data += hhex+' 'print 'hexshow:', hex_data###################################################
#
# 功 能: 将需要发送的字符串以hex形式发送
# 参 数: 待发送的数据
# 返 回: 转换后的数据
#
###################################################def hexsend(string_data=''):hex_data = string_data.decode("hex")return hex_dataif __name__ == '__main__':serial = serial.Serial('/dev/ttyS0', 115200)print serialif serial.isOpen():print("open success")else:print("open failed")try:while True:count = serial.inWaiting()if count > 0:data = serial.read(count)if data != b'':print("receive:", data)serial.write(data)else:serial.write(hexsend(data))except KeyboardInterrupt:if serial != None:serial.close()
参考文档
神奇的python(六)之python的串口操作(pyserial) - absinjun的博客 - CSDN博客
python串口通信 - 微小冷的学习笔记 - CSDN博客
Python3+PyQT5+Pyserial 实现简单的串口工具 - 钟鸣的博客 - CSDN博客
二、开发实践
1、实践项目
实现基于python开发脚本控制可程式恒温恒湿试验箱
温箱控制器型号:广州庆瑞 TEMI880
2、协议介绍
2.1 一般的指令格式:
S[地址][命令ID][…其它操作数….]A E[地址][命令ID][…其它操作数….]A
注意: 1.开头第一个字母,S表示读取仪表的数据,E表示修改和控制仪表
2.地址只能两个字节,并且只能在第2,3位,
3.两个操作数之间用“#”作为分隔符
4.本协议使用和校验方式。
2.2 举例:
这是仪表回发PC的报文:01 63 02 1B 18 00 00 7C 15 00 00 E8 1E 00 00 88 13 00 00 CB CB
校验码=MOD((01+63+02+1B+18+00+00+7C+15+00+00+E8+1E+00+00+88+13+00+00),256)
【和校验方式】
对整个报文(不包括最后两个字节)进行求和后,对总和对256求余,只保留最一个字节,最后两个校验码是相同的。
2.3 协议命令
命令1:查询仪表的运行状态:
访问格式 S0199A
或者S01#99#A
注:[01]是仪表的地址 [99]是查询指令
以下是仪表返回的数据,以16进制显示 01 63 02 1B 18 00 00 7C 15 00 00 E8 1E 00 00 88 13 00 00 CB CB
01 是仪表的地址
63 是ID,标识这段数据包是何种格式
02运行状态 0:程式停止1:程式运行2:定值停止3:定值运行
1B 18 00 00 是当前温度值, 还原算法如下,以下的数是16进制
温度值=(00 * 1000000 + 0010000 +18 * 100 + 1B)/64
结果是:61.71
例如:当温度为负数时,根据数制原理求补数的方法
最高位为1表示为负数 (60 F0 FF FF)
<1>原数:60 F0 FF FF (实为:-4000)
<2>取反: 9F 0F 00 00
<3>求和: (00 * 1000000 + 0010000 +0F * 100 + 9F)=F9F
<4>加1:(F9F=3999) 3999 + 1 = 4000
<5>取反-4000
<6>转化成单精度:-4000/100.0 = -40.0
7C 15 00 00 是当前温度设定值, 还原算法如下,以下的数是16进制
温度设定值=(00 * 1000000 + 0010000 +15 * 100 + 7C)/64
结果是:55.00
8E 1E 00 00 是当前湿度, 还原算法如下,以下的数是16进制
湿度=(00 * 1000000 + 0010000 +1E * 100 + 8E)/64
结果是:78.22
88 13 00 00 是当前湿度设定值, 还原算法如下,以下的数是16进制
湿度设定值=(00 * 1000000 + 00*10000 +13 * 100 + 88)/64
结果是:50.00
【如果是单温仪表,湿度的设定和显示值也会发过来,不用就行了】
CB CB 是本段数据的校验码,两个值相同,建议使用倒数第二个。
命令2:启动运行:
格式:E01#99#1#A 说明:[01]是仪表的地址 [99]是查询指令 [1]表示启动运行
命令3:停止运行:
格式:E01#99#2#A 说明:[01]是仪表的地址 [99]是查询指令 [2]表示停止运行
命令4:修改定值温度设定值
格式:E01#600#478#修改值#A 例如:E01#600#478#56.24#A 把温度的设定值改为56.24
命令5:修改定值湿度设定值
格式:E01#600#479#修改值#A 例如:E01#600#479#90.0#A 把湿度的设定值改为90.0
命令6:解除程式的保持:
格式:E01#99#10#A 说明:[01]是仪表的地址 [99]是查询指令 [10]表示解除保持
命令7:启动程式的保持:
格式:E01#99#11#A 说明:[01]是仪表的地址 [99]是查询指令 [11]表示启动保持
3、串口测试
测试能否正常收发
测试源码如下:
#!/usr/bin/python
# coding=UTF-8import serial
import os
import timeif __name__ == '__main__':serial = serial.Serial('COM3', 2400)print (serial)if serial.isOpen():print("打开串口成功")else:print("打开串口 failed")cmd1 = b"S01#99#A"try:while True:serial.write(cmd1)time.sleep(2)count = serial.inWaiting()if count > 0:data = serial.read(count)if data != b'':print("receive:", data)serial.write(data)except KeyboardInterrupt:if serial != None:serial.close()
运行结果
F:\MyPython\testDemo1\venv\Scripts\python.exe F:/MyPython/testDemo1/test1.py
Serial<id=0x189bf608048, open=True>(port='COM3', baudrate=2400, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
打开串口成功
receive: b'\x01c\x01\x9b\x11\x00\x00\x94\x11\x00\x00\x17$\x00\x00T$\x00\x00ii'
receive: b'\x01c\x01\x9a\x11\x00\x00\x94\x11\x00\x00\x17$\x00\x00T$\x00\x00hh'
4、温箱串口控制类实现
#!/usr/bin/env python
# -*- coding:utf-8 -*-import serial
from array import array
import os
import timeclass CTEMI880:"""该类是广州庆瑞的TEMI880的串口控制驱动""" #类文档字符串# 定义基本属性comName = ""#定义私有属性,私有属性在类外部无法直接进行访问__tempSV = 0__tempCV = 0__humiSV = 0__humiCV = 0__stateV = 0__dstate = { #用字典实现switch 功能0x00: '程式停止',0x01: '程式运行',0x02: '定值停止',0x03: '定值运行',}def __init__(self, comName = "COM3"): #构造方法comName = comNameself.__serial = serial.Serial(comName, 2400)print(serial)if self.__serial.isOpen():print("打开串口成功")else:print("打开串口 failed")def __del__(self):if self.__serial != None:self.__serial.close()@staticmethoddef __checkSum(self,array):if len(array) == 21:sum = 0temp = array[0:19]for b in temp:sum += bsum = 0x00ff & sumprint('sum is:',sum,'array[19] is:',array[19])if (sum == array[19]) and (sum == array[20]):return Trueelse:return Falsereturn Falsedef get_state(self):cmd1 = b"S01#99#A"try:self.__serial.write(cmd1)time.sleep(1)count = self.__serial.inWaiting()if count > 0:data = self.__serial.read(count)if data != b'':print("receive:", data)if self.__checkSum(self, data) is True:self.__stateV = self.__dstate.get(data[2], '未知状态')self.__tempCV = int.from_bytes(data[3:7],byteorder='little',signed=True)/100self.__tempSV = int.from_bytes(data[7:11],byteorder='little',signed=True)/100self.__humiCV = int.from_bytes(data[11:15],byteorder='little',signed=True)/100self.__humiSV = int.from_bytes(data[15:19],byteorder='little',signed=True)/100print(self.__stateV,'TCV:',self.__tempCV,'TSV:',self.__tempSV,' ',self.__humiCV,' ',self.__humiSV)#print('校验成功')else:print('校验失败')except KeyboardInterrupt:if self.__serial is not None:self.__serial.close()def temi_run(self):cmd1 = b"E01#99#1#A" #格式:E01#99#1#A 说明:[01]是仪表的地址 [99]是查询指令 [1]表示启动运行try:if self.__serial.is_open:self.__serial.write(cmd1)else:print('串口未打开或不存在')except KeyboardInterrupt:if self.__serial is not None:self.__serial.close()def temi_stop(self):cmd1 = b"E01#99#2#A" #格式:E01#99#2#A 说明:[01]是仪表的地址 [99]是查询指令 [2]表示停止运行try:if self.__serial.is_open:self.__serial.write(cmd1)else:print('串口未打开或不存在')except KeyboardInterrupt:if self.__serial is not None:self.__serial.close()def temi_set_temp(self,flaot):"""修改定值温度设定值"""cmd1 = b'E01#600#478#%.2f#A' % (flaot) #格式:E01#600#478#修改值#A 例如:E01#600#478#56.24#A 把温度的设定值改为56.24#cmd1 = bytes(str1,'ascii')print('修改定值温度设定值',cmd1)try:if self.__serial.is_open:self.__serial.write(cmd1)else:print('串口未打开或不存在')except KeyboardInterrupt:if self.__serial is not None:self.__serial.close()def temi_set_humi(self, flaot):"""修改定值湿度设定值"""cmd1 = b'E01#600#479#%.1f#A' % (flaot) #格式:E01#600#479#修改值#A 例如:E01#600#479#90.0#A 把湿度的设定值改为90.0# cmd1 = bytes(str1,'ascii')print('修改定值湿度设定值',cmd1)try:if self.__serial.is_open:self.__serial.write(cmd1)else:print('串口未打开或不存在')except KeyboardInterrupt:if self.__serial is not None:self.__serial.close()def displayState(self):print('当前运行状态:',self.__stateV)return self.__stateVdef displayTempCV(self):print('当前实时温度:', self.__tempCV)return self.__tempCVdef displayTempSV(self):print('当前设置温度:', self.__tempSV)return self.__tempSVdef displayHumiCV(self):print('当前实时湿度:', self.__humiCV)return self.__humiCVdef displayHumiSV(self):print('当前设置湿度:', self.__humiSV)return self.__humiSVtemi880 = CTEMI880("COM3")
temi880.temi_run()
time.sleep(2)
temi880.temi_set_temp(-39)
time.sleep(2)
while True:temi880.displayHumiCV()temi880.displayHumiSV()temi880.displayTempCV()temi880.displayTempSV()temi880.displayState()temi880.get_state()print(temi880.__class__)
参考
python之将byte转换为int类型函数 int.from_bytes 详解与原码反码补码的简单介绍 - aic1999的博客 - CSDN博客
Python学习之道-串口编程TEMI880温箱控制相关推荐
- Python学习之道-串口Modbus开发
Python学习之道-串口Modbus开发 一.环境准备 二.编程实践 2.1 实践目的 2.2 协议分析 PS:工作中需要实现自动化测试,其中要控制恒温恒湿试验箱,涉及Mogbus通信 一.环境准备 ...
- Python学习笔记三之编程练习:循环、迭代器与函数
Python学习笔记三之编程练习 1. 编程第一步 # 求解斐波纳契数列 #/user/bin/python3#Fibonacci series:斐波那契数列 #两个元素的总和确定了下一个数 a,b= ...
- Python学习之道-烤机测试日志Log分析统计
Python学习之道-烤机测试日志Log分析统计 问题引出 一.环境准备 二.实践代码 1.初步实现 2.更新CSV文件写入统计结果 3.运行脚本 4.实现遍历多个Log并汇总结果到Excel 三.遇 ...
- Python学习之面向对象高级编程
Python学习目录 1. 在Mac下使用Python3 2. Python学习之数据类型 3. Python学习之函数 4. Python学习之高级特性 5. Python学习之函数式编程 6. P ...
- Python学习之道-打包成exe程序
Python学习之道-打包成exe程序 一.打包成exe程序 Pyinstaller安装 作用 使用 Pyinstaller相关参数 Pyinstaller使用总结 尽量用from.....impor ...
- Python学习笔记·交互式图形编程
Python学习笔记·交互式图形编程 注:在校计算机学生一名,菜鸟一枚,最近开始学习Python的基础知识希望有什么不对的地方各位大佬能够不令赐教! 课程是在中国大学MOOC上学的,有兴趣的同学可以自 ...
- Python学习十:网络编程
文章目录 一.网络基础 1.1 为什么要使用通信协议 1.2 TCP/IP 简介 1.3 UDP 简介 1.4 Socket 简介 1.41 Python 使用 二.TCP 编程 2.1 创建TCP服 ...
- Python学习笔记:Io编程序列化
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- Python学习笔记:IO编程StringIO和BytesIO
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
最新文章
- win10虚拟机服务器错误怎么解决方法,虚拟机下安装win10系统后出现升级报错故障的解决方法【图文】...
- .Net配置文件中数据库中连接字符串用法总结
- VS2010中打开VS2013/VS2012项目
- 如何解决xp进系统的时候需要按enter键
- 购物车代码(html+css)
- UltraEdit中Matlab语法高亮显示的操作方法
- 免费IP切换工具有用吗?
- 微软代码审查工具_微软代码审查的工作方式
- MathType输入花体字
- C语言中文网设计模式,C语言和设计模式(访问者模式)
- 解决Google 云端硬盘,文件下载问题
- 基于飞桨本地ocr安卓按键插件
- 《守望先锋》模型提取实例
- Android应用中实现系统“分享”接口
- 【经典算法】-算术表达式求值
- Kali之Crunch:自定义字典
- 数据库 多表 查询练习题
- 1148: 考试晋级(java版)
- Python matplotlib 批量绘图内存不够问题(Out of memory)
- There is insufficient memory for the Java Runtime Environment to continue IDEA闪退