这里记录 micropython 485从机的驱动类,由于是自己写的所以可读性不强,大概率还是我自己用用
- slave.py文件如下,放在主文件同级目录下
"""
#from slave import slave485
#from esp32 import NVS
#slaveCtr= slave485(U1)
#关于主机请求从机的数据
#slaveCtr.recData(*data)#这里就循环调用就可以持续监听了,因为是轮询串口所以可靠性差一点,
# 其他程序不要太耗时就行,作为从机无非就是两件事,主机来要数据和主机送来数据,对于主机要数据的情况,我们可以传入任意个数的数据来给主机读取,例如:
# slaveCtr.recData(数据1,数据2,....,数据n)
# 比如: slaveCtr.recData(5,6,7,8) 这个都可以我写了自适应逻辑,程序自己会识别主机要几个数据然后给主机发过去,如果你给的数据不够则空余位置会补上-1这个值,给主机发回去
#关于主机送来数据给从机的情况,我们作为从机要保持串口轮询这个状态是对的就是不停的调用上面的slaveCtr.recData(*data)
#此状态下如果主机送来数据直接调用:
#rec_data=slaveCtr.recData_4Data
#主机给的数据这里就会有,如果主机没给数据,这里的数据就是[-1,-1,-1,-1]
#这里也写了自适应逻辑,可以自动判断传进来任意个偶个数的数据返回列表,列表自适应。
#NVS这个是非易失存储用来存设备地址,没有地址自动定为1号
#因为结合西门子200PLC写的所以是根据modbusRTU来写的从机设备
"""
import time
import struct,time
from machine import UART,I2C,Pin
from crc_esp32 import CRC_esp32
from esp32 import NVS
class slave485(object):
def __init__(self,u1):
self.local=NVS('local')
self.u1=u1
self.crc=CRC_esp32()
self.recData_4Data=[-1,-1,-1,-1]
try:
self.addr=self.local.get_i32('addr')
except:
self.local.set_i32('addr',1)
self.local.commit()
self.addr=1
def recData(self,*data_a):
if self.u1.any()>0:
recData=self.u1.read()
recDataCrc=self.crc.into(recData[:-2])
if recDataCrc == recData:
if len(recData)==8:
recDataList=struct.unpack('>6b',recData)
if recDataList[0]==self.addr and recDataList[1]==3 :
if len(data_a)== recDataList[5]:
data_ture=data_a
elif len(data_a) > recDataList[5]:
data_ture=data_a[:recDataList[5]]
elif len(data_a) < recDataList[5]:
data_ture=list(data_a)
while len(data_ture) < recDataList[5]:
data_ture.append(-1)
sendDataList=[self.addr,3,recDataList[5]*2]
sendDataList.extend(data_ture)
sendData=struct.pack('>3b%dh'%recDataList[5],*sendDataList)
print(self.crc.into(sendData))
time.sleep_ms(10)
self.u1.write(self.crc.into(sendData))
print(sendData)
if recDataList[0]==0 and recDataList[1]==6:
self.local.set_i32('addr',recDataList[5])
self.local.commit()
self.addr=recDataList[5]
if len(recData)== (7+recData[6]+2):
recDataList=struct.unpack('>7b%dhbb'%recData[5],recData)
if recDataList[0]==self.addr and recDataList[1]==16 :
self.recData_4Data= recDataList[7:-2]
crc_esp32.py
import struct
import binascii
class CRC_esp32():
def __init__(self):
pass
def calculateCRC(self,dataarray):
datalist = dataarray
date03=dataarray[:]
try:
print (u'对应的序列:{0}'.format(datalist))
temp = self.calculateonebyte(datalist.pop(0), 0xFFFF)
for data in datalist:
temp = self.calculateonebyte(data,temp)
date03.append(temp&0xff)
date03.append(temp>>8)
return date03
except:
pass
def calculateonebyte(self,databyte, tempcrc):
"""
计算1字节数据的CRC值
:param databyte: 需计算的字节数据
:param tempcrc: 当前的CRC值
:return: 当道新的CRC值
"""
if not 0x00 <= databyte <= 0xFF:
raise Exception((u'数据:0x{0:<02X}不是字节数据[0x00-0xFF]'.format(databyte)).encode('utf-8'))
low_byte = (databyte ^ tempcrc) & 0x00FF
resultCRC = (tempcrc & 0xFF00) | low_byte
for index in range(8):
if resultCRC & 0x0001 == 1:
resultCRC >>= 1
resultCRC ^= 0xA001
else:
resultCRC >>= 1
return resultCRC
def into(self,strr):
into0=self.calculateCRC(list(struct.unpack('%dB'%len(strr),strr)))
into0=struct.pack('%dB'%len(into0),*into0)
return into0
"""
# 用into 输入流输出流
# import crc_esp32
# x1=CRC_esp32()
# xx=x1.into(b'\x01\x05\x00\x02\xff\x00')
# print(xx)
# -------------or or or --------------------
# 用calculateCRC 输入列表输出列表
# import crc_esp32
# x1=CRC_esp32()
# xx=x1.calculateCRC([1,5,0,2,255,0])
# print(xx)==>[1, 5, 0, 2, 255, 0, 45, 250]
"""