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.
Código: Seleccionar todo
/* 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.