Closed diegopivoto closed 2 years ago
Here, I will insert just the code of the Modbus, singly, in a text file.
Basically, here it gets and shows the data from the 3 holding registers in real time:
for(;;) {
// Check for read/write events of Modbus master for certain events
mb_event_group_t event = mbc_slave_check_event(MB_READ_WRITE_MASK);
const char* rw_str = (event & MB_READ_MASK) ? "READ" : "WRITE";
// Filter events and process them accordingly
if (event & (MB_EVENT_HOLDING_REG_WR | MB_EVENT_HOLDING_REG_RD)) {
// Get parameter information from parameter queue
ESP_ERROR_CHECK(mbc_slave_get_param_info(®_info, MB_PAR_INFO_GET_TOUT));
ESP_LOGI(SLAVE_TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
rw_str,
(uint32_t)reg_info.time_stamp,
(uint32_t)reg_info.mb_offset,
(uint32_t)reg_info.type,
(uint32_t)reg_info.address,
(uint32_t)reg_info.size);
// a variable that keeps the value of the action when being accessed
uint16_t action_value = *(uint16_t*)reg_info.address;
// Check if the holding register structure field being accessed my host
if (IS_FIELD_IN_RANGE(reg_info.address, reg_info.size, device_action_0, action_value)) {
ESP_LOGI(SLAVE_TAG, "Handle ACTION_0 %s , value = %d.", rw_str, action_value);
// Check the action value and do associated action (set/reset led pin currently)
// The register can include more actions instead of just switch led on/off (handle these actions appropriately later)
if (action_value == DEV_ACTION_LAMP_ON) {
// Switch lamp on
// The state of lamp is available as discrete inputs over Modbus protocol
portENTER_CRITICAL(¶m_lock);
discrete_reg_params.device_action_state0 = 1;
// Change the value inside critical section if required.
portEXIT_CRITICAL(¶m_lock);
gpio_set_level(DEV_LED_ACTION_0, 1);
} else if (action_value == DEV_ACTION_LAMP_OFF) {
// Switch lamp off
discrete_reg_params.device_action_state0 = 0;
gpio_set_level(DEV_LED_ACTION_0, 0);
}
}
// The same way check other fields in range of read/wrote registers
if (IS_FIELD_IN_RANGE(reg_info.address, reg_info.size, device_action_1, action_value)) {
ESP_LOGI(SLAVE_TAG, "Handle ACTION_1 %s , value = %d.", rw_str, action_value);
if (action_value == DEV_ACTION_LAMP_ON) {
// Switch lamp on
discrete_reg_params.device_action_state1 = 1;
gpio_set_level(DEV_LED_ACTION_1, 1);
} else if (action_value == DEV_ACTION_LAMP_OFF) {
// Switch lamp off
discrete_reg_params.device_action_state1 = 0;
gpio_set_level(DEV_LED_ACTION_1, 0);
}
}
if (IS_FIELD_IN_RANGE(reg_info.address, reg_info.size, device_action_2, action_value)) {
ESP_LOGI(SLAVE_TAG, "Handle ACTION_2 %s , value = %d.", rw_str, action_value);
if (action_value == DEV_ACTION_LAMP_ON) {
// Switch lamp on
discrete_reg_params.device_action_state2 = 1;
gpio_set_level(DEV_LED_ACTION_2, 1);
} else if (action_value == DEV_ACTION_LAMP_OFF) {
// Switch lamp off
discrete_reg_params.device_action_state2 = 0;
gpio_set_level(DEV_LED_ACTION_2, 0);
}
}
if (IS_FIELD_IN_RANGE(reg_info.address, reg_info.size, device_action_9, action_value)) {
// Exit condition: device_action_9
break;
}
// This is how to safely change fields in the Modbus structure that being accessed by Modbus driver
portENTER_CRITICAL(¶m_lock);
holding_reg_params.device_action_last = action_value; // Keep last action
portEXIT_CRITICAL(¶m_lock);
// Do the same to filter other actions accordingly
}
}
So, it shows the values received from device_action_0, device_action_1 and device_action_2, and according to these values lamps are switched or not (just ignore this application). So, while I'm receiving these data, I need to store and send them in real-time to other ESP32 via ESP-NOW. Please, someone can help me! I will be very grateful.
hi @diegopivoto
I think Modbus TCP and ESP-NOW can work at the same time.
You can refer to the IDF example.
esp-idf/examples/wifi/espnow/main/espnow_example_main.c
Hi @diegopivoto,
but if I try to implement the ESP-NOW for store the data from the holding registers and send them to other ESP32, a lot of errors appear and I can't even run the code.
What exactly errors do you have?
@diegopivoto Thanks for reporting and sorry for slow turnaround, would you please help share if any further updates for the issue? Thanks.
Thanks for reporting, feel free to reopen.
Hello, everybody! I've worked in the Modbus TCP and ESP-NOW separately, but now I have a situation which I need to use both to run in the same ESP32. So, basically, I will divide the situation in two parts:
[PART 1] First, I need to receive data from 3 Holding Registers via Modbus TCP of a PLC to my ESP32. This part is working very well if I run it singly. For this, I use the software Modbus Poll to simulate a PlC for sending the data from the 3 Holding Registers, and my ESP32 receives them, and shows it in real-time.
[PART 2] Now, the second part is my problem. I need to get these data from the 3 Holding Registers and send them to other ESP32, using ESP-NOW. So, simultaneously, I need to keep receiving the data from the 3 Holding Registers via Modbus TCP and find a way to store them to send in real-time to other ESP32 via ESP-NOW.
As I said before, the code for the Modbus [PART 1] works fine singly, but if I try to implement the ESP-NOW for store the data from the holding registers and send them to other ESP32, a lot of errors appear and I can't even run the code.
I would like to ask for help for someone who can guide me or give me an example about how to do it.