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 + 00
10000 +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 + 00
10000 +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温箱控制相关推荐

  1. Python学习之道-串口Modbus开发

    Python学习之道-串口Modbus开发 一.环境准备 二.编程实践 2.1 实践目的 2.2 协议分析 PS:工作中需要实现自动化测试,其中要控制恒温恒湿试验箱,涉及Mogbus通信 一.环境准备 ...

  2. Python学习笔记三之编程练习:循环、迭代器与函数

    Python学习笔记三之编程练习 1. 编程第一步 # 求解斐波纳契数列 #/user/bin/python3#Fibonacci series:斐波那契数列 #两个元素的总和确定了下一个数 a,b= ...

  3. Python学习之道-烤机测试日志Log分析统计

    Python学习之道-烤机测试日志Log分析统计 问题引出 一.环境准备 二.实践代码 1.初步实现 2.更新CSV文件写入统计结果 3.运行脚本 4.实现遍历多个Log并汇总结果到Excel 三.遇 ...

  4. Python学习之面向对象高级编程

    Python学习目录 1. 在Mac下使用Python3 2. Python学习之数据类型 3. Python学习之函数 4. Python学习之高级特性 5. Python学习之函数式编程 6. P ...

  5. Python学习之道-打包成exe程序

    Python学习之道-打包成exe程序 一.打包成exe程序 Pyinstaller安装 作用 使用 Pyinstaller相关参数 Pyinstaller使用总结 尽量用from.....impor ...

  6. Python学习笔记·交互式图形编程

    Python学习笔记·交互式图形编程 注:在校计算机学生一名,菜鸟一枚,最近开始学习Python的基础知识希望有什么不对的地方各位大佬能够不令赐教! 课程是在中国大学MOOC上学的,有兴趣的同学可以自 ...

  7. Python学习十:网络编程

    文章目录 一.网络基础 1.1 为什么要使用通信协议 1.2 TCP/IP 简介 1.3 UDP 简介 1.4 Socket 简介 1.41 Python 使用 二.TCP 编程 2.1 创建TCP服 ...

  8. Python学习笔记:Io编程序列化

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  9. Python学习笔记:IO编程StringIO和BytesIO

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

最新文章

  1. win10虚拟机服务器错误怎么解决方法,虚拟机下安装win10系统后出现升级报错故障的解决方法【图文】...
  2. .Net配置文件中数据库中连接字符串用法总结
  3. VS2010中打开VS2013/VS2012项目
  4. 如何解决xp进系统的时候需要按enter键
  5. 购物车代码(html+css)
  6. UltraEdit中Matlab语法高亮显示的操作方法
  7. 免费IP切换工具有用吗?
  8. 微软代码审查工具_微软代码审查的工作方式
  9. MathType输入花体字
  10. C语言中文网设计模式,C语言和设计模式(访问者模式)
  11. 解决Google 云端硬盘,文件下载问题
  12. 基于飞桨本地ocr安卓按键插件
  13. 《守望先锋》模型提取实例
  14. Android应用中实现系统“分享”接口
  15. 【经典算法】-算术表达式求值
  16. Kali之Crunch:自定义字典
  17. 数据库 多表 查询练习题
  18. 1148: 考试晋级(java版)
  19. Python matplotlib 批量绘图内存不够问题(Out of memory)
  20. There is insufficient memory for the Java Runtime Environment to continue IDEA闪退

热门文章

  1. 爬取美女图片实现翻页
  2. 【openlayers】ol3切换图层源
  3. Docker 部署微服务
  4. hexo中matery主题的个性化定制
  5. 关于手机模拟器的探索
  6. 【系统收藏——中天证券创鑫软件 官方版 [同时支持三板、港股行情、沪深300指数。]】
  7. 2022年最新浙江机动车签字授权人模拟试题及答案
  8. tcl语言读取文件一行_tcl读取数据输入输出
  9. 挂耳式骨传导蓝牙耳机,2021骨传导耳机推荐
  10. Paypal学习 3 -- 接受信用卡直接付款 (DoDirectPayment)