我正在尝试使用modbus_master示例读取电表的寄存器值。电表的输入寄存器从30001到30156。
寄存器长度:2
寄存器类型:浮点型(只读)
波特率:9600
从站ID:1
在device_param.c中,我尝试更改值
const mb_parameter_descriptor_t device_parameters[] = {
// { Cid, Param Name, Units, Modbus Slave Addr, Modbus Reg Type, Reg Start, Reg Size, Instance Offset, Data Type, Data Size, Parameter Options, Access Mode}
// Parameter: Data channel 0 : Data channel 0 = Voltage
{ CID_DATA_CHAN_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x30021,2,
INPUT_OFFSET(data_chan0), PARAM_TYPE_FLOAT, 2, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
{ CID_HUMIDITY_1, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x30021, 2,
HOLD_OFFSET(mb_device1_humidity), PARAM_TYPE_FLOAT, 2, OPTS( 0, 65535, 1 ), PAR_PERMS_READ },
// Parameter: Temperature_2 : Temperature from device slave address = 1
{ CID_TEMPERATURE_1, STR("Temperature_1"), STR("°C"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x30021, 2,
HOLD_OFFSET(mb_device1_temperature), PARAM_TYPE_FLOAT, 2, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
// Parameter: Humidity_2 : Humidity from device slave address = 2
{ CID_HUMIDITY_2, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x30021, 2,
HOLD_OFFSET(mb_device2_humidity), PARAM_TYPE_FLOAT, 2, OPTS( 0, 100, 1 ), PAR_PERMS_READ },
// Parameter: Temperature_2 : Temperature from device slave address = 2
{ CID_TEMPERATURE_2, STR("Temperature_2"), STR("°C"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x30021, 2,
HOLD_OFFSET(mb_device2_temperature), PARAM_TYPE_FLOAT, 2, OPTS( -40, 80, 1 ), PAR_PERMS_READ }
但是什么都没用,我在控制台中一直坚持下去:
I (473) sense_main: Characteristic (Data_channel_0) data = 0x0000 read successful.
E (623) MB_CONTROLLER_MASTER: mbc_master_get_parameter(111): SERIAL master get parameter failure error=(0x107).
E (623) sense_main: Characteristic (Humidity_1) read value fail, err = 259 (ESP_ERR_INVALID_STATE).
I (693) sense_main: Characteristic (Temperature_1) data = 0x0000 read successful.
E (853) MB_CONTROLLER_MASTER: mbc_master_get_parameter(111): SERIAL master get parameter failure error=(0x107).
E (853) sense_main: Characteristic (Humidity_2) read value fail, err = 259 (ESP_ERR_INVALID_STATE).
I (923) sense_main: Characteristic (Temperature_2) data = 0x0000 read successful.
如何更改此0x0000?
如何在Modbus_master示例中更改地址
-
- Posts: 211
- Joined: Fri Feb 01, 2019 4:02 pm
- Contact:
Re: 如何在Modbus_master示例中更改地址
Hello @ lalitahuja33,
You can not read the registers because you configured the data dictionary of master incorrectly. The address 30001 - means input register with address 0. The 30156 - means the input register with address 155. The Reg Start field in the data dictionary is uint16_t but you put there 0x30021 = 0x0021 and type of register is MB_PARAM_INPUT.
The specific register within the function is referenced by an offset (starting at 0). This is the actual data which is transmitted during the data query. At some point, certain PLC manufacturers starting using a “3xxxx” or “4xxxx” reference designation in an attempt to provide an absolute address to the register (ie: which would reference both the function and the register). Note however, that it is counter-intuitive since the “3x” references function 04 (Read Input Register) and the “4x” references function 03 (Read Holding Register), which furthers confusion.
Register types:
0x = Coil
1x = Discrete Input
3x = Input Register
4x = Holding Register
The Data Size = 2 bytes instead of 4 bytes for PARAM_TYPE_FLOAT type.
This is why you are able to read the temperature parameters as 0x0000 from input register 0x0021 (there is the input parameter in the device with address) and you it is stored just 2 bytes of data.
The correct configuration should be like: Read 2 input registers from address 21 (or 20) depending of your device and store them as float value in input_regs.data_chan0, instance size is 4 bytes.
You can not read the registers because you configured the data dictionary of master incorrectly. The address 30001 - means input register with address 0. The 30156 - means the input register with address 155. The Reg Start field in the data dictionary is uint16_t but you put there 0x30021 = 0x0021 and type of register is MB_PARAM_INPUT.
The specific register within the function is referenced by an offset (starting at 0). This is the actual data which is transmitted during the data query. At some point, certain PLC manufacturers starting using a “3xxxx” or “4xxxx” reference designation in an attempt to provide an absolute address to the register (ie: which would reference both the function and the register). Note however, that it is counter-intuitive since the “3x” references function 04 (Read Input Register) and the “4x” references function 03 (Read Holding Register), which furthers confusion.
Register types:
0x = Coil
1x = Discrete Input
3x = Input Register
4x = Holding Register
The Data Size = 2 bytes instead of 4 bytes for PARAM_TYPE_FLOAT type.
This is why you are able to read the temperature parameters as 0x0000 from input register 0x0021 (there is the input parameter in the device with address) and you it is stored just 2 bytes of data.
The correct configuration should be like: Read 2 input registers from address 21 (or 20) depending of your device and store them as float value in input_regs.data_chan0, instance size is 4 bytes.
Code: Select all
const mb_parameter_descriptor_t device_parameters[] = {
{ CID_DATA_CHAN_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 21, 2,
INPUT_OFFSET(data_chan0), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
...
}
-
- Posts: 211
- Joined: Fri Feb 01, 2019 4:02 pm
- Contact:
Re: 如何在Modbus_master示例中更改地址
The updated link: viewtopic.php?f=2&t=17797&hilit=modbus
Who is online
Users browsing this forum: No registered users and 93 guests