ESPTOOL.EXE en windows XP x32

¿Quien usa ya Windows XP? Es un sistema operativo de 2001, tiene una antigüedad de más de 20 años, y Microsoft dejó de darle soporte hace 10 años, en 2014… Pero para algunos programas o para hardware antiguo sigue siendo necesario.

El caso es que necesito la herramienta esptool de expresiff https://github.com/espressif/esptool/releases que corra en Windows XP de 32 bits. Esta herramienta sirve para programar los chips ESP32 por puerto serie. Suelo proporcionar a mis clientes un script que llama a esptool.exe con los parámetros adecuados para programar los chips con el firmware que proporciono.

En este caso, el cliente tiene en el taller de verificación y control de calidad un antiguo PC con Windows XP x32 que utiliza para probar y programar dispositivos antiguos, es la herramienta que quiere utilizar también con mis programas.

Desgraciadamente esptool.exe sólo existe para Windows 7 y superiores. Expresiff lo proporciona escrito en python https://www.python.org/, aunque existen versiones ejecutables independientes construidas usando el compilador de python a .exe pyinstaller: https://pyinstaller.org/en/stable/.

En principio parece fácil: instalo python y pyinstaller en una máquina de Windows XP, cargo esptool.py y lo compilo. Pero la práctica es algo más dificil por problemas de compatibilidad de las herramientas de compilación con el antiguo Windows XP. Aquí voy a describir cómo instalar las versiones adecuadas de cada herramienta o librería para la compilación bajo Windows XP SP3 de 32 bits:

En primer lugar necesito una versión del intérprete de python que corra en Windows XP… pero que también sea compatible con pyinstaller. Las versiones posibles serían phthon 2.7.9 y la 3.4.4 según comentan en https://stackoverflow.com/questions/47516712/what-versions-of-python-will-work-in-windows-xp. Pero lo mejor sería una versión superior a 3.5 por compatibilidad con pyinstaller, pero no funcionaría en Windows XP, sólo en versiones superiores de Windows. Por suerte python se distribuye en código fuente y es posible modificarlo y recompilarlo para adaptarlo. Eso ya lo ha hecho «Zorba the Geek» y lo ha publicado en este hilo: una versión modificada de python 3.8.13 para Windows XP SP3: https://msfn.org/board/topic/183741-python-3813-for-windows-xp-sp3/page/4/

En la máquina con Windows XP copio «Python 3.8.1350.7z» y lo descomprimo a «c:\python_». A continuación ejecuto el instalador «c:\python_\install c:\». No funciona!. Es necesaria una librería .dll. Es necesario instalar previamente «vc2015_redist.x86.exe», que todavía puede descargarse de la página de microsoft: https://www.microsoft.com/es-es/download/details.aspx?id=53840. Entonces sí funciona la instalación de python, que creará un directorio «c:\python38». Ya puede borrarse el instalador en «c:\Python_».

Ahora hay que configurar el python para compilar esptool, esto se hace desde línea de comandos (abrir un CMD con Win+R y ejecutar CMD).

Instalar PIP (esta línea instalará PIP 22.0.4):
C:\Python38\python -m ensurepip --default-pip

Instalar intelhex (esta línea instalará intelhex 2.30):
C:\Python38\python -m pip install intelhex

Instalar pyserial en la versión compatible con pyinstaller y esptool (3.0.1):
C:\Python38\python -m pip install pyserial==3.0.1

Instalar pyinstaller en la versión compatible con windows XP y esptool 4.10):
C:\Python38\python -m pip install pyinstaller==4.10

Instalar wheel:
C:\Python38\python -m pip install wheel

Actualizar el entorno (actualiza setuptools de 56.0.0 a 69.1.1 y pip de 22.0.4 a 24.0.4):
C:\Python38\python -m pip install --upgrade pip setuptools wheel

A continuación es necesario salir de la consola con EXIT y reiniciar la máquina. Si no no carga algunas variables de entorno que se necesitan para el correcto funcionamiento de python y se producen errores raros de paths no encontrados etc.

Descargar la última versión del código fuente de esptool (esptool-4.7.0.zip) de https://github.com/espressif/esptool/archive/refs/tags/v4.7.0.zip y descomprimirlo en «c:\esptool_». Ahora bastaría con compilarlo con pyinstaller. Para mi sorpresa, una vez compilado correctamente, al ejecutarlo conectado correctamente a un ESP32 falla después de iniciar la comunicación correctamente, al no encontrar unos ficheros .json «esptool/targets/stub_flasher/*.json». Parece que no se han incluido en el proceso de compilación. Después de mucho tiempo buscando el problema sólo encuentro una pista, cómo no en stackoverflow, https://stackoverflow.com/questions/41870727/pyinstaller-adding-data-files

El comando correcto para compilar con TODOS los ficheros necesarios es:
cd c:\esptool_
pyinstaller -F --add-data "c:/esptool_/esptool/targets/stub_flasher/*.json;esptool/targets/stub_flasher/" --onefile esptool.py   

Esto debe dejar el ejecutable «esptool.exe» en «C:\esptool_\dist».

Como internet es efímero, dejo aquí el ejecutable compilado y la versión de python personalizada:

El ejecutable esptool.exe para Windows XP ya compilado:

La versión de «Zorba the Geek» de python3 para Windows XP:

Ingeniería inversa de un convertidor RS232 a ETHERNET parte 3

Ahora que ya tengo terminado el protocolo «discover» puedo hacer que el instalador del driver «NPORT Windows Driver Manager 3.5» reconozca mi ESP32 como un dispositivo MOXA y monte los puertos COM1 y COM2. El siguiente paso es identificar el protocolo de configuración del puerto y el protocolo de transmisión de datos. Aparentemente los puertos TCP/IP 960 y 966 tienen algo que ver:

Para averiguarlos monto el MOXA DE-311como puerto COM1 y analizo con WireShark la comunicación cuando abro el puerto con un programa terminal (Realterm)y envío datos:

Voy cambiando las configuraciones del puerto, baudrate, bits, paridad, control de flujo etc

Los datos de configuración del puerto se envían por el puerto TCP/IP 966. He observado que si hay más puertos activos utiliza los puertos TCP/IP 967, 968 etc hasta 982. El protocolo es algo distinto del protocolo «discover» pero sencillo:

El primer byte es el código de comando, el segundo es la longitud total mensaje y a continuación un grupo de datos variable, con un significado distinto según el comando.

He identificado bastantes comandos de configuración, aunque a otros no he sido capaz de encontrarles la utilidad.

  • 39 00 = Abrir el puerto
  • 2F 04 E8 03 00 00 = repetido x3 = Cerrar el puerto
  • 13 00 = KeepAlive o Heartbeat
  • 2C 13 10 03 01 01 00 00 00 00 4C454E4F564F2D54455354 = Configurar baudrate, bits etc
  • 17 04 40380000 = Baudrate arbitrario
  • 10 02 00 03 = Configurar baudrate, bits, paridad y bits stop
  • 11 04 00 00 00 00 = Establecer de flujo RTS/CTS DTR/DSR XON/FOFF
  • 12 02 00 00 = Establecer estado de RTS y DTR
  • 21 00 = Establecer BREAK
  • 22 00 = Cancelar BREAK
  • 30 01 10 = Sin identificar
  • 18 02 11 13 = Sin identificar

El MOXA contesta a casi todos estos comandos con ACK que es siempre COMANDO+4F4B

Los datos viajan bidireccionalmente entre el puerto COM y el MOXA por el puerto TCP/IP 950 sin modificación.

Con estos datos escribo el programa para ESP32 (DeVkit V2 o similar) «MoxaEmulator.ino» que realiza todas las funciones necesarias. El programa responde al «discover» y comunica por los puertos necesarios para emular un MOXA DE-302 de dos puertos. El programa sólo hace ECO de los datos serie que entran, enviándolos a la salida, pero eso permite ver que funciona. En esta captura se ve la detección del MOXA DE-311 auténtico y el DE-302 emulado:

El programa del ESP32 envía gran cantidad de información de depuración por el puerto serie, mostrando el intercambio de mensajes con el driver.

Y eso es todo… al final me ha llevado dos tardes más de lo que pensaba, pero los programas han quedado más depurados y fáciles de entender. Analizando el código puede seguirse con relativa facilidad el protocolo de MOXA y puede usarse en otros proyectos.

Links de descarga de los tres programas, aunque como cada uno es la evolución del anterior el «MoxaEmulator.ino» es el más completo y contiene el código de los anteriores.

MoxaDiscover1.ino

MoxaDiscover2.ino

MoxaEmulator.ino

Ingeniería inversa de un convertidor RS232 a ETHERNET parte 2

Con el primer programa el software DSU ya identifica el ESP32 como un dispositivo MOXA de la serie DE. Ahora sigo analizando paquetes para depurar las respuestas. Usando el software «Nport Windows Driver Manager» observo otro mensaje de descubrimiento, lo incorporo también al programa.

El siguiente paso es analizar el protocolo para el cambio de IP del dispositivo.

Y observo con Wireshark la comunicación:

Con estas captura puedo identificar comandos distintos: 0x45 que parece sirve para habilitar la configuración y seleccionar IP estática o DHCP, 0x33 para cambiar la IP y la máscara de red, 0x34 para cambiar el gateway y 0x35 que parece sirve para salvar los cambios, ya que no contiene información.

Con esta información actualizo el programa y ahora es posible también cambiar la IP del ESP32 usando la aplicación DSU. Se trata de un programa de pruebas, la configuración recibida no se salva en EEPROM y se pierde al reiniciar, pero sirve como prueba de concepto: MoxaDiscover2.ino

Ingeniería inversa de un convertidor RS232 a ETHERNET

Motivación:
Llevo más de 15 años usando los dispositivos del fabricante MOXA para llevar puertos serie RS232/RS485/RS422 a distancias largas a través de ethernet.
He usado principalmente los DE-311
https://www.moxa.com/en/products/industrial-edge-connectivity/serial-device-servers/general-device-servers/nport-express-series/de-311
y los NPort5210
https://www.moxa.com/en/products/industrial-edge-connectivity/serial-device-servers/general-device-servers/nport-5200-series/nport-5210

He conectado PLCs Siemens, Hiachi, Omron mediante estos dispositivos a HMI Proface, Omron, ESA VT100 (https://www.esa-automation.com/en/en-products/hmi/), transmisores de peso AUMAT4100 y DAT500 (https://www.pavonesistemi.com/es/electronica-de-pesaje-transmisores-de-peso-dat500) etc
El proceso es fácil, se conecta un dispositivo MOXA adecuadamente configurado para la red ethernet y con un cable personalizado al PLC y en el otro extremo otro al HMI, sensor etc.
Los datos serie entran por uno junto con las señales de control DTR/DSR y RTS/CTS etc y salen por el otro también con sus señales de control DTR/DSR y RTS/CTS después de viajar enrutadas por la red.

Pero una de las mejores funciones que tienen los dispositivos de MOXA es que permiten la opción «Windows Real COM Driver»!!
Cuando el dispositivo de un extremo es un PC con sistema operativo Windows no es necesario montar un MOXA conectado a un puerto serie del PC. Basta con conectar el PC a la red e instalar un driver que crea un «puerto serie virtual» en el PC conectado con un MOXA remoto.
De esta manera los programas en el PC trabajan con un puerto serie como siempre, mientras los datos se envían por la red al moxa remoto por donde salen al dispositivo.
Estos drivers tienen soporte desde Windows 95 hasta Windos 11.

Los productos de MOXA son excelentes y la calidad es excepcional, incluso indican el MTBF en la hoja de datos (más de 225000 horas!). Nunca me ha fallado uno, por lo que no tengo razones para dejar de usarlos.
Sin embargo, para aplicaciones domésticas y experimentación, siempre he ansiado poder tener un puerto serie virtual en el PC que me conecte por la red con mis micros, por ejemplo con ESP32.
De esta forma podría seguir usando los programas antiguos, que comunican por puerto serie, pero a través de la red.

Entonces… si averiguo el protocolo que usa MOXA en sus dispositivos cuando están en modo «REAL COM» podría escribir un programa para mis micros y usar su driver «Windows Real COM Driver»!

Proceso:
Para llevar a cabo la ingeniería inversa del protocolo necesitaré un sniffer de red, utilizaré WireShark: https://www.wireshark.org/
Como esto va a ser una «chapucilla de fin de semana» utilizaré la última versión bajo Windows 11 (Wireshark 4.2.0) en mi taller y una versión más antigua con soporte (no oficial) para Windows 7 para cuando trabaje en el pueblo con un viejo Packard Bell con Core2Duo T7200 http://ftp.uni-kl.de/pub/wireshark/win64/Wireshark-win64-3.6.18.msi.
Analizaré el protocolo de dos MOXA distintos, un DE-311 y un NPort5210 conectados mediante cable cruzado (aunque no es necesario los moxa tienen conexión de red RJ45 10/100 MDi/MDiX) directamente con el PC.
De esta forma minimizo el tráfico de red y no tengo que usar filtros en WireShark.

En el PC instalaré los dos programas que proporciona MOXA para gestionar estos dispositivos.
El programa que permite descubrir dispositivos en la red y asignarles IP:
DSU 2.7 build 23032110 (moxa-device-search-utility-v2.7.zip /dsu_setup_Ver2.7_Build_23032110.exe)
El instalador del driver COM que desubre dispositivos en la red y permite configurarlos como puerto serie local existe en varias versiones según el sistema operativo:
NPORT Windows Driver Manager 3.5 build 22120118 (moxa-win-driver-manager-v3.5-win-7-to-10-and-win-server-2008-r2-to-2019-whql-certified-driver-v3.5.zip / drvmgr_setup_Ver3.5_Build_22120118_whql.exe): Para Windows 7 a Windows 10 y
NPORT Windows Driver Manager 4.2 build (moxa-win-driver-manager-win-11-and-server-2022-and-later-whql-certified-driver-v4.2.zip / drvmgr_setup_Ver4.2_Build_23120717_whql.exe): Para Windows 11
También existen versiones para Windows 95 a Windows Vista que no necesito usar en este proyecto…

Alimento el DE311 y lo conecto al PC mediante un cable de red.

Arranco el WireShark como administrador para capturar de la tarjeta ethernet donde he conectado los MOXA.

Arranco el DSU como Administrador y pulso search.

Si todo va bien deberé poder ver la IP del MOXA en el DSU.

Cierro el DSU y voy a mirar los paquetes capturados por el WireShark.

Identifico varios paquetes UDP desde la IP del PC a la IP de broadcast 255.255.255.255, repetidos varias veces. Seguro que esta es la forma que tiene DSU de «llamar» a los MOXA:
PC (192.168.0.2) port 63683 envia UDP a broadcast (255.255.255.255) port 29168 con 8 bytes 0100000800000000
PC (192.168.0.2) port 63685 envia UDP a broadcast (255.255.255.255) port 4800 con 8 bytes 0100000800000000
PC (192.168.0.2) port 63687 envia UDP a broadcast (255.255.255.255) port 1029 con 6 bytes 490000060000
PC (IPV6 ) port 63691 envia UDP a multicast (IPV6 FF02::1) port 1029 con 28 bytes 7900001c000000000000000000000000000000000100000000010001

Observo que la IP del MOXA sólo contesta a uno de ellos, el sexto, enviado al port 1029 en IPV4 con la respuesta:
MOXA (192.168.0.31) port 50546 envia UDP a broadcast (255.255.255.255) port 1029 con 24 bytes C900001800007EF94CB81103EB9EC0A8006F0090E8049EEB

Supongo que el resto de paquetes no contestados que envía el PC para «llamar» a los posibles MOXA de la red son debidos a que el software DSU soporta varios modelos de MOXA y estará usando varios protocolos distintos…

A continuación el DSU envía un paquete, no ya de broadcast, sino a la dirección IP del MOXA que ha descubierto:

Posiblemente este paquete sirva para obtener información precisa del dispositivo:

PC (192.168.0.111) port 1028 envia UDP a MOXA (192.168.0.31) port 1029 con 6 bytes 010000060000
MOXA (192.168.0.31) port 1029 envia UDP a PC (192.168.0.111) port 1028 con 86 bytes 810000560000FC70148C1103EB9EC0A8006F000104730000040202014E5034303638332020202020202020202020202020202020202020202020020F0F0F0F0F0F0F0F0F0F0F0F0F0F0FC0A80021FFFFFF00C0A80001
También repito el proceso varias veces y siempre obtengo respuesta por el port 1029, también cambian cambian 4 bytes:
MOXA (192.168.0.31) port 1029 envia UDP a PC (192.168.0.111) port 1028 con 86 bytes 810000560000 E118A3CE 1103EB9EC…

Repito varias capturas cambiando la IP del MOXA y del PC para ver las diferencias en los paquetes. A continuación comparo a información que conozco con los datos obtenidos en las capturas para averiguar el significado de cada paquete:

Ahora compararé los paquetes capturados con la información que conozco para ver en que posición hay informacion reconocible.
MOXA DE-311 HW 2.1C, SW 2.4
production S/N á0BEE1240683
S/N 40683 = 9EEB hex
MAC 0090E8049EEB
IP 192.168.0.31 C0A8001F
mask 255.255.255.0 FFFFFF00
gw 192.168.0.1 C0A80001
PC Win 11 con
MAC F8:E4:3B:AF:97:87
IP 192.168.0.111 C0A8006F
mask 255.255.255.0 FFFFFF00

Estas pruebas veo que el primer paquete (comienza por 0x49) y su respuesta podrían tener esta estructura:

Y el segundo paquete, que comienza por 0x01, podría tener esta otra:

Con esta información recopilada he podido escribir un pequeño programa para ARDUINO ESP32 y probar si es correcto. He confirmado que los campos «Modelo» y «Version SW» son correctos cambiándolos por otros valores y observando en DSU la detección. Por ejemplo, en la siguiente captura hago que el ESP32 se identifique como MOXA DE-302 con un firmware version 4.2.

Esta es la captura de la salida de depuración del programa «MoxaDiscover1.ino«. (he eliminado las líneas repetidas):

Moxa discover responder (c) Heli Tejedor, V0.1, enero 2024
Reporting MOXA DE-302 SW version 4.2
Connecting to: xxxxxxxxxx:yyyyyyyyyy
……
Connected!
Signal %:86
MAC: 24:62:AB:F1:DA:44
IP: 192.168.0.165
NetMask: 255.255.255.0
Gateway: 192.168.0.1
DNS: 100.100.1.1
UDP Listening on PORT: 1029… OK
Running at Mhz: 240, Free RAM: 259432
UDP packet type: broadcast, from: 192.168.0.220:57202, to: 255.255.255.255:1029, length: 6, data: 490000060000
Response -> C900001800001214FAFB0203EB9EC0A800DC2462ABF1DA44
Discover CMD 0x49

UDP packet type: broadcast, from: 192.168.0.220:57202, to: 255.255.255.255:1029, length: 10, data: 4900000A00000203EB9E
Response -> C900001800001214FAFB0203EB9EC0A800DC2462ABF1DA44
Discover long CMD 0x49

UDP packet type: unicast, from: 192.168.0.220:1028, to: 192.168.0.165:1029, length: 6, data: 010000060000
Response -> 8100005600001214FAFB0203EB9EC0A800DC000104730000020402014E5034303638332020202020202020202020202020202020202020202020020F0F0F0F0F0F0F0F0F0F0F0F0F0F0FC0A800A5FFFFFF00C0A80001
Read Config CMD 0x01

La siguiente fase: averiguar el protocolo de configuración para cambiar a IP y los otros parámetros de la red

Diagnóstico de una válvula EGR de PSA / STELLANTIS averiada.

Pues resulta que también me voy a atrever con la mecánica… Y es que me ha tocado la moral que haya fallado con 80.000Km y que cueste 780€ (más mano de obra y otro montón de conceptos) .

Y es que mi DS5 edición aniversario de 180Cv es un coche genial: bonito, cómodo, buenos acabados, potente, con un consumo ajustado, pegatina C (cumple EURO 6)… pero ha pasado 4 veces por el taller para averías antes de los 90000Km y eso es inadmisible en un coche «premium».

Tres problemas con el depósito de urea: primero con 40.000Km, cubierto por la garantía. Segundo con 60.000 que me costó unos 600€ y el tercero con 73.000Km, este último sin cargo. Y ahora la válvula EGR con 80.000, que como el depósito de urea forma parte del sistema anticontaminación. A este coche se le cambia el aceite cada 30.000Km… no he podido hacer un cambio sin antes pasar por taller con una avería!!!

Este vehículo viene equipado con un depósito de urea para la reducción de los óxidos de nitrógeno NOx, que es un conjunto indivisible de depósito, bomba y electrónica de control. Según me comentan en el taller, no existe despiece ni es reparable «para evitar la manipulación del sistema anticontaminación». Cuesta unos 660€ más la mano de obra del cambio.

Vamos con la válvula EGR… su misión es también reducir las emisiones de óxidos de nitrógeno (dañinos para la salud y el medio ambiente), pero de una forma distinta y muy interesante. Lo que hace es mezclar parte de los gases de combustión del escape con el aire de la admisión para introducirlo de nuevo en los cilindros. ¿Absurdo? No tanto. Los óxidos de nitrógeno se producen en el interior de los cilindros debido a las altas presiones y altas temperaturas producto de una combustión muy eficiente (menos consumo y más potencia), combinado con la gran cantidad de oxígeno y de nitrógeno que hay en los gases de admisión. Los antiguos motores con bombas mecánicas, menos eficientes no generan estos gases.

Los motores diésel siempre deben aspirar la máxima cantidad de gases posible para poder comprimirlos y que aumente la temperatura y se produzca la combustión. Por lo tanto limitar la cantidad de aire que aspiran, para reducir la cantidad de oxígeno y nitrógeno y en consecuencia los óxidos nitrosos, no es una opción, el motor no funcionaria. Aquí es donde entra en funcionamiento la válvula EGR (Exhaust Gas Recirculation). Para disminuir la cantidad de oxígeno disponible lo que hace esta válvula es recircular los gases ya quemados, que a penas contienen oxígeno y sí mucho CO2, a la admisión. El volumen de gases admitidos es el óptimo, pero la concentración de oxígeno es la adecuada para la combustión del gasóil, no más. De esto se encarga la ECU (Electronic Control Unit,) del motor). No hay suficiente oxígeno como para producir óxidos de nitrógeno. Esto sólo sirve con el motor a bajo régimen, cuando la demanda de potencia es alta la necesidad de oxígeno también y no se puede sustituir parte del aire por gases quemados.

Mi coche viene equipado con una válvula EGR (Exhaust Gas Recirculation), modelo 9807593080 que se usa en muchos modelos de DS, citroen, ford y peugeot. Además también es producida por muchos fabricantes distintos (manías de la industria del automóvil: de tener muchos proveedores distintos para cada elemento).

Es un armatoste considerable, pero yo veo al menos 5 elementos completamente independientes y desmontables… ¿Por qué venden todo el conjunto y no los elementos por separado? Además del cuerpo de la válvula, arriba se ve un actuador por depresión, un sensor hall para detectar la posición del actuador, a la derecha un intercambiador de calor aceite / gases y abajo un motor de CC con sensor de posición.

Efectivamente, la válvula tiene elementos extra, además del mecanismo para permitir / impedir la recirculación de gases. El intercambiador de la derecha tiene la misión de enfriar los gases de escape antes de introducirlos en la admisión, algo lógico si pensamos que los gases de admisión interesa que estén lo más fríos posible y los gases de combustión están a más de 600 grados. Esto lo hace intercambiando el calor con el aceite del motor… sí, esta válvula tiene una conexión de entrada y otra de salida del aceite de motor. Como función extra, mediante este intercambiador, es posible calentar el aceite del motor cuando el motor está frío en pocos minutos, a costa del calor residual de los gases de escape. El actuador por depresión comanda una clapeta que abre o cierra el paso de los gases de combustión por el enfriador. Por defecto, un muelle en acatuador mantiene el paso de gases por el intercambiador abierto, se cierra por succión (depresión) de la admisión quizás mediante alguna válvula electroneumática (no he profundizado en este aspecto).

Una vez quitado el intercambiador se ve su entrada de gases a a derecha y salida de gases a la izquierda. Abano una apertura ovalada para el paso del aceite. Paso de gases por el intercambiador abierto:

Paso por el intercambiador cerrado:

Esta es la válvula que regula la recirculación de gases, similar en construcción a una válvula de admisión de los cilindros, pero comandada eléctricamente.

Este es el motor que la acciona, mediante un reductor de una etapa, una leva y un empujador. La placa electrónica contiene un sensor HALL que detecta la posición del piñón secundario, indicando la posición de la válvula a la ECU.

Esta era la posición de la leva que comanda la válvula cuando desmonté el conjunto, hacía tope en la posición casi cerrada, pero no llegaba nunca a cerrar por completo. La ECU detectaba este estado e informaba «Válvula EGR en posición distinta a la comandada».

La válvula cierra por acción de un muelle, de forma que al cortar la alimentación del motor se garantiza el cierre… desconozco si el motor tiene control bidireccional. Si sólo acciona en un sentido para abrir y el cierre se produce por la acción del muelle.. entonces es un diseño muy deficiente. La suciedad que impide el cierre esta alojada en la guía del vástago de la válvula (sometido a los gases de combustión calientes y carbonilla) pero no estaba tan agarrotada como para que un motor con algo más de par (quizás un paso más de reducción) no pudiera moverla.

Después de forzarla un poco con la mano cierra al completo:

Esta es la guía del vástago de la válvula y el propio vástago. No parece un mal diseño, la guía es solidaria al cuerpo de aluminio y todo esta refrigerado mediante al aceite del motor. En mi opinión tiene muy poca suciedad para que haya fallado.

Así ha quedado después de limpiarlo todo, no había mucha suciedad, pero ahora ya se mueve sin ninguna resistencia y el muelle la cierra por completo.

Así se ve ahora la válvula y la lumbrera por donde entran los gases calientes:

En general ha quedado bastante limpia…

Este es el intercambiador de calor entre los gases de combustión y el aceite. El aceite circula por el cuerpo de la válvula y la refrigera, y también por la carcasa de plástico donde está este elemento bañado en flujo de aceite del motor. Los gases de combustión entran por los dos tubos horizontales superiores y sale por los dos inferiores, El texturizado de los tubos es para aumentar la superficie de contacto con el aceite:

Por esta parte entran y salen los gases de combustión. La clapeta de la foto anterior hace de bypass: en una posición lleva la circulación de los gases por el intercambiador de calor y en otra los dirige directamente a la válvula EGR:.

Mi diagnóstico: el accionamiento de la válvula es demasiado flojo, con muy poca suciedad se ha bloqueado y sólo con la mano he podido desbloquearlo. ¿Podría un motor con más par solucionar este fallo? ¿O la suciedad se acumularía más y más con los sucesivos accionamientos y solo se retrasaría el fallo unas semanas?

Doble puerto serie simultáneo SoftwareSerial para arduino

Como las placas Arduino UNO, micro nano etc (todas las basadas en el ATMEGA328P) solo disponen de un puerto serie es necesario usar la librería «SoftwareSerial.h» del entorno Arduino para manejar más de un puertos serie.

Esa librería es multi instancia, pueden declararse varios objetos tipo «SoftwareSerial» pero solo se puede escuchar la recepción de UNO en cada momento (seleccioándolo mediante el procedimiento listen().

En el proyecto que estoy trabajando ahora necesito escuchar simultáneamente dos puertos, y la opción de conmutar mediante listen() no sirve porque pierde caracteres.

Para solucionarlo he creado esta bominación, una librería que he llamado «SoftwareSerial2RX.h» que permite tener DOS puertos serie de solo recepción (no necesito transmitir y he eliminado esa parte para no consumir pines) por cada instancia.

Es necesario que los dos pines de recepción se encuentren en el mismo puerto del micro, pero pueden crearse varias instancias con parejas de pines en puertos distintos y escuchar 2, 4 ó 6 puertos en un solo arduino. Este horror no permite la recepción concurrente: si esta recibiendo datos de un puerto y llegan por el otro se interrumpen las dos recepciones. No esta muy currado, pero para leer tarjetas RFID es suficiente porque el usuario pasa de nuevo la tarjeta por el lector si observa que no se ha leido correctamente. Como uso un puerto para el tarjetero de entrada y otro para el de salida no se usarán nunca los dos puertos a la vez.

Esta es la librería, con un ejemplo de utilización: SoftwareSerial2RX

Este es un ejemplo de utilización, los procedimientos estan duplicados, uno para cada puerto: available() y available1(), read() y read1() etc…

#include <SoftwareSerial2RX.h>
// Double software serial: RX0 = digital pin 2, RX1 = digital pin 3
SoftwareSerial2RX TwoPortSerial(2, 3); 

void setup() { 
// Open serial communications and wait for port to open: 
  Serial.begin(9600); 
  
  while (!Serial) {; // wait for serial port to connect. Needed for native USB port only 
  }
  Serial.println (F("SoftwareSerial2RX: Two simultaneous receive only serial ports"));
  // Start only RX serial ports 
  TwoPortSerial.begin(9600); 
} 

void loop() { 
// while there is data coming in, read it 
// and send to the hardware serial port: 
  if (TwoPortSerial.c() > 0) { 
    Serial.print (F("FromPort0: ")); 
    while (TwoPortSerial.available() > 0) { 
        char inByte = TwoPortSerial.read(); 
        Serial.write(inByte); 
      }
      Serial.println(); 
    } 

  if (TwoPortSerial.available1() > 0) { 
    Serial.print (F("FromPort1: ")); 
    while (TwoPortSerial.available1() > 0) { 
        char inByte = TwoPortSerial.read1(); 
        Serial.write(inByte); 
      } 
      Serial.println(); 
   } 
   delay (50); // Slow down! 
}

Mejorando un lector RFID de 125Khz RDM6300

He comprado un par de lectores RFID de 125Khz modelo RDM6300 V3.1 para un proyecto de control de accesos. https://www.amazon.es/dp/B00K8R7FR6
Son muy fáciles de usar y se encuentra bastante documentación en internet:

Pero la sensibilidad de lectura es bastante baja, aunque promete leer las tarjetas desde 15mm, solo llega a 10mm. En cualquier caso 15mm es una distancia de lectura bastante baja, obliga a pegar la tarjeta contra la carcasa del lector y no permite leerlas si estan guardadas en una cartera abultada o en una mochila.

He pensado que sería posible aumentar la distancia con alguna modificación, en primer lugar he obtenido el esquema aproximado de la placa:

No he medido muchos componentes, pero no es relevante para entender el funcionamiento. La primera modificación que se me ha ocurrido es alimentar la bobina desde 5V en lugar de hacerlo desde 3,3V. Esto puede hacerse desoldando una pata de la boina de choque SMD que alimenta el emisor del transistor PNP y soldando un hilo a +5V. Aumenta un poco la sensibilidad pero no es relevante.

La solución óptima es usar una antena mejor. La antena que se suministra con el módulo es de pequeño tamaño, de hilo de 0,24mm de diámetro. Despues de probar con distintas antenas he encontrado una excelente: esta construida con hilo de 0,3mm de diámeto y consta de 60 espiras sobre un soporte de 60mm de diámetro.

El resultado es espectacular, con la antena original la señal en la antena es de 20V pp:

Con la antena de 60mm de diámetro de 60 espiras la tensión sube hasta 60V pp, quizás hasta demasiado para los transistores S8050 y S8550 (VCE de 25), pero funciona!! La distancia de detección es ahora de 60mm. Ahora puede leer tarjetas guardadas en una cartera dentro de una mochila!!

Para probar el módulo he usado un arduino UNO con el PIN 2 conectado a la salida TX del módulo. El módulo se alimenta entre GND y +5V del arduino. El programa de test es este: Rdm6300Test

El caso de los firmwares corruptos. SPI EEPROM 25Qxx

Un amigo me ha dejado un TV de marca ANSONIC (marca de Hipercor) para reparar. Aunque el televisor es una marca genérica la electrónica es Vestel, que es un gran fabricante de electrónica de consumo. La misma placa, modelo 17MB55, se usa en televisores Telefunken y otras marcas conocidas.

Los síntomas son que el TV se mantiene en standby, al encenderlo no hace nada de nada. La primera sospecha es de alimentaciones, pero todas son correctas. Comprobando los relojes y reset todo es correcto, pero sique sin arrancar. Si tiene alimentación, tiene reloj y no esta reseteado el procesador debería comenzar a ejecutar el programa y arrancar el TV, pero no… Por último sospecho del propio programa ¿y si es incorrecto?.
Esta placa usa dos memorias EEprom SPI de 8 patas para almacenar el programa, es facil encontrar los puntos de test para leerlas y progrmarlas por ICSP, pero yo prefiero desmontarlas y pincharlas directamente al lector/grabador porque me es mas rápido que preparar un cable ICSP específico para esta placa.

Añadiendo unos hilillos a las memorias SO8 puedo insertar las memorias en el lector/grabador para DIL. Leo las memorias y hago un backup, importante!, que nunca se sabe…

A continuación busco en distintos foros de internet dedicados al servicio técnico de Audio y Video, pero no encuentro el firmware exacto para esta Ansonic. Hay que buscar «Dump» no «firmware» porque lo que la gente sube a la web no es el firmware tal y como lo proporciona el fabricante sino un volcado binario de lo que se lee de las propias eeprom. Por suerte encuentro un firmware para esta placa Vestel, pero para un televisor Telefunken: http://remont-aud.net/dump/lcd_pdp_tv/telefunken/telefunken_d32h125n3_shassi_main_board_vestel_17mb55/378-1-0-31790 Flasheo las memorias y las sueldo provisionalmente en su sitio:

PERFECTO. El TV vuelve a funcionar, aunque ahora los menús son los de Telefunken.

Ya solo queda desoldarlas, quitar las patillas y soldarlas de forma definitiva.
Todavía me quedaba por averiguar la razón de la corrución de los datos… un amigo bromeó que había sido un rayo cósmico, pero yo pensaba que era un error del firmware que al grabar algún parámetro había sobreescrito el bloque equivocado.

Cuando devuelvo el TV a mi amigo y le explico la avería, muy contento, me dice que esta podía ser también la avería de otro TV que tenía. Es cierto, hacía unos meses habíamos estado intentando reparar un Blaupunkt BLA-236/173J con lector de DVD pero nos había sido imposible. Él lo solucionó comprando otro igual pero con el TFT roto y cambiando la placa base. Pero el cambio le funcionó unos meses y de nuevo muerto…
Recuperamos los restos de los TV del trastero y nos ponemos a ello. A ver que sacamos partiendo de dos Blaupunkt iguales averiados con el mismo problema en la placa base, modelo T.MSD309.B66B:

Esta placa base solo tiene una EEPROM, pero la técnica es la misma: desoldarla, leerla, buscar un firmware nuevo adecuado, grabarla, resoldarla para pruebas y soldarla definitivamente, si todo va bien.

Buscando por aqui: http://remont-aud.net/dump/lcd_pdp_tv/blaupunkt/blaupunkt_bla_23207i_gb_3b_hkdp_uk_b23u207thdd_shassi_main_board_t_msd309_b66b/380-1-0-37955
Encontré algunos que mediofuncionaban, aunque no manejaban adecuadamente el modelo de panel que este TV usaba:

Encontré otross que funcionaron bien, lo que confirmaba que el problema era el firmware corrupto, pero ninguno tenían soporte para DVD:

Pensando que el problema era un bloque de eeprom incorrecto, me pongo a comparar todas los firmwares .bin que había descargado con el backup que había leído, intentando buscar un bloque discrepante. Estos firmwares son modulares y dentro contienen secciones con el bootloader, el driver del panel, sintonizador, etc y los menús que cada fabricante personaliza.
Después de mucho comparar no pude ver diferencias en la estructura entre el backup corrupto y los firmwares operativos. Todo parecía estar en su sitio y no había bloques borrados.
Pero la casualidad, que a veces ayuda, me hace ver, en un bloque vacío, un dato discordante:

Un cuatro (04 hexadecimal, que es 00000100 en binario) en medio de un bloque de ceros… Un bit que debia estar a cero esta a uno!!! ¿Es este el problema? Pues SI! después de cambiar este 04 a 00 y grabar la memoria de nuevo el TV vuelve a funcionar como al principio, y con soporte para el lector de DVD! Es mucha casualidad haber encontrado un bit cambiado en 32 millones, pero estaba en una zona de buena visibilidad. Si el bit eeróneo hubiera estado en una zona con datos habría sido imposible identificarlo. Aunque el bit estaba en una zona vacía es común que el firmware realize un autochequeo con un checksum y si no es correcto no arranque, por seguridad.

Ahora ya no me parece tan raro lo del rayo cósmico, aunque es raro… También puede deberse a una mala calidad de la memoria EEPROM o un proceso de grabación incorrecto. La eeprom de este modelo era una GD25Q32 de GigaDevice: http://www.gigadevice.com/product/detail/5/365.html?locale=en_US.

Lo claro es que flasheando este firmware parcheado en las dos EEPROM se repararon las dos placas base del Blaupunkt y el TV funcionó de nuevo. Ya hora con una placa base de repuesto!

Si puede serle de ayuda a alguien, este es el firmware leido y reparado para esta placa T.MSD309.B66B del Blaupunkt BLA-236/173J-GB-4B-FHKDUP-EU: T.MSD309.B66B uf11 GD25Q32 Leida Reparada

Actualización 24/11/2017
Parece que la epidemia de datos corruptos en memorias SPI se extiende a otros aparatos, y a memorias I2C. Ayer reparé un (bastante caro) medidor de espesores por ultrasonidos Krautkramer Branson DM4E.
El aparato es muy parecido a este:

Mide espesores mediante una sonda de contacto por ultrasonidos de entre 1Mhz a 10Mhz. El aparato mostraba «FAIL» en la pantalla y un proveedor nos ofertó repararlo por casi 2000€. Por suerte teníamos otro igual para comprobar…
El problema estaba en una EEPROM I2C Microchip 24lc65.

Por alguna extraña razón el medidor interpretaba que los datos contenidos en la memoria, a penas 64 bytes de los 8K bytes disponibles, no eran correctos y se negaba a trabajar. Un «transplante» de datos desde la EEPROM del otro medidor que funcionaba correctamente y una nueva calibración y reparado!

Usando CIS (Contact Image Sensor) con Arduino y Processing

En construcción.
Esta semana estoy trabajando un poco la ingenieria inversa, a ver si soy capaz de sacar algo en claro de los CIS Contact Image Sensor).
Tengo un puñado de ellos, incluido uno enorme y antiguo para DIN A3 TCD120AC.

Desgraciadamente no hay mucha información técnica pública en internet. De lo poco que he podido encontrar esta hoja de datos de Dyna Image es muy interesante: https://www.tvsat.com.pl/pdf/D/dl100_dyna.pdf
Parece ser que son dispositivos muy personalizables y los fabricantes de escáners los encargan a medida. http://www.csensor.com/M118_CIS.htm
Los sensores CIS son mucho mas fáciles de usar que los CCD (que requieren varios clock y tiempos muy precisos y la salida necesita preamplificador etc). La salida de los CIS suele ser de entre 2,5V a 5V de fondo de escala. Podemos introducirla directamente en un A/D de cualquier micro.
Los elementos sensores son CMOS y eso les da unas características electro ópticas bastante buenas. No he podido encontrar las curvas de sensibilidad espectral de los elementos supongo que serán las típicas de los fotodiodos para luz visible.
Los fabricantes estan empleando CIS para sustituir los CCDs en los escáneres, faxes etc porque les simplifica y abarata los diseños: ya no neceesitan complejas ópticas con espejos y delicados ajustes.
Eso también ayuda a usarlos con facilidad a nivel de aficionado que sean grandes, 216mm (ancho del papel DIN A4), y que tengan bastantes elementos (mínimo unos 8 por mm, 1728 en total).

De todos los que tengo no he podido encontrar hoja de datos de ninguno, algunos se ve claramente que el código marcado es un código de cliente…
Por suerte tengo dos Dyna Image similares a los de la hoja de datos.
Uno es un DL100-10AFJK con conector de 12 pines y el otro un DL100-05EUJK con conector de 7 pines que parece coincidir con la hoja de datos.

Preparo un programa para Arduino UNO sencillo, para tratar de comunicar con él.
Parece ser que todos usan un sistema muy parecido, la salida es analógica y de un nivel compatible con un A/D de 5V fondo de escala. Solo hay que proporcionar dos señales para la lectura:
Pulso SP, (Start pulse) que señala el comienzo de línea y
Pulsos SP o CLK (Clock) que generan la salida del valor analógico de cada punto de imagen.

Para la visualización de las líneas capturadas uso un programa en Processing en un PC con Windows:

Fuentes para probar la lectura de datos de diversos CIS Contact Image Sensor), para Arduino UNO y para el PC, en java con Processing:

Descargar todas las fuentes del proyecto: CISReader.zip

Lectura de CIS DynaImage DL100-05EUJK a baja velocidad:

Lectura de CIS DynaImage DL100-05EUJK a alta velocidad:

Lectura de CIS SS30009B de color RGB: