Enable and disable I/O of a M-Duino with UDP

May 10, 2019 by
Enable and disable I/O of a M-Duino with UDP
Serzh Ohanyan


1. Introduction
2. Requirements
3. Application
4. Reception
    4.1 Messages Protocol
5. Transmission
6. Code
7. Demonstration
8. Video


This post will be shown an application of using a UDP connection between PC and M-DUINO. The aim is to enable and disable Inputs and Outputs with a message. 


M-Duino family

Ethernet2 library provided by Industrial Shields. Downloading our boards you will have this library. In this link you can read the blog where it explains how to get it. 


With Ethernet2.h we also have available EthernetUDP2.h. This library allows you to send and receive messages with UDP. 

First of all, we have to create your local network to work better without disturbing anyone. Here you have an example diagram:

Our M-Duino has be:ad:be:ef:fe:ed as address mac, as IP and 8888 as local port. The steps to follow are:

    - Configurate our M-Duino with these parameters.

    - Waiting for a message to be received.

    - Transmit confirmation message.

    - Analyze the message.    


Messages Protocol

There are different ways to send the messages, it's up to you, but in our case we have used the next protocol:

ON:QX.X to enable a relay

OFF:QX.X to disable a relay

Knowing the structure of the message that we will receive allows us to know how to filter/analyze it to enable or disable the desired input/output. In this example, we enable and disable a Digital output, but can be applied to an Analog Input/Output or Relay Output using the same protocol. As we know the structure of the messages we can filter by types, Q -> Digital, A -> Analog, R -> Relay...and enable or disable the pin according to the entrance: ON or OFF.


Once we have received a message, we send a confirmation message, ACK, to the remote IP. The port used to transmit the message is 5566.   


This code is prepared for an M-Duino 21+, so we have used Digital I/O (Q0.0...Q0.7). However, as you can see, if you use other boards where there are more zones or have relays, you only have to add the necessary code to filter correctly. 
Here you have the code:  

#include <Ethernet2.h>
#include <EthernetUdp2.h>

byte mac[] = { 0xBE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 20, 1, 2);
uint16_t rx_udp_port = 8888; // local port to listen on
uint16_t tx_udp_port = 5566;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
char *replyBuffer = "ACK\n"; // acknoleged;

EthernetUDP Udp;

void setup() {
  // start Ethernet
  Ethernet.begin(mac, ip);
  // start UDP

static void filter_message(char *packet){
  char zone, pin; switch(packet[1]){ case 'N': // Filter by N -> ON  if (packet[3] == 'Q'){ // Filter by Q -> Digital pin  zone = packet[4]; pin = packet[6]; if (zone == '0'){ // Filter by zone 0, 1 or 2  switch(pin){ // Filter by pin 0, 1, 2, 3, 4, 5, 6 or 7 case '0': digitalWrite(Q0_0, HIGH); break; case '1': digitalWrite(Q0_1, HIGH); break; case '2': digitalWrite(Q0_2, HIGH); break; case '3': digitalWrite(Q0_3, HIGH); break; case '4': digitalWrite(Q0_4, HIGH); break; case '5': digitalWrite(Q0_5, HIGH); break; case '6': digitalWrite(Q0_6, HIGH); break; case '7': digitalWrite(Q0_7, HIGH); break; } }/* If it had more zones else if (zone == '1'){ switch(pin){ case '1': digitalWrite(Q1_0, HIGH); break; case '2': digitalWrite(Q1_1, HIGH); break; case '3': digitalWrite(Q1_2, HIGH); break; . . . } } else if (zone == '2'){ switch(pin){ case '1': digitalWrite(Q2_0, HIGH); break; case '2': digitalWrite(Q2_1, HIGH); break; case '3': digitalWrite(Q2_2, HIGH); break; . . . } }*/ Serial.print("Digital "); Serial.print(zone); Serial.print("."); Serial.print(pin); Serial.println(" activated"); } break; case 'F': // Filter by F -> OFF if (packet[4] == 'Q'){ // some relay I/O zone = packet[5]; pin = packet[7]; if (zone == '0'){ switch(pin){ case '0': digitalWrite(Q0_0, LOW); break; case '1': digitalWrite(Q0_1, LOW); break; case '2': digitalWrite(Q0_2, LOW); break; case '3': digitalWrite(Q0_3, LOW); break; case '4': digitalWrite(Q0_4, LOW); break; case '5': digitalWrite(Q0_5, LOW); break; case '6': digitalWrite(Q0_6, LOW); break; case '7': digitalWrite(Q0_7, LOW); break; } }/* else if (zone == '1'){ switch(pin){ case '1': digitalWrite(Q1_0, LOW); break; case '2': digitalWrite(Q1_1, LOW); break; case '3': digitalWrite(Q1_2, LOW); break; . . . } } else if (zone == '2'){ switch(pin){ case '1': digitalWrite(Q2_0, LOW); break; case '2': digitalWrite(Q2_1, LOW); break; case '3': digitalWrite(Q2_2, LOW); break; . . . } }*/ Serial.print("Digital "); Serial.print(zone); Serial.print("."); Serial.print(pin); Serial.println(" desactivated"); } break; } } void loop() { int packetSize = Udp.parsePacket(); if (packetSize) { // read the packet into packetBufffer Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); // send a reply to the IP address and port that sent us the packet we received Udp.beginPacket(Udp.remoteIP(), tx_udp_port); Udp.write(replyBuffer); Udp.endPacket(); filter_message(packetBuffer); } delay(10); }


In this demonstration we send four messages from the PC (IP : to the M-Duino (IP :

Message 1: Enable Digital pin 0.1

Message 2: Enable Digital pin 0.5

Message 3: Disable Digital pin 0.1

Message 4: Disable Digital pin 0.5 

The following image shows this



​Search in our Blog

Enable and disable I/O of a M-Duino with UDP
Serzh Ohanyan May 10, 2019
Share this post

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.

Industrial PLC comparison >>>