2

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.

3

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);
}
  • 2
    Could 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. – Greenonline Jun 23 '17 at 18:08
  • 1
    While 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 – Greenonline Jun 23 '17 at 18:09
  • I have updated the post. Please share your concern for downvotes. I will try to help you. – goddland_16 Jun 24 '17 at 5:12
  • 1
    Few 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. – goddland_16 Jun 24 '17 at 5:22
  • 2
    Your 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) :-) – Greenonline Jun 24 '17 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.