Objetivos
Material requerido.
Arduino UNO | |
Shield Ethernet |
Un cable Ethernet RJ45 | Acceso a la red local y al Switch |
Qué es el protocolo UDP
UDP o Protocolo de Datagrama de Usuario (User Datagram Protocol) es un protocolo de Internet que permite la transmisión de datos sin conexión. De esta forma nos permite enviar información de una forma muy rápida, sin necesidad de establecer una conexión y esperar la respuesta.
De la misma forma que en el TCP, necesitamos especificar un puerto para la comunicación, y suele usarse en conexiones VPN o streaming de audio y vídeo.
Como contrapartida, no tenemos seguridad de que los paquetes vayan a llegar enteros y en mismo orden que los hemos enviado, ni ofrece protección al acceso de terceras personas, aunque es posible añadir una verificación para identificar los paquetes defectuosos.
Programación del Arduino
Vamos a tratar de programar el Arduino para que al recibir una petición devuelva un número aleatorio usando UDP. Para ello vamos a usar un shield de Ethernet y el propio Arduino, y necesitaremos también un router al que poder conectarnos.
Como siempre comenzaremos con incluir las librerías que vamos a utilizar. Incluiremos la librería EthernetUdp para poder gestionar el protocolo.
#include <Ethernet.h> //Load Ethernet Library #include <EthernetUdp.h> //Load the Udp Library #include <SPI.h> //Load SPI Library #include "Wire.h" //imports the wire library
Después ponemos los parámetros para la la conexión, asignándole una una IP fija. Además seleccionamos el puerto para la comunicación, que no tiene por qué ser ese, y definimos las variables para la comunicación UDP.
Necesitamos un un buffer para ir guardando los caracteres, un string donde los guardaremos una vez recibidos y otra para el tamaño de los paquetes. Además crearemos un objeto UDP.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress subnet(255, 255, 255, 0); // set subnet mask to match your network IPAddress ip(192, 168, 0, 201); // where xx is the desired IP Address IPAddress gateway(192, 168, 0, 1); // set gateway to match your network unsigned int localPort = 5000; // Assign quea port to talk over char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //dimensian a char array to hold our data packet String datReq; //String for our data int packetSize; //Size of the packet EthernetUDP Udp; // Create a UDP Object
En el setup vamos a inicializar la conexióon Ethernet y el protocolo UDP.
void setup() { Serial.begin(9600); //Initialize Serial Port Ethernet.begin( mac, ip); //Inialize the Ethernet Udp.begin(localPort); //Initialize Udp delay(1500); //delay Serial.println(Ethernet.localIP()); }
En el loop lo primero que hacemos es leer el tamaño del paquete. Si es mayor que 0 significa que ha llegado una petición. En ese caso la leemos y lo guardamos en el buffer, para después pasarlo al String.
packetSize =Udp.parsePacket(); //Reads the packet size if(packetSize>0) { //if packetSize is >0, that means someone has sent a request Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request String datReq(packetBuffer); //Convert char array packetBuffer into a string called datReq
Ahora vamos a leer el contenido y si coincide con lo que esperamos le devolveremos un número aleatorio. Podríamos usar varios condicionales para devolver diferentes cosas en función de la petición si fuese necesario.
if (datReq =="Numero") { int num = random (0,100) ; Serial.print("Numero enviado: "); Serial.println(num); Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send Udp.print(num); //Send Udp.endPacket(); //End the packet }
Y ya sólo nos falta limpiar el buffer con esta instrucción.
memset(packetBuffer, 0, UDP_TX_PACKET_MAX_SIZE); //clear out the packetBuffer array
Podéis descargar el programa completo aquí: UDP.
Programa para el PC
Para probarlo nosotros hemos desarrollado un programa en Python,porque nos gusta mucho ese lenguaje, pero podéis encontrar aplicaciones que permiten la comunicación UDP como esta: PacketSender.
El programa en Python lo primero que hace es importar las extensiones que vamos a usar y configurar los parámetros para la conexión UDP.
from socket import * import time address = ( '192.168.0.201', 5000) #define server IP and port client_socket = socket(AF_INET, SOCK_DGRAM) #Set up the Socket client_socket.settimeout(1) #Only wait 1 second for a response
El bucle principal consiste en enviar la cadena «Numero» y esperar la respuesta del Arduino. Una vez recibida la mostramos en la consola:
while(1): data = "Numero" #Set data request client_socket.sendto( data.encode(), address) #Send the data request try: rec_data, addr = client_socket.recvfrom(2048) #Read response from arduino num = int(rec_data) #Convert string rec_data to int print ("El valor es ", num) # Print the result except: pass time.sleep(1) #delay before sending next command
Y este es el resultado de ejecutar ambos programas:
Si nunca habéis trabajado con Python os recomendamos que le echéis un ojo. Es un lenguaje sencillo y que nos permite hacer muchas cosas sin demasiadas complicaciones.