I'm trying to read the Energy meter's registers value using the modbus_master example. The Input Registers of the energy meter starts from 30001 to 30156.
Length of registers: 2
Type of registers: Float (readable only)
baud rate: 9600
Slave ID: 1
In device_param.c I tried changing the values
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 }
But nothing is working I keep geeting this in the console:
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.
how to change this 0x0000?
How to change the address in Modbus_master example?
-
- Posts: 16
- Joined: Wed Jul 22, 2020 1:03 pm
-
- Posts: 211
- Joined: Fri Feb 01, 2019 4:02 pm
- Contact:
Re: How to change the address in Modbus_master example?
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 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 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: 16
- Joined: Wed Jul 22, 2020 1:03 pm
Re: How to change the address in Modbus_master example?
Hello @ESP_alisitsyn
Thank you so much for the detailed explanation.
The code is working. I changed the values of
In the console I'm getting this:
(146520) SENSE_MAIN: cid: 0, Data_channel_0(Volts) = 250.82
Thankyou so much.
Thank you so much for the detailed explanation.
The code is working. I changed the values of
Code: Select all
holding_reg_params_t holding_reg_params = { 4 };
input_reg_params_t input_reg_params = { 3 };
Code: Select all
{ CID_INP_DATA_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 21, 2,
INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
{ CID_HOLD_DATA_0, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 7, 2,
HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
(146520) SENSE_MAIN: cid: 0, Data_channel_0(Volts) = 250.82
Thankyou so much.
-
- Posts: 211
- Joined: Fri Feb 01, 2019 4:02 pm
- Contact:
Re: How to change the address in Modbus_master example?
@lalitahuja33,
Glad to hear it helps!
Glad to hear it helps!
Who is online
Users browsing this forum: No registered users and 176 guests