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

sábado, 2 de noviembre de 2024

ESP8266 con GPS NEO6MV2 y acelerómetro ADXL345: Mapa en tiempo real

Muy Buenas Arduineros y Arduineras

Ahora si, juntamos los proyectos con el sensor ADXL345 y el sistema GPS con NEO6MV2. Esta unión afecta tanto al microrontrolador ESP8266 tanto como al programa para Python.

Si ya has visto las entradas anteriores, Servidor socket adxl345 Servidor AP GPS NEO6MV2 socket interface hacemos un pequeño resumen.

Son interfaces para comunicar mediante Wi-Fi los sensores arriba descritos. En estas interfaces se muestran los datos de posición de los ejes para el ADXL345 y la telemetría de la señal GPS.

Tipo de conexión:

  • Cliente Se conecta a la red local.
  • Como punto de acceso Nos conectamos directamente al microcontrolador.

Ambas opciones funcionan igual de bien y la latencia dependerá más por la distancia que tengamos con respecto al módulo que por la lectura de los sensores.

En el caso que de que estemos usando un portátil la ventaja para la conexión cliente es que como estamos conectados al router de casa seguiremos teniendo internet. No pasa lo mismo con el modo AP, una vez conectado no tendremos acceso a internet a no ser que estemos usando ethernet.

El modo AP en el ESP8266 será muy útil en exteriores como gracias a su conexión directa con la interfaz.

Tener los datos de latitud y longitud esta bien pero es mucho mejor tener una representación visual del recorrido. Además podemos añadir puntos de control que irán construyendo un perímetro con estas referencias. Para lograr tener el mapa en la interfaz hemos recurrido a la librería de Tom Schimansky TkinterMapView.

TkinterMapView

TkinterMapView es una biblioteca de Python que nos permite crear mapas interactivos dentro de aplicaciones que utilicen la interfaz gráfica de usuario (GUI) de Tkinter. En otras palabras, es una herramienta que te facilita la integración de mapas en tus programas.

Entre sus características destacan:

  • Mostrar mapas: Es su función principal, mostrar mapas basados en mosaicos como los que ofrece OpenStreetMap.

  • Interactuar con el mapa: Los mapas que creas con TkinterMapView son interactivos. Los usuarios pueden hacer zoom, desplazarse y, en algunos casos, buscar ubicaciones específicas.

  • Personalización: Puedes seleccionar entre diferentes proveedores de mapas y capas.

  • Agregar marcadores y overlays: También puedes añadir marcadores para señalar puntos de interés en el mapa y superponer diferentes capas de información, como datos geográficos o imágenes.

  • Facilidad de uso: La biblioteca es relativamente sencilla de usar, especialmente si ya estás familiarizado con Tkinter.

  • Integración con Tkinter: Al ser compatible con Tkinter, puedes combinar los mapas con otros elementos de tu interfaz gráfica.

Alguna de las funciones que más usaras son:

  • set_position - (set_position(x_lat, y_lon) Vamos a la posición dada por las coordenadas de latitud y longitud
  • set_marker - (set_marker(x_lat, y_lon) Crea un marcador en el mapa
  • set_zoom - (set_zoom(int)) Aplica zoom sobre el mapa
  • set_address - (set_address("Almeria", marker=True, text="Spain")) Nos sitúa en la ciudad especificada
  • set_polygon - (self.coordinates, name="Route NEO6MV2") con set_polygon crearemos una cerca que sera delimitada por una lista de puntos de latitud y longitud

Ahora que sabemos la novedad en este programa, este es un ejemplo sencillo de su uso con las funciones "set_position" y "set_marker":


import tkinter
import tkintermapview

# create tkinter window
root_tk = tkinter.Tk()
root_tk.geometry(f"{1000}x{700}")
root_tk.title("map_view_simple_example.py")

# Crea el widget con el mapa
map_widget = tkintermapview.TkinterMapView(root_tk, width=1000, height=700, corner_radius=0)
map_widget.pack(fill="both", expand=True)


# Establece la posición por latitud y longitud y aplica zoon 
map_widget.set_position(37.179790, -1.821792, marker=False)  # Garrucha, Almería 
map_widget.set_zoom(17)

# Establece la posición actual según su dirección
# map_widget.set_address("Garrucha, Almeria", marker=False)

def marker_click(marker):
    print(f"marker clicked - text: {marker.text}  position: {marker.position}")

# Establece un marcador, puede tener un color personalizado y comando "onClick"
marker_2 = map_widget.set_marker(37.179790, -1.821792, text="Garrucha Ayto.", command=marker_click)


root_tk.mainloop()



Con esta pequeña introducción a la librería TkinterMapView y como es prácticamente la única función añadida en el programa, ahora si, veamos la interfaz:

Para dar un toque diferente a la interz, le he aplicado una capa visual llamado "Forest ttk theme" alojado en GitHub para romper un poco con la monotonía del apartado visual por defecto.


Como se puede apreciar, la parte superior es la dedicada al sensor ADXL345 y la parte inferior para el GPS NEO6MV2 junto con el mapa.

Para mostrar el mapa necesitamos tener conexión a internet, como explicaba más arriba esto no funcionará si estamos en el modo AP.

Para usar el programa en modo AP no tendremos que realizar ningún cambio en la interfaz, pero si tener cargado el programa adecuado en el microcontrolador.

Conexión ESP8266 como cliente:

Para conectarnos en modo cliente tenemos que averiguar la IP que nos asigna el router, esta información nos la proporciona el programa y la podemos ver en el monitor serial.

Conexión ESP8266 como AP:

Por otra parte si nos conectamos en modo AP, primero tenemos que conectarnos a la red: "gpsServer" y su contraseña es "gps12345". Una vez estemos conectados al ESP8266, la dirección IP por defecto para el modo AP es 192.168.4.1

Espero que os guste y si estáis aprendiendo a programar en Python os puede ayudar con vuestros proyectos Aquí teneís otros enlaces de este blog relacionados con Python:

Programa de ejemplo de este articulo en GitHub

Otras interfaces:

Interfaz de ejemplo con Tkinter de este articulo en GitHub

ADXL Socket Server en GitHub


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

Tienes este y otros proyectos en mi repositorio de GitHub

Espero que os guste el contenido, Saludos!!

lunes, 14 de octubre de 2024

ESP8266 en modo AP con GPS NEO-6MV2: Interfaz Python y pyTermTk

Interfaz GPS 6MV2 Tkinter
GPS-6MV2 Tkinter interface

Buenas a todos y todas!!!

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.


Interfaz GPS 6MV2 pyTermTk
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.

Los archivos del programa para ESP8266:

  • 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 (punto de acceso)

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 KDE
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.

Programa python para interzace NEO-GPS6MV2


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:

Espero que os guste el contenido, Saludos!!!


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

viernes, 27 de septiembre de 2024

ESP8266 con ADXL345: Servidor socket y visualización en Python con Tkinter

Si ya leíste la entrada anterior sobre el sensor ADXL345, hemos mostrado los datos que genera un sensor de 3 ejes en el monitor serial. A mucha gente, una serie de números en una pantalla no le dicen mucho, algo más "humano" puede ser representarlo en un gráfico.

¿Como dibujar con Python?

Aunque más que a Python nos referimos a una de las librerías más famosas para crear interfaces, Tkinter. Junto con esta librería viene uno de los widgets más versátil para el dibujo, Canvas.

Canvas te proporciona un espacio donde puedes dibujar y mostrar elementos gráficos de forma personalizada. Es como una hoja de papel en la que puedes dibujar líneas, formas, texto, imágenes e incluso vídeo si utilizas una librería externa como OpenCV (Open Source Computer Vision Library).

Dentro de Canvas encontraremos la función create_line, con la que representaremos las coordenadas X Y Z de forma visual de tal manera que van a tener sentido.


id = cv.create_line(obj, init_ancho, init_alto, ancho, alto, trazo)



El programa va estructurado en dos partes, por un lado tenemos el ESP8266 con el sensor ADXL345 en modo servidor y por otro lado tenemos un ordenador con Python y el programa ADXL345 Interface Axis. 

NodeMCU -> Python Tkinter

ESP8266 ModeMCU con ADXL345

Este sensor tiene su propia entrada en el blog "ESP8266 y ADXL345 acelerómetro de 3 ejes. Lectura Serial" y es recomendable leerlo para entender mejor el funcionamiento del sensor ADXL345.

Primero iniciamos el microcontrolador ESP8266 con el sketch "esp8266_adxl_socket_server.ino". La principal diferencia con el programa básico es la implementación de un servidor socket en modo servidor con la librería "ESP8266WiFi.h". Solo hay que cambiar los datos para el ssid y password.

 
#include "ESP8266WiFi.h"

const char* ssid = "YOUR_SSID";
const char* password =  "PASSWORD";

// Tipo de Socket y puerto
WiFiServer wifiServer(1314);

En la función setup() realizamos la conexión:

 
void setup() 
 
  Serial.begin(115200);
 
  delay(1000);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Conectando..");
  }
 
  Serial.print("Connected to WiFi. IP:");
  Serial.println(WiFi.localIP());
 
  wifiServer.begin();
  

Por último se ejecuta todo en loop()


void loop() {
 
  WiFiClient client = wifiServer.available();
 
  if (client) {
    Serial.println("Client connected");
    while (client.connected()) {
 	  
      // Función donde se obtienen los datos del sensor.
      client.print(getADXL());
      delay(10);
    }
 
    client.stop();
    Serial.println("Client disconnected");
 
  }
}

Ahora que sabemos como se conecta a nuestra red wifi,tenemos que averiguar la IP del dispositivo. La opción más sencilla es abrir el monitor serial y esperar la confirmación de conexión con la red que hayamos definido en YOUR_SSID y PASSWORD. Otra opción es mirar que dirección IP nos asigno el router.

Si utilizas el IDE de Arduino tras la confirmación se mostrará la IP del dispositivo ESP8266.

Monitor serial

El resto de información confirma que el sensor ADXL345 esta funcionando correctamente. Ahora podemos desconectar el ESP8266 y conectarlo a una fuente externa como una powerbank. Una vez que lo conectes se volverá a cargar la IP que nos dio el monitor serial.

Cliente ADXL345 Interface Axis

Por la parte del cliente, este programa creado con Python y la librería gráfica Tkinter. Consta de dos archivos, main_adxl345.py y class_cliente_adxl345.py.

  • main_adxl345.py es el encargado de dibujar la interfaz y las funciones que manejan los datos del sensor.
  • class_cliente_adxl345.py se encarga de la conexión wi-fi con el microcontrolador con el servicio socket server.

La interfaz:

Esta es la ventana principal donde se mostraran los datos que recibimos desde el ESP8266. Lo ejecutamos usando el comando:


python3 -m main_adxl345

Es bastante sencilla, en la parte izquierda es donde esta el canvas para representar los ejes y la parte derecha están los apartados de conexión y el muestreo de los datos.


En el apartado "socket connection" es donde hay que introducir la IP que nos ha proporcionado Arudino IDE en el monitor serial y pulsar el botón "start conn".

Si todo esta correcto, la pantalla empezará a mostrar los datos y representar en la pantalla los ejes del sensor. Podemos hacer que se muestren o no las lineas de cada eje de una manera independiente con los check button situados bajo el frame de recepción de datos.

 

 

ADXL345 Interface Axis es un programa sencillo con el que podremos ver los ejes de un sensor ADXL 345 de una manera visual, un código sencillo y reutilizable. De hecho con unas pocas modificaciones lo he usado para mi próximo ejemplo con un sensor GPS 6MV2 y representar sus datos. 

Programa de ejemplo de este articulo en GitHub

 

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

Muestra el estado del sistema Raspberry Pi

Raspberry pi PWM

Espero que os guste el contenido, Saludos!!