arduino for poor man automation

Hi,
I've been trying Arduino and ethernet module i.e communicating with Siemens S7-300 PLC and the other one is MODBUS TCP. But I can't merge those function Settimino and MODBUS TCP in one UNO and one ethernet module.
Is it possible to use an UNO and an ethernet module with two functionality? I plan to made data communication see my picture.
Thank you for your attention.

regards

sony

It is hard to guess.

Were you able to run each successfuly as independent sketches?

If yes. then answer lies within your code.

Also need to post your wiring and links to shields.

If you have not learned how to post code Please read how to use this forum. It is one of the sticky topics at the top of every forum.

thank you for response,
Yes I can successfully each code independently.

Here code for PLC read:

#include <SPI.h>
#include <Ethernet.h>
#include "Settimino.h"
// Uncomment next line to perform small and fast data access
#define DO_IT_SMALL
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE11 };  
IPAddress Local(192,168,1,70); // Local Address
IPAddress PLC(192,168,1,65);   // PLC Address
byte Buffer[256];
S7Client Client;
unsigned long Elapsed; // To calc the execution time
//----------------------------------------------------------------------
// Setup : Init Ethernet and Serial port
//----------------------------------------------------------------------
void setup() {
    // Open serial communications and wait for port to open:
    Serial.begin(9600);
     while (!Serial) {
      ; // wait for serial port to connect. Needed for Leonardo only
    }
    // Start the Ethernet Library
    Ethernet.begin(mac, Local);
    // Setup Time, someone said me to leave 2000 because some 
    // rubbish compatible boards are a bit deaf.
    delay(2000); 
    Serial.println(Ethernet.localIP());
}
//----------------------------------------------------------------------
// Connects to the PLC
//----------------------------------------------------------------------
bool Connect()
{
    int Result=Client.ConnectTo(PLC, 
                                  0,  // Rack (see the doc.)
                                  2); // Slot (see the doc.)
    Serial.print("Connecting to ");Serial.println(PLC);  
    if (Result==0) 
    {
      Serial.print("Connected ! PDU Length = ");Serial.println(Client.GetPDULength());
    }
    else
      Serial.println("Connection error");
    return Result==0;
}
//----------------------------------------------------------------------
// Dumps a buffer (a very rough routine)
//----------------------------------------------------------------------
void Dump(void *Buffer, int Length)
{
  int i, cnt=0;
  pbyte buf;
  
  if (Buffer!=NULL)
    buf = pbyte(Buffer);
  else  
    buf = pbyte(&PDU.DATA[0]);
  Serial.print("[ Dumping ");Serial.print(Length);
  Serial.println(" bytes ]==========================");
  for (i=0; i<Length; i++)
  {
    cnt++;
    if (buf[i]<0x10)
      Serial.print("0");
    Serial.print(buf[i], HEX);
    Serial.print(" ");
    if (cnt==16)
    {
      cnt=0;
      Serial.println();
    }
  }  
  Serial.println("===============================================");
}
//----------------------------------------------------------------------
// Prints the Error number
//----------------------------------------------------------------------
void CheckError(int ErrNo)
{
  Serial.print("Error No. 0x");
  Serial.println(ErrNo, HEX);
  
  // Checks if it's a Severe Error => we need to disconnect
  if (ErrNo & 0x00FF)
  {
    Serial.println("SEVERE ERROR, disconnecting.");
    Client.Disconnect(); 
  }
}
//----------------------------------------------------------------------
// Profiling routines
//----------------------------------------------------------------------
void MarkTime()
{
  Elapsed=millis();
}
//----------------------------------------------------------------------
void ShowTime()
{
  // Calcs the time
  Elapsed=millis()-Elapsed;
  Serial.print("Job time (ms) : ");
  Serial.println(Elapsed);   
}
//----------------------------------------------------------------------
// Main Loop
//----------------------------------------------------------------------
void loop() 
{  
  int Size, Result;
  void *Target;   
#ifdef DO_IT_SMALL
  Size=64;
  Target = NULL; // Uses the internal Buffer (PDU.DATA[])
#else
  Size=1024;
  Target = &Buffer; // Uses a larger buffer
#endif  
  // Connection
  while (!Client.Connected)
  {
    if (!Connect())
      delay(500);
  }  
  Serial.print("Reading ");Serial.print(Size);Serial.println(" bytes from DB1"); 
  // Get the current tick
  MarkTime();
  Result=Client.ReadArea(S7AreaDB, // We are requesting DB access
                         1,        // DB Number = 1
                         0,        // Start from byte N.0
                         Size,     // We need "Size" bytes
                         Target);  // Put them into our target (Buffer or PDU)
  if (Result==0)
  {
    ShowTime();
    Dump(Target, Size);
  }
  else
    CheckError(Result);
    
  delay(500);  
}

here the code for Modbus TCP:

#include <SPI.h>
#include <Ethernet.h>     //for W5100
#include "Mudbus.h"
Mudbus Mb;
void setup()
{
  uint8_t mac[]     = { 0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE11 };
  uint8_t ip[]      = { 192, 168, 1, 70 };
  uint8_t gateway[] = { 192, 168, 1, 1 };
  uint8_t subnet[]  = { 255, 255, 255, 0 };
  Ethernet.begin(mac, ip, gateway, subnet);
  delay(5000);  //Time to open the terminal
  Serial.begin(9600);
  analogReference(EXTERNAL);                      //Power the sensor with the 3.3V supply and run a wire from there to the AREF pin.  
}
#define AREF_VOLTS 3.33
void loop()
{
  Mb.Run();
  Mb.R[5]++;
  //Analog inputs 0-1023
  Mb.R[6] = analogRead(A2);                       //Raw signal from sensor.
  double Volts = double(Mb.R[6]) / 1023 * AREF_VOLTS;
  Mb.R[7] = Volts * 1000;                         //Volts on A2 (x1000 to get digits to the right of the decimal).
  Mb.R[8] = map(Mb.R[7], 100, 2000, -400, 1500);  //Degrees C x 10
  Mb.R[9] = map(Mb.R[7], 100, 2000, -400, 3020);  //Degrees F x 10
}

Is possible the code above merged?
thank

I see a problem on the horizon, calling Ethernet.begin() twice:
Modbus TCP: Ethernet.begin(mac, ip, gateway, subnet);
PLC read: Ethernet.begin(mac, Local);

PS.: Why is there a difference in the number of parameters?

uint8_t mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE11 };

I don't think 0xE11 is a valid number here.

Thank Erik,
The mac address 0xE11 is from settimino example and I test working, BTW if it's needed can be changes.
I will merge the code and try. I'll update later.

thank

Hi,
I try to merge and compile without major error.
here the code:

#include <SPI.h>
#include <Ethernet.h>     //for W5100
#include "Mudbus.h"
#include "Settimino.h"
IPAddress PLC(172,20,42,35);   // PLC Address
IPAddress Local(172,20,42,120); // Local Address
byte Buffer[128];
S7Client Client;
unsigned long Elapsed; // To calc the execution time
Mudbus Mb;
void setup()
{
  uint8_t mac[]     = { 0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE1 };
  uint8_t ip[]      = { 172,20,42,120 };
  uint8_t gateway[] = { 172,20,42,1 };
  uint8_t subnet[]  = { 255, 255, 255, 0 };
  Ethernet.begin(mac, ip, gateway, subnet);
  delay(5000);  //Time to open the terminal
  Serial.begin(9600);
  analogReference(EXTERNAL);                      //Power the sensor with the 3.3V supply and run a wire from there to the AREF pin.  
  Serial.println(Ethernet.localIP());
}
#define AREF_VOLTS 3.33
void loop()
{
  Mb.Run();
  Mb.R[5]++;
  //Analog inputs 0-1023
  Mb.R[6] = analogRead(A2);                       //Raw signal from sensor.
  double Volts = double(Mb.R[6]) / 1023 * AREF_VOLTS;
  Mb.R[7] = Volts * 1000;                         //Volts on A2 (x1000 to get digits to the right of the decimal).
  Mb.R[8] = map(Mb.R[7], 100, 2000, -400, 1500);  //Degrees C x 10
  Mb.R[9] = map(Mb.R[7], 100, 2000, -400, 3020);  //Degrees F x 10
//Loop for S7 PLC
  int Size, Result;
  void *Target;   
#ifdef DO_IT_SMALL
  Size=64;
  Target = NULL; // Uses the internal Buffer (PDU.DATA[])
#else
  Size=1024;
  Target = &Buffer; // Uses a larger buffer
#endif  
  // Connection
  while (!Client.Connected)
  {
    if (!Connect())
      delay(500);
  }  
  Serial.print("Reading ");
  Serial.print(Size);
  Serial.println(F(" bytes from DB1")); 
  // Get the current tick
  MarkTime();
  Result=Client.ReadArea(S7AreaDB, // We are requesting DB access
                         1,        // DB Number = 1
                         0,        // Start from byte N.0
                         Size,     // We need "Size" bytes
                         Target);  // Put them into our target (Buffer or PDU)
  if (Result==0)
  {
    ShowTime();
    Dump(Target, Size);
  }
  else
    CheckError(Result);   
  delay(500);  
}
//----------------------------------------------------------------------
// Connects to the PLC
//----------------------------------------------------------------------
bool Connect()
{
    int Result=Client.ConnectTo(PLC, 
                                  0,  // Rack (see the doc.)
                                  2); // Slot (see the doc.)
    Serial.print(F("Connecting to "));
    Serial.println(PLC);  
    if (Result==0) 
    {
      Serial.print(F("Connected ! PDU Length = "));
      Serial.println(Client.GetPDULength());
    }
    else
      Serial.println(F("Connection error"));
    return Result==0;
}
//----------------------------------------------------------------------
// Dumps a buffer (a very rough routine)
//----------------------------------------------------------------------
void Dump(void *Buffer, int Length)
{
  int i, cnt=0;
  pbyte buf;
  
  if (Buffer!=NULL)
    buf = pbyte(Buffer);
  else  
    buf = pbyte(&PDU.DATA[0]);
  Serial.print(F("[ Dumping "));
  Serial.print(Length);
  Serial.println(F(" bytes ]=========================="));
  for (i=0; i<Length; i++)
  {
    cnt++;
    if (buf[i]<0x10)
      Serial.print(F("0"));
    Serial.print(buf[i], HEX);
    Serial.print(F(" "));
    if (cnt==16)
    {
      cnt=0;
      Serial.println();
    }
  }  
  Serial.println(F("==============================================="));
}
//----------------------------------------------------------------------
// Prints the Error number
//----------------------------------------------------------------------
void CheckError(int ErrNo)
{
  Serial.print(F("Error No. 0x"));
  Serial.println(ErrNo, HEX);  
  // Checks if it's a Severe Error => we need to disconnect
  if (ErrNo & 0x00FF)
  {
    Serial.println(F("SEVERE ERROR, disconnecting."));
    Client.Disconnect(); 
  }
}
//----------------------------------------------------------------------
// Profiling routines
//----------------------------------------------------------------------
void MarkTime()
{
  Elapsed=millis();
}
//----------------------------------------------------------------------
void ShowTime()
{
  // Calcs the time
  Elapsed=millis()-Elapsed;
  Serial.print(F("Job time (ms) : "));
  Serial.println(Elapsed);   
}

But I can't ping 172,20,42,120

Your diagram in the OP suggests you don't have a switch in the network segment.
That could be a problem :slight_smile:

Of course the picture must be include ethernet switch.
Thank you for response.

regards

I would suggest you change the subject line of this thread. you want to know about connecting PLC's with both Eithernet and Modbus.

need help with connecting PLC's with both Eithernet and Modbus.

bottom right of your first post, more modify

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.