Nick-ccq 发表于 2023-9-1 18:21:29

行空板如何获取RS485设备数据 - RS485风速变送器

## 行空板如何获取RS485设备数据 - **RS485风速变送器**                                                                                                                        

## 1-介绍:RS-485协议

RS-485协议,是一种串行通信协议,用于在多个设备之间进行数据传输。它是一种差分信号通信协议,可以实现长距离、高速、可靠的数据传输。

RS-485协议使用两根传输线(A线和B线)进行数据传输,其中一个设备充当主设备,其他设备充当从设备。主设备负责控制通信的开始和结束,以及数据的传输速率。从设备只有在主设备允许的情况下才能发送数据。

RS-485协议具有以下特点:

- 高速传输:RS-485协议支持较高的数据传输速率,可以达到几十兆比特每秒的速度。

- 远距离传输:由于差分信号的使用,RS-485协议可以在较长的距离上进行数据传输,通常可覆盖数千米的距离。
- 抗干扰能力强:RS-485协议采用差分信号传输,可以有效地抵抗电磁干扰和噪声,提供可靠的数据传输。

- 多设备通信:RS-485协议支持多个设备之间的通信,主设备可以与多个从设备进行双向通信。

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/49c34ee76de1dd03524513874b296c65.png)

## 2-以RS485风速传感器为例((https://www.dfrobot.com.cn/goods-3195.html)):

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/5e9ccf9fcd6b24708bb0c7442f0080f6.png)

详细wiki介绍:(https://wiki.dfrobot.com.cn/SKU_SEN0483_RS485_Wind_Speed_Transmitter)

从wiki中可以得到这个传感器的一些关键信息:

### 2.1-线色说明

| 颜色 | 功能      |
| :--- | :---------- |
| 红色 | 电源正      |
| 黑色 | 电源负      |
| 黄色 | RS485+/A/T+ |
| 绿色 | RS485-/B/T- |

### 2.2-通讯协议:

- 主机(在这里是行空板)通过串口(使用串口转rs485模块)与从机(这里是风速传感器)通信,波特率为 9600 bps。

**通讯方式很简单**:主机按照协议发一串查询数据给从机,从机接受到查询指令后将风速数据返回给主机,然后主机接受到数据解析就可以得到风速值了。


读寄存器0x0000,即风速的测量值

- 主机查询帧(16进制):02 03 00 00 00 01 84 39(8byt)

| 从机地址 | 功能码 | 寄存器起始地址 | 寄存器长度 | 校验码高位 | 校验码低位 |
| :------- | :----- | :------------- | :--------- | :--------- | :--------- |
| 1byt   | 1byt   | 2byt         | 2byt       | 1byt       | 1byt       |
| 0x02   | 0x03   | 0x00 0x00      | 0x00 0x01| 0x84       | 0x39       |

- 从机应答帧(16进制):02 03 02 00 25 3D 9F(7byt)

| 从机地址 | 功能码 | 有效字节数 | 数据区    | 校验码高位 | 校验码低位 |
| :------- | :----- | :--------- | :-------- | :--------- | :--------- |
| 1byt   | 1byt   | 1byt       | 2byt      | 1byt       | 1byt       |
| 0x02   | 0x03   | 0x02       | 0x00 0x25 | 0x3D       | 0x9F       |

风速值为(16进制,原码)00 25 = 0x0025 = 37,那么风速测量值为37 / 10 = 3.7m/s

因此,要获取风速测量值,主机需要通过串口发送查询帧,并解析从机应答帧中的数据。

## 3-行空板串口通讯:

在行空板上有两种方法可以引出串口:
-1、USB接口插一个USB串口转RS
485模块( https://www.dfrobot.com.cn/goods-2997.html )

- 2、使用行空板金手指上的UART串口(P0和P3),然后使用一个UART转RS485模块( https://www.dfrobot.com.cn/goods-3283.html )

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/1dd50d97cda7d93b47d6962cfdcfedda.png)

前面介绍了**RS485风速变送器**的通讯协议,接下来将两种方法的使用步骤进行介绍。

## 3.1-使用USB串口通讯

### 3.1.1-USB转485模块和行空板接线图

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/a6fa56ea14b628b143bd16dc52178e85.png)





### 3.1.2-接线说明

根据接线说明,把**RS485风速变送器**其中的黄色和绿色分别接到**USB转485模块**A/B,需要注意电压问题:

- **RS485风速变送器**供电电压:7-24V
- **USB转485模块**供电电压:5V

因此需要额外外接电源,测试中我使用的使用12V电源。

### 3.1.3-编程

全部接好以后,就直接插上行空板USB,进行编程.

示例代码:

```python
import serial
import time
#使用的是USB转串口,因此不需要使用pinpong库
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.5) #USB转RS485模块的串口编号

while True:
    query_frame = # 查询帧
    ser.write(query_frame)
    time.sleep(1)
    try:
      response_frame = ser.read(7)# 读取从机应答帧,根据应答帧格式修改字节数
      byte4 = response_frame# 获取第4位数据
      byte5 = response_frame# 获取第5位数据

      value = ((byte4 << 8) + byte5) / 10 #根据风速传感器说明计算风速值
   
      print("风速值:", value)

      time.sleep(0.1)
    except:
      print("无数据")


```

测试结果:

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/7ff0deb4546f8949849b56ef509c8089.png)

### 3.1.4-数据校验
上面的案例中,我们直接读取了第4和5位获取风速值,实际上在通讯中可能会存在数据丢失一部分的情况,因此从机返回的数据里面还有校验码,通过将接收到的数据做计算与校验码比对,可以确保接收到的数据是正确的。

- 示例代码:

```python
import serial
import time

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.5)

def calculate_checksum(data):
    checksum = 0xFFFF# 初始校验码值

    for byte in data:
      checksum ^= byte# 异或操作
      for _ in range(8):
            if checksum & 0x0001:# 最低位为1
                checksum >>= 1# 右移一位
                checksum ^= 0xA001# 异或操作
            else:
                checksum >>= 1# 右移一位

    return checksum.to_bytes(2, byteorder='little')# 返回校验码的字节表示,小端序

def validate_response_frame(frame):
    if len(frame) < 5:
      return False
    received_checksum = frame[-2:]# 从应答帧中提取接收到的校验码
    expected_checksum = calculate_checksum(frame[:-2])# 计算期望的校验码
    return received_checksum == expected_checksum
while True:
    query_frame =    # 查询帧

    ser.write(query_frame)# 发送查询帧
    time.sleep(0.1)
    try:
      response_frame = ser.read(7)# 读取从机应答帧
      if validate_response_frame(response_frame):
            byte4 = response_frame# 获取第4位数据
            byte5 = response_frame# 获取第5位数据

            value = (( byte4<< 8) + byte5) / 10
            print("风速值:", value)
      else:
            print("应答帧校验失败")
      time.sleep(0.1)
    except:
      print("无数据")


```

测试结果:

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/01fd01ad7f78523055124b960ffe933e.png)

## 3.2-使用金手指上的UART引脚通讯

### 3.2.1-RS485转UART和行空板接线图

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/c0190134bec1e938ed16638841347a13.png)

### 3.2.2-接线说明

- 需要外部供电12V

### 3.2.3-编程

示例代码:

```python
# -*- coding: utf-8 -*-
import time
from pinpong.board import Board, UART
#使用的是行空板金手指上的UART口,因此使用pinpong库
Board().begin()#初始化,选择板型,不输入板型则进行自动识别
#硬串口1 P0-RX P3-TX
uart1 = UART(0)   
uart1.init() #默认波特率为9600

while True:
    query_frame = # 查询帧
    uart1.write(query_frame)
    time.sleep(1)
    try:
      response_frame = uart1.read(7)# 读取从机应答帧,根据应答帧格式修改字节数
      byte4 = response_frame# 获取第4位数据
      byte5 = response_frame# 获取第5位数据
      value = ((byte4 << 8) + byte5) / 10
   
      print("风速值:", value)

      time.sleep(0.1)
    except:
      print("无数据")

```

测试结果:

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/55f3ab18ee16e561934a0eedb322cc54.png)

### 3.2.4-数据校验
通过校验码,来确定数据的准确性,示例代码:

```python
import time
from pinpong.board import Board, UART
Board().begin()# 初始化,选择板型,不输入板型则进行自动识别
# 硬串口1 P0-RX P3-TX
uart1 = UART(0)
uart1.init()# 默认波特率为9600


def calculate_checksum(data):
    checksum = 0xFFFF# 初始校验码值

    for byte in data:
      checksum ^= byte# 异或操作
      for _ in range(8):
            if checksum & 0x0001:# 最低位为1
                checksum >>= 1# 右移一位
                checksum ^= 0xA001# 异或操作
            else:
                checksum >>= 1# 右移一位

    return checksum.to_bytes(2, byteorder='little')# 返回校验码的字节表示,小端序

def validate_response_frame(frame):
    if len(frame) < 5:
      return False
    received_checksum = frame[-2:]# 从应答帧中提取接收到的校验码
    expected_checksum = calculate_checksum(frame[:-2])# 计算期望的校验码
    return received_checksum == expected_checksum


while True:
    query_frame =    # 查询帧
    uart1.write(query_frame)# 发送查询帧
    time.sleep(0.1)
    try:
      response_frame = uart1.read(7)# 读取从机应答帧

      if validate_response_frame(bytes(response_frame)): # 与USB通讯不一样的,需要转化成字节串
            byte4 = response_frame# 获取第4位数据
            byte5 = response_frame# 获取第5位数据
            

            value = (( byte4<< 8) + byte5) / 10
            print("风速值:", value)
      else:
            print("应答帧校验失败")
      time.sleep(0.1)
    except:
      print("无数据")

```

测试结果:

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/f21d76c5e3467673cb33b098fc0b70ff.png)

## 4-常见问题:

## 如何查看usb转rs485模块的串口号

在行空板终端使用如何命令可以查看所有的串口编号,通过把USB转485插上查询一次,拔掉查询一次,多出来的串口就是这个模块的串口号。
```
ls /dev/tty*
```

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/b7e794920783b3e53e16dd595e6613d8.png)



有的USB转rs485模块使用的驱动在行空板上没有,例如PL2303驱动,则通过上述方法无法查询到串口,这里提供一下PL2303驱动的安装方法,如果找到串口了可忽略下文:

把附件**PL2303G_Unihiker_Driver.zip**放进行空板根目录后,输入下面命令:

```
unzip PL2303G_Unihiker_Driver.zip
```

```
cd PL2303G_Unihiker_Driver
```

```
chmod 777 install.sh
```

```
bash install.sh
```

输入最后一条指令会出现以下:

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/4f3e50227acee00d27a0cd946fcdcb02.png)

再次查询

```
ls /dev/tty*
```

出现下图,说明安装成功

![](https://img.dfrobot.com.cn/wiki/5d11bab74db88f1df9d7e8fb/637476445bba365754724d4b38a3596c.png)



IvanDMido 发表于 2023-9-4 16:05:06

{:6_209:}{:6_209:}{:6_209:}
页: [1]
查看完整版本: 行空板如何获取RS485设备数据 - RS485风速变送器