4-20ma / ModbusMaster

Enlighten your Arduino to be a Modbus master
http://4-20ma.io/ModbusMaster/
Apache License 2.0
594 stars 353 forks source link

Modbus Master communication with Multiple Slaves??? #109

Open dvvrao opened 6 years ago

dvvrao commented 6 years ago

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 commented 6 years ago

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

DIYDave commented 6 years ago

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

dvvrao commented 6 years ago

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

DIYDave commented 6 years ago

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

arthurkomatsu commented 5 years ago

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

dvvrao commented 5 years ago

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

apanasara commented 5 years ago

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

rbaumann commented 4 years ago

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_modbusaddr 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.

hasikp1 commented 4 years ago

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

joelmnz commented 4 years ago

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

DIYDave commented 4 years ago

@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.

tomek14 commented 4 years ago

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

DIYDave commented 4 years ago

@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.

IoTThinks commented 4 years ago

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

Thanks a lot.

mbta009 commented 3 years ago

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.

DIYDave commented 3 years ago

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)

haidvams commented 3 years ago

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

DIYDave commented 3 years ago

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.

haidvams commented 3 years ago

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

dvvrao commented 3 years ago

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 .

haidvams commented 3 years ago

I got did , i well share library very soon

lossonfire commented 2 years ago

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.
Hantuch commented 2 years ago

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

DIYDave commented 2 years ago

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

Hantuch commented 2 years ago

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!

Bobbimus commented 2 months ago

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