Modbus TCP - MgsModbus library - Write Holding Registers/Coils.

Good day to everyone.

I'm trying to use an Arduino Mega to control a Siemens LOGO. The LOGO has some switches at the inputs that start and stop a process, but I need to be able to start and stop this process from the Arduino via Modbus TCP.

Arduino is "Client" and LOGO is "Server".

I can read the status of the coils, and the Holding Registers from the LOGO, but I don't know how to write on them from the Arduino so I can start the process with the LOGO.

I'm using the MgsModbus library, but its documentation is zero. I can't find how to write on the registers.

Any help would be appreciated.

I'm using the MgsModbus library, but its documentation is zero. I can't find how to write on the registers.

It's almost identical to the reading but instead of the functions with "read" in their names you use the ones with "write" in the name.

Post the code you use to read the values, we can tell you what to change to write a value back.

BTW: You should post a link to the library you're using, I'm not sure I looked at the same you're using.

Thanks for the answer.

The link to the library: My Arduino Projects - Website dedicated to my arduino projects - A ModBus TCP library for the Arduino system

The function I use:

Mb.Req(MB_FC_READ_INPUT_REGISTER,      0,1,0);

The last three parameters are: Modbus address, quantity of addresses to read, position in the Modbus array to save the data.

What I don't understand, are the parameters at the end when I want to write. How/where should I write the value?

Do I write in the Modbus array (MbData) the value I want and then use:

Mb.Reg(MB_FC_WRITE_REGISTER,      0,1,0);

This is what I've found on the .CPP archive:

 if(MbsFC == MB_FC_WRITE_REGISTER) {
    Start = word(MbsByteArray[8],MbsByteArray[9]);
    MbData[Start] = word(MbsByteArray[10],MbsByteArray[11]);
    MbsByteArray[5] = 6; //Number of bytes after this one.
    MessageLength = 12;
    client.write(MbsByteArray, MessageLength);
    MbsFC = MB_FC_NONE;
    }

The form for Modbus messages is:

11 06 0001 0003 9A9B

11: The Slave Address (11 hex = address17 )
06: The Function Code 6 (Preset Single Register)
0001: The Data Address of the register.
             ( 0001 hex = 1 , + 40001 offset = register #40002 )
0003: The value to write 
9A9B: The CRC (cyclic redundancy check) for error checking.

So, I understand the third byte is the value, but... how can I modify it with this library?

Thanks.

MbData is an array of integers used to transfer data from your sketch to the library and back.

The last three parameters are: Modbus address, quantity of addresses to read, position in the Modbus array to save the data.

Not completely correct, they are register address, number of registers to write/read, position in the MbData array.

The Modbus address is constant in the source code of the library (192.168.200.163), so you have to modify the library to change this.
That library seems to be in a pre-alpha state and far from being used in a production environment.

Thanks.

I understood the parameters, but I didn't explain myself correctly with a spot on technical language. I'm sorry. English isn't my mother language and express myself in it causes this kind of confusions.

Can you tell me about any other finished library for Arduino that lets me use the Arduino as a Modbus client?

Do you know how to use that MsgModbus library to write Holding Registers?

Thanks again.

Kikerumbo:
Thanks.

I understood the parameters, but I didn't explain myself correctly with a spot on technical language. I'm sorry. English isn't my mother language and express myself in it causes this kind of confusions.

Can you tell me about any other finished library for Arduino that lets me use the Arduino as a Modbus client?

Do you know how to use that MsgModbus library to write Holding Registers?

Thanks again.

Modbus TCP is very simple. I use it without a library and could not find a way to convert the code to a meaningful library

thread Modbus TCP master library - #15 by Juraj - Networking, Protocols, and Devices - Arduino Forum

Thanks for the answer. Juraj.

I've been looking at your example and I really miss some comments, because for a noob like me, it's hard to understand.

I'm going to have to read 6 discreet inputs (for the status of physical buttons), 4 coils (for the status of the valves) and one input register (for an analog input). Also, I'll have to be able to write 2 coils (to bypass the physical buttons that start the process on the server).

I think the better way, would be to have a library.

Since this doesn't exist, what would it take to make a library for Modbus over TCP?

I understand the Ethernet.h will manage the communication and I'll "just" have to make the library to make the message with the MBAT Header, the Function Code and the Data. Am I right?

The libraries are programmed in C++, I think. I've been doing some C programming this last months, so it seems I'll have to change to C++.

Any advice? Thanks.

this reads 2 registers starting with register 40083 from device #1
the result is in array regs[2]

boolean requestInverter() {
  short regs[2];
  int res = modbusRequest(1, 40083, 2, regs);
  if (modbusError(res))
    return false;
  inverterAC = regs[0] * pow(10, regs[1]); // ac power * scale
  return true;
}

this writes to register (ADDR_STORCTL + reg) a value (limit * SCALE)
(device number 1 is hardcoded in the function)

int battSettSetLimit(byte reg, int limit) {
  return modbusWriteSingle(ADDR_STORCTL + reg, limit * SCALE);
}

try harder to understand the code. how do you want to write code, if you can't read it?