Un autómata programable (PLC) casero, otra vez.

Viene de aqui: http://heli.xbot.es/?p=33

Han pasado otros diez años (alguno más), y nos hemos metido en 2020. El PLC casero no esta muerto, una tarjeta con un micro H8-500 y la versión 3.8 en su EPROM 27C256 continúa trabajando. Todavía controla, con sus 32 entradas y sus 32 salidas digitales, sus dos puertos serie y sus 32K de RAM con RTC y batería de backup, un filtro prensa destinado a desecar lodos.

Aprovechando el parón por el coronavirus me he puesto a revisar el software de programación ECP. La intención era portarlo a Windows. ECP solo corre en MSDOS debido a que hace acceso directo al hardware. Esto era una necesidad en su momento, ni la BIOS ni MSDOS proporcionaban una API adecuada para manejar el hardware. Por ejemplo, la velocidad más alta que podía programarse en los puertos serie era 19200 bauds, aunque los chip UART 8250 podían trabajar hasta 115200 bauds. Solo escribiendo directamente en los registros adecuados de la UART podían conseguirse todas las velocidades diponibles.

Con la llegada de sistemas operativos más avanzados (XP y posteriores) ya no es posible interactuar directamente con el hardware de la máquina. De eso se encarga el propio sistema operativo mediante los drivers, pero proporciona una API para que los programas de usuario puedan acceder al hardware.

El plan era el siguiente: cambios mínimos en el programa ECP para eliminar todas los accesos al hardware y hacerlo a través de la API de Windows. El programa ECP estaba escrito en ANSI C (Borland Turbo C 2.0, todavía se puede mediante DOSBOX bajo Windows XP). Para la nueva versión usaría GCC 9.30 bajo Msys2 y MinGW en Windows 7 x64 ( y en otros momentos máquinas bajo Windows 10 x64). No uso interfaz gráfico, mantengo el interfaz en texto pero usando la librería ncurses.

El resultado es una vesión (alfa todavía) que corre en desde Windows Vista hasta Windows 10 (incluidos Windows 7 y 8.x) de 32 o 64 bits, y también en Windows XP de 32 bits: http://heli.xbot.es/wp-content/uploads/2020/05/EcDuino4.51.zip.

Del mismo modo he tomado los fuentes en C del firmware del PLC V3.8 y lo he portado a Arduino (uso en entorno arduino 1.8.12, aunque compilará con otros anteriores). Junto con algunas librerías he conseguido que entre en la limitada RAM (2K) del Arduino UNO (Atmega328). Teniendo en cuenta que las versiones antiguas trabajaban en micros con 32K de ram es todo un lograo. Para conseguirlo he tenido que rehacer el mapa de memoria del PLC, menos E/S, menos reles internos etc. El resultado es un PLC con las siguientes características:

256 pasos de programa, 32 temporicadores/contadores, 32 entradas y 32 salidas. Dos entradas analógicas 0 a 5V de 10 bit y una salida analógica de 10 bit de 0 a 5V. 64 + 64 relés internos y reloj (si se usa el módulo RTC DS3231).

Como extra he mantenido el HMI (human-machine interface), con teclado de 6 teclas por I2C mediante PCF8754 y pantalla LCD d e16 caracteres por 2 líneas por I2C. Esto nos permite interactuar con el PLC.

Este es el montaje de prueba:

Este es el software para el Arduino UNO. Yo he usado el entorno 1.8.12, pero funcionará con otros más antiguos. Son necesarias 3 librerías que se encuentran en el directorio «libraries» dentro del ZIP: http://heli.xbot.es/wp-content/uploads/2020/04/EcDuinoUno0.2

El reloj no es imprescindible para el funcionamiento del programa, eliminarse de forma opcional. También es posible eliminar el conjunto del display y teclado dejando sin conectar los dos hilos del I2C amarillo y gris que val a los pines A4 y A5 del arduino. En caso de eliminar todo es recomendable conectar en esos pines un par de resistencias de 10K a positivo, o mejor eliminar la línea 65 de header.h «#define _DISPLAY_» para que no se compile la parte del display.

Algunos programas para el PLC para hacer pruebas: http://heli.xbot.es/wp-content/uploads/2020/04/ProgramasTest.zip

Migrando de Arduino UNO a ESP8266: excepciones

Estoy portando un programa que tengo funcinando en varios Arduino UNO a un ESP8266 y me encuentro que no funciona, provoca una excepción 28 y un volcado de pila en cuanto introduzco datos…

Excepciones del ESP8266: https://arduino-esp8266.readthedocs.io/en/latest/exception_causes.html

Después de mucho revisar compruebo que el programa para Arduino no lo tengo demasiado bien escrito, pero no causa problemas. Eso es debido a que no tiene MMU (unidad de manejo de memoria). El ATMEGA328P es un micro muy sencillo y tiene toda la memoria expuesta. Si tengo un «puntero loco» siempre puedo leer el o escribir en la dirección de memoria a donde apunta.

Sin embargo, el ESP8266, tiene un micro Tensilica Xtensa, bastante más complejo, con MMU https://en.wikipedia.org/wiki/Memory_management_unit y excepciones. Si un puntero apunta a la zona de memoria incorrecta es muy facil que se genere una excepción al intentar leer o escribir datos.

El código mal programado es este:

char *SavePtr;

char * MySerialbuffer;

char *Token = strtok_r(MySerialBuffer, " ", &SavePtr);
if (strcmp(Token, "Read") == 0) // Primera palabra clave
{
Token = strtok_r(NULL, " ", &SavePtr);
while (*SavePtr == ' ') SavePtr++; // Elimina espacios extra
  if (strcmp(Token, "Data") == 0) // Segunda palabra clave
  {
  int Src = atoi(strtok_r(NULL, Space, &SavePtr)); // Primer parametro
  int Len = atoi(strtok_r(NULL, Space, &SavePtr)); // Segundo paametro
// etc...
}
}

En MySerialBuffer estan los comandos que recibo por el puero serie. El trozo de código anterior detecta si he escrito «Read Data 12 23» donde 12 y 23 serían dos parámetros numéricos… Pero ese código es un despropósito.

La función «Token = strtok_r(caden ade entrada, delimitadores, saveptr)» https://linux.die.net/man/3/strtok_r devolverá un puntero nulo (NULL) cuando no encuentre una cadena que terminada por los delimitadores. En un micro sin MMU eso no tiene trascendencia, excepto porque cuando leamos datos de *Token estaremos leyendo de la zona de memoria 0 que puede contener cualquier cosa. En mi caso como son comparaciones con palabras clave es casi imposible que en esa zona de memoria haya algo parecido a lo que busco, la comparación falla y ya esta.

Pero en el ESP8266, con el micro Xtensa y su MMU, leer datos de un puntero nulo genera una excepción y el programa termina en una detención halt.

La forma correcta de programar es ir comprobando que el puntero devuelto por strtok_r no es nulo:

char *Token = strtok_r(MySerialBuffer, " ", &SavePtr);  
if (Token==NULL) return 0; // No continuar
if (strcmp(Token, "Read") == 0) // Primera palabra clave
{
Token = strtok_r(NULL, " ", &SavePtr);
if (Token==NULL) return 0; // No continuar
// Elimina espacios extra, con seguridad
if (SavePtr!=NULL) while (*SavePtr == ' ') SavePtr++;
  if (strcmp(Token, "Data") == 0) // Segunda palabra clave
  {
Token = strtok_r(NULL, Space, &SavePtr);
  if (Token != NULL) Src = atoi(Token);
  else return 0; // Falta un parametro
  Token = strtok_r(NULL, Space, &SavePtr);
  if (Token != NULL) Len = atoi(Token);
  else return 0; // Falta un el otro parametro
// etc...
}
}

Es lo que pasa cuando uno se acostumbra demasiado a programar micros ulrasencillos, luego hay que volver a la realidad de las MMU, la alineaciones a página etc

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

Cerradura electronica con tarjetas de proximidad Mifare con Arduino UNO

Hace unos meses me pidieron un curso personalizado centrado en el uso de tarjetas de proximidad (contactless cards) con tecnología Mifare desde Arduino. Aunque es una tecnología que ya había usado antes no la conocía lo suficiente como para dar un curso. Entonces pensé que lo mejor sería desarrollar algún proyecto con esta tecnología para empaparme bien de sus peculiaridades. Y lo que empezó como un miniproyecto de autoaprendizaje esta terminando en un monstruo que ya ocupa 30K de los 32K que tiene Arduino UNO!

Esta cerradura es bastante completa, tiene casi todas las funciones que se pueden desear en una cerradura electrónica:
– Cada cerradura puede manejar 100 tarjetas distintas en sus listas, si no se usan listas el número de tarjetas es de 255 para cada cerradura. Se pueden configurar 255 cerraduras distintas.
– Funcionamiento Tarjeta + PIN o solo tarjeta. El PIN puede ser de hasta 8 dígitos.
– Funcionamiento en modo Trust, en el que todas las tarjetas son aceptadas si contienen los datos cifrados correctos, o NO trust en el que las tarjetas deben ser introducidas previamente en una de las listas de cada cerradura.
– Listas: Blanca: tarjeta aceptada, util en el modo NO Trust. Negra: La tarjeta incluida en esta lista es rechazada y activa la alarma. Gris: La tarjeta es aceptada pero activa la alarma silenciosa. Gold: Las tarjetas de esta lista NO necesitan PIN, Es más cómodo operar la cerradura pero menos seguro si un usuario pierde la tarjeta.
– Pin de pánico. Si se introduce el PIN 2 se permite el acceso pero se activa la alarma silenciosa.
– Tarjetas personalizables con un mensaje de 16 caracteres que se muestra al usarlas.
– Dos franjas horarias de permiso en cada tarjeta, la tarjeta se rechaza fuera de esas franjas horarias.
– Tarjetas con fecha de caducidad preprogramable, pasada la fecha son rechazadas por las cerraduras.
-Anti Passback programable. Si se activa esta función es necesario salir antes de volver a entrar. Son necesarias cerraduras distintas para la entrada y la salida.
– Niveles de acceso: cada tarjeta se programa para abrir las cerraduras de igual o menor nivel, y no las de mayor nivel.
– Permisos: cada tarjeta se programa con unos permisos: abrir, administrar, cancelar alarma etc. Es posible crear tarjetas que solo permiten poner en hora la cerradura o cancelar la alarma.
– Cambio de PIN por el usuario. Introduciendo el PIN actual en cualquier cerradura.
– Cambio de PIN administrativo. Si un usuario olvida su PIN es posible cambiarlo sin conocerlo. Se necesita autorizar la operación con una tarjeta que tenga activo el permiso de cambio administrativo de PIN.
– Las tarjetas son compatibles con otros sistemas. Los datos almacenados en la tarjeta ocupan 2 bloques y 7 sectores y es posible configurar 4 zonas distintas. El lector busca datos válidos en cada una de las 4 zonas. Esto permite utilizar los bloques que dejan libres otros sistemas y trabajar conjuntamente. Yo lo he probado con tarjetas de vending de Autobar y funciona perfectamente: la tarjeta sigue siendo válida en las máquinas de vending y además funciona en las cerraduras.
– Datos cifrados. La tecnología mifare cifra los datos en las comunicaciones y tiene unas Keys de 48 bits pero es una tecnología ya rota. Existen distintos tipos de ataques que podrían revelar los datos contenidos en las tarjetas o incluso copiarlas. Esta cerradura cifra los datos con elalgoritmo XXTEA y una key de 128 bits. Aunque un atacante pudiera leerla y copiarla no podría averiguar el PIN ni modificar los datos.
– Registro de acceso en las tarjetas: en cada tarjeta se almacenan los 5 últimos usos, con fecha y hora, número de cerradura y tipo de acceso. Estos datos pueden consultarse desde el menú administrativo.
– Registro de acceso en la cerradura: cada cerradura almacena el último acceso de cada una de las 100 tarjetas distintas.
– Configuración sencilla desde PC mediante un programa terminal serie (o desde el entorno Arduino). Una vez introducidos los datos mínimos: password de comunicaciones y Keys es posible crear y administrar las tarjetas desde la propia derradura sin PC.
– Sin Keys ni password por defecto. Eso suele ser un foco de problemas de seguridad. La cerradura NO funciona si no se programa el password de comunicaciones. Es necesario programar también las Keys y recordarlas si quiere que distintas cerraduras sean compatibles entre si.
– Configuración sencilla mediante tarjeta administrativa ZeroCard que permite el acceso a todos os menús de configuración.
– Pantalla LCD de 2×16 para mostrar estado y configurar la cerradura.
– Realimentación visual con dos LED de estado y sonora con altavoz para un uso más cómodo.
-Salida de relé para alarma silenciosa en caso de que el usuario introduzca el PIN 2 con una tarjeta válida o si la tarjeta esta en la lista negra o gris.
– Interruptor anti tamper para detectar manipulación de la cerradura, con alarma y bloqueo del funcionamiento. Posibilidad de autodestrucción en caso de manipulación (se borran las keys y contraseñas).
– Detección de hardware en runtime, que permite detectar y dar alarma si falla el RTC o el lector MFRC522.
– Alarma retentiva, no se desactiva al quitar alimentación. Es necesario borrarla usando una tarjeta con el permiso de cancelar alarma.
– Posibilidad de desformatear las tarjetas y dejarlas en configuración de fábrica (transport). De esta forma pueden usarse en otros sistemas.

El hardware es bastante sencillo:
– Arduino UNO: https://www.tiendatec.es/arduino/placas/379-placa-uno-r3-atmega328p-cable-usb-compatible-arduino-uno-r3-8403790020005.html
– Reloj RTC por I2C zs-042 (chip DS3231): https://www.tiendatec.es/arduino/modulos/400-modulo-zs-042-reloj-en-tiempo-real-rtc-basado-en-ds3231-at24c32-para-arduino-y-raspberry-pi-8404001180013.html
– Lector RFID MFRC522: https://www.tiendatec.es/arduino/rf-rfid-nfc/394-modulo-rfid-rc522-kit-rfid-nfc-con-tarjeta-y-llavero-para-arduino-y-raspberry-pi-8403941180015.html?search_query=mifare&results=7
– Display LCD de 2 líneas de 16 caracteres por I2C: https://www.tiendatec.es/arduino/pantallas-displays/683-pantalla-lcd-1602a-16×2-bus-i2c-iic-azul-para-arduino-8406831590000.html
– Dos relés de nivel lógico: https://www.tiendatec.es/arduino/reles/521-modulo-ky-019-rele-1-canal-5v-para-arduino-8405211430004.html
– Teclado de matriz de 4×4 (aunque solo uso 3×4): https://www.tiendatec.es/arduino/componentes-de-entrada/384-teclado-membrana-4×4-teclas-con-adhesivo-8403841270014.html
– Algunos componentes sueltos: 2 resistencias de 330 Ohmios, un LED rojo y otro verde, un condensador electrolítico de 10uF y 16V, un altavoz de 8 Ohmios y un microinterruptor o contacto reed. También son necesarias algunas resistencias más para convertir el teclado de matriz a analógico: 2 resistencias de 4K7, dos de 1K5, dos de 15K, y una de 2K2.

El esquema es este:

Y el montaje práctico este:

El programa del Arduino necesita algunas librerías adicionales:
Para gestionar el lector MFRC522: https://github.com/miguelbalboa/rfid
Para gesionar el display LCD por I2C: https://github.com/marcoschwartz/LiquidCrystal_I2C
Para gestionar el reloj RTC DS3231: https://github.com/adafruit/RTClib Esta librería la he modificado para detectar, en cada lectura, si el chip RTC esta presente, de forma parecida a como funciona esta otra: https://github.com/PaulStoffregen/DS1307RTC
Mi librería RTClib: RTClib_heli

Para que el programa funcione correctamente es necesario que la memoria EEPROM del Arduino este vacía (a 0xFF). En esta memoria se graban datos importantes, la contraseña de comunicaciones etc y si tiene valores incorrectos no podremos comunicar con la cerradura, ni podrá leer las tarjetas. Lo mejor es borrar previamente la memoria EEPROM, por ejemplo con este programa: http://heli.xbot.es/?p=415

Aunque no esta totalmente terminado y me faltan por probar de forma exaustiva algunas funciones el programa es completamente funcional. Todos los ficheros del proyecto, con los fuentes para Arduino, librerías y esquemas: Cerrojus 0.7.B

Así se ve el prototipo:, la electrónica con arduino y el teclado cony del display LCD. El lector MFRC522 esta pegado tras el teclado y es capaz de leer las tarjetas a través de él.

Y esta es la vista de los circuitos en la parte trasera:

Para el funcinamiento seguro de la cerraura se usan varias Keys y contraseñas que se almacenan en la EEPROM del arduino. Cuando se carga el programa por primera vez deben configurarse con los valores adecuados. Si queremos que distintas cerraduras sean compatibles entre sí deben configurarse con las mismas keys. Esta configuración inicial se realiza desde el propio entorno arduino de programación, mediante el monitor serie.
En el primer uso el menú de administrador no necesita autorización. La primera tarjeta que se cree será la ZeroCard que es la tarjeta administrativa con todos los permisos activos. Después el acceso a los menús necesitará una autorización usando una tarjeta y el PIN correspondiente, dependiendo de los permisos de la tarjeta estarán activos unos menús u otros.
Usando la ZeroCard es posible gestionar todas las funciones de la cerradura y administrar las demás tarjetas, sin necesidad de PC.

En la siguiente entrada el manual de configuración y el manual de uso!

Arduino UNO con wifi ESP8266 por comandos AT simple

Los módulos ESP8266 vienen programados de fábrica para usarse como módems wifi. Para ello se debe usar una extensión del juego de comandos AT estándar: http://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf

Un problema que he encontrado es que los módulos ESP8266 antiguos (firmware 0.9.5) venían configurados por defecto con el puerto serie a 9600 baudios. Esto es muy lento pero muy adecuado para trabajar con los puertos série de software de Arduino UNO (librería softwareserial).
Los nuevos ESP8266 con el firmware (por ejemplo con firmware 1.5.2 ó 2.0.0) vienen configurados con el puerto serie a 115200 bauds. Esto no es problema para un Arduino MEGA que tiene varios puertos serie de hardware. Pero con un Arduino UNO, que solo tiene un puerto serie de hardware y esta conectado al convertidor USB <-> Serie, no podremos usarlos.
Si conectamos el ESP8266 al puerto serie nativo perdemos la comunicación con el PC y la capacidad de depurar el programa por el puerto serie. Además nos interferirá en la carga de sketchs desde el IDE e Arduino.
Si usamos un puerto serie de software (con la librería softwareserial) no podremos comunicar a más de 38400 bauds (teóricamente a 57600 pero yo no lo he conseguido, incluso a 38400 se producen muchos errores).

La solución que propongo es reconfigurar la velocidad por defecto de los ESP8266 a una velocidad mas baja compatible con la librería softwareserial. Una velocidad razonable para esta librería es 19200 baudios.

El procedimiento es el siguiente:
Cargar un sketch vacío en el IDE de arduino y enviarlo al Arduino UNO. A continuación conectar ESP8266 ESP01 para comunicar PC con ESP8266:
ESP8266 PIN 1 (RXD) -> ARDUINO UNO PIN 0 RX
ESP8266 PIN 8 (TXD) -> ARDUINO UNO PIN 1 TX
Según este esquema:

Es necesario que el Arduino UNO tenga un sketch vacío para que no interfiera en las comunicaciones con el ESP8266. Este esquema nos permite usar la placa Arduino UNO como convertidor USB <-> RS232 para comunicar el PC con la placa ESP8266.

A continuación abrir el monitor serie del IDE Arduino ( Herramientas -> Monitor Serie o pulsando Control + Mayúsculas + M) y configurar enviar «Ambos NL & CR» y la velocidad a 115200 baudios.
Enviar AT y enter y el módulo deberá responder OK si todo es correcto. Si la velocidad por defecto del módulo no es 115200 no responerá y posiblemente se vea «basura» en el monitor serie. Entonces habrá que probar distintas velocidades hasta conseguir que el módulo responda OK al comando AT.
Para configurar la velocidad por defecto a 19200 baudios, 8 bits de datos, uno de stop y sin control de flujo hay que enviar el comando:
AT+UART_DEF=19200,8,1,0,0
y el módulo responderá AT.
A continuación no responderá más a AT porque ya habrá conmutado a la nueva velocidad. Para probarlo seleccionar 19200 baudios en el monitor serie y enviar AT. La respuesta deberá ser OK si todo es correcto. Tras este procedimiento la velocidad por defecto queda fijada a 119200 baudios incluso tras un eset del módulo o tras quitarle alimentación.
En este fichero estan los esquemas e instrucciones para este proceso: Esp8266_Config

Ahora ya puede conectarse el ESP8266 en una par de pines generales y configurarlos para puerto serie de software.
Podemos usar los pines 2 y 3 para el puerto serie y conectar también un LED y un pulsador siguiendo este esquema:

A continuación cargamos en el IDE de arduino el sketch «Esp8266_Simple.ino»: Esp8266_Simple
Para monitorizar el trabajo de este sketch se puede usar el monitor serie configurado a 115200 baudios.
La salida será similar a esta:
Enviando: AT+RST
Respuesta: AT+RST
OK
(algo de basura…)
ready
Enviando: AT+CWSAP_CUR=»MyESP8266″,»Test1234″,5,3
Respuesta: AT+CWSAP_CUR=»MyESP8266″,»Test1234″,5,3
OK
Enviando: AT+CWMODE=2
Respuesta: AT+CWMODE=2
OK
Enviando: AT+CIPMUX=1
Respuesta: AT+CIPMUX=1
OK
Enviando: AT+CIPSERVER=1,80
Respuesta: AT+CIPSERVER=1,80
OK
Enviando: AT+CIFSR
Respuesta: AT+CIFSR
+CIFSR:APIP,»192.168.4.1″
+CIFSR:APMAC,»1a:fe:00:00:00:00″
OK
Trabajando
Trabajando
Trabajando
Trabajando

Este programa crea un punto de acceso WIFI (AP) llamado «MyESP8266» con contraseña WPA2 «Test1234» en el canal 5. Nos conectamos a ese punto de acceso, introducimos la contraseña y abrimos en un navegador la dirección 192.168.4.1.
Podremos ver una página web simple con dos botones rotulados ON y OFF. Pulsándolos podremos cambiar el estado del LED conectado el PIN 13 del Arduino. Más abajo podemos ver el estado del PULSADOR conectado en el pin 4.

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:

El caso de las fuentes de alimentación zombies

No sé que pensará George A. Romero del título de esta entrada. A mi me suena bien, pero no es acertado. Realmente estas fuentes no son zombies sino que son fantasmas: estan muertas pero ellas no lo saben. También he conocido fuentes verdaderamente zombies: que estaban muertas y volvían a la vida pero no es el caso.
Quedamos en que son fuentes fantasmas. Fuentes muertas pero que no lo saben… hasta que lo descubren y mueren definitivamente.
¿Como las identificamos? Fácil. Tenemos un dispositivo electrónico que lleva incorporada una fuente de alimentación conmutada. Actualmente casi todo, desde TVs, ordenadores personales, cargadores de télefonos, fuentes de laboratorio… Funciona perfectamente pero, en un momento determinado, necesitamos moverlo de sitio. Lo desenchufamos de la alimentación y lo volvemos a enchufar en otro lugar, pero ya no funciona mas. O sufrimos un corte de suministro eléctrico y varios aparatos de la casa no vuelven a funcionar al recuperar la ennergía.
Otras veces vemos que la fuente proporciona pulsos cortos de alimentción y sospechamos de un cortocircuito que dispara la autoprotección. A veces se pueden ver esos pulsos cortos en algún LED indicador que flashea.

Lo primero que pensamos es que un transitorio durante la restitución de la alimentación los ha quemado.
ERROR: Lo que ocurre es que las fuentes ya estaban muertas, pero eran fantasmas de si mismas, que continuaban trabajando después de haber sufrido un fallo interno. Quizás el fallo se produjo hace dias, o meses, pero ellas seguian trabajando como si nada. Hasta que la falta de alimentación descubrió el fallo y ya no funcionaron mas.
Cuando vamos a reparar estas fuentes enontramos que los componentes que fallan mas habitualemente: fusible, rectificador, filtro, conmutador de potencia y en el secundario los diodos y condensadores de filtro estan todos bien. Es una avería chunga si no sabes de antemano donde buscar.

A mi me ha pasado en muchas ocasiones, pero la mas llamativa fue este verano. Durante un corte de energía programado, para para el mantenimiento anual de las estaciones transformadoras, murieron nada menos que 31 inyectores poe (SMCPWR–INJ4)!

Ahora vamos con la parte técnica del asunto.
Las fuentes de alimentación conmutadas suelen tener todas una topología similar en la cara del primario: filtro EMI (las mas modernas o potentes también compensación PFC), las grandes NTC, rectificador, filtro, elemento de control, conmutador de potencia y trafo. Después del trafo la parte del secundario con sus rectificadores, fltros, algunas reguladores y el circuito de realimentación.
Esto es a grandes rasgos una fuente conmutada. Mas o menos este diagrama de bloques:

Bloques

Los diseñadores de fuentes conmutadas step-down se encuentran siempre con el mismo problema: si vamos a reducir unas tensión alta (220V a 12V, por ejemplo), ¿como alimentamos el chip controlador PWM? Antes de que la fuente entre en funcionamiento solo hay 310V (220V rectificados y filtrados) en el primario. Con eso no podemos alimentar un chip controlador, que normalmente funcionan con tensiones de alrededor de 12V (algunos hasta 36V).
Basta con un simple cálculo par ver que un divisor resistivo es inapropiado. Por poco que consuma el controlador la disipación será muy alta. Un pequeño transformador convencional también presenta inconvenientes… La solución óptima, la que usan prácticamente todas las fuentes, es alimentar el chip controlador usando un secundario adicional en el trafo de potencia de la propia fuente, con un rectificador y filtro, y usar un circuito especial de arranque (start up). Este circuito es necesario para el momento en que conectamos la fuente y todavía no ha podido entrar en funcionamiento para autoalimentarse. Solo funcionará durante unos cientos de milisegundos al energizar la fuente, luego ya no será necesario porque el controlador PWM se alimentará a si mismo por el secundario citado anteriormente.
Y si ese circuito se avería la fuente continúa funcionando, hasta que se desalimenta, que ya no es capaz de arrancar.
Ya tenemos la explicación para nuestras fuentes fantasmas: el circuito de start-up.

Lo vemos en esta uente de ejemlo, tomada de aqui: http://www.circuitdiagramworld.com/power_supply_circuit_diagram/70_W_switching_power_supply_10316.html

En este esquema controlador PWM y el conmutador de potencia son un único chip: KA2S0880
El circuito de start-up de esta fuente esta formado por la resistencia R2 de 220K y el condensador electrolítico C6 de 47uF. Existe otro condensador cerámico C7 de 0.1uF para filtrar altas frecuencias. Con estos dos componentes se genera la tensión de alimentación para la patilla 3 del controlador PWM.
La resistencia serie en cualquier fuente será una resistencia de entre 56K a 1M y 1/2 a 5W de potencia. Muchas veces se usa una cadena de resistencias, cuando son SMD, para evitar arcos eléctricos (estarán sometidas a 300V de ddp). El condensador electrolítico será de entre 4,7uF hasta 100uF y una tensión relativamente alta: de 25V hasta 63V. En algunas fuentes hay un zéner de 12V a 18V en paralelo con el condensador electrolítico. En esta fuente el zéner esta integrado en la patilla 3 del controlador KA2S0880 y es de 36V.
El circuito de autoalimentación lo forma el diodo D2 FR207 y el bobinado de la patillas 1 y 4 del transformador.
Esto se puede ver repetido casi de forma exacta en todas las fuentes conmutadas…
El funcionamiento es sencillo: al energizar la fuente tenemos 320V a la salida del rectifcador, poco a poco cargan el condensador C6 a través de la resistencia R2. Cuando la tensión sobrepasa la tensión de arranque del controlador PWM este comienza a oscilar y proporciona potencia al transformador. La tensión en C6 cae unos voltios al producirse consumo, pero eso lo tiene previsto el fabricante del chip controlador que tiene una histéresis de varios voltios en la alimentación: arranca con 15V pero una vez que esta trabajando puede hacerlo incluso con tensiones tan bajas como 10V (Start threshold voltage y Minimum operating voltage en la hoja de datos del KA2S0880). Una vez que ha arrancado la bobina del secundario del trafo de potencia (terminales 1 y 4) proporciona una tensión de alrededor de 12V que se rectifica con C6 (para esta tarea esta sobredimensionado, son pulsos de alta frecuencia) y autoalimenta al KA2S0880.
En estas condiciones, si falla R2 (cierto, he visto resistencias abiertas por arco eléctrico) o el condensador C6 pierde capacidad por envejecimiento, la fuente continuará funcionando autolimentada por D2 y filtrada por la poca capacidad que le quede a C6.
Pero cuando la desconectemos necesitamos de nuevo que R2 proporcione la carga inicial a C6, y que C6 tenga capacidad suficiente para almacenar la energía necesaria para arrancar el controlador y mantenerlo en funcionamiento hasta que la tensión en el transformador pueda autoalimentalo por D2. Algunas veces la capacidad de C6 es baja y la histéresis del controlador de pocos voltios y podemos ver que la fuente intenta arrancar y se para. Se puede observar un diente de sierra en C6 subiendo hasta la tensión de arranque y bajando hasta a mínima de funcionamiento. La fuente proporcioa pulsos cortos de alimentación pero no trabaja en contínuo.

Generalmente el malo de esta película es el condensador electrolítico, C6 de 47uF en este esquema.

En este otro esquema con el popular UC3842 se puede ver también el circuto de startup, formado por un aresistencia de 150K, un condensador de 10uF, un zéner de 18V y un diodo rectifiacor 1N4148 (aqui con una resistencia de 150 Ohmios en serie):
Fuente con UC3842
En esta otra el sospechoso sería el condensador de 10uF.

Voy a ver si este es el problema de los inyectores poe. Abrir estas fuentes es fácil, si sabes como. Se aprientan cerca de la unión de las carcasas con un tornillo de banco y se apalanca con un destornillador para hacer saltar el pegamento:

Se localiza el componente sospechoso. Hay que buscar un condensador electrolítico pequeño en el primario, cerca de un diodo:

En este caso el diodo rectificador para la autoalimentación es uno negro a la derecha del condensador sospechoso. También hay un diodo zéner de cristal a la izquierda. Mejor revisar las pistas para asegurarse de esta fuente lleva este tipo de circuito de startup:

Efectivamente el condensdor esta muy bajo de capacidad, a cambiarlo en todas:

Y ya funcionan de nevo:

Como no tengo claro si voy a usarlas así o integrarlas en algún otro aparato no las voy a pegar definitivamente, que sería lo mejor para su uso normal como inyectores poe:

Todavía me quedan unas horas de trabajo por delante!

Lector, copiador y borrador de tarjetas RFID MIFARE

Estoy liado con varios proyectos que involucran lectores de tarjetas RFID tipo MIFARE de NXP https://www.nxp.com/products/identification-and-security/mifare-ics/mifare-classic:MC_41863 con lectores MFRC522 https://www.prometec.net/producto/rfid-kit-arduino y Arduino UNO

MFRC522

Uno de los probemas que he encontrado es que, cuando trabajas con montones de tarjetas y varios proyectos a la vez, es muy facil confundir tarjetas o incluso programar keys incorrectas. En esas condiciones las tarjetas pueden quedar inútiles (es imprescindible conocer las keys internas para usarlas o borrarlas).

Este programa para Arduino UNO (posiblemente funcione en otros) nos permite averiguar las keys programadas en las tarjetas para luego borrarlas o copiarlas sin preocuparnos de buscar las keys exactas que fueron programadas dentro.
Para ello es necesario compilar el programa con la lista de las keys comunmente usadas en nuestros proyectos. El programa intenta autentificarse en cada sector con cada una de las keys programadas y crea una lista de keys y secores. Esto nos permite luego borrar la tarjeta y dejarla en condiciones de fábrica o copiarla a otra vacía.
Es necesaria la librería de arduino MRFC522 que puede instalarse desde el gestor de librerías del arduino IDE o de aqui: https://github.com/miguelbalboa/rfid

El conexionado necesario es muy sencillo:

Fos ficheros del proyecto: HeliMifareClonner.zip

Para usar el programa se abre con el IDE de arduino y se carga en el arduino. Luego se abre el «monitor serie» y se configura a 115200 baudios y «sin ajuste de linea». Aparecerá un menú con 5 opciones, que es autoexplicativo:
1: PROBAR las Keys conocidas. Intenta averiguar que key, de la lista incluida en el programa, corresponde con cada sector de la tarjeta.
2: LEER Tarjeta: Lee la tarjeta usando la lista de keys averiguada anteriormente.
3: VER DATOS de tarjeta: Muestra el bloque de datos (1024 bytes) que ha podido leer con la opción 2
4: ESCRIBIR nueva tarjeta: Escribe una tarjeta vacía, que este con las keys de fábrica a FFFFFFFFFFFF, con los datos leidos anteriormente y luego instala las keys averiguadas en cada sector. Esto crea una tarjeta clon de la leíada anteriormente. El bloque 0, que contiene el UID y otros datos del fabricante, no se copia. Aunque algunas tarjetas de fabricantes alternativos (No NXP) permiten escribir en el bloque 0 usando una secuencia de comandos especial, este programa no lo hace (la línea de código necearia esta comentada en el programa) porque no he podido probar que funcione correctamente.
5: COMPROBAR Tarjeta con datos Compara los datos leidos previamente con los datos de otra tarjeta. Si las keys no son las mismas en las dos tarjetas los bloques trailer no podrán coincidir y habrá otros sectores que no podrán leerse y quedarán sin comparar «SIN DATOS».
6: BORRAR tarjeta: Borra una tarjeta usando las keys averiguadas para dejarla tal y como vienen de fábrica, con las keys a FFFFFFFFFFFF («transport keys»).