Índice general Foros Digital, Electricidad e Informática Descodificador DCC para 8 señales con Arduino

Descodificador DCC para 8 señales con Arduino

Moderador: 241-2001



Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
Con una resistencia solo en el cable negro también funciona. Eso no es el problema. Verifica lo demás.
Suerte!
Saludos

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

ERG Avatar de Usuario

Desconectado
Mensajes: 1545
Ubicación: Blanes (Girona)
Registrado: 03 Dic 2009 21:03
Esta placa creo que no vale para señales Mafen, por que al menos en H0, el comun es el positivo.


Desconectado
Mensajes: 43
Registrado: 11 Feb 2014 09:47
Vaya, justamente iba a escribir sobre esto, pille unos semaforos en zaratren y resulta efectivamente que el positivo es el cable negro, vaya chasco me he llevado, encima tengo la placa hecha y montada.
Hay dos alternativas, o desarmar los leds y cambiarles la polaridad, o rediseñar/modificar la placa y modificar el software.
Vaya faena me ha hecho esto.
Lo que no entiendo es si los decoders normales, como dijikeijs y demás contemplan esto, porque que yo sepa el negativo de estos decoders es el cable negro, no se si se podrá invertir esto.

Espero que el código de Norber sea fácil de adaptar.

Un saludo.


Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
Habría que retocar algo la placa, creo que un cambio mínimo. Y el código sería sustancialmente el mismo, salvo alguna pijadita. Tiene fácil solución me parece. Estudio el asunto y os cuento.
Ando liado con el siguiente proyecto. Probando el primer prototipo.

¿Alguien sabe si hay algún estándar en esto de los accesorios?
LEDs con cátodo (-) común o deben ser con ánodo (+) común?
Gracias
Saludos

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


Desconectado
Mensajes: 43
Registrado: 11 Feb 2014 09:47
Pues no lo se si hay algún standard, no se si ERG sabra algo mas sobre lo que comentó.
Esta mañana llamé al de zaratren para saber si el tema de los semáfores es así o es un fallo de diseño. No lo tenía claro, pero si los 4 que compre se comportan igual, eso quiere decir que son con cátodo común. Por cierto, el fabricante es chino, pero también son bastante baratos, menos de 5€.

Pues toca cambiar placa y sketch imagino, ahora que ya la tenía hecha, toca cortar pistas y hacer puentes de cables, arrgg.


Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
Probablemente con dos cortes (en rojo) y dos puentes (en azul) quede solucionado. El programa habría que variarlo algo también. A ver si puedo hacer algunas pruebas antes de confirmar la solución. De momento voy a intentar con esto:
ASALAF_8sig_CommAnode.png
Saludos

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


Desconectado
Mensajes: 43
Registrado: 11 Feb 2014 09:47
Norber escribió:
Probablemente con dos cortes (en rojo) y dos puentes (en azul) quede solucionado. El programa habría que variarlo algo también. A ver si puedo hacer algunas pruebas antes de confirmar la solución. De momento voy a intentar con esto:
ASALAF_8sig_CommAnode.png


ya he hecho los cambios en la placa y con el mismo código funciona, pero creo que el diming no lo realiza tan bien como antes, no se si habrá que ajustar algo en el código. He probado a cambiar los LOW por los HIGH, pero no he conesguido el efecto esperado. Quizás lo del diming sea por la resistencia, que es de 1k y la vez pasada probe con 330ohm.
El problema no es la resistencia, es el código creo, lo que hace ahora es que la luz que tiene que desaparecer rápido, tarda mas en apagarse, y hay un momento en que están las dos luces bastante luminosas.


Desconectado
Mensajes: 167
Registrado: 28 Oct 2015 09:35
Hola un saludo.
Tengo semáforos de Mafen y vienen así montados, el efecto que hace ahora es que hay un momento que los dos leds están encendido.
Yo he modificado el código en este punto, solamente (no he modificado la placa):
if (i & 0x01) digitalWrite(i, HIGH); // Green leds at odd pins start off
else digitalWrite(i, LOW);
y cuando arranco el sistema aparece el diodo rojo encendido, tengo la salida 4-rojo, 5-verde.
El montaje sería como dice el folleto de Mafen el negro a +5v, y rojo - verde a las salidas de nuestro arduino.
Espero que halla ayudado.
Un saludo, Pablo


Desconectado
Mensajes: 167
Registrado: 28 Oct 2015 09:35
Disculpar pero no me he dado cuenta de la placa, ya q estoy trabajando sobre una de prototipo y ataco a los 5v directamente.
Hay q modificarla como nos cuenta el compañero.
Un saludo


Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
haute escribió:
El problema no es la resistencia, es el código creo, lo que hace ahora es que la luz que tiene que desaparecer rápido, tarda mas en apagarse, y hay un momento en que están las dos luces bastante luminosas.

En efecto. Hay que hacer la atenuación en el código también al revés: ver cuál está encendido, darle pulsos largos al principio y más cortos, hasta que sean muy pequeños, para que vaya cediendo luminosidad y se apague. Y luego para encender el led compañero pues lo recíproco. Ahora funciona exactamente al revés, que es lo adecuado para las señales de cátodo común.

Insisto en que me interesa muchísimo saber si la mayoría de las señales a escala vienen con el ánodo común o la cuestión es aleatoria, a gusto del fabricante. ¿Hay algún estándar sobre esto? Gracias.
Saludos

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


Desconectado
Mensajes: 43
Registrado: 11 Feb 2014 09:47
Norber escribió:
haute escribió:
El problema no es la resistencia, es el código creo, lo que hace ahora es que la luz que tiene que desaparecer rápido, tarda mas en apagarse, y hay un momento en que están las dos luces bastante luminosas.

En efecto. Hay que hacer la atenuación en el código también al revés: ver cuál está encendido, darle pulsos largos al principio y más cortos, hasta que sean muy pequeños, para que vaya cediendo luminosidad y se apague. Y luego para encender el led compañero pues lo recíproco. Ahora funciona exactamente al revés, que es lo adecuado para las señales de cátodo común.

Insisto en que me interesa muchísimo saber si la mayoría de las señales a escala vienen con el ánodo común o la cuestión es aleatoria, a gusto del fabricante. ¿Hay algún estándar sobre esto? Gracias.


Se me ocurre hacer un mismo circuito con un jumper , donde elijas el tipo de semáforo a usar, si de ánodo o cátodo común. Luego dos códigos para el arduino en función del que se use.
Incluso si el arduino tiene una entrada libre, se puede acoplar el jumper a eta entrada y crear un código universal que valga para las dos formas, detectando con esa entrada lo que se está escogiendo.


Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
A los que estáis probando el circuito ASALAF: probad a cambiar todos los HIGH por LOW, y todos los LOW por HIGH en el código, a ver si con eso es suficiente para configurar el descodificador para aceptar señales de ánodo común. Avisad por aquí. Yo no puedo probar con lo que tengo. Muchas gracias.
Saludos

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


Desconectado
Mensajes: 43
Registrado: 11 Feb 2014 09:47
Norber escribió:
A los que estáis probando el circuito ASALAF: probad a cambiar todos los HIGH por LOW, y todos los LOW por HIGH en el código, a ver si con eso es suficiente para configurar el descodificador para aceptar señales de ánodo común. Avisad por aquí. Yo no puedo probar con lo que tengo. Muchas gracias.


Ya lo he probado y nada, hace un efecto muy distinto al que tenia que hacer, se enciende la otra y se apaga, se vuelve a encender la misma y la otra que estaba encendida hace un diming rápido de apagarse y se vuelve a encender.
Sin variar nada es como mejor funciona, pero hay unos instantes que están las dos encendidas y se nota mucho, quizás es una cuestión de ajustar tiempos.
Probé a invertir el tiempo de 20 a 40, mejoro algo pero no del todo.

Solucionado, hay que cambiar también los números del pin dimmable. Y los primeros LOW HIGH dejarlos como están.
Probarlo, porque yo uso una versión un poco modificada, porque estoy usando aruino Mini Pro y las salidas son diferentes.

/* 2 x 8 dimming LEDs with Arduino Nano DCC decoder for common anode
   By German Trinidad and Norber, Spain, December 2015
   Freely distributable for private, non commercial, use

   Attach led anodes (+) to #1 to #8 outputs
   Attach all led catodes (-) to GNDs
   Don't forget to add serial resistors! */

#define ADR_MMAUS_01  129  // Assign here your addresses
#define ADR_MMAUS_02  130
#define ADR_MMAUS_03  131
#define ADR_MMAUS_04  132
#define ADR_MMAUS_05  133
#define ADR_MMAUS_06  134
#define ADR_MMAUS_07  135
#define ADR_MMAUS_08  136
#define ADR_MMAUS_09  137

byte comb[][4] = {
  //Address                      , Port                    , Pin-√ , Pin--
  {((ADR_MMAUS_01 - 1) / 4) + 128, ((ADR_MMAUS_01 - 1) % 4), 4     , 5   },
  {((ADR_MMAUS_02 - 1) / 4) + 128, ((ADR_MMAUS_02 - 1) % 4), 6     , 7   },
  {((ADR_MMAUS_03 - 1) / 4) + 128, ((ADR_MMAUS_03 - 1) % 4), 8     , 9   },
  {((ADR_MMAUS_04 - 1) / 4) + 128, ((ADR_MMAUS_04 - 1) % 4), 10    , 11  },
  {((ADR_MMAUS_05 - 1) / 4) + 128, ((ADR_MMAUS_05 - 1) % 4), 12    , 13  },
  {((ADR_MMAUS_06 - 1) / 4) + 128, ((ADR_MMAUS_06 - 1) % 4), 14    , 15  },
  {((ADR_MMAUS_07 - 1) / 4) + 128, ((ADR_MMAUS_07 - 1) % 4), 16    , 17  },
  {((ADR_MMAUS_08 - 1) / 4) + 128, ((ADR_MMAUS_08 - 1) % 4), 18    , 19  },
  {((ADR_MMAUS_09 - 1) / 4) + 128, ((ADR_MMAUS_09 - 1) % 4), 20    , 21  },
};

#define DCC_INT   2
#define SI        0
#define NO        1
#define TICKS    215           // Prescaler 8 -> Timer pulse every 0.5 µs -> 200 ticks are 100 µs
#define FREQ     120           // 15 ms aprox
#define DELTA     3            // PWM
#define TO_OFF   20
#define PAUSE    30
#define TO_ON    40

volatile byte buf_dcc[6];
volatile byte pinPWM_1, pinPWM_2;
volatile boolean varyingLed = false;
volatile int duty = FREQ - 1;
volatile byte state = TO_OFF;

void setup() {
  for (int i = 4; i < 20; i++) {
    pinMode(i, OUTPUT);
    if (i & 0x01) digitalWrite(i, LOW);      // Green leds at odd pins start off
    else digitalWrite(i, HIGH);              // Red leds at even pins start on
  }
  pinMode(DCC_INT, INPUT);
  Serial.begin(9600);
  Serial.print("Iniciando...");
  delay(500);
  attachInterrupt(0, dcc_int, CHANGE);       // pin2 = DCC      externalInterrupt 0
  cli();
  TCCR0A = 0;
  TCCR0B = 0;
  TCCR0B |= (1 << CS01);                     // Set CS01 bit for 8 prescaler (0.5 µs) on Timer0 - DCC
  TCCR2A = 0;
  TCCR2B = 0;
  TCCR2B |= (1 << CS21);                     // Set CS21 bit for 8 prescaler (0.5 µs) on Timer2 - Dimming
  TIMSK2 = 0;
  TIMSK2 |= (1 << TOIE2);                    // Enable Timer2 Overflow interrupt
  sei();
}

void dcc_int() {                               // ISR(INT0_vect) External interrupt routine for signal on pin2
  static int tmp_pulse;                        // German is a genius!
  static byte bit_dcc;
  static byte preamb;
  static byte aux_dcc, x_or, idx, num_bits;

  if (PIND & (0x04)) TCNT0 = 0;
  else  {
    tmp_pulse = TCNT0;
    if (tmp_pulse > TICKS) bit_dcc = 0;
    else bit_dcc = 1;
    if (preamb == SI) {
      if (bit_dcc) {
        if (num_bits) num_bits--;
      }
      else {
        if (!num_bits) {
          preamb = NO;
          num_bits = 9;
          x_or = 0;
          idx = 0;
        }
        else num_bits = 10;
      }
    }
    else {
      if (--num_bits) aux_dcc = aux_dcc * 2 + bit_dcc;
      else {
        if (!bit_dcc) {
          buf_dcc [idx++] = aux_dcc;
          x_or ^= aux_dcc;
          num_bits = 9;
        }
        else {
          preamb = SI;
          num_bits = 10;
          if (x_or == aux_dcc) {                        // Data received OK!
           Serial.print(buf_dcc[0]);
            // buf_dcc[0] is Address
            // buf_dcc[1] is Port and command
            if (!varyingLed) {                          // While commuting, ignore commands
              byte port = (buf_dcc[1] & 0x06) >> 1;     // 0x06 = B0000 0110
              for (int i = 0; i < 9; i++) {
                if ((buf_dcc[0] == comb[i][0]) && (port == comb[i][1])) { // It's ours
                  if (buf_dcc[1] & 0x01) {
                    pinPWM_1 = comb[i][2];              // Pin to dim off
                    pinPWM_2 = comb[i][3];              // Pin to dim on
                  }
                  else {
                    pinPWM_1 = comb[i][3];
                    pinPWM_2 = comb[i][2];
                  }
                  if (digitalRead(pinPWM_1)) {          // Needs to be dimmed off indeed
                    varyingLed = true;
                    duty = 255;
                    state = TO_OFF;
                  }
                  return;
                }
              }
            }
          }
        }
      }
    }
  }
}

ISR(TIMER2_OVF_vect) {                         // Timer2 Overflow interrupt every 128 µs for dimmming leds
  if (varyingLed == true) {
    static int cont;
    cont++;
    switch (state) {
      case TO_OFF:
        if (cont == FREQ) {                    // High pulse starts when 'cont' reaches FREQ
          digitalWrite(pinPWM_2, LOW);
          cont = 0;
          duty = duty - DELTA;
        }
        if (cont == duty) {
          digitalWrite(pinPWM_2, HIGH);         // And ends when 'cont' reaches 'duty'
          if (duty < DELTA) state = PAUSE;
        }
        break;
      case PAUSE:
        if (cont == 5 * FREQ) {                 // Small dramatic pausae
          state = TO_ON;
          duty = DELTA;
          cont = 0;
        }
        break;
      case TO_ON:
        if (cont == FREQ) {
          digitalWrite(pinPWM_1, LOW);
          cont = 0;
          duty = duty + DELTA;
          if (duty > 255 - DELTA) varyingLed = false;  // We're done
        }
        if (cont == duty) {
          digitalWrite(pinPWM_1, HIGH);
        }
        break;
    }
  }
}

void loop() {
}

ERG Avatar de Usuario

Desconectado
Mensajes: 1545
Ubicación: Blanes (Girona)
Registrado: 03 Dic 2009 21:03
Mis conocimientos son muy basicos, y aun que hago mis pinitos, hay cosas que se me escapan.

Si la salida pwm entiendo que es un positivo, y el led en el otro lado tiene positivo, ¿por que narices se enciende? ¿por que el pwm cuando no damos positivo se convierte en negativo? Entonces lo que hacemos para apagar el led es, ¿dar el maximo pwm para que los dos positivos se igualen y no se encienda? O lo que deduzco no tiene sentido.

Gracias.


Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
haute escribió:
Solucionado, hay que cambiar también los números del pin dimmable. Y los primeros LOW HIGH dejarlos como están.
Probarlo, porque yo uso una versión un poco modificada, porque estoy usando aruino Mini Pro y las salidas son diferentes.


Solucionado pues. Con tu código entiendo que ya funcionaría la versión "ánodo común". Muchas gracias.

Y a modo de explicación, para que se entienda mi preferencia por programar en el modo opuesto "cátodo común", ocurre que en dicho modo las salidas del Arduino proporcionan la corriente necesaria para encender los leds, de manera que un "1" lógico en dichas salidas causa el encendido del led asociado. Así me lo represento más cómodamente en mi cabeza cuando voy escribiendo el programa.

El modo "ánodo común" es el dual, y en él las salidas del Arduino absorben la corriente necesaria para luzcan los leds. Para absorber corriente hay que poner cada salida a "0" lógico, lo que significa que los leds se encienden cuando se programa su pin a "0", y esto es algo contra-intuitivo que me cansa tener en cuenta continuamente. Y programar cansa la cabeza :lol: . Por eso tiendo a pensar en leds (y cualquier accesorio similar) en el modo "cátodo común".

El hecho de usar el Arduino Mini Pro o el Arduino Nano no afecta, en principio, más que a la forma de la placa, pues el Mini es más pequeño que el Nano. O al menos yo no he encontrado nunca diferencia alguna. Aparte, claro está, de que el Mini carece del conector USB para programarlo (requiere adaptador USB externo).
small-arduino-boards.jpg
small-arduino-boards.jpg (8.19 KiB) Visto 4924 veces


Gracias de nuevo por las pruebas haute.
Saludos

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


Desconectado
Mensajes: 43
Registrado: 11 Feb 2014 09:47
Norber escribió:

El hecho de usar el Arduino Mini Pro o el Arduino Nano no afecta, en principio, más que a la forma de la placa, pues el Mini es más pequeño que el Nano. O al menos yo no he encontrado nunca diferencia alguna. Aparte, claro está, de que el Mini carece del conector USB para programarlo (requiere adaptador USB externo).
small-arduino-boards.jpg



Cuando uso el arduino mini pro, este suele tener el pin 13 conectado a un led en placa, normalmente procuro evitar este pin y lo suelo usar a modo de indicador. Por ejemplo, en este montaje, como sobraba una salida, he dejado este pin 13 libre. Realmente son lo mismo, es el mismo micro y velocidad. En los chinos normalmente lo encuentras a mitad de precio, el mini que el nano, como contra es el puerto usb que no tiene conector.


Desconectado
Mensajes: 167
Registrado: 28 Oct 2015 09:35
Muchas gracias haute, se me complicaba como el agua.
Respecto al tema de cátodo o ánodo común, no creo que exista ninguna normativa, ademas hay un convertidor para estos casos,
es decir que debe ser algo general, Norber.
Saludos


Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
Respecto al tema de cátodo o ánodo común, no creo que exista ninguna normativa, ademas hay un convertidor para estos casos,
es decir que debe ser algo general, Norber.


A una conclusión parecida he llegado yo, porque no parece haber nada normalizado. Cuando pueda saco una placa adaptada al ánodo común y subo las dos, junto a los dos programas.

Y doy por cumplido el objetivo de sacar algo fácil y útil con Arduino, para ver si 'engancha' a cada vez más gente, y vamos poco a poco introduciendo la programación en esta afición. Yo seguiré con más proyectos, a ver si gustan ;) .
Saludos

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


Desconectado
Mensajes: 43
Registrado: 11 Feb 2014 09:47
He creado una nueva placa con selector de anodo/catodo común, con un simple jumper.
Es para el arduino Pro mini y he usado un 4n35 en vez del 6n137, porque estos últimos no tenia a mano.
Es una pcb que mide aproximadamente 40x60mm de una sola cara, las pistas marcadas en rojo son puentes.
Adjunto los sketch de los dos modelos para programar el arduino y un pdf con la pcb a escala real.
https://mega.nz/#!NZYj1CzY!3zhmkHRZeiwq-KChpAElIVhWgsqQ8Qn8eCA2fy0FVDc
Si puedo creo uno para la placa Arduno nano, si es que no la está creando ya Norber.

Imagen Imagen

Imagen


Desconectado
Mensajes: 666
Ubicación: Salamanca
Registrado: 12 Ene 2012 14:44
Hala! Qué bonito!!!
Muy bien haute, muy bien hecho, sí señor. Con su selector y todo.
Profesional.

Doy por resuelto el asunto gracias a tu colaboración, a falta únicamente de un bonito vídeo explicándolo todo y, a ser posible, con señales funcionando en una maqueta….
De momento el descodificador está resuelto: circuito y código.
Genial!
Saludos

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

AnteriorSiguiente

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