Con una resistencia solo en el cable negro también funciona. Eso no es el problema. Verifica lo demás.
Suerte!
Moderador: 241-2001
/* 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() {
}
Volver a Digital, Electricidad e Informática