You are on page 1of 21

Brayan Baquero Cardozo-Brayan Torres Malaver

T’’ ACTIVIDAD: Comunicación Modbus TCP entre


NodeMCU e InTouch

Desarrollo de la practica

1 programación NodeMCU

1.1 Librerías
1.1.1. Para integrar la plataforma Arduino al NodeMcu es necesario la instalación de las librerías
necesarias, para ello lo primero que se debe hacer es abrir la plataforma de Arduino y seleccionar
Archivo>Preferencias.
Brayan Baquero Cardozo-Brayan Torres Malaver

1.1.2. Una vez en preferencias buscamos la opción que dice Gestor de URLs Adicionales de Tarjetas y
copiamos en el espacio el siguiente enlace:

1.1.3. En la plataforma de Arduino se selección Herramientas>Placa>Gestor de Tarjetas.


Brayan Baquero Cardozo-Brayan Torres Malaver

1.1.4. Una vez en el gestor de tarjetas buscamos el módulo esp8266 luego damos click en Instalar

1.1.5. Una vez instalado el modulo volvemos a seleccionar la opción que dice Placa y luego damos click
en NodeMCU1.0 (ESP-12EModule).

1.2. Código

A continuación de muestra el código implementado para la comunicación Modbus TCP. Las variables
ssid y password se declaran en base a la red wifi a la cual se va a conectar el dispositivo. La función
del código va ser recibir 2 valores de registros enviados por InTouch y asignar uno a una salida
análoga conectada al led de la placa, y la otra asignada a un pin conectado a un led. A su vez va a
enviar el valor de una potenciómetro conectado a la entrada análoga A0 a un registro asociado a la
dirección 40001 y el valor del pulsador de la placa asociado al registro 40002
Brayan Baquero Cardozo-Brayan Torres Malaver

#include <ESP8266WiFi.h>
#include <ESP8266WiFiAP.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFiScan.h>
#include <ESP8266WiFiSTA.h>
#include <ESP8266WiFiType.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiServer.h>
#include <WiFiServerSecure.h>
#include <WiFiUdp.h>

const char* ssid = "**********";//Nombre de la Red


const char* password = "**********";// Contraseña
int ModbusTCP_port = 502;

int sensorvalue=0;//Entrada analoga

/// Requerido para Modbus TCP/IP /////////


#define maxInputRegister 20
#define maxHoldingRegister 20

#define MB_FC_NONE 0
#define MB_FC_READ_REGISTERS 3 //implemented
#define MB_FC_WRITE_REGISTER 6 //implemented
#define MB_FC_WRITE_MULTIPLE_REGISTERS 16 //implemented
//
// MODBUS Error Codes
//
#define MB_EC_NONE 0
#define MB_EC_ILLEGAL_FUNCTION 1
#define MB_EC_ILLEGAL_DATA_ADDRESS 2
#define MB_EC_ILLEGAL_DATA_VALUE 3
#define MB_EC_SLAVE_DEVICE_FAILURE 4
//
// MODBUS MBAP offsets
//
#define MB_TCP_TID 0
#define MB_TCP_PID 2
#define MB_TCP_LEN 4
#define MB_TCP_UID 6
#define MB_TCP_FUNC 7
#define MB_TCP_REGISTER_START 8
#define MB_TCP_REGISTER_NUMBER 10

byte ByteArray[260];
unsigned int MBHoldingRegister[maxHoldingRegister];

//////////////////////////////////////////////////////////////////////////

WiFiServer MBServer(ModbusTCP_port);

void setup() {
pinMode(2, OUTPUT);//Salida análoga Led de la placa
Brayan Baquero Cardozo-Brayan Torres Malaver

pinMode(0, INPUT);// entrada digital, botón flash de la placa


pinMode(14, OUTPUT);// salida digital Led

Serial.begin(9600);
delay(100) ;
WiFi.begin(ssid, password);
delay(100) ;
Serial.println(".");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
MBServer.begin();
Serial.println("Connected ");
Serial.print("ESP8266 Slave Modbus TCP/IP ");
Serial.print(WiFi.localIP());
Serial.print(":");
Serial.println(String(ModbusTCP_port));
Serial.println("Modbus TCP/IP Online");

void loop() {

// Check if a client has connected // Modbus TCP/IP


WiFiClient client = MBServer.available();
if (!client) {
return;
}

boolean flagClientConnected = 0;
byte byteFN = MB_FC_NONE;
int Start;
int WordDataLength;
int ByteDataLength;
int MessageLength;

// Modbus TCP/IP
while (client.connected()) {

if(client.available())
{
flagClientConnected = 1;
int i = 0;
while(client.available())
{
ByteArray[i] = client.read();
i++;
}

client.flush();

///////// Holding Register [0] A [9] = 10 Holding Registers Escritura


///////// Holding Register [0] A [9] = 10 Holding Registers Writing

sensorvalue=analogRead(A0);
int estado = digitalRead(boton);

MBHoldingRegister[0] = sensorvalue;
Brayan Baquero Cardozo-Brayan Torres Malaver

MBHoldingRegister[1] = estado;
MBHoldingRegister[2] = random(0,12);
MBHoldingRegister[3] = random(0,12);
MBHoldingRegister[4] = random(0,12);
MBHoldingRegister[5] = random(0,12);
MBHoldingRegister[6] = random(0,12);
MBHoldingRegister[7] = random(0,12);
MBHoldingRegister[8] = random(0,12);
MBHoldingRegister[9] = random(0,12);

///////// Holding Register [10] A [19] = 10 Holding Registers Lectura


///// Holding Register [10] A [19] = 10 Holding Registers Reading

int Temporal[10];

Temporal[0] = MBHoldingRegister[10];
Temporal[1] = MBHoldingRegister[11];
Temporal[2] = MBHoldingRegister[12];
Temporal[3] = MBHoldingRegister[13];
Temporal[4] = MBHoldingRegister[14];
Temporal[5] = MBHoldingRegister[15];
Temporal[6] = MBHoldingRegister[16];
Temporal[7] = MBHoldingRegister[17];
Temporal[8] = MBHoldingRegister[18];
Temporal[9] = MBHoldingRegister[19];

analogWrite(2,MBHoldingRegister[10]);//Escribe el valor del HoldingRegister al led

/// Enable Output 14


digitalWrite(14, MBHoldingRegister[14] );

//// debug

for (int i = 0; i < 10; i++) {

Serial.print("[");
Serial.print(i);
Serial.print("] ");
Serial.print(Temporal[i]);

}
Serial.println("");

//// rutine Modbus TCP


byteFN = ByteArray[MB_TCP_FUNC];
Start = word(ByteArray[MB_TCP_REGISTER_START],ByteArray[MB_TCP_REGISTER_START+1]);
WordDataLength = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]);
}

// Handle request

switch(byteFN) {
case MB_FC_NONE:
break;

case MB_FC_READ_REGISTERS: // 03 Read Holding Registers


ByteDataLength = WordDataLength * 2;
Brayan Baquero Cardozo-Brayan Torres Malaver

ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.


ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
for(int i = 0; i < WordDataLength; i++)
{
ByteArray[ 9 + i * 2] = highByte(MBHoldingRegister[Start + i]);
ByteArray[10 + i * 2] = lowByte(MBHoldingRegister[Start + i]);
}
MessageLength = ByteDataLength + 9;
client.write((const uint8_t *)ByteArray,MessageLength);

byteFN = MB_FC_NONE;

break;

case MB_FC_WRITE_REGISTER: // 06 Write Holding Register


MBHoldingRegister[Start] =
word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]);
ByteArray[5] = 6; //Number of bytes after this one.
MessageLength = 12;
client.write((const uint8_t *)ByteArray,MessageLength);
byteFN = MB_FC_NONE;
break;

case MB_FC_WRITE_MULTIPLE_REGISTERS: //16 Write Holding Registers


ByteDataLength = WordDataLength * 2;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
for(int i = 0; i < WordDataLength; i++)
{
MBHoldingRegister[Start + i] = word(ByteArray[ 13 + i * 2],ByteArray[14 + i * 2]);
}
MessageLength = 12;
client.write((const uint8_t *)ByteArray,MessageLength);
byteFN = MB_FC_NONE;

break;
}
}
}

2 Configuración de Modbus TCP en InTouch

Para la realización de esta práctica se implementó InTouch 2014 R2SP1. Para la utilización de
ModbusTCP en InTouch es necesaria la instalación de DAS-MTCP el cual permite establecer
comunicación ModbusTCP entre InTouch y otros dispositivos. Una vez instalado se procede a la
configuración del mismo.

2.1.1 Abrir System Management Console y dirigirse a DAserver Manager>Default


Group>Local>ArchestrA.DASMBTCP.3
Brayan Baquero Cardozo-Brayan Torres Malaver

2.1.2 Para habilitar el servidor Modbus TCP se da click derecho en ArchetrA.DASMBTCP.3 y se selecciona
Actívate server.
Brayan Baquero Cardozo-Brayan Torres Malaver

2.1.3 Ubicados en ArchetrA.DASMBTCP.3 dirigirse a Configuration>Port , dar click derecho en port y


seleccionar Add ModbusBridge Object, y asignarle un nombre, en este caso será Gateway.
Brayan Baquero Cardozo-Brayan Torres Malaver

2.1.4 Ubicarse en Gateway en Bridge Type seleccionar Modbus Bridge, y en Network Address poner la
dirección ip del NodeMCU.

2.1.5 Dar click derecho en Gateway y seleccionar Add ModbusPLCRS Object y dar el nombre de
preferencia al nodo creado, en este caso será PLC
Brayan Baquero Cardozo-Brayan Torres Malaver

2.1.6 Se procede a configurar PLC Parameters como se ilustra en la siguiente figura.


Brayan Baquero Cardozo-Brayan Torres Malaver

2.1.7 Ir a Device Groups dar Clik derecho Add para agregar un nuevo tópico se le da un nombre de
preferencia, en este caso es Vr1 y se configura el intervalo de actualización el cual se dejó en 500ms.

3. Programación Scripts InTouch

3.1. Una vez terminada la configuración en System Management Console, se crea una nueva aplicación
en intouch, se va a Especial>Access Names.. y en la ventana que aparezca darle en Add
Brayan Baquero Cardozo-Brayan Torres Malaver

3.1. Se procede a configurar el Access Name como se ilustra en la siguiente figura


Brayan Baquero Cardozo-Brayan Torres Malaver

3.2. Para esta aplicación se realiza un tanque en donde el valor análogo obtenido con el NodeMCU
modifique el nivel del mismo, siempre y cuando boton de la placa este accionado, también se
activara un indicador cuando el nivel sobrepaso un valor predeterminado, el nivel del tanque
modificara la intensidad del led. En la ventana de InTouch dirigirse a Wizard>Simbol Factory, una
vez abierta la ventana de Sylbol Factorry dirigirse a tanks y selecciones tank2
Brayan Baquero Cardozo-Brayan Torres Malaver

Agregar dos tanques y un circulo como se ilustra en la siguiente figura.


Brayan Baquero Cardozo-Brayan Torres Malaver

3.3. Click derecho en el tanque y seleccionar Cell>symbol>Break Cell

3.4. Se va a Tagname Dictionary dar new y agregar un nuevo Tag de tipo I/O Real
Brayan Baquero Cardozo-Brayan Torres Malaver

3.5. Entrar a Access Name Seleccionar el que se creo anteriormente en este caso es Port, en ítem
asignar la dirección correspondiente al registro que se envió del NodeMCU , para la entrada
análoga se asignó a la posición 0 del registro MBHoldingRegister, entonces el correspondería a
la dirección 40001, para la entrada digital se sigue el mismo procedimiento y se le asigna el
registro 40002, para la salida análoga que se le asignara al led se crear otro tag con el registro
40011

3.6. Dar click derecho en Scripts New Script>Application Script


Brayan Baquero Cardozo-Brayan Torres Malaver

3.7. Copiar el siguiente Script , y definir las variables aun no definidas

3.8. Dar doble click en el tanque Percent Fill>Vertical en Expression poner la variable tank1, en
Value at Max Fill poner 1024, en Direcction marcar Down, y en Background color seleccionar el
color de preferencia.
Brayan Baquero Cardozo-Brayan Torres Malaver

3.9. Dar doble click en el circulo dirigirse a Fill color>Discrete y configurar de la siguiente manera

Probando la aplicación completa se tiene


Brayan Baquero Cardozo-Brayan Torres Malaver

Como verificación se visualizan los datos en System Management Consolé


Brayan Baquero Cardozo-Brayan Torres Malaver

You might also like