一.配置环境
python版本3.8
pip install pymysql==1.0.2
pyserial==3.5 (这里不是serial,使用:import serial)
modbus-tk==1.1.2
pyodbc==4.0.31
pip install pymssql==2.1.5
二.学习代码
(一)modbus_sqlserver_meter模块
参考: python实用模块之pyodbc 执行代码部分还可参考…
conn=pyodbc.connect(Trusted_Connection='yes', driver = '{SQL Server}',server = 'DESKTOP-RAF8AL9\SQLEXPRESS' , database = 'pytest')
# 创建一个pyodbc的对象并调用connect方法连接到字符串所指定的数据库上。
# driver:mssql server(微软)
# DATABASE=数据库名; SERVER=服务器所在的计算机名;
# UID=你的用户名;PWD=你的密码
# 大小写不分
cursor=conn.cursor()
# 创建一个服务器的游标,一闪一闪,开启与服务器的会话.创建完游标后你就可以执行sql语句了
cursor.execute('create table meter_data(id int not null IDENTITY(1,1) ,频率 int,电压 int,采集时间 datetime,primary key(id))')
# 执行一个sql语句
进行开发的一般步骤都是:
1.对象名=pyodbc.connect(‘连接字符串’),创建一个pyodbc的对象,然后连接数据库 2.对象名2=对象名.cursor(),创建一个服务器游标,开始与服务器的会话 3.对象名2.execute(你要执行的sql语句),执行sql语句,返回一个记录集。 4.后续处理,这个就自己发挥
Modbus 一个工业上常用的通讯协议 协议包括RTU、ASCII、TCP.其中,RTU最常用,比较简单,在单片机上很容易实现参考:ModBus-RTU详解 MODBUS-RTU通讯协议简介 可能用不到深奥的协议知识: MODBUS协议最简单又是最直白的解释 在线版的手册,将就看:ModBus 协议手册
RTU使用,参考:modbus rtu六种功能码详细解析
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu,modbus_tcp
master = modbus_rtu.RtuMaster(serial.Serial(port="COM16",baudrate=9600, bytesize=8, parity='N', stopbits=1))
# Serial的参数依次为:波特率,数据位,检验方式,停止位(1位)
# 检验方式5种:'N', 'E', 'O', 'M', 'S',代表'None','Even','Odd','Mark','Space'校验
# 详细使用见文末
master.set_timeout(1.0)
read1 = master.execute(50, cst.READ_HOLDING_REGISTERS, 304, 10) # 这里可以修改需要读取的功能码
time_now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
data=[read1[0],read1[4],time_now]
cursor.execute("insert into meter_data(频率,电压,采集时间) values (?, ?, ?)",read1[0], read1[4],time_now)
master.execute参数说明:详细的见参考链接:modbus-master-读写
参数说明: @slave=1 : identifier of the slave. from 1 to 247. @function_code=READ_HOLDING_REGISTERS:功能码 @starting_address=100:寄存器的开始地址 @quantity_of_x=3:寄存器/线圈的数量 @output_value:一个整数或可迭代的值:1/[1,1,1,0,0,1]/xrange(12) @data_format:对接收的数据进行格式化 @expected_length:(没对这个设置过)
一篇比较综合的讲解文章:python modbus 实现RTU 通信 ModBus的主客模拟,参考:Modbus Slave / Poll:用来模拟客户端(从)和Modbus Poll服务端(主) 用python操作,参考这里:python下通过modbus_tk实现modbus主机 又是一个rtu master Modbus_tk在树莓派上实现rtu master 怎么个流程呢,这里有详细知识 Modbus RTU Master开发
游标: 相当于mysql自带的那个客户端的游标mysql> 在这后面输入指令,回车执行
(二)modbus_master_meter
import pymysql
conn=pymysql.connect(host="localhost",port=3306,db="pytest",user="root",password="123456")
#链接,指定ip地址和端口,本机上测试时ip地址可以写localhost或者自己的ip地址或者127.0.0.1,然后你操作数据库的时候的用户名,密码,要指定你操作的是哪个数据库,指定库名,还要指定字符集。不然会出现乱码
cursor=conn.cursor()
cursor.execute('create table temp_data6(id int(4) not null auto_increment,频率 int(2),电压 int(2),采集时间 datetime,primary key(id))')
#执行sql语句
cursor.close() #关闭游标
conn.commit()
#必须执行conn.commit,注意是conn,不是cursor,执行这句提交后才发现表中插入记录成功,没有这句,上面的这几步操作其实都没有成功保存。
conn.close() #关闭连接
参考链接:pymysql模块使用介绍 使用用户名与密码登录的样例:
uname = input('请输入用户名:') #输入的内容是:chao' -- xxx或者xxx' or 1=1 -- xxxxx
pword = input('请输入密码:')
sql = "select * from userinfo where username=%s and password=%s;"
print(sql)
res = cursor.execute(sql,[uname,pword]) #res我们说是得到的行数,如果这个行数不为零,说明用户输入的用户名和密码存在
print(res) #如果输入的用户名和密码错误,这个结果为0,如果正确,这个结果为1
if res:
print('登陆成功')
sql='insert into userinfo(name,password) values(%s,%s);'
res=cursor.executemany(sql,[("root","123456"),("lhf","12356"),("eee","156")])
conn.commit()
参考链接:基本使用
(三) lianxi3模块: 基本完成
ser=serial.Serial("COM4",9600,timeout=6)
# 串口的申请:很多参数,参考下面
print("串口参数:",ser)
r1=ser.read()
r1_list=int.from_bytes(r1,byteorder='big', signed=False)
# 可能类似于r1.decode()
ser.close() # 关闭端口
class serial.Serial的初始化函数:参考链接
__init__(port=None, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE,
timeout=None, xonxoff=False,rtscts=False, write_timeout=None, dsrdtr=False, inter_byte_timeout=None)
port:如COM1,COM2,COM3,COM4......如果port设置为0对应的为COM1
baudrate:设置波特率
bytesize:数据位
stopbits:停止位
timeout:超时时间
timeout = None: 长时间等待
timeout = 0: 不阻塞形式 (读完之后就返回)
timeout = x: x秒后超时 (float allowed)
其他用法:
ser.write("test_chr".encode())
# 串口数据的写入:串口模块内,传输的都是字节数据,所以,在写入数据的时候,不能直接写字符串数据
ser.write(b"1")
#也可尝试:传入2的ASCII码 这里用b+str强制转换
# 串口数据的读取:如需打印,则要解码
msg = ser.read(64) #是读64个字符
print(msg.decode())
print(ser.name,ser.port)#打印设备名称,端口名
ser.open() #打开端口
print(ser.is_open)#检验串口是否打开
data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。
data = ser.readlines()和ser.xreadlines()#都需要设置超时时间
其中,属性既可以读,也可以写,也可以用print(ser)全打:
串行口的属性:name, port:读或者写端口, baudrate:波特率, bytesize:字节大小, parity:校验位, stopbits:停止位, timeout:读超时设置, writeTimeout:写超时, xonxoff:软件流控, rtscts:硬件流控, dsrdtr:硬件流控, interCharTimeout:字符间隔超时,
可以如下设置
ser.baudrate = 9600 #设置波特率(这里使用的是stc89c52)
ser.port = 'COM3' #端口是COM3
一个使用样例:python3中利用serial模块实现
|