Índice general Foros Digital, Electricidad e Informática Monitor DCC (sniffer)

Monitor DCC (sniffer)

Moderador: 241-2001


Nota 10 Feb 2018 08:49

Desconectado
Mensajes: 751
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
Es cuestión de tiempo que más aficionados comiencen a 'desentrañar' por sí mismos los secretos del DCC y se fabriquen sus propios descodificadores de accesorios, o adapten otros cuyo código de programación alteren según su conveniencia. Hay ya ejemplos en este y otros foros de intentos de este tipo.

Perdido por este foro está el código para leer toda la información que las centrales ponen en las vías en formato DCC. Se trata de 'escuchar' simplemente los comandos, todos ellos, para ir aprendiendo cómo son y cuándo aparecen, y poder después hacer algo con ellos.

El código estaba aquí, pero lo reproduzco a continuación en este hilo, para ayudar a encontrarlo y centrar la conversación sobre él.

/*  Monitor_DCC espía para Arduino
    Lee los comandos en la vía y los presenta en HEX por el puerto serie
    Desarrollado por Germán y Nórber
*/

#define TICKS    180
#define SI        0
#define NO        1
volatile byte buf_dcc[6];                    // Buffer del último comando recibido
volatile byte idx;                           // Índice y contador de bytes en comando
volatile boolean mensajeRecibido = false;
unsigned int cont = 1;
String rad = "0x", valor;

void setup() {
  pinMode(2, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), dcc_int, CHANGE);
  cli();
  TCCR0A = 0;
  TCCR0B = 0;
  TCCR0B |= (1 << CS01); // Uno en bit CS01 para prescaler 8 (0.5 µs) en Timer0 - DCC
  sei();
  Serial.begin(57600);
  while (!Serial);
  Serial.println();
  Serial.println("Iniciado");
  Serial.println();
}

void loop() {   // Si se recibe un mensaje correcto, se imprime en
  if (mensajeRecibido == true) {  // el puerto serie a 57600 baudios (velocidad suficiente)
    Serial.print(cont);
    for (byte i = 0; i <= idx; i++) {
      valor = String(buf_dcc[i], HEX);
      if (valor.length() == 1) valor = rad+"0"+valor; // Para que todo HEX tenga dos cifras
      else valor = rad + valor;
      Serial.print("\t");
      Serial.print(valor);
    }
    Serial.print("\n");
    cont++;
    mensajeRecibido = false;
  }
}

void dcc_int() {
  static int tmp_pulso;
  static byte bit_dcc, preamb, aux_dcc, x_or, num_bits;
  if (PIND & (0x04)) TCNT0 = 0;   // pin2 acaba de pasar a HIGH: se reinicia el Timer0
  else  {    // pin2 acaba de pasar a LOW:
    tmp_pulso = TCNT0;     // lee los ticks del Timer0 transcurridos
    if (tmp_pulso > TICKS) bit_dcc = 0;    // duración mayor de XX µs => cero
    else bit_dcc = 1;     // duración menor => uno
    if (preamb == SI) {    // Preámbulo
      if (bit_dcc) {    // otro '1'
        if (num_bits) num_bits--;
      }
      else {
        if (!num_bits) {   // el '0' de inicio de datos
          preamb = NO;
          num_bits = 9;
          x_or = 0;
          idx = 0;
        }
        else num_bits = 10;   // no se cumple la trama, vuelta a inicio
      }
    }
    else {   // Superado el preámbulo toca recibir el mensaje:
      if (--num_bits) aux_dcc = aux_dcc * 2 + bit_dcc;  // formamos un byte sobre 'aux_dcc'
      else {   // el separador de bytes
        if (!bit_dcc) {   // cero, a por el siguiente byte
          buf_dcc[idx++] = aux_dcc;   // pero antes guardamos el byte recibido en 'buf_dcc[ ]'
          x_or ^= aux_dcc;  // actualiza la x_or
          num_bits = 9;
        }
        else {   // uno, fin del paquete
          preamb = SI;
          num_bits = 10;   // Podemos volver a empezar
          if (x_or == aux_dcc) {  // y si lo recibido vale
            buf_dcc[idx] = aux_dcc;   // guardamos la 'x_or' para completar el paquete y
            mensajeRecibido = true;   // ¡mensaje correcto!
          }
        }
      }
    }
  }
}


Se programa sobre Arduino Uno, y la señal DCC optoacoplada debe introducirse entre el pin2 y GND. Cualquier montaje de deco de accesorios ASALAF está diseñado ya así. Sólo habría que volcarle este programa y abrir la pantalla de escribir/recibir por el puerto serie del Arduino IDE. Empezarán a aparecer todos los comandos DCC presentes en las vías y podréis conseguir muchas cosas:

    - Comprobar que el decodificador efectivamente funciona (aparece la lista interminable de comandos continuamente).
    - Comprobar que funciona con regularidad (no se para la sucesión continua de comandos en pantalla).
    - Apreciar la variación de comandos cuando se produce (al hacer algo con la central).
    - Relacionar el comando con la acción (verificar qué comando corresponde a la acción sobre cada accesorio, por ejemplo).
    - Entender el funcionamiento de la central y razonar cómo hacer que un deco determinado ignore todos los comandos menos aquellos que nos interesen.

Y muchas más cosas que se os ocurrirán.
Saludos

[Multimaus + GenLi-S88 + +z21f. + RocRail (MacOsX)]
H0 Renfe, sin catenaria

Nota 10 Feb 2018 14:03

Desconectado
Mensajes: 434
Ubicación: Madrid
Registrado: 05 Ene 2017 11:09
Muchas gracias, Norber.
Me será de gran utilidad para mis experimentos de novato.

Nota 03 Mar 2018 21:03

Desconectado
Mensajes: 46
Registrado: 14 Dic 2015 17:19
Buenas
Aparte de utilizar el monitor del ordenador ,se podría utilizar una pantalla LCD tipo Nokia 5110 para visualizar la trama?
Un saludo


Volver a Digital, Electricidad e Informática

Síguenos en Facebook Síguenos en Youtube Síguenos en Instagram Feed - Nuevos Temas
©2017   -   Información Legal