Introducción al Poder de la Automatización en Programación Electrónica
En el dinámico mundo de la electrónica moderna, particularmente en sectores tan exigentes como el automotriz, la capacidad de programar, modificar y diagnosticar microcontroladores y memorias de manera eficiente y precisa es una habilidad indispensable.
El Programador UPA-USB, desarrollado por la compañía búlgara ELRASOFT Ltd., se ha consolidado como una herramienta fundamental para profesionales que trabajan con una vasta gama de dispositivos electrónicos, desde EEPROMs seriales hasta complejas unidades de control electrónico (ECUs). Su robusto hardware —compatible con interfaces como I²C, SPI y Microwire— y su software asociado, UUPROG (UPA-USB Device Programmer Software), proporciona una plataforma integral para tareas de lectura, escritura y verificación.
Sin embargo, la verdadera potencia del Programador UPA-USB se despliega a través de su capacidad para ejecutar scripts. Estos scripts, pequeños programas escritos en un dialecto de Pascal, permiten a los usuarios:
- Automatizar secuencias complejas (ej. "leer, modificar un PIN, escribir").
- Personalizar algoritmos para aplicaciones específicas, sin depender del soporte oficial.
- Crear flujos de trabajo adaptados a desafíos únicos, como el cálculo de códigos a partir de bytes específicos.
- Convertir el programador en una herramienta altamente extensible y adaptable.
En esta clase, exploraremos desde los conceptos fundamentales hasta la creación práctica de scripts, para que puedas aprovechar al máximo esta funcionalidad avanzada del Programador UPA.
Imagen 1: Diagrama de arquitectura del flujo de trabajo: Chip -> UPA -> UUPROG -> Script.
El Lenguaje de los Scripts UPA: Pascal Script y la Librería UUPROG
La base de los scripts UPA es Pascal Script. Es un lenguaje sencillo pero potente que se integra completamente con la API (Interfaz de Programación de Aplicaciones) expuesta por el software UUPROG, a través de la cláusula uses UUPROG;.
Tipos de Datos Esenciales
A diferencia de Pascal puro, en los scripts UPA solo se utilizan unos pocos tipos de datos para la lógica automotriz:
Integer: Números enteros. Se utiliza para direcciones de memoria (Ej: $00 a $1FFF), contadores o valores de bytes (0 a 255).String: Cadenas de texto. Se utiliza para mensajes al usuario, etiquetas y, lo más importante, para almacenar códigos PIN o VIN en formato legible.Byte: Un tipo especial que en realidad se maneja a menudo como unIntegeren las funciones, representando un valor de 8 bits.
var
Address: Integer; // Para la dirección de memoria
ByteValue: Integer; // Para el valor del byte leído (0..255)
CalculatedPin: String; // Para el resultado final del PIN
Funciones clave para Manipulación de Datos y E/S
Estas funciones son el núcleo de cualquier script de lectura y modificación:
GetByteHexEdit(Direccion): Integer;
// Devuelve el valor del byte (0-255) en la dirección especificada ($0000, $00FF, etc.).
// 2. Escritura en el Búfer de Memoria (Editor Hex)
SetByteHexEdit(Direccion, Valor): Procedure;
// Establece un nuevo Valor (0-255) para el byte en la Dirección. ¡Esto modifica el BÚFER, no el chip!
// 3. Conversiones (Cruciales para mostrar resultados)
IntToHex(Valor: Integer; Digitos: Integer): String;
// Convierte un número entero a su representación hexadecimal (Ej: IntToHex(255, 2) -> 'FF').
HexToInt(ValorHex: String): Integer;
// Convierte una cadena hexadecimal a su número entero (Ej: HexToInt('FF') -> 255).
// 4. Interacción con el Usuario (Input/Output)
MsgBox('Mensaje', 'Título', Banderas): Integer;
// Muestra un mensaje emergente. Es la función que presenta el código PIN al usuario.
AddMsg('Mensaje'): Procedure;
// Agrega un mensaje a la ventana de registro inferior de UUPROG (útil para depuración).
Anatomía de un Script UPA: Estructura y Componentes Fundamentales
La estructura de un script UPA debe asegurar que la lógica de la tarea (procedure) esté separada de la forma en que el script se integra al software UUPROG (bloque principal).
El Bloque Principal: El Registro del Script
A diferencia de Pascal tradicional, donde el bloque principal (begin...end.) ejecuta la lógica, aquí solo se utiliza para decirle a UUPROG cómo construir el menú de selección.
Imagen 2: El bloque principal (begin...end.) define la estructura de menú y el nombre del procedimiento a ejecutar.
// 1. Organiza tu script en una 'Carpeta' en el menú.
AddDeviceGroup('GRUPO_PRINCIPAL', 'Descripción Visible');
// 2. Define el chip que se va a programar y la memoria a leer.
AddDevice('NOMBRE_DISPOSITIVO', 'Descripción', 'GRUPO_PRINCIPAL', 'MemoriaSeleccionada');
// 3. Crea el botón que ejecuta la lógica real.
AddAction('NOMBRE DE LA ACCION', 'NombreProcedimientoLogico', 'NOMBRE_DISPOSITIVO');
end.
**Parámetros clave de AddDevice:**
- Primer parámetro (Ej: 'NOMBRE\_DISPOSITIVO'): Es una **etiqueta interna** para referenciar el dispositivo en
AddAction. - Segundo parámetro (Ej: '24C04'): Es la **descripción visible** para el usuario.
- Tercer parámetro (Ej: 'GRUPO\_PRINCIPAL'): Debe coincidir exactamente con el nombre dado en
AddDeviceGroup. - Cuarto parámetro (Ej: 'MemoriaSeleccionada'): Este es el **algoritmo de chip real** que UUPROG debe cargar, como '24C04', '93C56', o 'HC05'.
El Ciclo de Vida de un Script UPA: Creación, Instalación y Ejecución
1. Creación e Instalación
Tras escribir el código, el archivo .usc se copia en la carpeta de scripts de UUPROG. La ubicación estándar es:
Una vez copiado y reiniciado UUPROG, el software lee el bloque principal del script para mapear la estructura del menú.
2. Activación y Ejecución del Script: La Interfaz de UUPROG
Los comandos AddDeviceGroup, AddDevice y AddAction se traducen directamente en el árbol de dispositivos del software.
Paso 1: El grupo principal definido por AddDeviceGroup aparece en el árbol.
Paso 2: Se selecciona el dispositivo, cargando el algoritmo de chip (95040, por ejemplo). El panel inferior se habilita.
Paso 3: Al pulsar el botón de acción (LEER PIN CODE), se ejecuta el procedimiento de lógica asociado en el script.
5. Ejemplo Práctico REAL: Extracción de PIN de ECU Bosch ME7.5.30 (95040)
Gracias al script real proporcionado, podemos analizar una de las lógicas más comunes y potentes: la **Extracción del PIN a partir de bytes de control mediante operaciones aritméticas (Suma y Módulo 10)**.
El PIN de 4 dígitos (Ej: 1234) se calcula a partir de los valores decimales de cuatro bytes críticos de la EEPROM, localizados en las direcciones $19, $1A, $1B y $1C.
Análisis Comentado del Script Real
Este es el script real que se utiliza para esta ECU. A continuación, analizamos línea por línea el código Pascal Script:
Imagen 7: Script real que ejecuta la lógica de cálculo de PIN a partir de bytes de la EEPROM 95040.
uses UUPROG;
// Declara todas las variables necesarias para los bytes y el resultado final.
var
d1, d2, d3, d4: Integer; // Dígitos del PIN (0-9).
a, b, c, d: Integer; // Bytes leídos de la memoria (0-255).
s1, s2, s3, s4: String; // Cadenas temporales para construir el PIN.
// **********************************************
// ** PROCEDIMIENTO DE LÓGICA (CALCULAR EL PIN) **
// **********************************************
procedure LER_CODE; // Nombre del procedimiento llamado por AddAction.
begin
// 1. LECTURA DE BYTES CRÍTICOS
// Lee los valores decimales (0-255) del búfer en las direcciones críticas.
a := GetByteHexEdit($19);
b := GetByteHexEdit($1A);
c := GetByteHexEdit($1B);
d := GetByteHexEdit($1C);
// 2. CÁLCULO DEL PIN - DÍGITO POR DÍGITO
// Lógica: (Byte + Byte siguiente) MOD 10.
// La función MOD (módulo) devuelve el residuo de una división. Es clave para obtener el último dígito.
// Cálculo del PRIMER dígito: (Byte $19 + Byte $1A) MOD 10
d1 := (a + b) MOD 10;
// Cálculo del SEGUNDO dígito: (Byte $1A + Byte $1B) MOD 10
d2 := (b + c) MOD 10;
// Cálculo del TERCER dígito: (Byte $1B + Byte $1C) MOD 10
d3 := (c + d) MOD 10;
// Cálculo del CUARTO dígito: (Byte $1C + Byte $19) MOD 10 (cierra el ciclo)
d4 := (d + a) MOD 10;
// 3. CONVERSIÓN Y CONCATENACIÓN
// Convierte cada dígito (integer) a su representación en cadena (string).
s1 := IntToStr(d1);
s2 := IntToStr(d2);
s3 := IntToStr(d3);
s4 := IntToStr(d4);
// Concatena los 4 dígitos para formar el PIN final.
s1 := s1 + s2 + s3 + s4;
// 4. PRESENTACIÓN DE RESULTADOS
// Muestra el PIN resultante en una ventana emergente (MsgBox).
MsgBox('PIN Code ECU Bosch ME7.5.30: ' + s1, 'LEER CODE (95040)', MB_OK or MB_ICONINFORMATION);
// Muestra el PIN y los bytes leídos en el log de UUPROG para depuración (opcional).
AddMsg('PIN extraído: ' + s1);
AddMsg('Bytes leídos: A=' + IntToHex(a, 2) + ', B=' + IntToHex(b, 2) + ', C=' + IntToHex(c, 2) + ', D=' + IntToHex(d, 2));
end;
// **********************************************
// ** BLOQUE DE REGISTRO (MENÚ DE UUPROG) **
// **********************************************
begin
// Crea el grupo visible en el árbol de dispositivos.
AddDeviceGroup('ECUS_BOSCH_VAG', 'ECUs de Motor (Immo)');
// Registra el dispositivo y carga el algoritmo de chip '95040'.
AddDevice('BOSCH_ME7530', 'ECU Bosch ME7.5.30 (95040)', 'ECUS_BOSCH_VAG', '95040');
// Crea el botón visible y lo vincula al procedimiento 'LER_CODE'.
AddAction('LEER PIN CODE', 'LER_CODE', 'BOSCH_ME7530');
end.
Punto Clave: La Operación Módulo (MOD 10)
La función Módulo es la esencia de este script:
- Si la suma de dos bytes es **125**, entonces
125 MOD 10es **5**. El dígito del PIN es **5**. - Si la suma de dos bytes es **249**, entonces
249 MOD 10es **9**. El dígito del PIN es **9**.
Esto significa que la ECU almacena el PIN de forma cifrada (no en BCD directo), y el script actúa como la **llave matemática** para descifrar el código utilizando esta sencilla, pero poderosa, relación cíclica entre los cuatro bytes.
Navegando los Desafíos: Depuración, Errores Comunes y Mejores Prácticas
Errores Comunes y Soluciones
→ **Causa:** Olvidaste declarar una variable con
var o la función uses UUPROG;.→ **Solución:** Revisa el bloque
var al inicio del script y verifica que todas las funciones de UUPROG (como GetByteHexEdit) estén correctamente escritas.
→ **Causa:** El programador no ha leído la memoria correctamente o el usuario no cargó el archivo (en caso de trabajar con un archivo BIN).
GetByteHexEdit está leyendo bytes vacíos (generalmente FF o 00).→ **Solución:** Confirma que el chip está conectado correctamente y el botón "Read" (Leer) se pulsó antes de ejecutar el script. Si trabajas con un archivo, verifica que la ruta de memoria en la PC sea correcta.
→ **Causa:** No se especificó el número de dígitos.
IntToHex(Valor) es incorrecto.→ **Solución:** Siempre usa el segundo parámetro para forzar el formato, especialmente en bytes:
IntToHex(Valor, 2).
Mejores Prácticas Esenciales
AddMsg('Byte en $00: ' + IntToHex(byte1, 2));. Esto te permite ver el flujo de datos en el log inferior de UUPROG.
✅ Lógica de Seguridad: Si el script va a **escribir** en el chip (
ProgramDevice), incluye una MsgBox de confirmación para evitar escrituras accidentales.
✅ Estructura Clara: Mantén la lógica de la tarea en procedimientos separados (
procedure CalcularKM) y el registro del menú en el bloque principal (begin...end.).
Imagen 6: Uso de AddMsg para la depuración en tiempo real del flujo de datos.
Conclusión: Dominando el Arte de la Automatización con Scripts UPA
Dominar los Scripts UPA no es solo aprender una sintaxis, sino desarrollar una mentalidad de ingeniería inversa, precisión y respeto por los sistemas electrónicos. Es una habilidad que te permite no solo usar una herramienta, sino redefinirla, transformando horas de trabajo manual en segundos de ejecución automatizada. Con la comprensión del Pascal Script y la librería UUPROG, estás listo para llevar tus servicios de electrónica automotriz al siguiente nivel de eficiencia y confianza.
¿Listo para crear tu primer script?
Copia esta plantilla base, guárdala como mi-script.usc y comienza a personalizarla.
uses UUPROG;
// Declara tus variables y procedimientos de lógica aquí
procedure TuProcedimiento;
begin
AddMsg('Ejecutando lógica...');
// ** Lógica de lectura, cálculo o escritura va aquí **
// Ejemplo: var ValorByte := GetByteHexEdit($00);
// Ejemplo: MsgBox('Valor Leído: ' + IntToStr(ValorByte), 'Resultado', MB_OK);
end;
begin
AddMsg('Script iniciado.');
AddDeviceGroup('Mi Taller', 'Scripts Personalizados');
AddDevice('CHIP_GENERICO', 'EEPROM 95040', 'Mi Taller', '95040');
AddAction('CALCULAR DATO', 'TuProcedimiento', 'CHIP_GENERICO');
AddMsg('Script registrado en el menú.');
end.