miércoles, 9 de octubre de 2024

Primer barco RC Zhong Shan Gunship

Muy buenas a todos, marineros!! 

Ya sabéis que nos encantan los vehículos RC, generalmente son vehículos terrestres Pero el verano pasado decidí comprar un kit para un barco, y mirando por mi web chinesca de confianza encontré este modelo de plástico para montar:  Zhongshan Gunship. lo que más me llamo la atención es que estaba medio preparado con motor. Como no entiendo de barcos, me dije, pues este mismo, y esto es lo que pasó...

 

Pero antes, un poco de la historia sobre este barco:

 

Según wikipedia este barco cañonero de 65,8 metros de longitud y 8,8 metros de manga, pertenecía a la Marina China y fue construido en Japón en 1913 e irónicamente hundido por esta misma armada japonesa durante un bombardeo en la segunda guerra Sino-Japonesa (1937-1945) en el rio Yangtze el 24 de octubre de 1938.

En 1986, cuando decidieron recuperar los restos del naufragio, recuperación que se llevo a cabo en 1997, 59 años después de su hundimiento. En 2001 recuero su apariencia de 1925 pero decidieron conservar daños sufridos durante su hundimiento-

 

El Zhongshan restaurado ahora se encuentra en el Museo de Buques de Guerra Zhongshan en Wuhan.

Fin de un poquito de historia :)

No soy experto en montar maquetas de barcos ni en barcos en general, asi que primero mis disculpas a los que si por que me imagino que no estaré usando las palabras técnicas del mundillo. Y casi con seguridad podría decir que es la primera maqueta de plástico que monto. ¿La experiencia? Ha sido entretenida y sobre todo, divertido.

Para montar el kit he utilizado las siguientes herramientas:

  • Cuter
  • Lima
  • Alicates de corte
  • Taladro manual
  • Vaselina o grasa
  • Pinturas en spray

Como el motor ya viene prácticamente montado, solo lo he desmontado para aplicar un poco de grasa en los piñones interiores. Y la primera parte que he mecanizado es el timón.

 

Para poner el timón primero he cortado la parte que va en el interior de barco, después con una broca de 1.5mm he agrandado el agujero para poder introducir un tornillo de 35mm. En la parte superior he puesto el enganche que conectará con el servo que mueve el timón.

Antes de poner el timón en su posición definitiva hay que aplicar grasa en todo el tornillo hasta que todo el hueco quede estanco. Esto evitará que el agua pueda introducirse en el interior del barco.

Para colocar las helices primero tenemos que quitar los 4 tornillos que sujetan el motor, de esta manera se trabaja con mayor comodidad. Después hay que introducir la vaselina en los tubos (¿bocinas?) antes de meter los ejes donde colocaremos las helices. Como los tubos son algo pequeños, apliqué la vaselina, primero calentando un poco al baó maría y aplicandola con una jeringa. Al empujar, tiene que salir parte de esta vaselina hasta que salga el eje. Con esto, igual que con el timón, evitamos que el agua se filtre al interior de la embarcación

Con esto hecho, poniendo el receptor para la radio Taranis y un par de ajustes rápidos, ya estaba preparado su primera prueba de navegación





Una vez termine de probar que todo funcionaba correctamente desmonte la electrónica y pase al segundo paso, pintar.

Pintar no es algo que se me de especialmente bien, aún así primero pinte todo de negro, para darle opacidad al platico, esto es por que el plástico es bastante fno y la otra pintura al ser gris, no creo que sea capaz de no dejar pasar la luz del ESC o del receptor desde el interior y es algo que no me gusta.

Para el casco he usado color rojo claro para la parte inferior y el gris oscuro para la parte que va sobre el agua. Si bien hay una franja blanca, ya me había quedado bien el corte de rojo a gris y no quise arriesgar

Para el puente he usado una especie de marrón y el mismo gris oscuro que he usado en el casco. Al ser escala 1/150 me ha venido vien para ponerle un personaje en el puente como timonel.

Electrónica y reglaje:


Para la electrónica he probado varias emisoras. Primero probé con la radio "Taranis" pero hay un fallo que no supe arreglar y es que al desconectar la radio, el servo se pone en una posición que hace que el timón estuviera forzado.

Imagino que no le he dedicado el suficiente tiempo a esta radio, por que no lo logre quitar. Curiosamente también me pasa con otros receptores de la misma marca.

En la prueba con GT5 la cosa mejoró notablemente. Ahora el servo siempre esta en su sitio.

  • Receptor: FS2A AFHDS 2A de 4 canales
  • ESC: Genérico motor escobillas
  • Baterías: 2 x 18650
  • Motor: Genérico 130
  • Servo: Servo 9G genérico

 

 

Una vez que ponemos las baterías el barco pierde estabilidad así que probé a poner más peso en la parte posterior. En total se han añadido 30g extra que sumados a los 110g de la batería, 10g del servo y 20g del ESC hacen un total de 170g.

Como primera experiencia de navegación ha sido bastante fácil de poner en marcha e incluso de subsanar pequeños errores que han ido surgiendo durante el montaje y pruebas.


 

ARRR!!! Marineros!!!! Si esta entrada gusta, compraré otro diferente para montar y compartir mis experencias. A ver si para el póximo consigo hacer funcionar la "Taranis y probamos. Además si encuentro el fallo comento como corregirlo.

Saludos!!!


miércoles, 2 de octubre de 2024

Modulo GPS 6MV2 Serial ESP8266 NodeMCU

¿Qué es el Módulo GPS-6MV2?

GPS-6MV2

El módulo GPS-6MV2 es un dispositivo electrónico pequeño y, sobre todo, económico. Este dispositivo que permite determinar la posición geográfica de un objeto, como un dron, a través de las señales emitidas por los satélites GPS. Es ampliamente utilizado en proyectos de electrónica, robótica y aplicaciones de seguimiento. Fácil de programar y con multitud de librerías disponibles para leer los datos que proporciona de manera serial. Datos que posteriormente se pueden buscar en paginas como Google maps.

Antes de empezar a programar vamos a ver primero sus características, los usos más comunes y, sobre todo, su funcionamiento.

Características técnicas principales:

  • Chipset: U-blox NEO-6M
  • Alimentación: 3.3V a 5V
  • Consumo: Aproximadamente 45mA en funcionamiento
  • Comunicación: Serial UART (TTL)
  • Velocidad de comunicación: Hasta 9600 bps (Configurable)
  • Precisión: Hasta 2.5 metros
  • Antena: Integrada (cerámica)
  • Temperatura de funcionamiento: -40°C a 85°C
  • Dimensiones: Pequeño y compacto
  • Memoria: EEPROM interna para configuración

 

¿Cómo Funciona el módulo GPS 6MV2?

El módulo recibe las señales de los satélites GPS, calcula su posición en base a la demora de las señales y proporciona esta información a través de la interfaz serial. Los datos que se pueden obtener incluyen:

  • Latitud y longitud: Coordenadas geográficas exactas.
  • Altitud: Altura sobre el nivel del mar.
  • Velocidad: Velocidad del dispositivo.
  • Curso: Dirección en la que se mueve el dispositivo.
  • Número de satélites: Cantidad de satélites detectados.
  • Hora: Hora UTC (Tiempo Universal Coordinado)

¿En que aplicaciones es un gran aliado?

La versatilidad del módulo GPS-6MV2 lo hace ideal para una amplia gama de proyectos y aplicaciones, entre las que destacan:
      Seguimiento:
    • Seguimiento de vehículos, personas o mascotas.
    • Sistemas de flotas.
    • Geolocalización de activos.
      Robótica:
    • Navegación autónoma de robots móviles.
    • Drones con GPS.
    • Vehículos aéreos no tripulados (UAV).
      Proyectos con microcontroladores:
    • Creación de sistemas de posicionamiento para Arduino.
    • Desarrollo de aplicaciones de geolocalización.
      IoT (Internet de las Cosas):
    • Dispositivos IoT con seguimiento GPS.
    • Sensores remotos con geolocalización.
      Meteorología:
    • Balones sonda con GPS.
    • Estaciones meteorológicas móviles.
      Deportes:
    • Seguimiento de actividades al aire libre (running, ciclismo, etc.).
    • Análisis de rutas.

Su capacidad para determinar la posición geográfica de un dispositivo hace que sea una opción popular y accesible para los aficionados a la electrónica y los ingenieros.

Sin embargo, como cualquier tecnología, el GPS-6MV2 presenta tanto ventajas como desventajas. A continuación, veremos los puntos positivos y negativos de este módulo, esto nos permitirá tomar la decisión adecuada sobre si aplicarlo o no en nuestro proyecto.

Ventajas del módulo GPS-6MV2:

  • Bajo costo: Es una opción económica para proyectos de GPS.
  • Fácil de usar: Su interfaz serial simplifica la integración con microcontroladores como Arduino.
  • Pequeño y ligero: Ideal para aplicaciones móviles.
  • Alta precisión: Proporciona datos de posición precisos para la mayoría de las aplicaciones.
  • Amplia disponibilidad: Se encuentra fácilmente en tiendas de electrónica y en línea.

Desventajas del módulo GPS-6MV2:

  • Precisión: La precisión, pese a ser muy buena en condiciones optimas, puede verse afectada por factores como la obstrucción de la señal GPS por edificios, vegetación o factores meteorológicos como la lluvia o tormenta. El número de satélites visibles se vera afectado por estos factores y se reducirá la precisión
  • Consumo de energía: Durante la búsqueda inicial el consumo es más elevado si lo comparamos a cuando el sistema ya ha establecido conexión.
  • Configuración: Es posible configurar el módulo para ajustar parámetros como la velocidad de baudios, el formato de datos y otros.

Como vemos no todo es bonito con el módulo GPS 6MV2, pero queda claro que sus ventajas lo hacen ideal para casi cualquier proyecto que requiera la posición de un objeto.

Librerías Arduino para el Módulo GPS-6MV2

Para comunicarnos con este módulo existen diversas librerías que puedes utilizar con Arduino para interactuar con el módulo GPS-6MV2. Cada una ofrece diferentes funcionalidades y niveles de complejidad. A continuación, te presentaré algunas de las librerías más comunes y algunas otras menos conocidas pero no por ello menos importantes:

 

Librerías Principales para el módulo GPS-6MV2:

  • TinyGPS: Una de las librerías más populares y sencillas de usar. Proporciona una interfaz intuitiva para leer los datos NMEA (National Marine Electronics Association) del módulo GPS y extraer información como latitud, longitud, altitud, velocidad y tiempo. Es una excelente opción para comenzar.
  • TinyGPSPlus: Una versión mejorada de TinyGPS que ofrece funciones adicionales y un mayor rendimiento. Es ideal para proyectos que requieren un procesamiento más avanzado de los datos GPS.
  • Adafruit_GPS: Desarrollada, como su nombre indica, por Adafruit, esta librería proporciona una interfaz fácil de usar y es compatible con una amplia variedad de módulos GPS. Ofrece funciones para configurar el módulo, leer datos y calcular distancias.
  • NewSoftSerial: Esta librería no es específica para GPS, pero es útil si necesitas utilizar pines diferentes a los seriales estándar de Arduino para la comunicación con el módulo GPS.

Otras librerías menos conocidas

  • SparkFun_Ublox_GPS: Diseñada específicamente para los módulos GPS U-blox, como el NEO-6MV2. Ofrece un control más granular sobre las configuraciones del módulo y acceso a características avanzadas.
  • GPSLib: Una librería más completa que ofrece funciones para calcular distancias, rumbos y realizar otras operaciones geográficas.

Librería TinyGPSPlus y el ESP8266 NodeMCU

Es una de las librería de Arduino más populares y fáciles de usar. Procesa los datos específicos para del módulo GPS que transmite información en formato NMEA. Esta librería es una evolución de la librería TinyGPS.

Además de su facilidad de uso, cuenta con una amplia comunidad y documentación que nos proveen de toda la información necesaria para usos más específicos

Para las conexiones entre microcontrolador y módulo unicamente usaremos 2 pines, más concretamente el pin, Rx GPIO0 (D3) y Tx GPIO2 (D4). Para la alimentación usaremos los 3.3V y GND

Conexión entre NodeMCU y GPS6MV2

Es importante recordar que para muchos microcontroladores con un solo puerto serial, es imprescindible el uso de la librería "SoftwareSerial". Esta herramienta nos permite simular una comunicación serial en cualquier par de pines digitales de tu placa


#include <tinyGPSPlus.h>
#include <SoftwareSerial.h>
/*
    Este ejemplo demuestra el uso de TinyGPSPlus, requiere el uso 
    de SoftwareSerial, para el dispositivo GPS-6MV2 usaremos 9600-baud 
    y conectado al pin GPIO 0 (Rx) y el GPIO 2(Tx) del microcontrolador
    ESP8266 NodeMCU.
*/

static const int RXPin = 0, TXPin = 2;
static const uint32_t GPSBaud = 9600;
String gpsdate = "";
String gpstime = "";

// Objeto TinyGPSPlus
TinyGPSPlus gps;

// Conexión serial con el dispositivo GPS
SoftwareSerial ss(RXPin, TXPin);

// Inicia el Serial y la comunicación GPS-6MV2 
void setup() 
	{
	Serial.begin(115200);
	delay(1000);
    Serial.println("Iniciando GPS-6MV2...");
	ss.begin(GPSBaud);
	}

void loop() 
	{
	Serial.println(neo6mv2data());
    smartDelay(1000);

	if (millis() > 5000 && gps.charsProcessed() < 10) 
    	{
    	Serial.println(F("No se reciben datos GPS, revise las conexiones"));
    	}
    }

static void smartDelay(unsigned long ms) {
	unsigned long start = millis();
	do 
    	{
		while (ss.available()) 
        	{
			gps.encode(ss.read());
            }
		} while (millis() - start < ms);
}

La función principal del loop() se hace una llamada a la función neo6mv2data() Esta es la función encargada de devolvernos un String con los datos que se mandan en la comunicación serial


String neo6mv2data() {

  int satellites = -1;
  float hdop = 0.0;
  float location_lat = 0.0;
  float location_lng = 0.0;
  int age = 0;
  char dateBuffer[10]; // 00/00/0000
  char timeBuffer[8]; // 00:00:00
  float altitude = 0;
  float course = 0;
  float speed = 0;

  if (gps.satellites.isValid()) satellites = gps.satellites.value();
  else satellites = -1;
  if (gps.hdop.isValid()) hdop = gps.hdop.hdop();
  else hdop = -1;
  if (gps.location.isValid()) location_lat = gps.location.lat();
  else location_lat = 0.0;    
  if (gps.location.isValid()) location_lng = gps.location.lng();
  else location_lng = -1;
  if (gps.location.isValid()) age = gps.location.age();
  else age = -1;
  if (gps.altitude.isValid()) altitude = gps.altitude.meters();
  else altitude = -1;
  if (gps.course.isValid()) course = gps.course.deg();
  else course = -1;      
  if (gps.speed.isValid()) speed = gps.speed.kmph();
  else speed = -1;
  
   if (gps.date.isUpdated())
  {
    sprintf(dateBuffer, "%d/%d/%d", gps.date.day(), gps.date.month(), gps.date.year());
    gpsdate = String(dateBuffer);
  }
  
  if (gps.time.isUpdated())
  {
    sprintf(timeBuffer, "%d:%d:%d", gps.time.hour(), gps.time.minute(), gps.time.second());
    gpstime = String(timeBuffer);
  }

 return "<gps" 
            + String(satellites)
            + " " 
            + String(hdop)
            + " " 
            + String(location_lat,6)
            + " "
            + String(location_lng,6)
            + " "
            + String(age)
            + " "
            + String(gpsdate)
            + " "
            + String(gpstime)
            + " "
            + String(altitude, 2)
            + " "
            + String(course, 2)
            + " "
            + String(speed, 2)
            + ">";
}

Si nos fijamos en las lineas de location_lat o location_lng, al formar el Srting, conservamos los decimales, en este caso 6:


String(location_lat, 6) // x.000000

String(location_lng, 6)	// y.000000

Salida serial GPS-6MV2

Y esta es la captura de los datos seriales que recibe el microcontrolador ESP8266.

Cada uno de los valores esta delimitados por "< ">, con una cabecera con los caracteres "gps" y separados por un espacios " " y esto hace que a la hora de usar otro programa sea más sencilla su decodificación.

Versátil y barato, este módulo puede hacer las delicias de cualquier aficionado a la electrónica o la radio frecuencia. Esperamos que con esta información se pueden tener más claros ciertos conceptos y ventajas y desventajas del módulo GPS-6MV2

Descargar ESP8266 Basic GPS6MV2 Serial desde GitHub

Saludos!!!

viernes, 27 de septiembre de 2024

ESP8266 Servidor socket ADXL 345

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!!

sábado, 21 de septiembre de 2024

ESP8266 y ADXL345 acelerómetro de 3 ejes. Lectura Serial

ADXL345

Buenas a todos!! El ADXL345 es un sensor súper versátil en campos como la robótica, drones o sistemas de seguridad.

Pues tengo varias ideas para el pero por el momento es mejor hablar sobre que es el sensor ADXL345 y cuales son sus características más destacadas.

¿Que es el sensor ADXL345?

El sensor ADXL345 es un acelerómetro digital de 3 ejes ampliamente utilizado en aplicaciones muy diversas, desde drones y robots hasta dispositivos portátiles y sistemas de control industrial. El sensor ADXL345 tiene una muy popular gracias a su alta precisión, bajo consumo de energía y facilidad de uso.

Las aplicaciones típicas para el sensor ADXL345:

  • Detección de movimiento: Detección de movimiento: En sistemas de seguridad, juegos, interfaces gestuales.
  • Control de orientación: Control de orientación: En drones, robots, estabilizadores de imagen.
  • Monitoreo de vibraciones: En maquinaria industrial, equipos de diagnóstico.
  • Interfaz hombre-máquina: En dispositivos portátiles, controles remotos.
  • Reconocimiento de patrones de movimiento: En aplicaciones de fitness, rehabilitación.

Principales Características técnicas funcionalidades:

  • Consumo de 23uA en modo de medición y 0.1uA en modo standby
  • Voltaje en un rango de 2.0V a 3.6V (ADXL345 funciona a 3,3V)
  • Conexión SPI de 3 o 4 lineas e interfaces I2C
  • Resolución fija de 10-bits y una máxima de 13-bits
  • Temperatura de uso -40º hasta +85º

Las principales funcionalidades del sensor ADXL345 pueden ser:

  • Medición de Aceleración: Mide la aceleración en los tres ejes del espacio (X, Y, Z), así permite determinar la orientación, inclinación o movimiento de un objeto.
  • Rango de medición configurable: Permite mediciones de ±2g, ±4g, ±8g y ±16g, adaptándose a diferentes aplicaciones.
  • Alta Resolución: Con una resolución de hasta 13 bits, lo que se traduce en una alta precisión en la medición de la aceleración.
  • Bajo Consumo de Energía: Consume muy poca energía, tanto en modo de medición como en modo de espera, con consumos tan reducidos es ideal para dispositivos alimentados por batería.
  • Comunicación: Puede comunicarse a través de interfaces I2C o SPI.
  • Regulador de Voltaje Integrado: Incorpora un regulador de voltaje interno, simplificando el diseño del circuito.
  • Tasa de muestreo configurable: Permite ajustar la frecuencia a la que se toman las medidas
  • Interrupciones configurables: Se puede configurar para generar interrupciones cuando se detectan ciertos eventos, como una aceleración determinada o un cambio de orientación.

¿Cómo Funciona?

El ADXL345 utiliza micro-condensadores que se desplazan físicamente cuando se aplica una fuerza (aceleración). Este desplazamiento cambia la capacitancia de los condensadores, lo que se traduce en una señal eléctrica que es convertida a un valor digital por un convertidor analógico-digital (ADC) interno.

En esta señal digital es donde se encuentran los datos que utilizaremos para representar las coordenadas X Y Z

Como usar el sensor ADXL345

Para utilizar el sensor ADXL345 de una manera más amigable tenemos disponibles varias librerías que simplifican su uso y que como comentamos mas arriba, nos permitirá tanto lectura de datos como programar eventos. Estas son las librerías más populares:

  • Adafruit ADXL345 library: Es una de las librerías más conocidas y documentadas, desarrollada por Adafruit Industries.

    Esta librería ofrece una amplia gama de funciones para configurar y leer datos del sensor, como establecer el rango de medición, ajustar la tasa de muestreo y leer los valores de aceleración en los tres ejes. Es muy fácil de usar gracias a su interfaz es intuitiva y bien estructurada, lo que facilita su integración en tus proyectos.

  • SparkFun ADXnodemcu adxl 345L345 library: Muy similar a la librería de Adafruit pero desarrollada por SparkFun Electronics.

    Esta librería comparte muchas similitudes con la de Adafruit y puede incluir algunas funciones adicionales o variaciones en la implementación, pero en general, su funcionalidad es prácticamente la misma.

  • Jarzebski Arduino ADXL345: Esta librería ofrece algunas funciones más avanzadas, como la detección de caídas libres y la detección de golpes y una mayor personalización de la configuración del sensor. Incluye gravedades como Marte, la Luna o el sol. No es la más conocida pero merece la pena darle un vistazo.

Opciones avanzadas:


Para el ejemplo del sensor ADXL345 vamos a utilizar la librería Adafruit ADXL345 library conectado a un microcontrolador ESP8266 NodeMCU por protocolo I2C. El sensor es alimentado por los 3.3V que ofrece el microcontrolador y el NodeMCU se alimenta por el mismo cable USB por donde recibiremos los datos.

El ejemplo es el mismo que aparece en su web así que no pondré parte del ejemplo que esta en la misma librería. Una vez cargado el programa pasará por los siguientes procesos:

  • Creamos el sensor:
    
        /* Crea el sensor. 12345 asigna una ID unica para el sensor*/
        Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
        
        
  • En el apartado void setup() inicializamos el sensor y seleccionamos el rango:
    
          /* Inicializa el sensor */
          if(!accel.begin()) {
          	/* Hay un problema al conectar ADXL345 ... compruebe las conexiones... */
          	Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
          	while(1);
          }
          
          /* Selecciona el rango apropiado para tu proyecto */
          accel.setRange(ADXL345_RANGE_16_G);
        
        
  • Una vez en el loop tomamos los eventos para luego mostrarlos en el monitor serial. Los datos se acualizan cada 500ms.
    
        void loop(void) {
        /* Get a new sensor event */ 
        sensors_event_t event;
        accel.getEvent(&event);
        
        /* Display the results (acceleration is measured in m/s^2) */
        Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
        Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
        Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
        delay(500);
        }
        
        

Con todo funcionando tenemos que tener una salida en el monitor similar a esta:


Accelerometer Test

------------------------------------
Sensor:       ADXL345
Driver Ver:   1
Unique ID:    12345
Max Value:    -156.91 m/s^2
Min Value:    156.91 m/s^2
Resolution:   0.04 m/s^2
------------------------------------

Data Rate:    100  Hz
Range:         +/- 16  g

X: 0.47  Y: -1.18  Z: 12.20  m/s^2 
X: 0.59  Y: -1.06  Z: 12.32  m/s^2 
X: 0.51  Y: -1.10  Z: 12.28  m/s^2 
X: 0.59  Y: -1.14  Z: 12.24  m/s^2 
X: 0.08  Y: -0.71  Z: 12.24  m/s^2 
X: 10.16  Y: -1.22  Z: 2.51  m/s^2 
X: 10.40  Y: -0.90  Z: 2.51  m/s^2

Salida serial ESP8266 NodeMCU y ADXL3345

Es realmente sencillo conectar el sensor a cualquier microcontrolador que admita protocolo I2C además de tener la opción SPI. Espero que este ejemplo os sirva de ayuda para futuros proyectos

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!!

miércoles, 11 de septiembre de 2024

Terminal DCC - Controla trenes DCC con la terminal

Muy Buenas a todos!!! Hoy traigo un programa creado con el ya comentado creador de interfaces de terminal pyTermTk. He vuelto a juntar las dos cosas que más me gustan, la informática y los trenes (si, muy a lo Sheldon).

Ya hacía tiempo que le iba dando vueltas a un controlador desde el terminal que no fuera estar metiendo instrucciones a mano desde una terminal. Entonces hace unos meses descubrí pyTermTk y empece a trabajar con el.

Tengo que decir que el diseñador de interfaces ttkDesigner ayudó mucho en el proceso, algunas veces me ha dado algún quebradero de cabeza, pero más por inexperiencia con la librería

También se han incluido los archivos json de las interfaces generados por ttkDesigner en la carpeta del repositorio

Terminal DCC esta diseñado para leer una base de datos generada con Rocrail y conectarnos a una central DCC de tipo hazlo tu mismo (DIY).

Para seleccionar el archivo desde un file picker que se abrirá al pulsar sobre el botón de menú "open". Desde aquí seleccionaremos el archivo .xml donde estén almacenados los datos del plan Rocrail.

 

Cuenta con dos pantallas principales llamadas Controller y List. En la primera de ellas, Controller, podemos manejar las locomotoras. Por otra parte List nos mostrará un resumen de los elementos almacenados en el archivo plan.xml


A la ventana configuración accedemos desde el menú superior "File", en "Config". Una vez que se abre la pantalla, encuentran los parámetros IP, que será la IP de la central DCC y el puerto que por defecto es el "2560" para realizar la conexión con wi-fi y sockets.

También se pueden configurar las pantallas Controller y List para que aparezcan al iniciar Terminal DCC.

Con estos datos ya podremos realizar la conexión pulsando sobre "Connection On/Off". Si todos los datos son correctos recibiremos un mensaje de confirmación:


--> [CONNECTED] to DCC station 192.168.1.5:2560

Una vez conectados podemos interactuar con la central introduciendo comandos con el widget de texto en la parte inferior. 

Con el botón "DCC On/Off" encendemos o apagamos la central DCC. Con la cental encendida ya podemos  manejar locomotoras desde el Controller con sus funciones básicas de avance, retroceso, parada. Las funciones de las locomotoras aún no están implementadas.

 


Instalación: 

Para instalar Terminal DCC solo necesitamos tener acceso a un terminal linux.

Una vez estamos en el terminal creamos un entorno virtual donde instalaremos las librerías y accedemos a el:


python3 -m venv ~/venv/TerminalDCC

source ~/venv/TerminalDCC/bin/activate

Nos situamos en la carpeta donde vamos a descargar Terminal DCC y lo podemos descargar directamente desde GitHub con la "git":


git clone https://github.com/Peyutron/TerminalDCC

Instalamos las librerías del archivo "requirements.txt" con "pip":


pip install -r requirements.txt

Ya solo queda ejecutar el programa:


python3 -m TerminalDCC_main
o
python3 TerminalDCC_main.py

 Bien pues esto es todo, las funciones son básicas y seguramente haya otro programa que no sea Rocrail, pero por el momento me ha servido para practicar Python con sus librerías, listas, diccionarios y sockets entre otros. La intención es actualizar la entrada cuando vaya haciendo cambios en el programa.

 

Si te gusta la programación y el contenido que realizo puedes aportar comentando tanto aquí como en el canal de Youtube.

 



Terminal DCC en GitHub

Y aquí tienes algunos ejemplos sobre TermTk y ttkDesigner:

pyTermTk y ttkDesigner: Button y Lablel

pyTermTk y ttkDesigner: List, ListSelect y Lablel

pyTermTk y ttkDesigner: Slider y Label

Librería PyTermTk crea interfaces en terminal

Librería PyTermTk en GitHub

Sígueme para más artículos sobre TermTk y otros temas de programación, Saludos!!!