Vous êtes sur la page 1sur 15

Instrumentación Avanzada. G. Murcia – J.

Strack

GUIA DE EJERCICIOS
Nº 12
INSTRUMENTACIÓN AVANZADA

Comunicación Ethernet con


Arduino y LabVIEW

1
Instrumentación Avanzada. G. Murcia – J. Strack

12.-Ejemplo de servidor Ethernet con Arduino y LabVIEW

Ejercicio 12.1

Formar 2 grupos con los elementos provistos por la cátedra.

Luego de reconocer los elementos realizar el cableado del conjunto variador de velocidad –
motor basado en la siguiente figura:

Esquema de conexiones de Fuerza Motriz y Maniobra:

Una vez realizadas todas las conexiones, procederemos a configurar el variador de velocidad
ATV 11 siguiendo las instrucciones del Anexo I y probaremos su correcto funcionamiento.

Para comandar y monitorear el ATV 11 desde Arduino realizaremos cuatro circuitos:

1. Un circuito de relés para accionar las entradas digitales del variador.


2. Un circuito optoacoplado para accionar la entrada analógica Al1 del variador
desde una salida PWM del Arduino.
3. Un circuito optoacoplado para leer desde una entrada digital de Arduino la
salida D0 (PWM) del variador.
4. Un circuito optoacoplado para detectar la marcha o parada del variador sobre
la entrada digital LI1 del ATV11.

2
Instrumentación Avanzada. G. Murcia – J. Strack
Circuito 1: Mando para los relés de Arduino (para generar marcha / parada sobre LI1)

Circuito 2: Mando de velocidad optoacoplado (para generar un PWM sobre Al1)

Circuito 3: Medición de velocidad optoacoplado (para leer un PWM desde D0)

Circuito 4: Detección del estado de marcha/parada (para leer el estado de LI1)

Luego de realizar los circuitos acondicionadores anteriores cargaremos el siguiente código en la


placa Arduino UNO ó MEGA. El mismo consiste en el driver de comandos muy similar al que
veníamos utilizando, pero ahora en lugar de comunicarnos con la placa a través del puerto serie
3
Instrumentación Avanzada. G. Murcia – J. Strack
(COM virtual desde USB), nos comunicaremos a través de Ethernet utilizando el protocolo
TCP/IP.
Además se agrega una interrupción que se dispara cada 1us para leer la salida PWM del ATV11
(que es de 2 kHz) sobre el PIN 22 y un comando para generar una salida PWM sobre la salida
digital D3 (pin 9).

///////////////////////////////////////////////////////////////////
// Cátedra Instrumentación Avanzada //
// Driver de comunicación TCP/IP para Arduino UNO y MEGA 2560 //
// Versión: 1.0.10 //
// Fecha: 20/11/2017 //
///////////////////////////////////////////////////////////////////

//DECLARACIONES_________________________________

// LIBRERÍAS
#include <SPI.h> //comunicación SPI utilizada por ethernet shield (pines
10,11,12,13)
#include <Ethernet.h> //funciones para comunicación ethernet

// CONFIGURACION DE LA PLACA ETHERNET


byte mac[] = {0x00, 0x22, 0x68, 0x2F, 0xA0, 0x9C }; // Direccion MAC
IPAddress ip(169,254,130,100); // Direccion IP
EthernetServer server(80); // puerto de comunicacion HTTP

// SALIDAS DIGITALES:
const int D0=4;
const int D1=5;
const int D2=7;
const int D3=9;

// ENTRADAS DIGITALES:
const int D4=2;
const int D5=3;
const int D6=6;
const int D7=8;
const int PIN_PWM_in=22;

// VARIABLES
char caracterEntrada;
int entradaDigital, b0, b1, b2, b3, dato, PWM;
byte vector1[2], vector2[10];
char canal;
int valor_analog;
int contador;
volatile int PWM_alto;

//SETUP_________________________________________
void setup() {

Serial.begin(9600);
// DECLARACIÓN DE SALIDAS DIGITALES:
pinMode(D0, OUTPUT);
pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);

// DECLARACIÓN DE ENTRADAS DIGITALES:


pinMode(D4, INPUT);
pinMode(D5, INPUT);
pinMode(D6, INPUT);
pinMode(D7, INPUT);
pinMode(D7, INPUT);
pinMode(PIN_PWM_in, INPUT);
4
Instrumentación Avanzada. G. Murcia – J. Strack

// CONFIGURACIÓN DE LA COMUNICACION TCP/IP


Ethernet.begin(mac, ip); // Inicialización de la pila TCP/IP
server.begin(); // Inicialización del servidor

// INICIALIZACIÓN DE SALIDAS (se ponen en 0)


digitalWrite(D0,0);
digitalWrite(D1,0);
digitalWrite(D2,0);
digitalWrite(D3,0);

}// FIN DEL SETUP

//CICLO PRINCIPAL________________________________
void loop() {
EthernetClient client = server.available(); // Se crea el objeto cliente
if (client) { // Si se recibe una petición de un cliente
while (client.connected()) { // Mientras el cliente esté conectado
if (client.available()) { // Si el cliente está disponible
caracterEntrada = client.read(); // toma un nuevo byte

// ATENCIÓN AL COMANDO 'A' (ESCRITURA DE SALIDAS DIGITALES)


if (caracterEntrada == 'A') {
caracterEntrada = client.read(); // toma un nuevo byte
digitalWrite(D0,caracterEntrada); // escribe la salida digital D0
caracterEntrada = client.read();
digitalWrite(D1,caracterEntrada);
caracterEntrada = client.read();
digitalWrite(D2,caracterEntrada);
caracterEntrada = client.read();
digitalWrite(D3,caracterEntrada);
}// FIN DE ATENCIÓN AL COMANDO 'A'___________

// ATENCIÓN AL COMANDO 'B' (LECTURA DE ENTRADAS DIGITALES)


if (caracterEntrada == 'B') {
b0 = digitalRead(D4); // lee la entrada D4
b1 = digitalRead(D5);
b2 = digitalRead(D6);
b3 = digitalRead(D7);
entradaDigital = 1 * b0 + 2 * b1 + 4 * b2 + 8 * b3;
client.write(lowByte(byte(entradaDigital))); // envía el estado de
las entradas
// en los 4 bits menos
significativos
}// FIN DE ATENCIÓN AL COMANDO 'B'___________

// ATENCIÓN AL COMANDO 'C' (LECTURA DE UNA ENTRADA ANALÓGICA)


if (caracterEntrada == 'C') {
canal = client.read(); // toma un nuevo byte
dato = analogRead(canal); // lee el canal analógico solicitado
vector1[0] = lowByte(word(dato)); // genera el primer byte
vector1[1] = highByte(word(dato)); // genera el segundo byte
client.write(vector1,2); // envía los dos bytes en binario
}// FIN DE ATENCIÓN AL COMANDO 'C'___________

// ATENCIÓN AL COMANDO 'E' (ESCRITURA DE SALIDA PWM)


if (caracterEntrada == 'E') {
caracterEntrada = client.read();
valor_analog = caracterEntrada;
analogWrite(D3,valor_analog);
}// FIN DE ATENCIÓN AL COMANDO 'E'___________

5
Instrumentación Avanzada. G. Murcia – J. Strack
// ATENCIÓN AL COMANDO 'F' (LECTURA DE ENTRADA PWM)
if (caracterEntrada == 'F') {
contador = 0;
configuraInterrupcion1(1,0,0,15);
delay(500);
vector1[0] = lowByte(word(PWM_alto)); // genera el primer byte
vector1[1] = highByte(word(PWM_alto)); // genera el segundo byte
client.write(vector1,2); // envía los dos bytes en binario
}// FIN DE ATENCIÓN AL COMANDO 'E'

}// fin del if(client.available())

}// fin del while (client.connected())


}// fin del if principal (if(client))
}// fin del loop

//FUNCIÓN configuraInterrupcion1()______________
void configuraInterrupcion1(boolean b0, boolean b1, boolean b2, int dN) {
cli(); // Deshabilita las interrupciones globales para configurar los
registros del Timer 1
TCCR1A = 0; // Se vacía el registro
TCCR1B = 0; // Se vacía el registro
OCR1A = dN; // Registro que se comparará constantemente con el timer
TCCR1B |= (1 << WGM12);
// Se configura un preescalador:
TCCR1B |= (b0 << CS10); // Se pone a b0 el bit CS10 (Clock Select bit 10)
TCCR1B |= (b1 << CS11); // Se pone a b1 el bit CS11 (Clock Select bit 11)
TCCR1B |= (b2 << CS12); // Se pone a b2 el bit CS12 (Clock Select bit 12)
TIMSK1 = (1 << OCIE1A); // Se configura el timer como comparador
PWM_alto=0;

sei(); // Habilita las interrupciones globales para que funcionen las


interrupciones programadas
}// fin de la función configuraInterrupcion1()

//FUNCIÓN deshabilitaInterrupcion1()_______________
void deshabilitaInterrupcion1(){
cli(); // Deshabilita las interrupciones globales para configurar los
registros del Timer 1
TCCR1A = 0; // Se vacía el registro
TCCR1B = 0; // Se vacía el registro
// deshabilita el clock del contador
TCCR1B |= (0 << CS10); // Se pone a 0 el bit CS10 (Clock Select bit 10)
TCCR1B |= (0 << CS11); // Se pone a 0 el bit CS11 (Clock Select bit 11)
TCCR1B |= (0 << CS12); // Se pone a 0 el bit CS12 (Clock Select bit 12)
sei(); // Habilita las interrupciones globales
}// fin de la función deshabilitaInterrupcion1()

// INTERRUPCIÓN para leer PWM cada 1 us_______________________________


ISR(TIMER1_COMPA_vect) {
PWM = 1*digitalRead(PIN_PWM_in);
if (PWM == 1){
PWM_alto = PWM_alto+1;
}

contador = contador + 1;
if (contador == 2000){
contador = 0;

deshabilitaInterrupcion1();
}
}// FIN DE LA INTERRUPCIÓN 1

El driver anterior nos servirá para este y otros proyectos, ya que podremos crear cualquier
programa en LabVIEW que envíe comandos a través de TCP/IP a nuestra placa, de forma tal de
6
Instrumentación Avanzada. G. Murcia – J. Strack
escribir o leer pines digitales, leer entradas analógicas, escribir una salida pseudoanalógica
(PWM) o leer una señal PWM.
Finalmente desarrollaremos un programa en LabVIEW que nos permita comandar el variador de
velocidad ATV11 a través de TCP/IP.

Panel Frontal sugerido:

Diagrama de Bloques:

7
Instrumentación Avanzada. G. Murcia – J. Strack
Ejercicio 12.2

Conectar el shield Ethernet a la placa Arduino UNO o MEGA y realizar un programa en el IDE
de ARDUINO que permita generar una página web en formato HTML. En dicha página se debe
poder ver una entrada analógica y una entrada digital, a la vez que se debe poder accionar una
salida digital de la placa.

Pagina web sugerida:

Algunos comandos y funciones específicas disponibles útiles para resolver este ejercicio:

// LIBRERIAS
#include <Ethernet.h> // Librería para la comunicación Ethernet

// VARIABLES ESPECIALES
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Escribe una dirección
MAC para el controlador.
IPAddress ip(10,2,0,100); // Escribe una IP para el controlador.
EthernetServer server(80); // Puerto 80 es el valor predeterminado para HTTP

// FUNCIONES
Ethernet.begin(mac, ip); // Inicialización del servidor
server.begin();// comienza a recibir conexiones
EthernetClient client = server.available(); // Obtiene un cliente que esté
conectado al servidor y posea datos disponibles para lectura.
client.connected(); //Vale 1 si el cliente está conectado
client.available(); //Vale 1 si el cliente está disponible
client.read(); // Lee un caracter del cliente
client.println(); // Envía una línea al cliente
client.println("<meta http-equiv=\"refresh\" content=\"5\">"); // Añade una
etiqueta para conseguir que el navegador se actualice cada 5 segundos por
ejemplo.
client.println("<input type=submit value=ON style=width:200px;height:75px
onClick=location.href='./?LED=T\'>"); // arma un botón y retorna lo escrito
detras del signo ? (LED=T en este caso)
client.stop(); // cierra la conexión:

8
Instrumentación Avanzada. G. Murcia – J. Strack
Ejercicio 12.3

Formar 2 grupos con los elementos provistos por la cátedra.

Crear una página web en Arduino para comandar y monitorear un conjunto variador de
velocidad ATV-11 y motor asincrónico trifásico. El objetivo es controlar el variador de
velocidad desde LabVIEW utilizando Ethernet, pero a su vez queremos que también se pueda
controlar desde una página web HTML, de forma tal que se pueda acceder a ella desde cualquier
dispositivo (smartphone, tablet) conectado a internet simplemente utilizando un navegador web.

Luego de realizar los circuitos acondicionadores anteriores cargaremos el siguiente código en la


placa Arduino UNO ó MEGA

///////////////////////////////////////////////////////////////////
// Cátedra Instrumentación Avanzada //
// Ejercicio 13.2 //
// Fecha: 21/11/2017 //
///////////////////////////////////////////////////////////////////

//DECLARACIONES_________________________________
// LIBRERÍAS
#include<SPI.h>//comunicación SPI utilizada por Ethernet shield (pines
10,11,12,13)
#include<Ethernet.h>//funciones para comunicación ethernet

// CONFIGURACIÓN DE LA PLACA ETHERNET


byte mac[] = {0x98, 0x4F, 0xEE, 0x01, 0x10, 0x77}; // Direccion MAC
//IPAddress ip(10,2,0,100); // Direccion IP
IPAddress ip(169,254,130,100); // Direccion IP
EthernetServer server(80); // puerto de comunicacion HTTP

// CONSTANTES Y VARIABLES
const int marcha=4; // pin de salida marcha
//const int parada=5; // pin de salida parada
const int in_marcha=3;
int aux;
//const int in_parada=2;
const int vel=9;
String estado="PARADA"; // estado del motor inicialmente "PARADA"
String velocidad="0000";
int vel_actual;
int v=0;
int HSP=50;
int contador=0;
int PWM;
volatile int PWM_alto;
const int PIN_PWM_in=22;

//SETUP_________________________________________
void setup(){

// DECLARACIÓN DE SALIDAS DIGITALES:


pinMode(marcha,OUTPUT);
pinMode(vel,OUTPUT);

// DECLARACIÓN DE ENTRADAS DIGITALES:


pinMode(in_marcha,INPUT); // se configura el pin in_marcha como entrada
pinMode(PIN_PWM_in, INPUT);

// CONFIGURACIÓN DE LA COMUNICACION TCP/IP


Ethernet.begin(mac,ip); // se inicializa la comunicación Ethernet
server.begin(); // se inicializa el servidor

9
Instrumentación Avanzada. G. Murcia – J. Strack

// CONFIGURACIÓN DEL PUERTO SERIE (visualización)


Serial.begin(115200);

// INICIALIZACIÓN DE SALIDAS
digitalWrite(marcha,0);
analogWrite(vel,v);

} // fin del setup

void loop(){
// lectura ENTRADA PWM

configuraInterrupcion1(1,0,0,15);
delay(500);
vel_actual=60*(PWM_alto/(2*2000.0))*HSP;
aux=1*digitalRead(in_marcha);
if (aux==1){
estado="MARCHA";
}
else{
estado="PARADA";
}

EthernetClient client=server.available(); // se crea el objeto cliente


if (client) { // si se detecta un cliente a través de una petición HTTP
boolean linea_blanca= true; //Una petición HTTP acaba con una línea en
blanco
String cadena=""; // se crea una cadena de caracteres vacía
while (client.connected()) { // mientras el cliente esté conectado
analogWrite(vel,v);
if (client.available()) { // si el cliente está disponible
char c =client.read();// se lee la petición HTTP carácter por
carácter
cadena.concat(c);// se convierte la petición HTTP en un String
int posicion=cadena.indexOf("M="); // se guarda la posición de la
cadena "M="
if(cadena.substring(posicion)=="M=1") { // si en esa posición dice
"M=1"
digitalWrite(marcha,1);
client.write('1');
} // fin del if
if(cadena.substring(posicion)=="M=0") { // si en esa posición dice
"M=0"
digitalWrite(marcha,0);
client.write('0');
} // fin del if
int pos=cadena.indexOf("V="); // se guarda la posición de la cadena
"V="
if(cadena.substring(pos,pos+2)=="V="){
velocidad =cadena.substring(pos+2,pos+6);
v =floor(velocidad.toInt()*255/1350);
}
if (v>0){
analogWrite(vel,v);
}

Serial.write(c);// se visualiza la petición por el monitor serie


// Cuando reciba una línea en blanco, la petición HTTP habrá acabado
// y el servidor web estará listo para enviar una respuesta
if (c =='\n'&&linea_blanca) {
// Se envía al cliente una respuesta HTTP
client.println("HTTP/1.1 200 OK"); // envia una standard http
response header

10
Instrumentación Avanzada. G. Murcia – J. Strack
client.println("Content-Type: text/html");
client.println("Conexion Cerrada: cerrada");
client.println();
client.println("<!DOCTYPE HTML>"); // aqui empieza la pagina web
que se visualizará
client.println("<meta http-equiv=\"refresh\" content=\"5\">"); //
Añade una etiqueta para conseguir que el navegador se actualice cada 5
segundos:
client.println("<html>");
client.println("<head>");
client.println("</head>");
client.println("<body>");
client.println("<h1 align='center'>INSTRUMENTACION
AVANZADA</h1><h3 align='center'>MOTOR controlado por Servidor Web con
Arduino</h3>");
//Se crean los botones. Para enviar parametros a través de HTML
se utiliza el metodo URL encode. Los parámetros se envian a través del
símbolo '?'
client.println("<div style='text-align:center;'>");
client.println("<button onClick=location.href='./?M=1\'
style='margin:auto;background-color: #3ADF00;color: snow;padding:
10px;border: 1px solid #3ADF00;width:100px;'>");
client.println("MARCHA");
client.println("</button>");
client.println("<button onClick=location.href='./?M=0\'
style='margin:auto;background-color: #FF0000;color: snow;padding:
10px;border: 1px solid #FF0000;width:100px;'>");
client.println("PARADA");
client.println("</button>");
client.println("<br /><br />");
client.println("<b>ESTADO DEL ACCIONAMIENTO = ");
client.print(estado);
client.println("<br /><br />");
client.println("<button onClick=location.href='./?V=0000\'
style='margin:auto;background-color: #81BEF7;color: snow;padding:
10px;border: 1px solid #81BEF7;width:100px;'>");
client.println("0 RPM");
client.println("</button>");
client.println("<button onClick=location.href='./?V=0500\'
style='margin:auto;background-color: #2E9AFE;color: snow;padding:
10px;border: 1px solid #2E9AFE;width:100px;'>");
client.println("500 RPM");
client.println("</button>");
client.println("<button onClick=location.href='./?V=1000\'
style='margin:auto;background-color: #0174DF;color: snow;padding:
10px;border: 1px solid #0174DF;width:100px;'>");
client.println("1000 RPM");
client.println("</button>");
client.println("<button onClick=location.href='./?V=1350\'
style='margin:auto;background-color: #084B8A;color: snow;padding:
10px;border: 1px solid #084B8A;width:100px;'>");
client.println("1350 RPM");
client.println("</button>");
client.println("<br /><br />");
client.println("<b>VELOCIDAD DEL MOTOR: ");
client.print(vel_actual);
client.println(" RPM");
client.println("</b><br />");
client.println("</b></body>");
client.println("</html>");
break;
} // fin del if
if (c =='\n') { // si hay nueva linea
linea_blanca= true;
} // fin del if

11
Instrumentación Avanzada. G. Murcia – J. Strack
else if (c !='\r') {
linea_blanca= false; // si hay retorno de carro
} // fin del if
} // fin del if (client.available)
} // fin del while
delay(1); // se le da tiempo al navegador para recibir los datos
client.stop();// se cierra la conexión
} // fin del if (client)
} // fin del loop

//FUNCIÓN configuraInterrupcion1()______________
void configuraInterrupcion1(boolean b0, boolean b1, boolean b2, int dN) {
cli(); // Deshabilita las interrupciones globales para configurar los
registros del Timer 1
TCCR1A = 0; // Se vacía el registro
TCCR1B = 0; // Se vacía el registro
OCR1A = dN; // Registro que se comparará constantemente con el timer
TCCR1B |= (1 << WGM12);
// Se configura un preescalador:
TCCR1B |= (b0 << CS10); // Se pone a b0 el bit CS10 (Clock Select bit 10)
TCCR1B |= (b1 << CS11); // Se pone a b1 el bit CS11 (Clock Select bit 11)
TCCR1B |= (b2 << CS12); // Se pone a b2 el bit CS12 (Clock Select bit 12)
TIMSK1 = (1 << OCIE1A); // Se configura el timer como comparador
PWM_alto=0;

sei(); // Habilita las interrupciones globales para que funcionen las


interrupciones programadas
}// fin de la función configuraInterrupcion1()

//FUNCIÓN deshabilitaInterrupcion1()_______________
void deshabilitaInterrupcion1(){
cli(); // Deshabilita las interrupciones globales para configurar los
registros del Timer 1
TCCR1A = 0; // Se vacía el registro
TCCR1B = 0; // Se vacía el registro
// deshabilita el clock del contador
TCCR1B |= (0 << CS10); // Se pone a 0 el bit CS10 (Clock Select bit 10)
TCCR1B |= (0 << CS11); // Se pone a 0 el bit CS11 (Clock Select bit 11)
TCCR1B |= (0 << CS12); // Se pone a 0 el bit CS12 (Clock Select bit 12)
sei(); // Habilita las interrupciones globales
}// fin de la función deshabilitaInterrupcion1()

// INTERRUPCIÓN para leer PWM cada 1 us_______________________________


ISR(TIMER1_COMPA_vect) {
PWM = 1*digitalRead(PIN_PWM_in);
if (PWM == 1){
PWM_alto = PWM_alto+1;
}

contador = contador + 1;
if (contador == 2000){
contador = 0;
deshabilitaInterrupcion1();
}
}// FIN DE LA INTERRUPCIÓN

Ya estamos en condiciones de visualizar la página web creada en Arduino. Sólo debemos abrir el
navegador y acceder a la IP que configuramos en el código anterior.

12
Instrumentación Avanzada. G. Murcia – J. Strack

Si también queremos realizar el control desde LabVIEW, ya que disponemos de más


herramientas gráficas, podemos construir un programa como el que sigue:
Panel Frontal

Diagrama de Bloques

13
Instrumentación Avanzada. G. Murcia – J. Strack

14
Instrumentación Avanzada. G. Murcia – J. Strack

15

Vous aimerez peut-être aussi