I would like to connect with Fronius solar inverter through MODBUS TCP with Arduino to READ and WRITE register values only. I want to set the Arduino as master and the Inverter as slave. I want to use only two functions "Read Holding Registers" and "Write Single Holding Register" function code '3' and function code '6' respectively. Is there any good and working library available for these? And also an example.
1 Answer
Check out the library Modbus-TCP on Github. It has the facility for all the function codes as asked. It has provision for Wiznet W5100 and ENC28J60 Ethernet IC. All tested with Arduino Mega. See the well documented example code for the Wiznet module in the library.
For detailed knowledge about the library, read the index.html inside the doc folder of the library.
Here is an example code explaining a few function codes for the Arduino Mega and a W5100 module.
/*
This is Modbus test code to demonstrate all the Modbus functions with
with Ethernet IC WIZNET W5100
ModbusTCP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ModbusTCP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ModbusTCP. If not, see <http://www.gnu.org/licenses/>.
Adopted from ModbusMaster for RTU over RS-485 by Doc Walker
Modified by Narendra Dehury for TCP.
copyright @ phoenixrobotix.com
*/
#define WIZNET_W5100 1
unsigned int param_value_int[7];
#include <Ethernet.h>
IPAddress ModbusDeviceIP(10, 10, 108, 211); // Put IP Address of PLC here
IPAddress moduleIPAddress(10, 10, 108, 23); // Assign Anything other than the PLC IP Address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xE1 };
#include <ModbusTCP.h>
ModbusTCP node(1); // Unit Identifier.
void setup()
{
pinMode(4, OUTPUT);
digitalWrite(4, HIGH); // To disable slave select for SD card; depricated.
Serial.begin(9600);
delay(1000);
Ethernet.begin(mac, moduleIPAddress);
node.setServerIPAddress(ModbusDeviceIP);
delay(6000); // To provide sufficient time to initialize.
}
void loop()
{
uint8_t result;
node.setTransactionID(random(100)); // Not necessary; but good to distinguish each frame individually.
result = node.readHoldingRegisters(1, 12); // Read Holding Registers
Serial.println(result, HEX);
if(result != 0)
{
Serial.println("TimeOut");
delay(6000);
}
int len = node.getResponseBufferLength();
Serial.println("Response Length: " + String(len));// See the length of data packet received.
for (byte j = 0; j < len; j++)
{
Serial.print(node.getResponseBuffer(j)); // Inspect the data.
Serial.print(" ");
}
Serial.println();
node.clearResponseBuffer();
delay(100);
node.writeSingleRegister(5, 3); // Write single register
Serial.println(result, HEX);
delay(500);
for (byte i = 0; i < 5; i++)
{
node.setTransmitBuffer(i, (i+100));
}
node.writeMultipleRegisters(2, 5); // Write multiple register
Serial.println(result, HEX);
delay(500);
node.writeSingleCoil(20, 1); // Write Single coil
delay(500);
node.setTransmitBuffer(0, 0b1010101001010101);
node.writeMultipleCoils(20, 16); // Write multiple coils
delay(500);
result = node.readCoils(20, 18);
len = node.getResponseBufferLength();
Serial.println("Response Length: " + String(len));
Serial.println(node.getResponseBuffer(0), BIN);
node.clearResponseBuffer();
delay(5000);
}
-
2Could you explain why you think it is useful, as well as giving a summary of the link? As it stands if it a link only answer. Should the link die, at some point in the future, your answer would not be very useful. Jun 23, 2017 at 18:08
-
1While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review Jun 23, 2017 at 18:09
-
I have updated the post. Please share your concern for downvotes. I will try to help you. Jun 24, 2017 at 5:12
-
1Few days back I was facing the same situation, I could not find a suitable library for Modbus TCP where Arduino will act as a client. So I decided to make one. And that link is the link to the library. You should encourage such activity rather than asking for deletion. Jun 24, 2017 at 5:22
-
2Your answer had been paced in the review queue on account of its brevity, and I was merely going through the reviews... you have been on SE for over a year, and as such you should know how SE works and that link only answers are frowned upon, and an additional explanation is generally required. I didn't down vote it, btw. Your expanded answer is much better, thanks (although I'm not sure about the now suit yourself, as that could be taken the wrong way) :-) Jun 24, 2017 at 13:40