#!/usr/bin/env python3 """ Toma la foto real enviada por el usuario (gps_pinout.jpg) y genera una imagen anotada con el pinout exacto, colores de cables soldados y su conexion a los conectores P1 y P3 de la placa ESP32 CYD. """ from PIL import Image, ImageDraw, ImageFont import os # 1. Cargar y recortar la foto original src = Image.open("hardware/gps_pinout.jpg") sw, sh = src.size # Queremos enfocar el módulo y los cables # El módulo está entre x = 0.2 y 0.85 crop_box = (int(sw * 0.15), 0, int(sw * 0.85), sh) cropped = src.crop(crop_box) # Redimensionar la foto recortada a un tamaño adecuado para el panel izquierdo (ancho 600) target_h = 680 target_w = int(cropped.width * (target_h / cropped.height)) cropped_resized = cropped.resize((target_w, target_h), Image.Resampling.LANCZOS) # Dimensiones finales del canvas W = target_w + 580 H = 760 im = Image.new("RGB", (W, H), (11, 15, 25)) draw = ImageDraw.Draw(im) # Pegar la foto en el lateral izquierdo photo_x = 30 photo_y = 65 im.paste(cropped_resized, (photo_x, photo_y)) # Borde decorativo alrededor de la foto draw.rectangle([photo_x - 1, photo_y - 1, photo_x + target_w, photo_y + target_h], outline=(50, 70, 110), width=2) # Cargar fuentes try: f_title = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20) f_sub = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 13) f_sec = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 15) f_bold = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 13) f_reg = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12) f_small = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 11) except Exception: f_title = f_sub = f_sec = f_bold = f_reg = f_small = ImageFont.load_default() # ------------------------------------------------------------- # ENCABEZADO # ------------------------------------------------------------- draw.text((30, 15), "PINOUT IDENTIFICADO DE TU MODULO GPS (FOTO REAL)", fill=(255, 255, 255), font=f_title) draw.text((30, 40), "Correspondencia de tus cables soldados con la placa ESP32 CYD (ESP32-2432S028)", fill=(0, 210, 255), font=f_sub) # ------------------------------------------------------------- # PANEL DERECHO: DETALLE DE PINES Y CABLES # ------------------------------------------------------------- rx = photo_x + target_w + 25 rw = W - rx - 30 def draw_card(box, fill, outline, radius=6): draw.rounded_rectangle(box, radius=radius, fill=fill, outline=outline, width=1) # Tarjeta 1: Cable Naranja (VCC y EN) c1_box = [rx, photo_y, rx + rw, photo_y + 115] draw_card(c1_box, (24, 30, 46), (220, 90, 30)) draw.rectangle([rx, photo_y, rx + 10, photo_y + 115], fill=(255, 120, 20)) draw.text((rx + 22, photo_y + 10), "1. CABLE NARANJA --> PADS 'V' y 'EN'", fill=(255, 140, 40), font=f_sec) draw.text((rx + 22, photo_y + 32), "• Señal: VCC (Alimentación 5V) + Enable activado.", fill=(220, 225, 235), font=f_reg) draw.text((rx + 22, photo_y + 52), " (Tu foto muestra el pad 'EN' puenteado con estaño a 'V').", fill=(160, 175, 195), font=f_small) draw.text((rx + 22, photo_y + 75), "• CONECTAR A:", fill=(255, 215, 60), font=f_bold) draw.text((rx + 145, photo_y + 75), "PIN 1 del Conector P1 (Vin 5V)", fill=(255, 255, 255), font=f_bold) draw.text((rx + 22, photo_y + 93), " Entrega 5V directo desde el puerto USB.", fill=(160, 175, 195), font=f_small) # Tarjeta 2: Cable Azul (TX) c2_box = [rx, photo_y + 128, rx + rw, photo_y + 243] draw_card(c2_box, (24, 30, 46), (40, 120, 220)) draw.rectangle([rx, photo_y + 128, rx + 10, photo_y + 243], fill=(35, 130, 245)) draw.text((rx + 22, photo_y + 138), "2. CABLE AZUL --> PAD 'T' (TX)", fill=(60, 160, 255), font=f_sec) draw.text((rx + 22, photo_y + 160), "• Señal: TX (Salida de datos NMEA del GPS al ESP32).", fill=(220, 225, 235), font=f_reg) draw.text((rx + 22, photo_y + 180), " Transmite velocidad, satélites, hora, rumbo y coordenadas.", fill=(160, 175, 195), font=f_small) draw.text((rx + 22, photo_y + 203), "• CONECTAR A:", fill=(255, 215, 60), font=f_bold) draw.text((rx + 145, photo_y + 203), "PIN 3 del Conector P3 (GPIO 35)", fill=(255, 255, 255), font=f_bold) draw.text((rx + 22, photo_y + 221), " Entrada RX1 por hardware de la placa CYD.", fill=(160, 175, 195), font=f_small) # Tarjeta 3: Cable Blanco (RX) c3_box = [rx, photo_y + 256, rx + rw, photo_y + 371] draw_card(c3_box, (24, 30, 46), (180, 185, 200)) draw.rectangle([rx, photo_y + 256, rx + 10, photo_y + 371], fill=(230, 235, 245)) draw.text((rx + 22, photo_y + 266), "3. CABLE BLANCO --> PAD 'R' (RX)", fill=(240, 245, 255), font=f_sec) draw.text((rx + 22, photo_y + 288), "• Señal: RX (Entrada de comandos al GPS desde el ESP32).", fill=(220, 225, 235), font=f_reg) draw.text((rx + 22, photo_y + 308), " Permite poner el GPS en modo Sleep y reactivarlo.", fill=(160, 175, 195), font=f_small) draw.text((rx + 22, photo_y + 331), "• CONECTAR A:", fill=(255, 215, 60), font=f_bold) draw.text((rx + 145, photo_y + 331), "PIN 2 del Conector P1 (GPIO 1 / TX0)", fill=(255, 255, 255), font=f_bold) draw.text((rx + 22, photo_y + 349), " Salida de comandos de reposo del instrumental.", fill=(160, 175, 195), font=f_small) # Tarjeta 4: Cable Verde (GND) c4_box = [rx, photo_y + 384, rx + rw, photo_y + 499] draw_card(c4_box, (24, 30, 46), (30, 170, 90)) draw.rectangle([rx, photo_y + 384, rx + 10, photo_y + 499], fill=(40, 200, 110)) draw.text((rx + 22, photo_y + 394), "4. CABLE VERDE --> PAD 'G' (GND)", fill=(50, 215, 120), font=f_sec) draw.text((rx + 22, photo_y + 416), "• Señal: GND (Masa / Retorno común de corriente).", fill=(220, 225, 235), font=f_reg) draw.text((rx + 22, photo_y + 436), " Referencia de masa para alimentación y bus serie.", fill=(160, 175, 195), font=f_small) draw.text((rx + 22, photo_y + 459), "• CONECTAR A:", fill=(255, 215, 60), font=f_bold) draw.text((rx + 145, photo_y + 459), "PIN 4 del Conector P1 (GND)", fill=(255, 255, 255), font=f_bold) draw.text((rx + 22, photo_y + 477), " (O bien al Pin 2 del conector P3).", fill=(160, 175, 195), font=f_small) # Tarjeta 5: Pad VB (Sin conectar) c5_box = [rx, photo_y + 512, rx + rw, photo_y + 610] draw_card(c5_box, (18, 22, 34), (60, 75, 100)) draw.rectangle([rx, photo_y + 512, rx + 10, photo_y + 610], fill=(120, 130, 150)) draw.text((rx + 22, photo_y + 522), "5. PAD 'VB' (V_BACKUP) --> SIN CONECTAR", fill=(170, 185, 205), font=f_bold) draw.text((rx + 22, photo_y + 544), "• Este pad dorado está abajo de todo, junto a la pila botón.", fill=(140, 155, 175), font=f_small) draw.text((rx + 22, photo_y + 564), "• No requiere conexión: Tu módulo ya tiene la pila recargable", fill=(140, 155, 175), font=f_small) draw.text((rx + 22, photo_y + 584), " soldada en la placa para retener la memoria satelital.", fill=(140, 155, 175), font=f_small) # Tarjeta inferior de resumen c6_box = [rx, photo_y + 623, rx + rw, photo_y + 680] draw_card(c6_box, (28, 24, 16), (220, 170, 40)) draw.text((rx + 18, photo_y + 632), "CONSEJO:", fill=(255, 200, 50), font=f_bold) draw.text((rx + 95, photo_y + 632), "Al flashear por USB el CYD, si el cable blanco (RX)", fill=(240, 240, 240), font=f_small) draw.text((rx + 18, photo_y + 652), "está enchufado a GPIO 1, desconéctalo temporalmente para evitar conflicto.", fill=(240, 240, 240), font=f_small) # Guardar out1 = "hardware/pinout_gps_foto_anotada.png" out2 = "pinout_gps_foto_anotada.png" im.save(out1, "PNG") im.save(out2, "PNG") print("Imagen generada con éxito:", out1)