Mostrando entradas con la etiqueta Sockets. Mostrar todas las entradas
Mostrando entradas con la etiqueta Sockets. Mostrar todas las entradas

lunes, 14 de octubre de 2024

ESP8266 AP con GPS-6MV2 socket interface


GPS-6MV2 Tkinter interface

Buenas a todos!!!

Aprovechando que ya sabemos como mostrar, de manera serial, los datos que nos proporciona el módulo GPS-6MV2

No es muy practico tener que abrir el monitor Serial del IDE Arduino, o putty, para tener que ver una serie de números que, a priori, no nos dicen nada.

Pero para eso tenemos a Python, la navaja suiza de los lenguajes de programación. Igual que hicimos con el módulo ADXL345 con la interfaz y la clase socket. Solo necesitamos unos cuantos labels para mostrar los datos GPS de una manera que tengan sentido para cualquier usuario.

GPS-6MV2 pyTermTk interface

Pero volver a mostrar el mismo programa en otra entrada diferente, ya que los cambios son mínimos, no me convencía mucho. He probado a crear un programa pero usando esta vez pyTermTk.

Para cambiar un poco la programación esta vez no he usado ttkDesigner, simplemente he ido creando la interfaz como si estuviera usando Tkinter.

El resultado han sido dos programas prácticamente iguales, pero uno diseñado para mostrar datos en un entorno con ventanas y el otro se puede usar directamente desde cualquier terminal.

Arduino ESP8266 en modo AP:

Otra de las cosas que he cambiado es la manera de conectar el módulo ESP8266 con el portátil. Generalmente programo en un entorno cerrado y la conexión del ESP8266 se realiza con una conexión al router.

¿Pero que pasa si quiero salir de casa? Pues que el sistema deja de funcionar y tendría que programar la IP de cada red a la que se conecte.

Poniendo el microcontrolador en modo AP (Access Point) convertimos el ESP8266 en el punto central de una pequeña red local. De esta manera son los dispositivos como portátiles o smartphones los que se conectan al microcontrolador

Puede ser una red abierta (no recomendado) o una red con contraseña WPA2-PSK y la programación cambia muy poco con respecto al modo cliente, que es que uso habitualmente.

El programa esta dividido en dos archivos:

  • ESP8266_GPS6MV2_AP_server.ino Establece el modo AP y la comunicación con el módulo GPS-6MV2.
  • neo6mv2.ino donde se construye el String con los datos recibidos por el GPS-6MV2.

Asignamos un nombre y contraseña para la red:


#include "ESP8266WiFi.h"

const char* ssid = "gpsServer";
const char* password =  "!2345678";
WiFiServer wifiServer(1314);
void setup(){

  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("Starting GPS-6MV2 in AP mode on IP: ");
  Serial.println(IP);
}


Con este código el microcontrolador ya está en modo AP

Es el loop() donde se crearán los nuevos clientes y donde se sitúa la función principal, en este caso las funciones relacionadas con el módulo GPS:


void loop() {
  
 WiFiClient client = wifiServer.available();
 
  if (client) {
    Serial.println("Client connected");
    while (client.connected()) {
    
    // Lo que haga el programa
    
    }
  client.stop();
  Serial.println("Client disconnected");
  } 
}

En este punto ya solo tenemos que añadir la parte de código que ya hemos visto en el artículo Modulo GPS 6MV2 Serial ESP8266 NodeMCU.

Si ya has descargado el código y conectado el ESP8266 a una fuente de alimentación tiene que aparecer en el gestor de conexiones de la distribución que estemos usando.

Gestor de conexiones

Cuando le damos a conectar, nos pedirá la contraseña, !2345678, la introducimos y tenemos la conexión establecida. Empecemos con el programa realizado con Tkinter:


python3 -m main_gps6mv2

Si ya estas conectado a la red "gpsServer", los datos aparecerán al pulsar el botón "Start Conn":


Para el ejemplo desarrollado con la librería pyTermTk tenemos que ejecutar:


python3 -m main_gps_termtk


Igual que con la otra interfaz, si estamos conectados a la red "gpsServer" y pulsamos "Connect":

Puedes descargar los programas estas interfaces para el módulo GPS-6MV2 desde GitHub desde los siguientes enlaces:

Programa para microcontrolador ES8266 comunicación en GitHub

Interfaz de ejemplo con Tkinter de este articulo en GitHub

Interfaz de ejemplo con pyTermTk de este articulo en GitHub

Aquí tienes otros enlaces de este blog relacionados con programas hechos en Python:

Interfaz para el módulo ADXL345

Muestra el estado del sistema Raspberry Pi

Raspberry pi PWM

Espero que os guste el contenido, Saludos!!

martes, 17 de septiembre de 2024

Python Sockets, manipular datos recibidos por cliente

Ahora que ya tengo en marchar Terminal DCC, una de las cosas que más me ha llamado la atención es la plasticidad de la biblioteca "sockets".

¿Que son los sockets?

De una manera simple, son los puntos de conexión entre procesos de diferentes sistemas a través de una red.

Con sockets no solo podemos transmitir texto entre cliente y servidor, también números, tanto int como float, binarios como imágenes o vídeo en resumen podemos enviar cualquier información que pueda ser representada como una secuencia de bytes.

Los usos más comunes que se le da a los sockets son como:

  • Servidor web
  • Transferencia de archivos
  • Clientes de chat
  • Juegos en red

En este ejemplo recibiremos los datos desde un servidor en formato bytes y los pasaremos a una codificación "UTF-8" para poder manejarlo como un String desde la misma u otra clase diferente.


Conceptos básicos:

  • Socket: Es el punto de conexión entre dos procesos. Se caracteriza por una dirección (IP) y un puerto.
  • Dirección IP: Es una etiqueta numérica única que identifica un dispositivo en una red.
  • Puerto: Es un número que identifica un servicio específico en un dispositivo.
  • TCP/IP: Es el protocolo de comunicación más utilizado en Internet. TCP (Transmission Control Protocol) garantiza la entrega ordenada y fiable de datos, mientras que IP (Internet Protocol) se encarga del enrutamiento de paquetes de datos.

Consideraciones importantes:

  • Serialización: Para enviar objetos de Python, debes serializarlos en una secuencia de bytes. Pickle es un módulo estándar de Python que permite la serialización de objetos, pero ten en cuenta que los objetos serializados con pickle pueden no ser compatibles entre diferentes versiones de Python.
  • Protocolo: El protocolo de comunicación que utilices (TCP, UDP, etc.) influirá en la forma en que se envían y reciben los datos.
  • Codificación: Es crucial elegir la codificación correcta para los datos de texto. La codificación UTF-8 es muy común, pero existen otras opciones.

Empecemos con el servidor:

Tanto el servidor como el cliente son clases. Para llamar a la clase "serverSocket" tenemos que pasarle los parámetros "IP" y "puerto"


## Inicia el programa principal
if __name__ == '__main__':
	# Inicia el socket con los parametros IP y puerto
	# Si no especificamos una dirección IP y usamos un 
	# String vacío, socket usará la IP de la maquina.
	server = serverSocket("", 1314)

	# Inicia el servidor
	server.iniciar()
    

Al iniciar el servidor con "python3 class_server_test.py", aparecerá el siguiente mensaje


[START] Server starting at 192.168.0.25
[LISTENING] Waiting for connections... 

Con esto ya tenemos el servidor a la escucha esperando conexiones desde los clientes

Cliente conectando con el servidor:

Del otro lado tenemos al cliente al que llamaremos "clienteSocket" desde el archivo "class_cliente_test.py" y al que tenemos que pasar los parámetros que usará para establecer la conexión con el servidor y son la IP del servidor, el puerto que esta a la escucha en el servidor y el número de cliente en caso de que conectemos mas de un cliente.


## Inicia el programa cliente
if __name__ == '__main__':
	# Establece conexión con el servidor
	cliente = clienteSocket("192.168.0.25", 1314, 1)

	# Inicia la conexión con el servidor
	estado = cliente.iniciar()
	
	# Imprime en pantalla el estado del servidor
	print(estado)

	# Si el estado contiene la palabra "CONNECTED"
	if "CONNECTED" in estado:

		# Envía un mensaje al servidor comunicando que estamos conectados
		cliente.clientSendData("Cliente conectado...")
		
		# Inicia un bucle con la respuesta del resta del servidor
		while True:

			# imprime los datos desde el cliente
			print(cliente.get_client_data())

			cliente.clientSendData(cliente.get_client_data())
			
			# Espera 2 segundos para volver a leer los datos
			time.sleep(2)

Si todo esta correcto en la pantalla del cliente se imprime el mensaje:


	[CONNECTED] 192.168.0.25:1314
    
	[OK] datos recibidos
    

Ahora ya tenemos el sistema conectado. Pero nosotros los datos que necesitamos no se van a quedar en el la clase cliente, queremos mostrarlos en otra pantalla como una interfaz con Tkinter o pyTermTk.

Los datos los obtenemos desde la función "cliente.get_client_data()" Es necesario tenerlo en bucle "while" o un "hilo" para que este constantemente a la escucha de los nuevos datos:


## Iniciar el cliente desde otra clase:
cliente = clienteSocket("192.168.0.25", 1314, 1)
cliente.iniciar()

# Obtener datos del cliente desde otra clase:
datas = cliente.get_client_data()

Y de está manera tenemos los datos de una conexión socket disponible para conectar cualquier dispositivo a nuestra red.

Conexión Cliente - Servidor


Con algunas modificaciones, estos ejemplos pueden servir para conectar dispositivos tan dispares como:

  • Ordenadores: Sobremesa, portátil, servidor...
  • Raspberry Pi: En todas sus versiones
  • Microcontroladores: Dispositivos como ESP8266 o ESP32

Programa de ejemplo de este articulo en GitHub

Espero que este ejemplo sea de ayuda y mejore las conexiones entre vuestros dispositivos, tanto tradicionales como IoT.

Saludos!!