Firmware del contador Endesa / Enel con telegestión

En la entrada anterior está desglosado a grandes rasgos el contador. Existen varios dispositivos en el contador que almacenan información. El principal es la memoria flash del microcontrolador principal (ARM STM32F101RCT6). Éste dispone de 512Kb de memoria flash, es decir memoria de programa. Esta memoria almacena el código que ejecuta el microcontrolador, y en principio no es editable en tiempo de ejecución. Es programable a efectos prácticos, un número de veces ilimitado. El contador, como se puede ver en la imagen en la entrada anterior, dispone de un puerto de programación JTAG. Es por ello que el microcontrolador, se sirve de una memoria externa. En este caso una clásica EEPROM 24512, mediante interfaz I2C. En esta entrada, me centraré en la lectura de la memoria en cuestión. No obstante en el circuito, existe una memoria adicional descrita en la entrada anterior, usada para almacenar información relativa a la comunicación PLC, objeto que hoy no nos ocupa.

Lectura EEPROM contador

Detalle de la lectura EEPROM

El primer paso para leer la EEPROM es desoldarla. Pese a que se puede leer, directamente conectada al contador, para las pruebas posteriores es preferible extraerla, asi se puede manejar con comodidad, y disponer de la propia alimentación. Para desoldar la EEPROM he utilizado una estación de aire caliente por comodidad, aunque perfectamente podría haber utilizado el soldador de tipo lápiz.

Punta de la pistola

Punta de la pistola

Detalle de la temperatura

Detalle de la temperatura

Desoldar la memoria es un proceso rápido. Así queda la placa después de extraer la memoria.

Lugar donde va soldada la EEPROM

Lugar donde va soldada la EEPROM

Una vez extraída la memoria debe conectarse a un lector. El encapsulado es un SO8, así que haría falta algún tipo de adaptador. Sino, siempre se puede recurrir al adaptador del pobre, esto es, soldar directamente cables en los pines de la memoria. Dado que el encapsulado tiene un espaciado de pines considerable, es una tarea relativamente sencilla.

EEPROM con cables soldados

EEPROM con cables soldados

Pinout EEPROM 24512

Pinout EEPROM 24512

Básicamente todo el lado izquierdo (pines 1 a 4) va conectado a GND. Vcc a +3.3V y SCL y SDA al lector. Por seguridad, he conectado WC (Write control) a +3.3V para evitar la escritura accidental.

Por curiosidad, si intentamos encender el contador sin la memoria EEPROM, en la pantalla muestra un mensaje de un BOOTLOADER y acto seguido muestra un error. Según la publicidad que Endesa está haciendo del contador, el firmware del mismo será actualizable vía PLC. No obstante, no es posible actualizar en tiempo de ejecución la memoria flash del contador. Por consiguiente, toda información relacionada con el firmware, y múltiples parámetros sujetos al cambio, incluso la propia calibración del aparato estarán almacenados en la memoria EEPROM. Quizá por ese motivo hayan escogido una memoria de capacidad considerable (512 Kbit).

Ya que no dispongo de ningún lector de EEPROM, he desempolvado el Arduino. Aunque arduino trabaja a 5V, según el datasheet de la memoria, soporta hasta 5.5V, con lo que no habrá problema. Tras conectarlo todo al ordenador, y escribir un sencillo programa, comienza a leer la memoria.

#include <Wire.h>

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(rdata);
    Wire.endTransmission();
  }

  void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddresspage >> 8)); // MSB
    Wire.write((int)(eeaddresspage & 0xFF)); // LSB
    byte c;
    for ( c = 0; c < length; c++)
      Wire.write(data[c]);
    Wire.endTransmission();
  }

  byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
  }

  void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
      if (Wire.available()) buffer[c] = Wire.read();
  }

  void PrintHex8(uint8_t *data, uint8_t length) //imprime los HEX con los ceros
{
        //Serial.print("0x");
        for (int i=0; i<length; i++) {
          if (data[i]<0x10) {Serial.print("0");}
          Serial.print(data[i],HEX);
          Serial.print(" ");
        }
}

void PrintHex16(uint16_t *data, uint8_t length) //imprime los HEX con los ceros
{
        Serial.print("0x");
        for (int i=0; i<length; i++)
        {
          uint8_t MSB=byte(data[i]>>8);
          uint8_t LSB=byte(data[i]);

          if (MSB<0x10) {Serial.print("0");} Serial.print(MSB,HEX); Serial.print(" ");
          if (LSB<0x10) {Serial.print("0");} Serial.print(LSB,HEX); Serial.print(" ");
        }
}

  void setup()
  {
    //char somedata[] = "mi mama me mima";
    Wire.begin(); // initialise the connection
    Serial.begin(115200);
    //i2c_eeprom_write_page(0x50, 0, (byte *)somedata, sizeof(somedata));

  }

  void loop()
  {
    uint8_t data;
    unsigned int count = 16;
    for(unsigned int y=0; y<65600; y++) {
      if(count == 16) {
        Serial.println("");
        Serial.print(y,HEX);
        Serial.print(":\t");
        count=0;
      }
       delay(5);
      data = i2c_eeprom_read_byte(0x50, y); /
      delay(5);
      Serial.print(" ");
      PrintHex8(&data,1);
      count++;

    }
  }
Montaje con el orden que me caracteriza

Montaje con el orden que me caracteriza

Finalmente obtenemos el código que contiene la memoria. En un principio, lo he copiado en hexadecimal, en un archivo de texto. A la izquierda, las direcciones de memoria. Cada pareja de caracteres representa un byte. Dada la extensión del texto, podéis consultar el archivo entero en este enlace.

0: 08 00 C7 FF 00 00 92 0E 03 0F 06 18 7D 1F 7A 15
10: C0 A2 04 16 06 86 31 31 4E 44 45 45 41 41 55 38
20: 30 38 33 30 B7 19 01 08 C4 02 01 08 00 00 00 01
30: 00 00 00 00 00 03 17 02 E9 5F 42 7F 3B B6 B2 87
40: F3 96 00 00 00 00 7A 53 79 38 8B 3F 22 2F E3 F6
50: 8A DF 00 00 00 00 06 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 50 03 E8 05 DC 00 FA FF
70: 37 00 00 00 00 00 00 00 00 00 00 00 87 07 E2 8A
80: 03 05 03 05 01 03 00 00 00 00 00 00 37 30 33 31
90: 30 4C 37 30 00 00 00 00 32 30 AB 15 4D 23 40 40
A0: A1 5A 72 5C B3 48 58 9A 23 68 00 00 00 00 00 00
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
F0: 00 00 00 00 00 00 00 00 00 00 00 00 DB AC 85 83
100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...

Como curiosidad, a la vista queda que la memoria está eminentemente vacía. En las próximas entradas, comenzaré con la interpretación del código  y con pruebas adicionales. Cabe decir que esta lectura corresponde al contador que no está programado, es decir, aun no se ha introducido información relativa al suministro o a la tarificación. Además en una de las pruebas desconecté la pila, perdiendo la información relativa a la hora, entre otras cosas.

EDIT: Por motivos legales he tenido que eliminar el contenido de la EEPROM.

EDIT: Actualización

14 comentarios en “Firmware del contador Endesa / Enel con telegestión

  1. Excelente.
    Buen trabajo todo lo relacionado con el contador.
    ¿Tiene circuitería la placa, para desde el ST7581 (PLC chip) escribir en la memoria EEPROM?

  2. Muy interesante.
    entiendo que los pulsos del leds llegan directos del ADE7753,
    tambien entiendo que por hay se podria hacer la lectura de consumos (contando pulsos).
    aunque lo veo lioso, ademas que pasaria si se aprueva el balance neto.
    no podriamos saber si estamos consumiendo o cediendo potencia a la red.
    por lo que entiendo que se usa tambien la comunicacion serie.
    pero si es intresante el aceso a la “calibracion”.
    si esto es asi seria tan facil (descontando lo de habrir cajas y eso) como desoldar el chip, reprogamar la nueva calibracion,borrar la apertura del la caja en la e2prom y cerrarlo todo muy bien (sin que vuelva a remarcar la apertura) y ya esta.

  3. Ya veo que sabeís del tema me interesaría saber si este contador tiene detección de intensidades de fuga además de como queda claro tiene función de ICP.

    Excelente trabajo por cierto.

  4. Hola,
    me ha sorprendido el detalle con el que analizas el contador.
    No sé si te resultará sencillo-posible, pero me gustaría saber cuanta energía consume el contador, si la paga el cliente, y qué parte se debe al maldito LED que se podían haber ahorrado. Gracias.

  5. el señor que instala los contadores lleva un aparato que pone sobre los led para verificar que funcionan correctamente y en todos contadores cuentan el 10% a favor de la compañia

  6. Se agradece el analisis. Apunto la URL para leer tus proximas entregas. Mucha gente estabamos esperando algo Así . Por cierto, el fichero binario parece que no está disponible. Un saludo

  7. Pingback: ¿Cuantos contadores instalados podrán tarifar en abril por horas? | TIECs

  8. Es del todo interesante, todo lo que en este hilo estáis comentando, pero tengo una duda, si por fin se consigue la comunicación con el contador, para poder cambiar los valores de calibración que han de estar grabados en la eeprom de bicho, que impedira despues que atraves de gestion remota o el operario encargado de hacer la lectura en los lugares en los que la telegestion aun no funciona, lean el estado de nuestro contador y detecten que no corresponde con los valores originales y en consecuencia o nos denucien o aun peor que los repongan a valores originales y ni nos avisen , con el consiguiente recivazo, en fin es una reflexion, a mi enternder la unica posibilidad de realizar lo que queremos seria la reprogramacion del microcontrolador del contador, de forma que ante la telegestion o el puerto infrarojo, siempre contestase los valores que la compañia suministradora grabe, pero en realidad en el nuevo programa no se usen para en calculo del consumo.
    Mientras tanto creo que hasta que consigamos eso, solo nos queda la manipulacion de hardware, que a mi parecer es bastante sencillo aunque con el problema que crea tener que desmontar el aparato y luego volver a dejarlo en su estado original, pero si nos olvidamos de esto y nos vamos a como hacerlo, una simples resistencias colocadas en los cablecitos que conectan el shunt con la placa son suficientes para variar la cantidad de energia que pasa al conversor analogico digital ADE7753, y por lo tanto haciendo que este de los valores que nos interesen

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s