ModbusMaster icon indicating copy to clipboard operation
ModbusMaster copied to clipboard

Modbus Master communication with Multiple Slaves???

Open dvvrao opened this issue 6 years ago • 26 comments

ModbusMaster version

[2.0.1]

Arduino IDE version

[1.8.5]

Arduino Hardware

[ESP32 Dev Module]

Platform Details

[Windows10]


Scenario:

[It's a Question. The question is "should I create multiple ModbusMaster objects to interact with multiple slaves? Or is there any other way to do it?]

Steps to Reproduce:

[Not Applicable]

Expected Result:

[Not Applicable]

Actual Result:

[Not Applicable]


Feature Request

Narrative:

As a [role]
I want [feature]
So that [benefit]

Acceptance Criteria:

Scenario 1: Title
Given [context]
  And [some more context]...
When  [event]
Then  [outcome]
  And [another outcome]...

dvvrao avatar Jun 19 '18 13:06 dvvrao

We used for interacting with multiple slaves and it is working.

dvvrao avatar Aug 20 '18 11:08 dvvrao

Hi dvvrao, How do you manage this? Create multiple ModbusMaster objects with different Slave ID ? Thanks in advance Dave

DIYDave avatar Sep 06 '18 14:09 DIYDave

Hi Dave,

Sorry for delayed answer. Yes, I did what you guessed. Below is the code snippet: /* instantiate ModbusMaster object(s) */ static ModbusMaster node1; // Flame proof temperature sensor. static ModbusMaster node2; // Arduino Nano. static ModbusMaster node3; // Arduino Nano. static ModbusMaster node4; // Arduino Nano. static ModbusMaster node5; // Arduino Nano. static ModbusMaster node6; // Arduino Nano.

// Start UART1. Used for RS485. UART1.begin(BAUD_RATE, /* baud speed / SERIAL_8N1, / UART mode / 36, / RX pin / 17 / TX pin. */ );

// communicate with Modbus slave ID 1, 2 and so on upto MAX_SLAVES over Serial (port 1) node1.begin(1, UART1); node2.begin(2, UART1); node3.begin(3, UART1); node4.begin(4, UART1); node5.begin(5, UART1); node6.begin(6, UART1); Files_To_GIT_ModbusMaster_App.zip

PFA the code.

Regards, Vishnuvardhan

dvvrao avatar Sep 07 '18 18:09 dvvrao

Hi Vishnuvardhan Many Thanks. In the meantime I have found a solution for me. I have changed the library so that every time a function is called from the sketch, the slave ID is also passed. So I just need a obejct and everything runs flawlessly. Example:

uint8_t ModbusMaster232::readHoldingRegisters(uint8_t u8MBSlave, uint16_t u16ReadAddress,
  uint16_t u16ReadQty)
{
  _u8MBSlave = u8MBSlave;
  _u16ReadAddress = u16ReadAddress;
  _u16ReadQty = u16ReadQty;
  return ModbusMasterTransaction(ku8MBReadHoldingRegisters);
}

From Sketch: int MBres = MB.readHoldingRegisters(ESP_ID,0, 13)

Dave

DIYDave avatar Sep 14 '18 16:09 DIYDave

Do you guys know if is it ok if I change the slave my calling the function ModbusMaster.begin() again?

arthurkomatsu avatar Oct 23 '18 13:10 arthurkomatsu

Yes. It is OK. I did this couple of days ago, so far i am not seeing any issues.

dvvrao avatar Oct 23 '18 13:10 dvvrao

Please close the issue... it seems resolved...

apanasara avatar Jan 17 '19 01:01 apanasara

There is still an issue with communication to multiple slaves. It is ok, to re-use .begin() with another modbus address but if I do have a class structure, where the a pointer to the MBdriver - object is passed as a parameter in constructor call, I can change the modbus - address in the receiving object but not restore to the previous modbus address before retuning to calling environment. e.g. _#include "ModbusMaster.h" #include "LAMP_MODBUS_SCOUT.h" ... // instantiate ModbusMaster object ModbusMaster MBdriver; ModbusMaster MBdriver_pt = &MBdriver; .... // Declare the Object which acts as a scout on the modbus, looking for // lamps declared in LAMP_SYS2MONITOR but not yet talked to LAMP_MODBUS_SCOUT MBscout(MBdriver_pt); ... ... // Modbus communication runs at 9600 baud; GPIO pin0=RX, GPIO pin1=TX Serial.begin(lamp_sys.get_MODBUS_baudrate(),RXpin,TXpin); .. // Provide the modbus address of the next lamp to poll to the MBdriver MBdriver.begin(CURR_modbus_addr, Serial); ... void loop() { ..... ..... //reading from CURR_modbus_addr retsta = MBdriver_pt->readHoldingRegisters(0x0000,numREG2LOAD); .... //MBscout will use MBdriver.begin(FND__modbus_addr, Serial); ret = MBscout.get_lampRELdata (FND_modbus_addr, &lamp_HWSWrel, &lamp_sys); // here we will CONTINUE sending data to FND_modbus_addr because MBscount can not // restore communication to CURR_modbus_addr before returning. This side effect creates a // mess .... };_* I SUGGEST adding a function: uint8_t getSLAVEaddr() into "ModbusMaster.h" which returns the private instance variable _u8MBSlave. so MBscount can save it at get_lampRELdata() entry and restore before returning. This will eliminate unwanted side effects.

rbaumann avatar Dec 12 '19 19:12 rbaumann

@DIYDave so there will be only one .begin() for all the slaves? or do you pass all the slave ids?

hasikp1 avatar Dec 27 '19 06:12 hasikp1

anyone still working on this? I see fake-name has already done a PR to fix this, who can approve PR into master?

joelmnz avatar Jan 03 '20 23:01 joelmnz

@DIYDave so there will be only one .begin() for all the slaves? or do you pass all the slave ids?

Yes, only one .begin(). Works great for me.

DIYDave avatar Jan 11 '20 09:01 DIYDave

@DIYDave Could you please share your changes on public repo?

tomek14 avatar Feb 15 '20 18:02 tomek14

@DIYDave Could you please share your changes on public repo? @tomek14 You can find my solution in my comment from 14 Sept 2018 above. Sorry, I don't know how to publish otherwise. You are welcome to publish the solution or tell me how I have to do it myself.

DIYDave avatar Feb 16 '20 12:02 DIYDave

The fix of @DIYDave seems very good to me. However, it is not in the official code yet?

Thanks a lot.

IoTThinks avatar Jun 01 '20 09:06 IoTThinks

Hello @DIYDave Test your solution in above https://github.com/4-20ma/ModbusMaster/issues/109#issuecomment-421412049 but don't work for me. change lib to add slave and use node1.begin(1, UART1); node2.begin(2, UART1); ... Only one of them works at the moment. To work on one of the nodes, I need to remove another node. Then the commands work. The error I receive is the E2 error related to Timeout.

mbta009 avatar May 21 '21 22:05 mbta009

Hello @DIYDave Test your solution in above #109 (comment) but don't work for me. change lib to add slave and use node1.begin(1, UART1); node2.begin(2, UART1); ... Only one of them works at the moment. To work on one of the nodes, I need to remove another node. Then the commands work. The error I receive is the E2 error related to Timeout.

Hi, you don‘t have to use .begin for each slave. Just one time. After that you can adress slaves by its ID. (If you have change the library)

DIYDave avatar May 26 '21 16:05 DIYDave

Can someone share the code to help me read and write data for muilti slave?

haidvams avatar Jun 13 '21 16:06 haidvams

Can someone share the code to help me read and write data for muilti slave?

The solution from my post from Sept. 2018 has been running 24/7 for three years without any problems. Change library for the MB commands you need. Use begin() 1x and transfer the slave ID as the first parameter when called from the sketch.

DIYDave avatar Jun 14 '21 06:06 DIYDave

Can someone share the code to help me read and write data for muilti slave?

The solution from my post from Sept. 2018 has been running 24/7 for three years without any problems. Change library for the MB commands you need. Use begin() 1x and transfer the slave ID as the first parameter when called from the sketch.

Thank for your reply But I am newbie, can you share your full example code a master read and write multi slave ? I'm so grateful to you

haidvams avatar Jun 15 '21 16:06 haidvams

Hi Dave,

Do not remember now exactly. I will check my code and let you know later.

Thanks, Vishnuvardhan

On Thu, 6 Sep, 2018, 8:19 PM DIYDave, @.***> wrote:

Hi dvvrao, How do you manage this? Create multiple ModbusMaster objects with different Slave ID ? Thanks in advance Dave

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/4-20ma/ModbusMaster/issues/109#issuecomment-419121935, or mute the thread https://github.com/notifications/unsubscribe-auth/AbXlEikv9RSc4RDXo65TkR_5FFVjSScPks5uYTXwgaJpZM4UtjYV .

dvvrao avatar Jun 16 '21 05:06 dvvrao

I got did , i well share library very soon

haidvams avatar Jun 19 '21 12:06 haidvams

The Solution from DIYDave works ok but he didnt say that you need to change this in the modbusmaster.h too:

Line 208, you need to include an uint8_t (the same that you added in the .cpp file). uint8_t readHoldingRegisters(uint8_t, uint16_t, uint16_t);

Sorry for my english, im not native.

lossonfire avatar Dec 07 '21 00:12 lossonfire

Since no one did it, I made a fork here

Basically I've done what @DIYDave did but to all read/write functions (the one that returns ModbusMasterTransaction, as it is the only function that use _u8MBSlave)

Tested it on my current project (power meters logger) using both readInputRegisters() and readHoldingRegisters() and it seems to work normally. Quite convenient for multiple-slave use, since you only got to create one modbus object.

For single slave use though... having to specify the address for each request might be inconvenient for some..

Oh the dilemma..

Hantuch avatar Jan 19 '22 17:01 Hantuch

Thanks for the fork, Hantuch. Unfortunately, I'm not very familiar with Github. I'm happy when I have my own reposotories under control. :-)

DIYDave avatar Jan 19 '22 17:01 DIYDave

You're welcome! It's very easy to be honest, you just click the fork button up there and it makes a copy of the repo under your name and control. If you're sure the codes works and you think it's essential you can make a pull request, which, if accepted by the original author (or anyone else with the access), will be merged into the original repo (although for this particular library, it seems to not have been updated since 2016, and many pull requests are left unattended)

cheers!

Hantuch avatar Jan 20 '22 06:01 Hantuch

Can

You're welcome! It's very easy to be honest, you just click the fork button up there and it makes a copy of the repo under your name and control. If you're sure the codes works and you think it's essential you can make a pull request, which, if accepted by the original author (or anyone else with the access), will be merged into the original repo (although for this particular library, it seems to not have been updated since 2016, and many pull requests are left unattended)

cheers!

Could you post an example code? Still trying to figure out if i got a bug in my code or smth in the bus confog is wrong...

Bobbimus avatar Jul 08 '24 06:07 Bobbimus