Programando Arduino en Ambientes Industriales

                                 

Curso de 10 Capítulos de Contenido General [IS.AC001.GC]

MATERIAL BÁSICO PARA DESARROLLAR UN PROYECTO INDUSTRIAL CON ARDUINO

Imagino que ya sabrás qué es Arduino por lo que en este curso nos centraremos en cómo utilizar en entornos industriales placas Arduino y los PLCs basados en Arduino para realizar proyectos un 30% más rápido.

Utilizando diferentes herramientas simples conseguirás sacar un alto rendimiento a la programación de Arduino y a la creación de proyectos con Arduino. El tiempo en un proyecto industrial es dinero por lo que te vamos a mostrar cómo ahorrar un 30% de tu tiempo.

  1. Verifica y evalúa las diferentes variables y señales conectadas a tu PLC con una interfaz gráfica.
  2. Utiliza ejemplos ya creados para no tener que empezar desde cero. (Si, ejemplos, no hace falta que el código inicial sea tuyo.  Existen muchos ejemplos válidos para desarrollar tu proyecto)
  3. Utiliza librerías para tus funciones estándar.

(Recuerda: Para nosotros un PLC funciona cómo una placa Arduino. Nuestros PLCs utilizan placas Arduino originales por lo que puedes probar este curso utilizando placas Arduino originales).

Prepara este material en tu ordenador para empezar el capítulo 1.  

Utilizando una una simple plataforma gráfica se puede visualizar el estado del PLC cómodamente y de forma amigable. Esta también la puedes utilizar como SCADA en tu proyecto y lo podrás integrar en tus proyectos como interfaz Hombre-Maquina. Simple, fácil y sin coste. Te recomendamos utilizar una plataforma Open Source llamada PROCESSING. (El Arduino IDE se basa en esta plataforma por lo que te resultará muy familiar).

Utiliza el Arduino IDE para programar tu PLC. Repasar los diferentes ejemplos del Arduino IDE ayuda para no tener que empezar desde cero tu proyecto. Con el Arduino IDE sólo tienes que seleccionar la placa Arduino que utilizas y el puerto USB en el que está conectado el equipo.

Para la configuración de las diferentes entradas y salidas utilizando los PLCs Industrial Shields puedes utilizar nuestra librería almacenada en GitHub y olvidarte de revisar el pinout de los equipos. Consulta cómo cargar la librería en nuestro post del blog.

Odoo image and text block

Do you want to continue the course?...for free!!!

If you are interested in receive the next chapters for free just fill the form.

You will receive a weekly chapter to program Arduino on industrial uses.

Industrial Applications can run under Open Source Platforms

Send

CONECTAR UNA PLACA ARDUINO AL ORDENADOR

Tienes que saber 2 cosas muy básicas:

Con Processing puedes hacer una Interfaz Gráfica de forma muy simple para Visualizar e interactuar con tu PLC y gobernar tu instalación.

El Arduino IDE permite utilizar librerías para que puedas estandarizar los algoritmos que mas utilizas y estructurar mejor tu programa. Te animamos a que veas la librería de Arduino de Industrial Shields en GitHub para que veas cómo están estructuradas las carpetas. En los próximos capítulos veremos cómo se estructura una librería y cómo se hacen llamadas a la acción de esta.

(Recuerda: Para nosotros un PLC funciona cómo una placa Arduino. Nuestros PLCs utilizan placas Arduino originales por lo que puedes probar este curso utilizando placas Arduino originales).

Links de interés:

Material para poder practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(The devices used with the Arduino Mega and Arduino Leonardo assembled inside have been: From the Ethernet PLCs; the M-duino21. From the 20I/Os PLC; The Ardbox Relay  ).

ENTRADAS

Tienes que saber 2 cosas muy básicas:

You can do the course practices using an original Arduino board. In fact, our PLCs have an original Arduino board assembled inside, So, it is not necessary to do practices using our devices if you don’t want. You can use an Arduino Leonardo board, which is the board used in our 20I/Os PLCs (they are called: Ardbox) and you also can use an Arduino Mega which is used inside the Ethernet family of PLCs (called M-duino).

Alerta conexionado:

Es importante tener en cuenta que cuando conectes una entrada a una placa Arduino esta no puede ser superior a 5Vcc. Por lo que si utilizas un sensor industrial que trabaje a 24Vdc no lo podrás conectar directamente a esta placa. En cualquier caso con los diferentes PLCs puedes conectar sensores industriales hasta 24Vcc.

(Recuerda: Para nosotros un PLC funciona cómo una placa Arduino. Nuestros PLCs utilizan placas Arduino originales por lo que puedes probar este curso utilizando placas Arduino originales).

Si quieres utilizar sensores analógicos, la placa Arduino trabaja de 0 a 5Vcc. No puedes conectar tensiones superiores. Por otro lado, en la industria nos encontramos sensores analógicos que ofrecen una señal del tipo 4-20mA o señales de 0-10Vcc. La conversión de una señal analógica que funciona con intensidad es muy sencillo transformarlo a Voltaje ya que, por la LEY de OHM puedesconvertir 4-20mA a 0-10Vcc.

Links de interés:

Material para poder practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(The devices used with the Arduino Mega and Arduino Leonardo assembled inside have been: From the Ethernet PLCs; the M-duino21. From the 20I/Os PLC; The Ardbox Relay  )

SALIDAS

Tienes que saber 2 cosas muy básicas:

You can do the course practices using an original Arduino board. In fact, our PLCs have an original Arduino board assembled inside, So, it is not necessary to do practices using our devices if you don’t want. You can use an Arduino Leonardo board, which is the board used in our 20I/Os PLCs (they are called: Ardbox) and you also can use an Arduino Mega which is used inside the Ethernet family of PLCs (called M-duino).

Alerta conexionado:

Las salidas de los PLCs ofrecen voltaje por lo que es importante que tengas en cuenta la polaridad de los diferentes elementos que conectes a estas. El voltaje de las salidas que no estén Opto-aisladas será el mismo que el voltaje de alimentación del equipo. Lo que será 12Vcc o 24Vcc en función de la tensión de alimentación del PLC. Para las salidas Opto-aisladas se puede conectar el voltaje de 5 a 24Vcc. Es importante conectar también el común a estas salidas, según se indica en el esquema del PLC. Para gobernar una salida digital utilizaras la sentencia DigitalWrite().

(Recuerda: Para nosotros un PLC funciona cómo una placa Arduino. Nuestros PLCs utilizan placas Arduino originales por lo que puedes probar este curso utilizando placas Arduino originales). 

Las salidas analógicas se programan exactamente igual que una salida PWM. En las placas Arduino las señales PWM trabajaran a 5Vcc. Para los PLCs el voltaje dependera del Vcc conectado al equipo. En caso de conectar las salidas Analógicas estas siempre serán de 0-10Vcc. La resolución de estas señales es de 8bits por lo que puedes variar el valor de la señal de 0 a 255 utilizando la sentencia AnalogWrite().

Material para poder practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(The devices used with the Arduino Mega and Arduino leonardo assembled inside have been: From the Ethernet PLCs; the M-duino21. From the 20I/Os PLC; The Ardbox Relay).

ENTRADAS ENTRADAS Y SALIDAS. TRABAJO SIMULTÁNEO

Tienes que saber algunas cosas muy básicas: 

You can practice with an Arduino board. In the different PLCs we use original Arduino boards, for this reason it is not necessary that you practice with our equipment.

A menudo, cuando se leen entradas en un PLC se almacena su estado en una variable. Esta variable se puede utilizar para enviar su estado a través de algún sistema de comunicación (RS485, RS232, Ethernet, Serial TTL, etc) o tambien para realizar una serie de funciones tales cómo filtros, trabajar por flancos, contadores, etc.  Para activar una salida también es común utilizar una seria de variables que serán las encargadas de definir el estado de la salida en cuestión.

Trabajo para el alumno:

te vamos a hacer trabajar. Ahora deberías saber como leer una entrada digital y una entrada analógica. También deberías saber activar una salida digital y una salida analógica. (Recuerda que las salidas analógicas se programan igual que las salidas PWM si bien unas te dan una señal por pulsos y la otra te ofrece una señal analógica 0-10Vdc en función al valor que según las salidas de 8bits oscila entre 0-255.

(Recuerda: Para nosotros un PLC funciona cómo una placa Arduino. Nuestros PLCs utilizan placas Arduino originales por lo que puedes probar este curso utilizando placas Arduino originales).

Links de interés:

Material para poder practicar:

  • Arduino Leonardo or Arduino Mega (You can also use an Arduino UNO board if you have one).

(The equipment used with the Arduino Mega and Arduino Leonardo boards inside it were: the Ethernet PLC family, the M-duino21 and the basic 20 I / Os PLCs, the Ardbox Relay).

VARIABLES I

Al leer este capitulo tienes que tener en cuenta una serie de puntos:

You can practice with an Arduino board. In the different PLCs we use original Arduino boards, for this reason it is not necessary that you practice with our equipment.

En este capitulo te contamos unas nociones básicas de los tipos de variables que tratamos en un programa.  Esto es importante ya que utilizar la variable del tipo adecuado en un proyecto es clave para evitar posibles problemas a la hora de operar con estas. También te permite optimizar bien el código cosa que agradecerás cuando vayas a utilizar diferentes sistemas de comunicación con los equipos (RS485, RS232, Ethernet, Serial TTL, etc) Todo lo que veremos en este capitulo te sirve tanto para la programación en General, no solo para la programación de Arduino pero es muy importante conocer y saber que existe diferencias entre los diferentes tipos de Variables. Y también ciertas similitudes entre una u otra por lo que tampoco será tienes que sentirte agobiado al ver este temario. Con los diferentes capítulos verás y asimilaras el uso de un tipo y otro.

Repaso del temario:

En este capitulo te vamos, a parte de ver el vídeo te recomendamos que te leas los diferentes tipos de variables que tratamos.

En el vídeo te mostramos de dónde puedes ver esta información por lo que de forma muy rápida puedes repasar el temario de este capitulo. El objetivo es que puedas identificar los diferentes tipos de variables tratados así como tener una idea de cuando utilizar un tipo u otro.

(Remember: For us a PLC works like an Arduino board, our PLCs use original Arduino boards so you can try this course using original Arduino boards).

Links de interés:

Material para poder practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(The equipment used with the Arduino Mega and Arduino Leonardo boards inside it were: the Ethernet PLC family, the M-duino21 and the basic 20 I / Os PLCs, the Ardbox Relay).

VARIABLES II

Al leer este capitulo tienes que tener en cuenta una serie de puntos:

You can practice with an Arduino board. In the different PLCs we use original Arduino boards, for this reason it is not necessary that you practice with our equipment.

In this chapter we continue with the types of variables that we treat in a program, where we left it in the previous chapter. This is important since using the variable of the appropriate type in a project is key to avoid possible problems when operating with these. It also allows you to optimize well the code thing that you will appreciate when you go to use different systems of communication with the equipment (RS485, RS232, Ethernet, Serial TTL, etc) Everything what we will see in this chapter serves you so much for the programming in General, not only for Arduino programming but it is very important to know and know that there are differences between the different types of Variables. And also certain similarities between one or the other so you will not have to feel overwhelmed to see this agenda. With the different chapters you will see and assimilate the use of one type and another.

Variables:

It is important to be clear about how different truths are declared and what options we have in each of them. In the final part of the video we also show you how to write these variables in the Arduino IDE.

In the video we show you where you can see this information so that very quickly you can review the agenda of this chapter. The objective is that you can identify the different types of variables treated as well as have an idea of when to use one type or another.

(Remember: For us a PLC works like an Arduino board, our PLCs use original Arduino boards so you can try this course using original Arduino boards).

Links de interés:

Material para poder practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(The equipment used with the Arduino Mega and Arduino Leonardo boards inside it were: the Ethernet PLC family, the M-duino21 and the basic 20 I / Os PLCs, the Ardbox Relay).

COMUNICACIONES

Al leer este capitulo tienes que tener en cuenta una serie de puntos:

You can practice with an Arduino board. In the different PLCs we use original Arduino boards, for this reason, it is not necessary that you practice with our equipment.

En este capitulo vamos a explicar los diferentes tipos de comunicaciones básicos de los que dispone una placa Arduino así como las diferentes adaptaciones industriales para conseguir comunicarse con equipos de uso industrial. Los diferentes tipos de comunicación habilitados en los PLCs basados en Arduino són: I2C, Serial TTL, RS232, RS485, y SPI, a través del cual conseguimos realizar una comunicación por Ethernet.

Comunicaciones:

Es importante tener claro como se conecta cada tipo de comunicación y que se puede realizar en cada uno de estas. Cuantos equipos se pueden conectar. Si se puede realizar un bus o simplemente permite comunicar 2 equipos uno con el otro. etc.

En el vídeo te mostramos diferencias entre las comunicaciones por parte de Arduino y en los PLCs basados en Arduino que permiten conectar directamente con otros equipos industriales. El objetivo es que entiendas que es mas recomendable utilizar en función de las necesidades para que en los proximos capitulos veamos mas en detalle cada uno de estos sistemas de comunicación.

(Recuerda: Para nosotros un PLC funciona cómo una placa Arduino. Nuestros PLCs utilizan placas Arduino originales por lo que puedes probar este curso utilizando placas Arduino originales). 

Links de interés:

Material para poder practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(The equipment used with the Arduino Mega and Arduino Leonardo boards inside it were: the Ethernet PLC family, the M-duino21 and the basic 20 I / Os PLCs, the Ardbox Relay).


ETHERNET

En este capítulo veremos cómo es el protocolo de comunicación Ethernet y cómo funciona en general y en nuestros equipos, teniendo en cuenta la plataforma Arduino IDE. Debemos recordar que cualquier equipo con puerto Ethernet se puede programar utilizando este protocolo, en nuestros dispositivos tenemos muchos con conexión Ethernet como la familia M-Duino y otros.


Introducción teórica

En primer lugar, es muy importante explicar el modelo OSI para comprender todos los elementos que conforman un sistema de telecomunicaciones. El OSI es el modelo de interconexión de sistemas abiertos y este es un modelo conceptual que caracteriza y estandariza las funciones de comunicación de un sistema de telecomunicaciones o informática sin tener en cuenta su estructura interna subyacente. Su objetivo principal es la interoperabilidad de diversos sistemas de comunicación con protocolos de comunicación estándar. Este modelo se divide en siete capas de abstracción diferentes.


Cada capa sirve a la capa de arriba y es servida por la capa debajo de ella. Por ejemplo, una capa que proporciona comunicaciones sin errores a través de una red proporciona la ruta requerida por las aplicaciones por encima de ella, mientras llama a la siguiente capa inferior para enviar y recibir paquetes que constituyen el contenido de esa ruta.


Las diferentes capas son:

1.-Capa de aplicación: es la más cercana al usuario, lo que significa que tanto este como el usuario interactúan directamente con la aplicación de software.

2.-Capa de presentación: establece el contexto entre las entidades de la capa de aplicación.

3.-Capa de sesión: controla las conexiones entre computadoras.

4.-Capa de transporte: proporciona los medios funcionales y de procedimiento para transferir secuencias de datos de longitud variable desde un host de origen a un host de destino, manteniendo la calidad de las funciones de servicio.

5.-Capa de red: proporciona los medios funcionales y de procedimiento para transferir paquetes de un nodo a otro conectado en diferentes redes.

6.-Capa de enlace de datos: proporciona transferencia de datos de nodo a nodo, un enlace entre dos nodos conectados directamente.

7.-Capa física: es responsable de la transmisión y recepción de datos brutos no estructurados entre un dispositivo y un medio de transmisión física.


Aquí, podemos ver un esquema de las capas:

Es importante tener en cuenta que hay dos tipos de Modbus; el Modbus TCP que usa Ethernet y está ubicado en la capa 7, y el Modbus 232/485 que usa estos protocolos y está ubicado en todas las capas. Tenemos que tener en cuenta que, muchas veces, las capas de red, datos y física están abarcadas como capas de medios y las otras como capas de host.


Ahora que estamos ubicados, podemos continuar con la explicación principal del vídeo y, si desea descubrir más información relacionada con Ethernet, puede consultar los enlaces que se muestran a continuación.


Enlaces útiles:


Material para practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(El equipo utilizado con las placas Arduino Mega y Arduino Leonardo en su interior eran: la familia de PLC Ethernet, el M-Duino21 y los PLC básicos de 20 E / S, el relé Ardbox).

Odoo image and text block

Do you want to continue the course?...for free!!!

If you are interested in receive the next chapters for free just fill the form.

You will receive a weekly chapter to program Arduino on industrial uses.

Industrial Applications can run under Open Source Platforms

Send

EJEMPLOS: CONTROLAR ENTRADAS-SALIDAS REMOTAMENTE USANDO ETHERNET

Al leer este capítulo, debe tener en cuenta una serie de puntos:

Puedes practicar con una placa Arduino. En los diferentes PLC utilizamos placas Arduino originales, por este motivo no es necesario que practique con nuestros equipos.

(Recuerde: para nosotros, un PLC funciona como una placa Arduino, nuestros PLC utilizan placas Arduino originales para que pueda probar este curso utilizando placas Arduino originales).


Introducción: 

Este es un nuevo capítulo sobre el curso de programación Arduino para uso industrial. En este capítulo veremos un ejemplo sobre cómo administrar las entradas y salidas de un PLC Arduino de forma remota utilizando Ethernet, relacionado con el capítulo anterior. Entonces, hablaremos sobre este ejemplo de control y el protocolo Ethernet.


There are a lot of different Ethernet protocols; UDP, for example, but the most used is TCP, which we will see a practical example of it. Our programming team developed a      new protocol, designed to perform better in our equipment and thinked for our clients, called SimpleComm.


Explicación teórica: 

En este capítulo veremos un ejemplo práctico sobre cómo administrar las entradas y salidas de un PLC usando Ethernet. Vamos a utilizar el protocolo TCP para establecer este tipo de comunicación pero, con respecto a esto, tenemos que recordar el modelo OSI explicado en el capítulo anterior y, relacionándolo con nuestro modelo específico, podemos ver un esquema como este:



Ejemplo 1:

Este tipo de comunicación se basa en un maestro y un esclavo, se puede encontrar más información sobre este tipo de relación en esta publicación ->    POST Configuración del Protocolo RS-485 en Arduino IDE                                                                                                                                                                                                                                                   -Configuración del Protocolo RS-485 en Arduino IDEEl ejemplo práctico que veremos en este capítulo se basa en dos publicaciones de nuestro blog, divididos en partes de esclavo (Slave) y maestro (Master):
-Cómo utilizar la biblioteca TCP Slave con controlador industrial basado en Arduino 
-Modbus TCP Master con PLCs Industriales basados en Arduino

-Cómo conectar PLCs basados en Arduino mediante Modbus TCP/IP

Slave:

En este ejemplo, como vimos en los párrafos anteriores, el protocolo de capa de aplicación utilizado es Modbus. Antes de todo tenemos que ver algunos aspectos para entender el código de una manera mejor. 


Tipo de objeto Acceso Tamaño
Bobina
Lectura y Escritura 1 bit
Entrada discreta
Lectura 1 bit
Registro de entrada
Lectura 16 bits
Registros de retención 
Lectura y Escritura 16 bits

Normalmente las bobinas se utilizan para escribir valores digitales en una salida. Las entradas discretas se utilizan para leer entradas digitales. Los registros se utilizan para     comunicar datos entre los dispositivos y también se utilizan normalmente para E/S analógicas. 

En este caso veremos cómo utilizar la biblioteca de esclavos de Tools40.

Requisitos

Funciones del Modbus TCP slave

El módulo ModbusTCPSlave implementa las capacidades Modbus TCP Slave.

#include <ModbusTCPSlave.h>

ModbusTCPSlave slave;

El puerto TCP predeterminado es el 502 pero puedes cambiarlo con:

// Set the TCP listening port to 510 instead of 502
ModbusTCPSlave slave(510);

Para cartografiar las bobinas, entradas discretas, registros de retención y direcciones de registros de entrada con los valores de variables deseados, el módulo      utiliza cuatro matrices de variables: 

bool coils[NUM_COILS];
bool discreteInputs[NUM_DISCRETE_INPUTS];
uint16_t holdingRegistesr[NUM_HOLDING_REGISTERS];
uint16_t inputRegisters[NUM_INPUT_REGISTERS];

Las longitudes de estas matrices dependen de la aplicación y de los usos de los registros. Obviamente, los nombres de las matrices también dependen de sus     preferencias.

Para asociar las matrices de registro con la biblioteca, es posible utilizar estas funciones en elsetup:

slave.setCoils(coils, NUM_COILS);
slave.setDiscreteInputs(discreteInputs, NUM_DISCRETE_INPUTS);
slave.setHoldingRegisters(holdingRegisters, NUM_HOLDING_REGISTERS);
slave.setInputRegisters(inputRegisters, NUM_INPUT_REGISTERS);

No es necesario tener todo tipo de asignación de registros para trabajar, sólo el utilizado por la aplicación.

Para iniciar el servidor ModbusTCP, llama a la función begin después de la asignación de registros. También es posible llamar a la funciónbeginantes de la         asignación de registros. Recuerda empezar el Ethernet antes del objeto ModbusTCPSlave en el setup.

// Init the Ethernet
Ethernet.begin(mac, ip);

// Init the ModbusTCPSlave object
slave.begin();

En este momento el servidor ModbusTCP se esta ejecutando y la único importante que hay que hacer es actualizar el objeto ModbusTCPSlave a menuda en la      funciónloop, y tratar los registros de valores de asignación para actualizar variables, entradas y salidas. 

// Update discrete inputs and input registers values
discreteInputs[0] = digitalRead(I0_7);
inputRegisters[0] = analogRead(I0_0);
// ...

// Update the ModbusTCPSlave object
slave.update();

// Update coils and holding registers
digitalWrite(Q0_0, coils[0]);
// ...


Ejemplo de Software para el controlador de automatización basado en Arduino

/*
   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <ModbusTCPSlave.h>
#if defined(MDUINO_PLUS)
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif
// Ethernet configuration values
uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };
IPAddress ip(10, 10, 10, 4);
int port = 502;
// Modbus registers mapping
// This example uses the M-Duino21+ mapping
int digitalOutputsPins[] = {
#if defined(PIN_Q0_4)
  Q0_0, Q0_1, Q0_2, Q0_3, Q0_4,
#endif
};
int digitalInputsPins[] = {
#if defined(PIN_I0_6)
  I0_0, I0_1, I0_2, I0_3, I0_4, I0_5, I0_6,
#endif
};
int analogOutputsPins[] = {
#if defined(PIN_A0_7)
  A0_5, A0_6, A0_7,
#endif
};
int analogInputsPins[] = {
#if defined(PIN_I0_12)
  I0_7, I0_8, I0_9, I0_10, I0_11, I0_12,
#endif
};
#define numDigitalOutputs int(sizeof(digitalOutputsPins) / sizeof(int))
#define numDigitalInputs int(sizeof(digitalInputsPins) / sizeof(int))
#define numAnalogOutputs int(sizeof(analogOutputsPins) / sizeof(int))
#define numAnalogInputs int(sizeof(analogInputsPins) / sizeof(int))
bool digitalOutputs[numDigitalOutputs];
bool digitalInputs[numDigitalInputs];
uint16_t analogOutputs[numAnalogOutputs];
uint16_t analogInputs[numAnalogInputs];
// Define the ModbusTCPSlave object
ModbusTCPSlave modbus(port);
////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600UL);
  // Init variables, inputs and outputs
  for (int i = 0; i < numDigitalOutputs; ++i) {
    digitalOutputs[i] = false;
    digitalWrite(digitalOutputsPins[i], digitalOutputs[i]);
  }
  for (int i = 0; i < numDigitalInputs; ++i) {
    digitalInputs[i] = digitalRead(digitalInputsPins[i]);
  }
  for (int i = 0; i < numAnalogOutputs; ++i) {
    analogOutputs[i] = 0;
    analogWrite(analogOutputsPins[i], analogOutputs[i]);
  }
  for (int i = 0; i < numAnalogInputs; ++i) {
    analogInputs[i] = analogRead(analogInputsPins[i]);
  }
  // Init Ethernet
  Ethernet.begin(mac, ip);
  Serial.println(Ethernet.localIP());
  // Init ModbusTCPSlave object
  modbus.begin();
  modbus.setCoils(digitalOutputs, numDigitalOutputs);
  modbus.setDiscreteInputs(digitalInputs, numDigitalInputs);
  modbus.setHoldingRegisters(analogOutputs, numAnalogOutputs);
  modbus.setInputRegisters(analogInputs, numAnalogInputs);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  // Update inputs
  for (int i = 0; i < numDigitalInputs; ++i) {
    digitalInputs[i] = digitalRead(digitalInputsPins[i]);
  }
  for (int i = 0; i < numAnalogInputs; ++i) {
    analogInputs[i] = analogRead(analogInputsPins[i]);
  }
  // Process modbus requests
  modbus.update();
  // Update outputs
  for (int i = 0; i < numDigitalOutputs; ++i) {
    digitalWrite(digitalOutputsPins[i], digitalOutputs[i]);
  }
  for (int i = 0; i < numAnalogOutputs; ++i) {
    analogWrite(analogOutputsPins[i], analogOutputs[i]);
  }
}

Recomendación

Familia de controladores M-Duino Biblioteca Tools40 instalada


Master:

Ahora, teniendo en cuenta la misma información Modbus que vimos en la parte Esclavo (Slave) y los mismos Requisitos, vamos a ver la parte Maestro  (Master):

Funciones Master del Modbus TCP 

Las funciones para leer y escribir valores esclavo son:

readCoils(client, slave_address, address, quantity);
readDiscreteInputs(client, slave_address, address, quantity);
readHoldingRegisters(client, slave_address, address, quantity);
readInputRegisters(client, slave_address, address, quantity);
writeSingleCoil(client, slave_address, address, value);
writeSingleRegister(client, slave_address, address, value);
writeMultipleCoils(client, slave_address, address, values, quantity);
writeMultipleRegisters(client, slave_address, address, values, quantity);

Dónde

  • client es el EthernetClient conectado al esclavo.
  • slave_addresses la dirección esclava TCP Modbus.
  • addresses la bobina, la entrada digital, el registro de retención o la dirección del registro de entrada. Normalmente esta dirección es la bobina, entrada       digital, registro de retención o número de registro de entrada menos 1: el número de registro de retención40009 tiene la dirección 8.
  • quantity es el número de bobinas, entradas digitales, registros de retención o registros de entrada para lectura/escritura.
  • valuees el valor dado de la bobina o registros de retención en una operación de escritura. Dependiendo de la función, el tipo de datos cambia. Una bobina esta representada por un valor bool i un registro de retención está representado por un valor uint16_t.

En una función de lectura y escritura múltiple, el argumentoaddress es la primera dirección de elemento. En una función de escritura múltiple, el argumento      valueses una matriz de valores para escribir.

Es importante tener en cuenta que estas funciones no son de bloqueo, por lo que no devuelven el valor de lectura. Devuelven true o falsedependiendo en el estado actual del módulo. Si hay una solicitud Modbus pendiente o el cliente no está conectado, devuelve false.

// Read 5 holding registers from address 0x24 of slave with address 0x10if (master.readHoldingRegisters(client, 0x10, 0x24, 5)) {
	// OK, the request is being processed
} else {
	// ERROR, the master is not in an IDLE state
}

Existe la función available() para comprobar si hay respuestas del Esclavo.

ModbusResponse response = master.available();
if (response) {
	// Process response
}

El ModbusResponse implementa algunas funciones para obtener la información de respuesta:

hasError();
getErrorCode();
getSlave();
getFC();
isCoilSet(offset);
isDiscreteInputSet(offset);
isDiscreteSet(offset);
getRegister(offset);
ModbusResponse response = master.available();
if (response) {
	if (response.hasError()) {
		// There is an error. You can get the error code with response.getErrorCode()
	} else {
		// Response ready: print the read holding registers
		for (int i = 0; i < 5; ++i) {
			Serial.println(response.getRegister(i);
		}
	}
}

Los posibles errores de código son:

                            0x01 ILLEGAL FUNCTION
0x02 ILLEGAL DATA ADDRESS
0x03 ILLEGAL DATA VALUE
0x04 SERVER DEVICE FAILURE
                          


Software

Después de ver las bases de la biblioteca Modbus TCP Master podemos proceder a desarrollar un código para comunicarnos con otro dispositivo Modbus en nuestra red. En este código se muestra cómo leer registros y cómo escribir bobinas desde otro esclavo Modbus TCP/IP. Este ejemplo escribirá números aleatorios en bobinas digitales cada segundo y también leerá 6 valores del esclavo cada 500 milisegundos. 


/*
   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <ModbusTCPMaster.h>
#if defined(MDUINO_PLUS)
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif

// Ethernet configuration values
uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 10, 10, 3);
IPAddress slaveIp(10, 10, 10, 4);
uint16_t slavePort = 502;

// Define the ModbusTCPMaster object
ModbusTCPMaster modbus;

// Ethernet client object used to connect to the slave
EthernetClient slave;
uint32_t lastSentTime = 0UL;
uint32_t lastSentTimeReadInputs = 0UL;

////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600UL);
  // Begin Ethernet
  Ethernet.begin(mac, ip);
  Serial.println(Ethernet.localIP());
  // NOTE: it is not necessary to start the modbus master object
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  // Connect to slave if not connected
  // The ethernet connection is managed by the application, not by the library
  // In this case the connection is opened once
  if (!slave.connected()) {
    slave.stop();
    slave.connect(slaveIp, slavePort);
    if (slave.connected()) {
      Serial.println("Reconnected");
    }
  }
  // Send a request every 1000ms if connected to slave
  if (slave.connected()) {
    if (millis() - lastSentTime > 1000) {
      // Set random values
      bool values[5];
      for (int i = 0; i < 5; ++i) {
        values[i] = random() & 0x01;
      }
      // Send a Write Multiple Coils request to the slave with address 31
      // It requests for setting 5 coils starting in address 0
      // IMPORTANT: all read and write functions start a Modbus transmission, but they are not
      // blocking, so you can continue the program while the Modbus functions work. To check for
      // available responses, call modbus.available() function often.
      if (!modbus.writeMultipleCoils(slave, 31, 0, values, 5)) {
        // Failure treatment
        Serial.println("Request fail");
      }
      lastSentTime = millis();
    }
    // Check available responses often
    if (modbus.isWaitingResponse()) {
      ModbusResponse response = modbus.available();
      if (response) {
        if (response.hasError()) {
          // Response failure treatment. You can use response.getErrorCode()
          // to get the error code.
          Serial.print("Error ");
          Serial.println(response.getErrorCode());
        } else {
          Serial.println("Done");
        }
      }
    }
    
    if (millis() - lastSentTimeReadInputs > 500) {
      // Send a Read Input Registers request to the slave with address 31
      // It requests for 6 registers starting at address 0
      // IMPORTANT: all read and write functions start a Modbus transmission, but they are not
      // blocking, so you can continue the program while the Modbus functions work. To check for
      // available responses, call master.available() function often.
      if (!modbus.readInputRegisters(slave, 31, 0, 6)) {
        // Failure treatment
      }
      lastSentTimeReadInputs = millis();
    }
    
    if (modbus.isWaitingResponse()) {
      ModbusResponse response = modbus.available();
      if (response) {
        if (response.hasError()) {
          // Response failure treatment. You can use response.getErrorCode()
          // to get the error code.
        } else {
          // Get the input registers values from the response
          Serial.print("Input registers values: ");
          for (int i = 0; i < 6; ++i) {
            Serial.print(response.getRegister(i));
            Serial.print(',');
          }
          Serial.println();
        }
      }
    }
  }
}



Ejemplo 2:

Siguiendo la parte anterior del Esclavo del ejemplo y, cambiando un poco el código del maestro para hacerlo más interactivo con el usuario, aquí               tenemos otro ejemplo: 

Arquitectura de la aplicación

M-Duino master tiene un menú serie interactivo que permite al usuario controlar la aplicación. El menú tiene 6 opciones. Las primeras cuatro opciones son controlar dos salidas del Esclavo, la quinta opción es obtener las entradas analógicas o registros del Esclavo y la última opción, sexta, es obtener las entradas digitales o entradas            discretas del Esclavo.

Utilizamos las funciones writeSingleCoil(), readInputRegisters() y readDiscreteInputs() para comunicarnos con el Esclavo. A continuación, simplemente ejecutando un corto bucle dependiendo del mensaje que hayamos enviado, leemos los valores usando response.getRegister() o response.isDiscreteInputSet().

El resto del código es sólo configuraciones Ethernet y comandos Serial para depurar y hacer la aplicación más interactiva.


Software

/*
   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <ModbusTCPMaster.h>
#if defined(MDUINO_PLUS)
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif
// Ethernet configuration values
uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 10, 10, 3);
IPAddress slaveIp(10, 10, 10, 4);
uint16_t slavePort = 502;
// Define the ModbusTCPMaster object
ModbusTCPMaster modbus;
//
bool registerSet = 0;
bool discreteSet = 0;
// Ethernet client object used to connect to the slave
EthernetClient slave;
uint32_t lastSentTime = 0UL;
uint32_t lastSentTimeReadInputs = 0UL;
////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600UL);
  // Begin Ethernet
  Ethernet.begin(mac, ip);
  Serial.println(Ethernet.localIP());
// NOTE: it is not necessary to start the modbus master object
mainUI();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  // Connect to slave if not connected
  // The ethernet connection is managed by the application, not by the library
  // In this case the connection is opened once
  if (!slave.connected()) {
    Serial.println("Slave not connected");
    slave.stop();
    slave.connect(slaveIp, slavePort);
    if (slave.connected()) {
      Serial.println("Reconnected");
    }
  }
  // Send a request every 1000ms if connected to slave
  if (slave.connected()) {
    //Serial.println("Slave connected");
  if (Serial.available()) {
      byte chosenOption= Serial.read();
  bool value;
  byte address;
  switch(chosenOption){
      case '1': //set Q0_0 to high
          value = 1;
          address = 0;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_0 set to HIGH");
          break; 
      case '2': //set Q0_0 to low
          value = 0;
          address = 0;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_0 set to LOW");
          break;
      case '3': //set Q0_1 to high
          value = 1;
          address = 1;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_1 set to HIGH");
          break;
      case '4':
          value = 0;
          address= 1;
          if (!(modbus.writeSingleCoil(slave, 0, address, value))) {
            // Failure treatment
            Serial.println("Request fail");
          }
          Serial.println("Q0_1 set to LOW");
          break;
      case '5':
          if (!modbus.readInputRegisters(slave, 0, 0, 6)) {
            // Failure treatment
            Serial.println("Error requesting registers");
          }else{registerSet = true;}
          break;
      case '6':
          if (!modbus.readDiscreteInputs(slave, 0, 0, 7)) {
          // Failure treatment
          Serial.println("Error requesting discrete input");
          }else{discreteSet = true;} 
          break;
  }
mainUI();
    }
    if (modbus.isWaitingResponse()) {
      ModbusResponse response = modbus.available();
      if (response) {
        if (response.hasError()) {
          // Response failure treatment. You can use response.getErrorCode()
          // to get the error code.
        }else if (registerSet){
          // Get the input registers values from the response
          Serial.print("Input registers values: ");
          for (int i = 0; i < 6; ++i) {
            Serial.print(response.getRegister(i));
            Serial.print(',');
          }
          registerSet = false; 
        } else if(discreteSet) {
          // Get the input registers values from the response
          Serial.print("Input discrete values: [");
          for (int i = 0; i < 7; ++i) {
            Serial.print(response.isDiscreteInputSet(i));
            Serial.print(',');
          }
          Serial.println(']');
          discreteSet = false;
        }
      }
    }
  }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void mainUI(){
    Serial.println("********************Modbus Test*********************");
    Serial.println("Chose an option:");
    Serial.println("1. Set Q0_0 to HIGH");
    Serial.println("2. Set Q0_0 to LOW");
    Serial.println("3. Set Q0_1 to HIGH");
    Serial.println("4. Set Q0_1 to LOW");
    Serial.println("5. Print slave input analog values");
    Serial.println("6. Print slave input digital values");
    Serial.println("****************************************************");


Enlaces útiles:


Material para practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(El equipo utilizado con las placas Arduino Mega y Arduino Leonardo en su interior eran: la familia de PLC Ethernet, el M-duino21 y los PLC básicos de 20 E / S, el Relé Ardbox). 


Odoo image and text block

Do you want to continue the course?...for free!!!

If you are interested in receive the next chapters for free just fill the form.

You will receive a weekly chapter to program Arduino on industrial uses.

Industrial Applications can run under Open Source Platforms

Send

SERIAL TTL, RS232, RS485

Las comunicaciones en el PLC de Arduino son uno de los puntos más destacados a considerar porque es uno de sus puntos fuertes y, en relación con esto, hay muchos protocolos de comunicación diferentes. En este capítulo, veremos tres tipos diferentes de los principales protocolos de comunicación; Serial TTL, RS-232 y RS-485.

Serial TTL es un tipo de comunicación TTL (Transistor-Transistor Logic) en serie. TTL es una familia lógica de transistores de unión bipolar. Este transistor realiza la lógica y la función de amplificación también.

RS-232 es otro estándar para la transmisión de datos en comunicación en serie. Define formalmente las señales que se conectan entre DTE (equipo terminal de datos), como un terminal de computadora, y un DCE (equipo de terminación de circuito de datos o equipo de comunicación de datos), como un módem.

RS-485 es, una vez más, un estándar para sistemas de comunicación en serie en los que la señalización eléctrica está equilibrada y se admiten sistemas multipunto. Las redes de comunicaciones digitales que implementan el estándar se pueden usar de manera efectiva a largas distancias y en entornos eléctricamente ruidosos. Se pueden conectar múltiples receptores a dicha red en un bus lineal de múltiples líneas.

Con la información que se muestra en esta introducción, podemos proceder a ver el vídeo.


Ahora que estamos ubicados, podemos continuar con la explicación principal del vídeo y, si desea descubrir más información relacionada con Ethernet, puede consultar los enlaces que se muestran a continuación.


Enlaces útiles:


Material para practicar:

  • Arduino Leonardo o Arduino Mega (También puedes utilizar una placa Arduino UNO si la tienes).

(El equipo utilizado con las placas Arduino Mega y Arduino Leonardo en su interior eran: la familia de PLC Ethernet, el M-Duino21 y los PLC básicos de 20 E / S, el relé Ardbox).