Modbus主站获取不了实际从站的数据

发布于 2019-12-04 21:21:32
    本帖最后由 coulson 于 2019-12-4 21:21 编辑


1.刚接触modbus 官方的例程是向从站的寄存器写数据,我先是在官方例程的基础上把写寄存器的程序改成了读寄存器数据的程序,用Modbus Slave做从站和stm32做主站进行测试,在主站的usMRegHoldBuf[ ] [ ]里能看到从站的数据。485_1.png

2.但是在我接真实的传感器从机时,问题出现了,我所要读的传感器的地址为0x0500 我需要在0x0500开始往后读取15个寄存器,于是我的读指令变成了01 03 00 05 00 0F 05 02 ,主站发出的指令确实也是01 03 00 05 00 0F 05 02
主站发出.png
从机的传感器在收到指令后也回复了,但是我再看usMRegHoldBuf[ ] [ ]里的数据全是0,请问这个是什么问题,是因为我传感器的地址为0x0500 ,超过了主站设计的usMRegHoldBuf[ ] [ ]的地址的缘故吗?

3.我把代码放在附件里了,有了解的大神帮忙看一下。附件里上传大文件好像有问题,一直上传不了,我把modbus部分的代码放在附件了


下载附件[sample_mb_master.c]

查看更多

关注者
0
被浏览
551
36 个回答
wwwzxddn
wwwzxddn 2019-12-05
你好,我也遇到了类似的问题,你读完后返回码是什么》?
whj467467222
whj467467222 2019-12-05
正确的调试办法是 查看eMBMasterReqWriteHoldingRegister 这个API的返回值。
不知道调整 user_mb_app.h里面的宏定义能不能解决你的问题
wwwzxddn
wwwzxddn 2019-12-05
static void send_thread_entry(void *parameter)
{
eMBMasterReqErrCode error_code = MB_MRE_NO_ERR;
rt_uint16_t error_count = 0;
while (1)
{
error_code = eMBMasterReqReadHoldingRegister(SLAVE_ADDR, /* salve address */
MB_READ_REG_START, /* register start address */
MB_READ_REG_NUM, /* data to be written */
RT_WAITING_FOREVER); /* timeout */
rt_kprintf("add1--error_code: %d \n",error_code);
rt_kprintf("<%#x><%#x><%#x><%#x>", usMRegHoldBuf[0][1],usMRegHoldBuf[0][2],usMRegHoldBuf[0][3],usMRegHoldBuf[0][4]);



error_code = eMBMasterReqReadHoldingRegister(0x02, /* salve address */
MB_READ_REG_START, /* register start address */
MB_READ_REG_NUM, /* data to be written */
RT_WAITING_FOREVER); /* timeout */
rt_kprintf("add2--error_code: %d \n",error_code);
rt_kprintf("<%#x><%#x><%#x><%#x>", usMRegHoldBuf[1][1],usMRegHoldBuf[1][2],usMRegHoldBuf[1][3],usMRegHoldBuf[1][4]);



/* Record the number of errors */
if (error_code != MB_MRE_NO_ERR)
{
error_count++;
}
}
}
wwwzxddn
wwwzxddn 2019-12-05

缓存的设备ID要减1,就可以了

TIM截图20191205090426.jpg
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 09:06
这个代码测试过了。没问题


ID减一我知道,可是我吧这个buff里全翻了一遍都没发现数据有变动啊
wwwzxddn
wwwzxddn 2019-12-05
查下故障码,是没上来数据,还是数据有误
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 09:42
查下故障码,是没上来数据,还是数据有误


error code 3
coulson
coulson 2019-12-05
coulson 发表于 2019-12-5 09:45
error code 3


typedef enum
{
MB_MRE_NO_ERR, /*!< no error. */
MB_MRE_NO_REG, /*!< illegal register address. */
MB_MRE_ILL_ARG, /*!< illegal argument. */
MB_MRE_REV_DATA, /*!< receive data error. */
MB_MRE_TIMEDOUT, /*!< timeout error occurred. */
MB_MRE_MASTER_BUSY, /*!< master is busy now. */
MB_MRE_EXE_FUN /*!< execute function error. */
} eMBMasterReqErrCode;
这个error code应该是MB_MRE_REV_DATA,数据接收错误?
wwwzxddn
wwwzxddn 2019-12-05
数据格式错误,检查电脑端 modbus slave设置
wwwzxddn
wwwzxddn 2019-12-05
复制我刚才发的那个程序,设置好电脑端就可以运行了。其余都不用修改
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 09:53
数据格式错误,检查电脑端 modbus slave设置


测试modbus slave是没问题的,我是接实际的传感器出现的问题
wwwzxddn
wwwzxddn 2019-12-05
传感器连接串口助手测下
coulson
coulson 2019-12-05
我把传感器正常回复的数据回复给主机,也是error 3
wwwzxddn
wwwzxddn 2019-12-05
调整下波特率和程序种的响应时间
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 10:01
调整下波特率和程序种的响应时间


我传感器上有两个指示灯,分别是TX和RX指示灯,传感器收到指令RX灯亮,指令正确,传感器返回数据时TX灯亮,波特率不正确时通讯不上,波特率这个我改过,问题不在这里,我在想,是不是我回复的数据有问题,因为传感器回复的数据超出数据的范围了,我把回复的数据给你看下
coulson
coulson 2019-12-05
coulson 发表于 2019-12-5 10:06
我传感器上有两个指示灯,分别是TX和RX指示灯,传感器收到指令RX灯亮,指令正确,传感器返回数据时TX灯亮 ...


01 03 1E 00 00 08 38 00 02 00 03 00 01 00 00 00 34 00 03 00 09 00 02 00 00 00 00 00 03 00 0B 00 02 69 26 //传感器返回的数据
01 03 1E //帧头
00 00 08 38 00 02 00 03 00 01 /data1 00 00 正常 08 38 浓度 00 02 小数位2位 00 03 氧气 00 01 %VOL 2104 21.04
00 00 00 34 00 03 00 09 00 02 //data2 00 00 正常 00 34 浓度 00 03 小数位3位 00 09 硫化氢 00 02 PPM 52 0.052
00 00 00 00 00 03 00 0B 00 02 //data3 00 00 正常 00 00 浓度 00 03 小数位3位 00 0B 氨气 00 02 PPM 0 0
69 26 //帧位校验位
coulson
coulson 2019-12-05
coulson 发表于 2019-12-5 10:08
01 03 1E 00 00 08 38 00 02 00 03 00 01 00 00 00 34 00 03 00 09 00 02 00 00 00 00 00 03 00 0B 00 02 ...


我感觉是这个usMRegHoldBuf[ ] [ ]装不下传感器的数据导致这样的问题
wwwzxddn
wwwzxddn 2019-12-05
#define RT_M_REG_HOLDING_NREGS 100

这个的定义是100啊,应该不会超出
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 10:12
#define RT_M_REG_HOLDING_NREGS 100

这个的定义是100啊,应该不会超出


按理说usMRegHoldBuf[0][0]应该存的data1的 00 00 usMRegHoldBuf[0][1]应该存的08 38 就按顺序这样刚好存15个,但是它报错就不知道为什么了
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 10:12
#define RT_M_REG_HOLDING_NREGS 100

这个的定义是100啊,应该不会超出


会不会是因为我每读1个传感器的寄存器,传感器都回复我两个字节的数据,而modbus主机把本来应该存在一起的2个字节的数据分开存在两个数组里,一共有30字节的数据,这样就有15字节的数据没地方放了?
wwwzxddn
wwwzxddn 2019-12-05
用PC端 slave模拟下你这个多字节的传感器
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 10:36
用PC端 slave模拟下你这个多字节的传感器


error2.png
wwwzxddn
wwwzxddn 2019-12-05
slave寄存器不够啊,要和你的传感器一致
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 10:48
slave寄存器不够啊,要和你的传感器一致


我在程序里把寄存器数量改成10个了,slave刚好10个
wwwzxddn
wwwzxddn 2019-12-05
降下波特率到9600 看好多帖子说将波特率能解决问题
coulson
coulson 2019-12-05
wwwzxddn 发表于 2019-12-5 11:09
降下波特率到9600 看好多帖子说将波特率能解决问题


现在的波特率就是9600:P
coulson
coulson 2019-12-05
coulson 发表于 2019-12-5 11:12
现在的波特率就是9600


libmodbus.png兄弟,我决定先用libmodbus测试了,libmodus目前用slave测试一切正常
whj467467222
whj467467222 2019-12-05
coulson 发表于 2019-12-5 11:46
兄弟,我决定先用libmodbus测试了,libmodus目前用slave测试一切正常


MODBUS MASTER支持的寄存器最大改到大于你的地址位置,因为MODBUS MASTER 默认是从1开始到100的,你从0x500开始,那就是访问不够了啊
coulson
coulson 2019-12-05
whj467467222 发表于 2019-12-5 13:26
MODBUS MASTER支持的寄存器最大改到大于你的地址位置,因为MODBUS MASTER 默认是从1开始到100的,你从0x5 ...


嗯嗯,我试一下,我想了很久好像也只有数据存不进数组这一个问题了
coulson
coulson 2019-12-05
coulson 发表于 2019-12-5 13:35
嗯嗯,我试一下,我想了很久好像也只有数据存不进数组这一个问题了


就是前面空了500个不知道会不会影响别的东西
coulson
coulson 2019-12-05
coulson 发表于 2019-12-5 13:36
就是前面空了500个不知道会不会影响别的东西


这500+的buff还是第一次见:lol
MikeCai
MikeCai 2019-12-05
只是看modbus 主从协议还不行,要看具体的传感器所用的协议。
MikeCai
MikeCai 2019-12-05
数据是否加CRC校验,等等。都要看清楚
coulson
coulson 2019-12-05
MikeCai 发表于 2019-12-5 14:18
数据是否加CRC校验,等等。都要看清楚


明白,现在只是读传感器的数据,正在把功能完善

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友