网站首页 > 教程文章 正文
风向变送器有8方位风向和360度风向两种;
外壳分为铝合金和聚碳两种;
风向传感器/变速器测量方式分为:
- 模拟量(4-20mA/0-5V/0-10V)
- RS485
由于风速和风向变送器是分开的,所以我们选择了RS485总线的测量方式,这样我们将两个模块并到一起,设为不同的地址,这样就可以只占用一个串口资源就可以获取风速和风向的数据了。
应用场景
广泛适用于气象、海洋、环境、机场、港口、实验室、工农业及交通等领域的风速和风向测量。
数据帧格式定义
采用Modbus-RTU 通讯规约,格式如下:
初始结构 ≥4 字节的时间
地址码 = 1 字节
功能码 = 1 字节
数据区 = N 字节
错误校验 = 16 位CRC 码
结束结构 ≥4 字节的时间
地址码:为变送器的地址,在通讯网络中是唯一的(出厂默认0x01)。
功能码:主机所发指令功能指示,本变送器只用到功能码0x03(读取寄存器数据)。
数据区:数据区是具体通讯数据,注意16bits数据高字节在前!
CRC码:二字节的校验码。
注意:此通讯协议只适用于我购买过的那款风速风向仪,不同厂家协议不同。
主机问询帧结构:
地址码 | 功能码 | 寄存器起始地址 | 寄存器长度 | 校验码低位 | 校验码高位 |
1字节 | 1字节 | 2字节 | 2字节 | 1字节 | 1字节 |
从机应答帧结构:
地址码 | 功能码 | 有效字节数 | 数据一区 | 第二数据区 | 第N数据区 | 校验码 |
1字节 | 1字节 | 1字节 | 2字节 | 2字节 | 2字节 | 2字节 |
通讯实例:
读取设备地址0x01的风向
问询帧:
地址码 | 功能码 | 起始地址 | 数据长度 | CRC低位 | CRC高位 |
0x01 | 0x03 | 0x00 0x00 | 0x00 0x02 | 0xC4 | 0x0B |
应答帧:(例如读到风向值(0-7档)为2,(0-360°)为90°)
地址码 | 功能码 | 返回字节数 | 风向(0-7档) | 风向(0-360°) | CRC低位 | CRC高位 |
0x01 | 0x03 | 0x04 | 0x00 0x02 | 0x00 0x5A | 0xDB | 0xC8 |
风向计算:
(0-7档):0002H(十六进制)= 2=> 风向 = 东风
(0-360°):005AH (十六进制)= 90=> 风向= 东风
读取设备地址0x01的风速值
问询帧:
地址码 | 功能码 | 起始地址 | 数据长度 | CRC低位 | CRC高位 |
0x01 | 0x03 | 0x00 0x00 | 0x00 0x01 | 0x84 | 0x0A |
应答帧:(例如读到当前风速为8.6m/s)
地址码 | 功能码 | 返回字节数 | 当前风速值 | CRC低位 | CRC高位 |
0x01 | 0x03 | 0x02 | 0x00 0x56 | 0x38 | 0x7A |
风速计算:
当前风速:0056H(十六进制)= 86=> 风速 = 8.6m/s
硬件连接
- 风速和风向变速器12V供电;
- 我们使用一个485接口,将风速和风向变速器并联到了一起。
由于RS485的子设备之间的设备地址不能相同,所以我们将风速仪的地址设为了1,风向仪的地址设为了2。
RS485总线参考电路
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!
无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。
点击这里找小助理0元领取:加微信领取资料
要想获取风速或风向值,我们要经过如下三步操作:
(1)发送问询帧:
if(times%10==1)
{
times2++;
if(times2%10==0)
{
//求风速
sprintf(dtbuf, "%c%c%c%c%c%c%c%c", 0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A);
MAX485DE=1;
USART2_OUT((u8 *)dtbuf, 8);
MAX485DE=0;
}
else if(times2%10==5)
{
//求风向
sprintf(dtbuf, "%c%c%c%c%c%c%c%c", 0x02,0x03,0x00,0x00,0x00,0x02,0xC4,0x38);
MAX485DE=1;
USART2_OUT((u8 *)dtbuf, 8);
MAX485DE=0;
}
}
(2)接收串口数据:
u16 USART2_RX_STA=0;
void USART2_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
res =USART_ReceiveData(USART2);
if(USART2_RX_STA<USART2_MAX_RECV_LEN)
{
TIM_SetCounter(TIM2,0);
if(USART2_RX_STA==0)
TIM2_Set(1);
USART2_RX_BUF[USART2_RX_STA++]=res;
}
else
{
USART2_RX_STA|=1<<15;
}
}
}
(3)解析数据帧:
//解析RS485信息
if(USART2_RX_STA&0x8000)
{
uart2Len=USART2_RX_STA&0x3f;
if(uart2Len==7)
{
nCRC16 = crc16(USART2_RX_BUF,5);
checkBitHig=(nCRC16>>8)&0xFF;
checkBitLow=nCRC16&0xFF;
if(checkBitHig==USART2_RX_BUF[5]&&checkBitLow==USART2_RX_BUF[6])
{
printf("收到风速数据包\r\n");
u16Value = USART2_RX_BUF[3] * 256 + USART2_RX_BUF[4];
stuAliOSIoT.WindSpeed = u16Value/10.0;
}
}
else if(uart2Len==9)
{
nCRC16 = crc16(USART2_RX_BUF,7);
checkBitHig=(nCRC16>>8)&0xFF;
checkBitLow=nCRC16&0xFF;
if(checkBitHig==USART2_RX_BUF[7]&&checkBitLow==USART2_RX_BUF[8])
{
printf("收到风向数据包\r\n");
stuAliOSIoT.WindDirection = USART2_RX_BUF[4];
}
}
USART2_RX_STA=0;
memset(USART2_RX_BUF, 0, sizeof(USART2_RX_BUF));
}
上面函数返回的数据帧,首先要对返回的数据进行CRC校验,只有合法的数据帧我们才会对数据帧进行解析,防止出现脏包。
文章链接:
https://mp.weixin.qq.com/s/HxmNOIvTEwLR4JVBzf5LoA
转载自:嵌入式从0到1 ,作者程序员XiaoHa
文章链接:485型风速和风向变送器数据包解析
- 上一篇: 毕业设计|语音识别智能家居制作
- 下一篇: 基于STM32的自动跟踪小车
猜你喜欢
- 2025-01-04 基于stm32的车辆减速灯项目——MPU6050或ADXL345
- 2025-01-04 基于STM32的自动跟踪小车
- 2025-01-04 Cortex-M3之串口与超级终端间发送与接收(STM32)
- 2025-01-04 毕业设计|语音识别智能家居制作
- 2025-01-04 《STM32电子DIY》Lora模块SX1278通信
- 2025-01-04 FreeRTOS:Queue队列及队列API函数
- 2025-01-04 STM32调试蓝牙平衡小车及bug处理
- 2025-01-04 嵌入式软件开发常用的三种架构你知道吗?
- 2025-01-04 stm32使用MPU6050或ADXL345控制的车辆减速灯
- 2025-01-04 「正点原子STM32Mini板资料连载」第三十章 PS2 鼠标实验
- 最近发表
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)