Modbus Arduino and HMI

Hello everyone. This is my first post on this forum, so I’d like to say hello.
Sorry for my English, I’m from Poland, and I’m not so good at English, and I’m sorry if I putted this topic in wrong category.

I have a problem. I’m using Arduino Leonardo + SoftwareSerial library, (later it will be Arduino Mega) to talk with HMI panel WECON 102L using Modbus/RS485. A have a MAX485 chip, and I can read what my HMI send to me. I did some simple interface on HMI. Only one bit indicator, which read register number 13.
Frame which I receive on SerialMonitor looks like that:

1 <- slave adress
2 <- function code (2, read registers)
0 <- register adress 0 * 256...
13 <- ... + 13 = 13
0 <- quanity of registers 0 * 256...
1 <- ... + 1 = 1
40 <- CRC
9 <- CRC
255 <- propably a trash

so it looks good. My response should be like that:

1 <- adress
2 <- function
1 <- quanity of data bytes
1 <- data - 1, because it is active
72 <- CRC
96 <- CRC

right?

but, indicator doesn’t want to change on HMI. And shows error to me “No. 1 PLC addr 1_X_000013 COMM timeout!”
so what’s wrong?

I’ve tried to do this much simpler, so now I have only code on my Arduino, which send message without request… I have switched MAX485 on transmit mode, transmit frame, and delay 300ms.
Led on HMI called “COM” is blinking every 300ms, so something is receiving by HMI, but no effect.

I’m using LiveStudioU to create interface on HMI.
Communication:
ModBus RS485
Data bits: 8
Parity: NONE
Stop bits: 2
Baud rate: 19200 (the same on Arduino and HMI ofc.)

long byteReceived;
long sendIt;

// (...)
void loop(){
    digitalWrite(TransmitDirection, RS485Transmit);
  sendIt = 1;
    RS485Serial.write(sendIt);
  sendIt = 2;
    RS485Serial.write(sendIt);
  sendIt = 1;
    RS485Serial.write(sendIt);
  sendIt = 1;
    RS485Serial.write(sendIt);
  sendIt = 96;
    RS485Serial.write(sendIt);
  sendIt = 72;
    RS485Serial.write(sendIt); 
  delay(300);
}

I would be very happy for any help, it is very important to me.
If you can, please - use simple language hehe.
Regards.

//----------------------
edit:
Or do you know some libraries for Arduino Modbus 485, which can communicate with HMI like mine? With description, or examples? Because maybe I would not have to learn this protocol, how it works, etc. Instead of that, I could just use some prepaired functions to talk between Arduino and HMI.

Please post your complete code, fragments often hide important details.

Also post your wiring schemata.

Don't use SoftwareSerial on a Leonardo. Use the hardware serial interface available with the Serial1 object. The same object is available on the Mega too, just on other pins.
SoftwareSerial is just a makeshift when you have absolutely no other chance. Even then the maximum baud rate is about 9600 baud if your counterpart is not very sensitive about timing.

Is the panel a ModBus master or slave? From your output it seems that it's a master. What exactly do you want to achieve? There are several Arduino library to let it act as a ModBus RTU slave. I may give you a suggestion if you tell me what you want it to use for.

Hi!

I'm sorry for long response, but I've lost link to this post, and can't find it in my browser history, or my arduino-forum profile.
Nevermind.

I'm going to use it like typical HMI - to control my arduino. Now, it works. I mean, almost..
The reason why I couldn't connect to HMI is solved - i have used a Modbus Library. It works fine.
BUT!
Now I have another problem - Everything goes well until I plug and put some code about PCF8574. When I add it into my code, my RE485 connection get lost. I've tried a lot of solution, but there is still the same problem.
I've discovered, that adding only library "pcf9574.h" don't make a problem, but when I add code:

expander.begin(0x20);

Arduino doesn't work....
Adress is fine. For sure. But I've also tried with another address. The same problem.

Any susgestions..?

p.s. Sorry for my English..
Regards.

Library(-ies):

I can’t find a link to that pcf9574.h library in your post. Please always provide links to the hardware and libraries you use. And post your complete sketch!

Hi, thanks for your answer.
Yes, you’re right, I shuld give you more code.
This is my simple sketch:

#include <Modbus.h>
#include <ModbusSerial.h>

// add library for I2C communication:
#include <Wire.h>    // Required for I2C communication (Wire.h is biult in)
#include "PCF8574.h" // Required for PCF8574 on I2C - link to github is at the bottom of this post

// Modbus Registers Offsets (0-9999)
const int LAMP1_COIL = 100; 
// Used Pins
const int ledPin = 4;

// ModbusSerial object
ModbusSerial mb;

//PCF8574 object:
PCF8574 expander;   // wejsciowy

void setup() {
    // Config Modbus Serial (port, speed, byte format) 
    mb.config(&Serial2, 19200, SERIAL_8N1, 6);
    // Set the Slave ID (1-247)
    mb.setSlaveId(1);  
    
    /*
     * until here, everything works well, even with libraries and declared object PCF8574.
     * But when I'm trying to begin my expander just like below - communication via RS485 doesn't 
     * work:
    */
    expander.begin(0x20); // address is good, Even i've tried with another adress - the same situation.
    
    // Set ledPin mode
    pinMode(ledPin, OUTPUT);
    // Add LAMP1_COIL register - Use addCoil() for digital outputs
    mb.addCoil(LAMP1_COIL);
}

void loop() {
   // Call once inside loop() - all magic here
   mb.task();
   
   // Attach ledPin to LAMP1_COIL register     
   digitalWrite(ledPin, mb.Coil(LAMP1_COIL));
}

Here is link to github with PCF8574 library:
https://github.com/skywodd/pcf8574_arduino_library
Arduino: Mega 2560

mb.config(&Serial2, 19200, SERIAL_8N1, 6);

If your panel is really following the ModBus standard, this configuration is wrong. ModBus supports only two stop bits or one parity bit and one stop bit but not only one stop bit.

Give your library decision I guess your panel is a ModBus master. Is this correct? Do you have a link to the ModBus documentation for your panel?

Please provide a wiring diagram for your (complete) setup.

The PCF8574 library you use unfortunately isn’t implemented very well. The following line is freezing the Arduino if no chip is connected or if it isn’t connected correctly:

while (Wire.available() < 1);

pylon:
If your panel is really following the ModBus standard, this configuration is wrong. ModBus supports only two stop bits or one parity bit and one stop bit but not only one stop bit.

Configuration is the same in both devices. And everything works well without PCF chip.

pylon:
I guess your panel is a ModBus master. Is this correct? Do you have a link to the ModBus documentation for your panel?

Yes. HMI is a Master, and Arduino is a slave. I have documentation, but it is very poor.

pylon:
The PCF8574 library you use unfortunately isn’t implemented very well. The following line is freezing the Arduino if no chip is connected or if it isn’t connected correctly:

while (Wire.available() < 1);

Thanks a lot! Maybe this is the reason! I’ve got a solution for my problem. I’ve implemented different library for PCF8574 chip from Adruino site:

http://playground.arduino.cc/Main/PCF8574Class

I’ve used it instead of library from github and it works!
That new library doesn’t have few functions which old library has, but it’s not a problem. Most important thing is that everything works fine.

Thank you so much for your help. I’m indepted.
Sorry for my English once again.
If i would have some more question I will ask here, but for now, I think that everything is clear for me.
Regards! :sunglasses:

Hi trolodk2
I want to test with a levi 700 screen you can give me the levi studio file a lot thanks in advance

Levi studio is availbe in wecon webstie. Google -> wecon or google -> levistudioU download.