I have a need to be able to do certain tasks with arduino and Modbus and have tried to put together a system. I can make a connection but I continually get a Illegal Data Address error when trying to poll for data in the holding registers.
Setup:
Arduino Unu R3
Arduino Ethernet2 board
Mach4
Ethernet2 library from arduino.org
Andre Sarmentos ModbuisIP Library
https://github.com/andresarmento/modbus-arduinoPic1 shows Mach4 with two Modbus setups, modbus0 is connected to the MODBUS Simulator
modbus1 is connected to the arduino through TCP 192.168.1.120
Note, modbus1 has no functions assigned, it's just connecting
Stay with me here...
Here is the arduino code that is simply checking 5 A-D floating inputs and sending that data across the Modbus in registers 40011 through 40015:
read the comments in the code:
/*
Modbus-Arduino Example - TempSensor (Modbus IP)
Copyright by André Sarmento Barbosa
http://github.com/andresarmento/modbus-arduino
*/
#include <SPI.h>
#include <Ethernet2.h>
#include <Modbus.h>
#include <ModbusIP.h>
//Modbus Registers Offsets (0-9999)
const int reg1 = 40011; //Setup the holding register numbers to use
const int reg2 = 40012;
const int reg3 = 40013;
const int reg4 = 40014;
const int reg5 = 40015;
//Used Pins
const int sensorPin1 = A0; //setup the A-d
const int sensorPin2 = A1;
const int sensorPin3 = A2;
const int sensorPin4 = A3;
const int sensorPin5 = A4;
//Instanciate the ModbusIP object
ModbusIP mb;
long ts;
void setup() {
Serial.begin(9600);
// The media access control (ethernet hardware) address for the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// The IP address for the shield
byte ip[] = { 192, 168, 1, 120 };
//Config Modbus IP
mb.config(mac, ip);
mb.addHreg(reg1);//Create the registers based on the values above
mb.addHreg(reg2);
mb.addHreg(reg3);
mb.addHreg(reg4);
mb.addHreg(reg5);
ts = millis();
}
void loop() {
//Call once inside loop() - all magic here
mb.task();
//Read each two seconds
if (millis() > ts + 1000) {
ts = millis();
//Setting raw value (0-1024)
mb.Hreg(reg1, analogRead(sensorPin1));//Send the A-D values through Modbus
mb.Hreg(reg2, analogRead(sensorPin2));
mb.Hreg(reg3, analogRead(sensorPin3));
mb.Hreg(reg4, analogRead(sensorPin4));
mb.Hreg(reg5, analogRead(sensorPin5));
Serial.println(mb.Hreg(reg1));
}
}//END
This code seems to work fine and when I run it and connect to it with a Modbus Master other than Mach4 I see the data
(I couldn't upload more than 4 pics but it ran fine)
I then create the function for modbus1 in Mach4 (pic3)
It is exactly the same as the other read function in modbus0(pic4) except I start at 40011 and only use 5 registers
The result (pic5) is modbus1 throws a Illegal Data Address error. This means that The data address received in the query is not an allowable address for the slave. More specifically, the combination of reference number and transfer length is invalid.
http://www.simplymodbus.ca/exceptions.htmI've tried changing the starting number in Mach to 0 and to 2 with no luck. Any ideas?
I think this would be a really good thing to be able to do and would allow for easy and fast connectivity to the arduino.
I really don't want to use serial but I will if I have to.
Let me know if you have any ideas or if you have any questions
Thanks
-Tim