How to program Modbus Master

edveralli
Posts: 1
Joined: Thu Jan 31, 2019 2:28 am

How to program Modbus Master

Postby edveralli » Thu Jan 31, 2019 2:37 am

Hello everybody,

I am trying to figure how to program an ESP32 as a Master Modbus device.
The code I found in the esp sdk (mbcontroller.h) seems to be only for the Slave.

Can you help me with a code example of the Master Modbus ?
I can program in Arduino IDE or with the C Espressif toolchain as well.


I appreciate your help.
Best regards,
Eduardo
Buenos Aires, Argentina

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

Re: How to program Modbus Master

Postby ESP_alisitsyn » Mon Feb 04, 2019 8:48 am

Hello Eduardo,

There are plans to support Modbus Master RTU and TCP in ESP-IDF v4.0, but it was postponed. However there is a "Work In Progress" version of Modbus Master and Slave with examples. I can share it with you. Would you like to get the WIP implementation or it is ok for you to wait for official release?

--
Alexey

Adham Aboud
Posts: 45
Joined: Mon Apr 30, 2018 5:32 pm

Re: How to program Modbus Master

Postby Adham Aboud » Sun Mar 17, 2019 9:47 am

Hello Alexy,

Could you please share the WIP implemenation for the Modbus mater RTU with me also ?

Thank you in advance,
Adham
ESP_alisitsyn wrote:
Mon Feb 04, 2019 8:48 am
Hello Eduardo,

There are plans to support Modbus Master RTU and TCP in ESP-IDF v4.0, but it was postponed. However there is a "Work In Progress" version of Modbus Master and Slave with examples. I can share it with you. Would you like to get the WIP implementation or it is ok for you to wait for official release?

--
Alexey

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

Re: How to program Modbus Master

Postby ESP_alisitsyn » Mon Mar 18, 2019 10:04 am

Hello Adham,

Sure, I can share the implementation with you. Please find this topic and WIP implementation there:
https://www.esp32.com/viewtopic.php?f=1 ... ter+modbus
The official support will be released later but API should be unchanged. It includes IDF component with common interface for Modbus Master and Slave. Please use it with official Espressif license.

--
Alexey

Adham Aboud
Posts: 45
Joined: Mon Apr 30, 2018 5:32 pm

Re: How to program Modbus Master

Postby Adham Aboud » Thu Mar 28, 2019 9:54 am

Thank you Alexy
ESP_alisitsyn wrote:
Mon Mar 18, 2019 10:04 am
Hello Adham,

Sure, I can share the implementation with you. Please find this topic and WIP implementation there:
https://www.esp32.com/viewtopic.php?f=1 ... ter+modbus
The official support will be released later but API should be unchanged. It includes IDF component with common interface for Modbus Master and Slave. Please use it with official Espressif license.

--
Alexey

protest_the_gyro
Posts: 3
Joined: Fri Sep 13, 2019 5:19 pm

Re: How to program Modbus Master

Postby protest_the_gyro » Fri Sep 13, 2019 5:26 pm

Hello Alexey,

I appreciate your sharing of the WIP modbus master code here, and was wondering if you could answer a question regarding the code here? It seems whenever my CID table contains more than 32 elements, I start getting assertion failures in the freertos queue implementation when trying to read certain registers. Some still work fine, and it always fails on the same registers, but shrinking down the CID table back to a size of 32 or less, results in all registers reading correctly.

Thanks,
Spencer

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

Re: How to program Modbus Master

Postby ESP_alisitsyn » Mon Sep 16, 2019 9:42 am

Hello Spencer,

Thank you for this question. I think I know what is the reason for this issue. However could you make some change in your code to help me check this bug?

Please in the your device_params.c file in the device_parameters[] table change the offset to parameter instance to 0 (HOLD_OFFSET(par_name) change to 0 for all the parameters). This will allow to create instance for each parameter on the fly. Below is the example:
```
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, 0, 2,
0, PARAM_TYPE_FLOAT, 4, OPTS( -10, 10, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HUMIDITY_1, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0, 2,
0, PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
{....... all other parameters in your table with 0 offset to instance.... but more than 32 elements}
};
```
Then compile master example, flash it into board and check communication again. Let me know the result.

Thank you.

--
Alex

protest_the_gyro
Posts: 3
Joined: Fri Sep 13, 2019 5:19 pm

Re: How to program Modbus Master

Postby protest_the_gyro » Mon Sep 16, 2019 11:31 pm

Hey Alex,

Thank you for the response. That does fix the modbus code. It seems the one of the instance pointers is being calculated incorrectly, and the line ```memset((void*)value_ptr, 0, cid_info->instance_size);``` in ```sense_modbus_read_value``` partially overwrites a pointer tied to one of my characteristics.

Best,
Spencer

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

Re: How to program Modbus Master

Postby ESP_alisitsyn » Tue Sep 17, 2019 7:32 am

Hi Spencer,

Thank you. Unfortunately this is a bug in the code that came after rebase and squesh of some commits during development. The root reason is in sense_modbus.c file in function ```sense_modbus_get_param_data(const mb_parameter_descriptor_t* param_descriptor)```. It calculates instance address based on offset of parameter incorrectly because of bug during squesh. In order to fix it temporary, please change its code to:
```
// The function to get pointer to parameter storage (instance) according to parameter description table
static void* sense_modbus_get_param_data(const mb_parameter_descriptor_t* param_descriptor)
{
assert(param_descriptor != NULL);
void* instance_ptr = NULL;
if (param_descriptor->param_offset != 0) {
switch(param_descriptor->mb_param_type)
{
case MB_PARAM_HOLDING:
instance_ptr = (void*)((uint32_t)&holding_reg_params + param_descriptor->param_offset - 1);
break;
case MB_PARAM_INPUT:
instance_ptr = (void*)((uint32_t)&input_reg_params + param_descriptor->param_offset - 1);
break;
case MB_PARAM_COIL:
instance_ptr = (void*)((uint32_t)&coil_reg_params + param_descriptor->param_offset - 1);
break;
case MB_PARAM_DISCRETE:
instance_ptr = (void*)((uint32_t)&discrete_reg_params + param_descriptor->param_offset - 1);
break;
default:
instance_ptr = NULL;
break;
}
} else {
instance_ptr = malloc((size_t)(param_descriptor->param_size));
}
return instance_ptr;
}
```
This bug is fixed but not merged yet and will be fixed as soon as possible and backported to previous releases.

Thank you!

--
Alex

protest_the_gyro
Posts: 3
Joined: Fri Sep 13, 2019 5:19 pm

Re: How to program Modbus Master

Postby protest_the_gyro » Tue Sep 17, 2019 7:30 pm

Hey Alex,

Thanks for the response! That works as well, ended up changing everything to follow the format of:

```
instance_ptr = ((void*)&holding_reg_params + param_descriptor->param_offset - 1);
```
which also works fine.

Thanks for the assistance!

Best,
Spencer

Who is online

Users browsing this forum: ESP_Alvin and 26 guests