How to connect a Siemens PLC to an Arduino over TCP or digital I/O

Based on contributions by alexandra, Jesse.

There are two common ways to get a Siemens PLC talking to an Arduino: a TCP/Ethernet connection, useful when you want to exchange several values through structured messages, or simple digital I/O signals, useful when you just need to pass single on/off signals and don’t want to deal with networking. This guide covers both.

What you need

Common to both methods:

  • A Siemens PLC (S7-1200 or similar) with TIA Portal.
  • An Arduino Uno or Mega with the Arduino IDE.

For the TCP method, also:

  • An Ethernet shield for the Arduino (or its native Wi-Fi, if your board has one) and the matching Ethernet library.
  • A network switch to connect the PLC, Arduino, and your laptop together.

For the digital I/O method, also:

  • A voltage converter (step-up and/or step-down) or a relay rated for both the 24V (PLC) and 5V (Arduino) sides.
  • A multimeter.
  • A breadboard or soldering equipment, and a pull-up/pull-down resistor if your circuit needs one.

Steps

Method A: TCP connection

1. Wire the network

  • PLC Ethernet port → switch
  • Arduino Ethernet shield → switch
  • Laptop (for TIA Portal) → switch
  • Set static IPs: 192.168.0.1 for the PLC (Device Configuration → PROFINET Interface) and 192.168.0.xx for the Arduino.

2. Configure the TCP connection in TIA Portal

Add TCON, TSEND and TRCV instructions in Main [OB1].

TCON (establishes the connection):

  • Local Device: Active
  • Remote IP: 192.168.0.xx (the Arduino’s IP address)
  • Remote Port: must match the port your Arduino server listens on
  • Active connection: TRUE
  • Connection type: TCP

Wire up the TCON block:

  • REQ — bool
  • CONNECT — "DB_TCP".CONNECT (a data block created specifically for the TCP connection)
  • DONE — bool
  • BUSY — bool
  • ERROR — bool
  • STATUS — word

Wire up TSEND/TRCV:

  • REQ — bool
  • ID — 1
  • DATA — "DB_TCP".SEND_CODE / "DB_TCP".RCV_CODE

SEND_CODE/RCV_CODE define the data type sent over the connection (in this example, a char).



3. Send commands from a function block

To keep Main [OB1] readable, put the char commands you send in a separate function block:


:warning: Check: the original source only documents the PLC side of this connection. On the Arduino, you need a sketch that opens a TCP server (with EthernetServer from the Ethernet library) listening on the port configured in TCON, and that reads/writes the same data type you configured in SEND_CODE/RCV_CODE. No such sketch was included in the source — write one that matches your Ethernet shield’s library and your chosen data format.

Method B: Digital I/O signals

A Siemens PLC’s inputs and outputs run at 24V, while an Arduino’s run at 5V — you can’t wire one directly into the other. You need either a voltage converter or a relay in between.

1. Using a voltage converter

Check, for each converter:

  1. Is the input side rated for the voltage you’re feeding it?
  2. Is the output side rated for the voltage you need?

Wire up the input side, then use a multimeter to check the output voltage. Turn the potentiometer until the output matches what you need, turn off the input voltage, and then wire up the output side. This works for both step-up and step-down converters.

To send a signal both ways (PLC → Arduino and Arduino → PLC), you need both a step-down converter (24V → 5V) and a step-up converter (5V → 24V).

2. Using a relay (alternative)

Check, for the relay:

  1. Is the switching coil rated for the voltage you’re supplying it with?
  2. Is the COM-to-NO/NC path rated for the voltage you need on the other side?

Wire the switching coil to the output and ground of the sending device (polarity usually doesn’t matter here), the COM pin to the live wire of the receiving device (24V for the PLC, 5V for the Arduino), and the Normally Open or Normally Closed pin to the input of the receiving device. Check whether you need a pull-up or pull-down resistor on that input so it doesn’t float.

3. Program the PLC side

Create an input tag and an output tag in your default tag table matching the pins you wired up. In this example, a start-button tag triggers the output, and a pneumatic-cylinder tag is triggered by the input received from the Arduino.

Send an output to the Arduino (example in FBD):

Receive an input from the Arduino:

4. Program the Arduino side

// Define the pins that will be used
#define RELAYINPUTPIN 13      // Goes from the 24V PLC output (through a converter/relay) to the 5V Arduino input
#define RELAYOUTPUTPIN 12     // Goes from the 5V Arduino output to the 24V PLC input

// Variable for rising-edge detection
int lastInput = LOW;

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

  pinMode(RELAYINPUTPIN, INPUT);   // use INPUT_PULLUP instead if you don't have a physical pull-down resistor
  pinMode(RELAYOUTPUTPIN, OUTPUT);

  digitalWrite(RELAYOUTPUTPIN, LOW);
}

void loop() {
  // Read the input and check for a rising edge (low to high)
  int status = digitalRead(RELAYINPUTPIN);
  if (status == HIGH && lastInput == LOW) {
    /*
    ---------------------------------
    Put your Arduino code that needs to run here
    ---------------------------------
    */

    // Tell the PLC the Arduino code is done running
    digitalWrite(RELAYOUTPUTPIN, HIGH);
    delay(250);   // signal length: 250 ms
    digitalWrite(RELAYOUTPUTPIN, LOW);
  }
  lastInput = status;
  delay(50);
}

This should work with other microcontrollers too, as long as they support digital I/O at the converted voltage.

Troubleshooting

  • If an input reads randomly instead of a clean LOW/HIGH, you’re likely missing a pull-up/pull-down resistor and the pin is floating.
  • Double-check both sides’ voltage ratings (converter or relay) before wiring anything up — mismatched ratings can damage the PLC, the Arduino, or the converter/relay itself.
  • For the TCP method, make sure the Arduino’s IP address and listening port exactly match the Remote IP/Remote Port set in the PLC’s TCON block.

Related


Rewritten and consolidated (Sept 2026) from the original student how-to’s: Create a TCP connection between PLC Siemens S7-1200 and Arduino Uno or Mega, How to send signals between a Siemens PLC and an Arduino.