手搓modbus485串口脚本

手搓一个小型气象站数据通过串口获取数据。

python先pip install serial模块,并在脚本引入进来

import serial
import time

# 打开串口, COM8, 9600波特率, 8数据位, 1停止位, 无校验
ser = serial.Serial('COM8', 9600, parity=serial.PARITY_NONE, bytesize=serial.EIGHTBITS, stopbits=serial.STOPBITS_ONE)

# 检查串口是否已经打开
if ser.is_open:
    print('串口已成功打开.')

try:
    # 要发送的Modbus数据(包括CRC校验,这里需要验证CRC是否正确)
    data_to_send = [0x01, 0x03, 0x00, 0x00, 0x00, 0x06]  # 假设这是正确的数据部分,不包括CRC
    # 注意:这里应该计算CRC并附加到data_to_send列表的末尾
    # crc_value = calculate_crc(data_to_send[:-2])  # 假设calculate_crc是一个计算CRC的函数
    # data_to_send.extend(crc_value)  # 假设crc_value是一个包含两个字节的列表
    # 由于我们没有实际的CRC计算函数,这里暂时使用您提供的CRC值(需要验证)
    data_to_send.extend([0xC5, 0xC8])  # 临时CRC值,需要验证

    while True:
        ser.write(bytes(data_to_send))
        print('发送成功')

        # 读取Modbus响应(这里假设响应格式正确且没有错误)
        response = ser.read(9)  # 假设响应包括1字节地址、1字节功能码、1字节数据长度和6字节数据(2个寄存器,每个2字节)
        if len(response) != 9:
            print("响应长度不正确")
            continue

        address, function_code, data_length = response[:3]
        data = response[3:]

        address_int = int.from_bytes([address], byteorder='big')
        function_code_int = int.from_bytes([function_code], byteorder='big')
        data_length_int = int.from_bytes([data_length], byteorder='big')

        # 检查功能码是否有错误标志
        if function_code_int & 0x80:
            print("Modbus功能码错误")
            continue

        # 解析数据(这里假设是4个16位寄存器,即8字节数据)
        humidity = int.from_bytes(data[:2], byteorder='big')
        temperature = int.from_bytes(data[2:4], byteorder='big')
        pressure = int.from_bytes(data[4:6], byteorder='big')
        noise = int.from_bytes(data[6:], byteorder='big')

        # 注意:这里的变量命名和计算可能需要根据实际情况调整
        print('地址:', address_int)
        print('功能码:', function_code_int & 0x7F)  # 清除错误标志位
        print('数据字节数:', data_length_int)
        print("湿度: ", humidity * 0.01, "%")
        print('温度:', temperature * 0.1, "°C")  # 这里假设温度数据需要乘以0.1
        print('大气压:', pressure)  # 这里可能需要根据实际单位进行调整
        print('噪声:', noise)  # 这里可能需要根据实际单位进行调整

        time.sleep(0.1)

except serial.SerialException as e:
    print(f"串口错误: {e}")
except KeyboardInterrupt:
    print("程序被用户中断")
finally:
    if ser.is_open:
        ser.close()
        print("串口已关闭")

对于每个数据位进行截取,有些数据还得通过计算才能输出出来,只是测试脚本。

另一个是获取车载定位数据的串口脚本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值