Forum Controllers/PLC

Welcome!

This community is for professionals and enthusiasts of our products and services. Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together.

0

Ardbox Modbus RTU Slave. Solved

Avatar
Tobias

Solved.

The input/output names needed to be changed to work with this model. ( Q0_0 -> R1 ).

This fault caused the available number of inputs/outputs to be zero and that's why I couldn't write to the outputs for example.


This code for testing the outputs works:

#include <RS485.h>
#include <ModbusRTUSlave.h>

#define RS485_RATE 9600UL

int digitalOutputsPins[] = {R1, R2, R3, R4, R5, R6};
#define numDigitalOutputs int(sizeof(digitalOutputsPins) / sizeof(int))

bool digitalOutputs[numDigitalOutputs];

// Define the ModbusRTUSlave object with Modbus RTU slave address: 1
ModbusRTUSlave modbus(RS485, 1);

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600) ;

  // Init RS485
  RS485.begin(RS485_RATE, HALFDUPLEX, SERIAL_8E1);

  // Init ModbusTCPSlave object
  modbus.begin(RS485_RATE);

  modbus.setCoils(digitalOutputs, numDigitalOutputs);

}

void loop() {

    // Process modbus requests
  modbus.update();
  
  // put your main code here, to run repeatedly:
  for (int i = 0; i < numDigitalOutputs; ++i) {

   digitalWrite(digitalOutputsPins[i], digitalOutputs[i]);
  }
}


The test results:

./modpoll -b 9600 -p even -m rtu -a1 -c6 -t0  /dev/ttyUSB0 1 1 0 1 1 1
modpoll 3.9 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2020 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: Modbus RTU, FC15
Slave configuration...: address = 1, start reference = 1, count = 6
Communication.........: /dev/ttyUSB0, 9600, 8, 1, even, t/o 1.00 s, poll rate 1000 ms
Data type.............: discrete output (coil)

Written 6 references.


Old question:

Hello,

I Bought a Ardbox Relay HF+ and was going to use it as a Modbus RTU Slave.

I found some programming examples on github but I can't get it to work.

I had some success when I used the RTU Master examples and could see data being transmitted but when configured as slave I get "Illegal Data Address exception response!". Can't seem to read any data from the slave device.

I have been using modpoll and diagslave from modbusdriver(dot)com and a Schneider PLC for testing. 


Is there any more information to find for the modbus slave functions or is the examples the only documentation?

Any tips on how to get it to work?

Regards

Tobias




Avatar
Discard
2 Answers
0
Avatar
Tobias
Best Answer

I tried the example on that page and got it to send traffic as master, but I need to run it as slave.

I tried this code from github and made some smaller adjustment in the communication settings.

Should I specify the registers that I use? I read that reg 9 is linked to 40008. But can't read any?


/*
   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program 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 Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <RS485.h>
#include <ModbusRTUSlave.h>
#define RS485_RATE 38400UL
// Modbus registers mapping
// This example uses the M-Duino21+ mapping
int digitalOutputsPins[] = {
#if defined(PIN_Q0_4)
  Q0_0, Q0_1, Q0_2, Q0_3, Q0_4,
#endif
};
int digitalInputsPins[] = {
#if defined(PIN_I0_6)
  I0_0, I0_1, I0_2, I0_3, I0_4, I0_5, I0_6,
#endif
};
int analogOutputsPins[] = {
#if defined(PIN_A0_7)
  A0_5, A0_6, A0_7,
#endif
};
int analogInputsPins[] = {
#if defined(PIN_I0_12)
  I0_7, I0_8, I0_9, I0_10, I0_11, I0_12,
#endif
};
#define numDigitalOutputs int(sizeof(digitalOutputsPins) / sizeof(int))
#define numDigitalInputs int(sizeof(digitalInputsPins) / sizeof(int))
#define numAnalogOutputs int(sizeof(analogOutputsPins) / sizeof(int))
#define numAnalogInputs int(sizeof(analogInputsPins) / sizeof(int))
bool digitalOutputs[numDigitalOutputs];
bool digitalInputs[numDigitalInputs];
uint16_t analogOutputs[numAnalogOutputs];
uint16_t analogInputs[numAnalogInputs];
// Define the ModbusRTUSlave object with Modbus RTU slave address: 11
ModbusRTUSlave modbus(RS485, 11);
////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600UL);
  Serial.println("Test!");
  // Init variables, inputs and outputs
  for (int i = 0; i < numDigitalOutputs; ++i) {
    digitalOutputs[i] = false;
    digitalWrite(digitalOutputsPins[i], digitalOutputs[i]);
  }
  for (int i = 0; i < numDigitalInputs; ++i) {
    digitalInputs[i] = digitalRead(digitalInputsPins[i]);
  }
  for (int i = 0; i < numAnalogOutputs; ++i) {
    analogOutputs[i] = 0;
    analogWrite(analogOutputsPins[i], analogOutputs[i]);
  }
  for (int i = 0; i < numAnalogInputs; ++i) {
    analogInputs[i] = analogRead(analogInputsPins[i]);
  }
  // Init RS485
  RS485.begin(RS485_RATE, HALFDUPLEX, SERIAL_8E1);
  // Init ModbusTCPSlave object
  modbus.begin(RS485_RATE);
  modbus.setCoils(digitalOutputs, numDigitalOutputs);
  modbus.setDiscreteInputs(digitalInputs, numDigitalInputs);
  modbus.setHoldingRegisters(analogOutputs, numAnalogOutputs);
  modbus.setInputRegisters(analogInputs, numAnalogInputs);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  // Update inputs
  for (int i = 0; i < numDigitalInputs; ++i) {
    digitalInputs[i] = digitalRead(digitalInputsPins[i]);
  }
  for (int i = 0; i < numAnalogInputs; ++i) {
    analogInputs[i] = analogRead(analogInputsPins[i]);
  }
  // Process modbus requests
  modbus.update();
  // Update outputs
  for (int i = 0; i < numDigitalOutputs; ++i) {
    digitalWrite(digitalOutputsPins[i], digitalOutputs[i]);
  }
  for (int i = 0; i < numAnalogOutputs; ++i) {
    analogWrite(analogOutputsPins[i], analogOutputs[i]);
  }
}



The test I tried with:

./modpoll -b 38400 -p even -m rtu -a 11 -r 1  /dev/ttyUSB0 
modpoll 3.9 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2020 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.
Protocol configuration: Modbus RTU, FC3
Slave configuration...: address = 11, start reference = 1, count = 1
Communication.........: /dev/ttyUSB0, 38400, 8, 1, even, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table
-- Polling slave... (Ctrl-C to stop)
Illegal Data Address exception response!



1 Comment
Avatar
Discard
Avatar
Marti Guillem Cura
-

On the following blog you can see all the specifications on which our library is based on. It is explained the format frame of the packets and the Modbus function codes. Although the code is for the Master connections, using the provided example and the code that you have got from the GitHub, you should be able to make some progress.

- Modbus RTU library for industrial automation blog: https://www.industrialshields.com/blog/arduino-industrial-1/post/modbus-rtu-master-library-for-industrial-automation-200

If not, feel free to contact us at [email protected]

0
Avatar
Marti Guillem Cura
Best Answer

the "Illegal Data Address exception response"  is raised when data address of some or all the required entities are not allowed or do not exist in salve. Make sure that you have properly configured the RS-485 parameters (in our examples RS485 is working at a 38400 baud rate for example).

On the following blog there are explained the basics of RS485 and an explained example of how to work with our PLCs.


I hope this helps! If not do not hesitate in reaching us at Contact Us 

Avatar
Discard