Tienes razón, quise acortar el mensaje y creo que lo que acorté fué la información, de modo que más abajo pego el sketch completo tal y como lo tengo, pero te comento ...
He designado la entrada 3 como conexión al pulsador con resistencia de 10K a OV y el pulsador cierra el circuito a +5V.
La función reset la he añadido para que una vez que se ha grabado la dirección, se resetee y lea esa dirección para trabajar.
El tiempo lo bajaré a 3 segundos, mientras busco otra solución.
Mientras realizo las pruebas, para tener visión de la temporización, uso la entrada 13 para el led, pero cuando pase a ser utilizable, la 13 será una salida hacia un semáforo y será la entrada la 20 la que usaré para conectarle un led.
/* 2 x 8 dimming LEDs with Arduino Nano DCC decoder
By German Trinidad and Norber, Spain, December 2015
Añadidos de Pedro Campos, enero 2018
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! */
//============ mio ====================================
#include <DCC_Decoder.h>
#define kDCC_INTERRUPT 0
#include <EEPROM.h>
#define EEPROM_ADDRESS 2 // we store our dcc address
#define aviso_tiempo 20
int direccion = EEPROM.read(EEPROM_ADDRESS) + (EEPROM.read(EEPROM_ADDRESS + 1) * 256);
int address = (direccion);
#define ADR_MMAUS_01 (address) // Assign here your addresses
#define ADR_MMAUS_02 (ADR_MMAUS_01+1)
#define ADR_MMAUS_03 (ADR_MMAUS_01+2)
#define ADR_MMAUS_04 (ADR_MMAUS_01+3)
#define ADR_MMAUS_05 (ADR_MMAUS_01+4)
#define ADR_MMAUS_06 (ADR_MMAUS_01+5)
#define ADR_MMAUS_07 (ADR_MMAUS_01+6)
#define ADR_MMAUS_08 (ADR_MMAUS_01+7)
int 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 , 20 }, //Cambiar a 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 },
};
#define PULSADOR 3
#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);
pinMode(PULSADOR, INPUT_PULLUP);
pinMode(13, OUTPUT); //provisional
Serial.begin(9600);
Serial.print("Iniciando...");
Serial.println();
Serial.print("Direccion inicial: ");
Serial.print(direccion);
Serial.println();
Serial.print("Direccion de trabajo: ");
Serial.println(address);
Serial.println();
attachInterrupt(1, pulsador, RISING); // pin 3 = HIGH
attachInterrupt(0, dcc_int, CHANGE); // pin 2 = 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 pulsador() {
int reset = 1;
unsigned long Tprog_Milli;
Tprog_Milli = millis();
digitalWrite(13, HIGH); //provisional
digitalWrite(aviso_tiempo, HIGH);
while (millis() - (Tprog_Milli) < 3000) {
// EEPROM.write(EEPROM_ADDRESS, address % 256);
// EEPROM.write(EEPROM_ADDRESS + 1, address / 256);
EEPROM.update(EEPROM_ADDRESS, address % 256);
EEPROM.update(EEPROM_ADDRESS + 1, address / 256);
}
digitalWrite(13, LOW); //provisional
digitalWrite(aviso_tiempo, LOW);
if (reset == 1) {
reset = 0;
//declara función de reset @ address 0
void(* resetFunc) (void) = 0;
resetFunc(); //Reset
}
}
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_1, HIGH);
cont = 0;
duty = duty - DELTA;
}
if (cont == duty) {
digitalWrite(pinPWM_1, LOW); // 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_2, HIGH);
cont = 0;
duty = duty + DELTA;
if (duty > 255 - DELTA) varyingLed = false; // We're done
}
if (cont == duty) {
digitalWrite(pinPWM_2, LOW);
}
break;
}
}
}
void loop() {
}