Modbus RS485 communication test with MAX481

Hy!

I want to thest the Modbus communication protocoll betwen two arduino based board.
The circuit and the connection is ok, I tested with another package type communication and its worked.
Now I want to use modbus.
I tryed to write on master side an holding register and on the slave side I want to read.
The MAX481 ic RE and DE pin is connected to 6 and 7 pin.

The master code:

#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

#define RE 6
#define DE 7

int counter=0;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  pinMode(RE,INPUT);
  pinMode(DE,INPUT);

  digitalWrite(RE,LOW);
  digitalWrite(DE,LOW);

  // start the Modbus RTU client
  if (!ModbusRTUClient.begin(9600)) {
    Serial.println("Failed to start Modbus RTU Client!");
    while (1);
  }
}

void loop(){
 writeHoldingRegisterValues();

 counter++;

  delay(5000);
  Serial.println();
}

void writeHoldingRegisterValues() {
  // set the Holding Register values to counter

 
  digitalWrite(RE,HIGH);
  digitalWrite(DE,HIGH);
 
  ModbusRTUClient.holdingRegisterWrite(42,4,counter);
  digitalWrite(RE,LOW);
  digitalWrite(DE,LOW);

  // Alternatively, to write a single Holding Register value use:
  // ModbusRTUClient.holdingRegisterWrite(...)
}

The slave code:

#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>
#include <SoftwareSerial.h>

#define RE 6
#define DE 7

SoftwareSerial mySerial (4, 5);

const int numHoldingRegisters = 10;

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  while (!Serial);


  pinMode(RE,INPUT);
  pinMode(DE,INPUT);

  digitalWrite(RE,LOW);
  digitalWrite(DE,LOW);

  // start the Modbus RTU server, with (slave) id 42
  if (!ModbusRTUServer.begin(42, 9600)) {
    Serial.println("Failed to start Modbus RTU Server!");
    while (1);
  }
   ModbusRTUServer.configureHoldingRegisters(0x00, numHoldingRegisters);
}



void loop() {
  // poll for Modbus RTU requests
  ModbusRTUServer.poll();

  // map the holiding register values to the input register values
  for (int i = 0; i < numHoldingRegisters; i++) {
    long holdingRegisterValue = ModbusRTUServer.holdingRegisterRead(i);

   mySerial.println(holdingRegisterValue);
  }
}

Can somebody help me do what i do wrong?
Thanks!
Benji

UPDATE: Modified the master and slave code.

/*
  Modbus RTU Server LED

  This sketch creates a Modbus RTU Server with a simulated coil.
  The value of the simulated coil is set on the LED

  Circuit:
   - MKR board
   - MKR 485 shield
     - ISO GND connected to GND of the Modbus RTU server
     - Y connected to A/Y of the Modbus RTU client
     - Z connected to B/Z of the Modbus RTU client
     - Jumper positions
       - FULL set to OFF
       - Z \/\/ Y set to OFF

  created 16 July 2018
  by Sandeep Mistry
*/

#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>
#include <SoftwareSerial.h>


SoftwareSerial mySerial (4, 5);

const int ledPin = LED_BUILTIN;

void setup() {
  mySerial.begin(9600);

  mySerial.println("Modbus RTU Server LED");

  // start the Modbus RTU server, with (slave) id 1
  if (!ModbusRTUServer.begin(1, 9600)) {
    mySerial.println("Failed to start Modbus RTU Server!");
    while (1);
  }

  // configure the LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // configure a single coil at address 0x00
  ModbusRTUServer.configureCoils(0x00, 1);
}

void loop() {
  // poll for Modbus RTU requests
  ModbusRTUServer.poll();

  // read the current value of the coil
  int coilValue = ModbusRTUServer.coilRead(0x00);

  if (coilValue) {
    // coil value set, turn LED on
    digitalWrite(ledPin, HIGH);
  } else {
    // coild value clear, turn LED off
    digitalWrite(ledPin, LOW);
  }
}
/*
  Modbus RTU Client Toggle

  This sketch toggles the coil of a Modbus RTU server connected via RS485
  on and off every second.

  Circuit:
   - MKR board
   - MKR 485 shield
     - ISO GND connected to GND of the Modbus RTU server
     - Y connected to A/Y of the Modbus RTU server
     - Z connected to B/Z of the Modbus RTU server
     - Jumper positions
       - FULL set to OFF
       - Z \/\/ Y set to ON

  created 16 July 2018
  by Sandeep Mistry
*/

#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>
#include <SoftwareSerial.h>


SoftwareSerial mySerial (4, 5);

void setup() {
  mySerial.begin(9600);
 // while (!Serial);

  mySerial.println("Modbus RTU Client Toggle");

  // start the Modbus RTU client
  if (!ModbusRTUClient.begin(9600)) {
    mySerial.println("Failed to start Modbus RTU Client!");
    while (1);
  }
}

void loop() {
  // for (slave) id 1: write the value of 0x01, to the coil at address 0x00 
  if (!ModbusRTUClient.coilWrite(1, 0x00, 0x01)) {
    mySerial.print("Failed to write coil! ");
    //mySerial.println(ModbusRTUClient.lastError());
  }else{
    mySerial.println("ON");
  }

  // wait for 1 second
  delay(1000);

  // for (slave) id 1: write the value of 0x00, to the coil at address 0x00 
  if (!ModbusRTUClient.coilWrite(1, 0x00, 0x00)) {
    mySerial.print("Failed to write coil! ");
    //mySerial.println(ModbusRTUClient.lastError());
  }else{
    mySerial.println("OFF");
  }

  // wait for 1 second
  delay(1000);
}

This works, the LED go ON and OFF but

ModbusRTUClient.coilWrite(1, 0x00, 0x01); -----> return 0

:o :o
It is very interesting...

The MAX481 ic RE and DE pin is connected to 6 and 7 pin.

If you want to use the ArduinoModbus library you're not free to choose these pins. On the AVR platform the pin is fixed to pin D2 (for both, so they must be connected) while on ARM it's A5/A6. If you want to change that you have to edit the file RS485.h of the ArduinoRS485 library.

pylon:
If you want to use the ArduinoModbus library you're not free to choose these pins. On the AVR platform the pin is fixed to pin D2 (for both, so they must be connected) while on ARM it's A5/A6. If you want to change that you have to edit the file RS485.h of the ArduinoRS485 library.

Hy!
I modified the RS485.h file to use 6 & 7 pin, but still not working. On the serial monitor I see "0";

On the serial monitor I see "0";

On which serial monitor?

pylon:
On which serial monitor?

On the slave device.(First code version)
The modified code work 2-3 times but the modbus libary "say" failed to write coil....
I tryed with PC connection USB-RS485 adapter + Modpus poll software. It also worked.

On the slave device.(First code version)

So you connected some other device you didn't tell us to be able to see the output of your SoftwareSerial in Serial Monitor?

The modified code work 2-3 times but the modbus libary "say" failed to write coil....

What does "work" mean in this context? Does it work as expected but suddenly stops to work?

I tryed with PC connection USB-RS485 adapter + Modpus poll software. It also worked.

What worked?

pylon:
So you connected some other device you didn't tell us to be able to see the output of your SoftwareSerial in Serial Monitor?

What does "work" mean in this context? Does it work as expected but suddenly stops to work?

What worked?

I made a mistake and didn't notice that on the slave device RE & DE pin connected diferent like a master device.
I've fixed the program and the ModbusRTUClientToggle and ModbusRTUServerLed works fine, the LED turns ON and OFF when client send a message.
After this i tested ModbusRTUClientKitchenSink and ModbusRTUServerKitchenSink combination but it didn't work. On the serial monitor I see "Connection timed out". This is very interesting for me....
For the RE and DE pin definition I used "RS485.setPins(1,DE,RE);"

I've fixed the program and the ModbusRTUClientToggle and ModbusRTUServerLed works fine,

Post the fixed code that works for you!

After this i tested ModbusRTUClientKitchenSink and ModbusRTUServerKitchenSink combination but it didn't work.

Post that code too in the exact version you're trying with.

pylon:
Post the fixed code that works for you!

Post that code too in the exact version you're trying with.

The only modifications on the program is I paste the following lines on the setup section with the correct pin number:
RS485.setPins(1,DE,RE);

On what hardware are you trying that? That ArduinoModbus library is designed for ARM based boards, it uses to much memory for AVR based boards, especially boards with an ATmega328.

pylon:
On what hardware are you trying that? That ArduinoModbus library is designed for ARM based boards, it uses to much memory for AVR based boards, especially boards with an ATmega328.

Thanks, the Atmega328 is too little for this...

Thanks, the Atmega328 is too little for this...

For this library: yes.
Why did you choose exactly this library and not any of the others that exist for Modbus on Arduino? Most others run fine on an ATmega328 based Arduino.