Hello all,
I was working in a project to connect the Arduino mega combines with Ethernet shield to a unit uses PLC (Allen-Bradley) in my job.
It worked fine and the data flow was fast and good, I had only one problem. When arduino connect to the PLC it takes about 10 sec.s to establish the communication. It was not important at that time because it was a one time thing at the beginning only.
Now I'm upgrading the project to connect the Arduino to all other PLC packages. Total 6 different packages (5 Allen-Bradley PLCs + 1 Schneider-Electric PLC)
First thing I though about is to use 1 Arduino mega with Ethernet shield for each package to avoid this problem, but I keep thinking why SCADA system which uses 1 computer station with 1 network card can connect to all packages with lag not more than 1 second.
If anyone can advice if Arduino can work like that and connect to all packages very fast to keep maximum about 3 seconds lag only or I should go with the first idea (1 Arduino for each package)
below my code (just keep in mind that it has some lines special for my project, I'm sending the data to another Arduino by I2C)
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>
#include <Ethernet.h>
#include <Wire.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Ethernet MAC Address
IPAddress ip(192,168,1,140); // Ethernet MAC IP address
EthernetClient client;
ModbusTCPClient modbusTCPClient(client);
IPAddress server(192,168,1,25); // update with the IP Address of your Modbus server
int regRawAddresses[21] = { 1971,1972 , 1911,1912, 1941,1942, 1701,1702 , 2001,2002, 1851,1852 , 1881,1882 , 155 , 152 , 456 , 156 , 601 , 602 , 3};
uint16_t regRaw[21] ={0};
int I2C_SLAVE_ADDRESS= 2;
byte masterSent;
byte I2cRawCounter=0;
void setup()
{
Serial.begin(9600);
/////////////////////for i2c////////////////
digitalWrite(20, LOW);
digitalWrite(21, LOW);
////////////////////////////////////////
// // start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// try to congifure using IP address :
Ethernet.begin(mac, ip);
} else {
Serial.print(" DHCP assigned IP ");
Serial.println(Ethernet.localIP());
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.print("connecting to ");
Serial.print(server);
Serial.println("...");
Serial.println("Modbus TCP Client Toggle");
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
delay(3000);
}
void loop()
{
long regStatusTest,regStatusTest2;
String readString;
long Address;
// Wire.setClock(10000);
if (!modbusTCPClient.connected()) {
// client not connected, start the Modbus TCP client
Serial.println("Attempting to connect to Modbus TCP server");
if (!modbusTCPClient.begin(server)) {
Serial.println("Modbus TCP Client failed to connect!");
} else {
Serial.println("Modbus TCP Client connected");
}
} else {
// client connected
// Read Registers
for (int i=0; i<21; i++)
{
regRaw[i] = modbusTCPClient.holdingRegisterRead(regRawAddresses[i]);
Serial.print("regRaw [");
Serial.print(i);
Serial.print("]= ");
Serial.println(regRaw[i]);
delay(500);
}
// wait for 1 second
}
delay(1000);
}
void receiveEvent(int howMany)
{
if(Wire.available())
{
masterSent = Wire.read();
}
}
// this function will be called from master when it's ready to recieve data
// I shall make a loop to send one single long element from PVvalues[] array each time this function called
// this loop shall has a global counter when it reach the max it returns back to zero
// every single element in PVvalues[] array much be converted to 4 elements array of type byte
void requestEvent(int howMany)
{
byte myrawArray[2];
////////////////////////////Sending Raw data/////////////////////////
if (I2cRawCounter >20) //
{
I2cRawCounter =0;
}
if(masterSent == 'R')
{
myrawArray[0] = (regRaw[I2cRawCounter] >> 8) & 0xFF;
myrawArray[1] = regRaw[I2cRawCounter] & 0xFF;
Wire.write(I2cRawCounter); //this is the representation of Element ID in the array
Wire.write(myrawArray, 2);
}
Serial.print("I2cRawCounter = ");
Serial.println(I2cRawCounter);
I2cRawCounter++;
////////////////////////////End of sending Raw data/////////////////////////
}