How to change the address in Modbus_master example?

lalitahuja33
Posts: 16
Joined: Wed Jul 22, 2020 1:03 pm

How to change the address in Modbus_master example?

Postby lalitahuja33 » Tue Oct 20, 2020 2:23 pm

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?

ESP_alisitsyn
Posts: 203
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: How to change the address in Modbus_master example?

Postby ESP_alisitsyn » Tue Oct 20, 2020 3:58 pm

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.

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 },
...
}

lalitahuja33
Posts: 16
Joined: Wed Jul 22, 2020 1:03 pm

Re: How to change the address in Modbus_master example?

Postby lalitahuja33 » Wed Oct 21, 2020 10:25 am

Hello @ESP_alisitsyn

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 },
In the console I'm getting this:

(146520) SENSE_MAIN: cid: 0, Data_channel_0(Volts) = 250.82

Thankyou so much.

ESP_alisitsyn
Posts: 203
Joined: Fri Feb 01, 2019 4:02 pm
Contact:

Re: How to change the address in Modbus_master example?

Postby ESP_alisitsyn » Mon Oct 26, 2020 12:44 pm

@lalitahuja33,

Glad to hear it helps!

Who is online

Users browsing this forum: davidv, Google [Bot], Majestic-12 [Bot] and 109 guests