Estoy peleado con un decoder con arduino para un desvío triple peco.
La idea es que funcione tanto en analógico como en digital
De momento malfunciona en analógico
La parte eléctrica está formada por un arduino mini, dos servos, dos relés y un pulsador para cambiar de posición (en analógico)
Utilizo la librería VarSpeedServo.h para mover los servos controlando la velocidad y una librería BotonSimple para contar el tiempo que el boton permanece pulsado.
La idea es que el desvío vaya pasando de una posición inicial izq a las otras dos, según la serie izq-centro-dch-centro.
El problema que tengo es que al conectar el arduino o al hacer un reset, el servo que corresponda, según la serie anterior se mueve.
El reset se está comportando como el botón pulsador, o casi.
Casi, porque en el setup tengo
activaSalida (0);
Serial.println(triple_desvio);
Siendo activaSalida la función para mover servos, relés, etc y triple_desvio la variable que marca la posición del desvío.
Al hacer reset se activa el servo y relé que toque, pero no aparece en el monitor serie el valor de triple_desvio.
No sé si será una falta de () o qué, pero de momento no lo encuentro.
Código: Seleccionar todo
//se cambia la libreria botonSimple para que el boton esté configurado como pull down
#include <BotonSimple.h>
#include <EEPROM.h>
#include <VarSpeedServo.h>
#include <NmraDcc.h>
NmraDcc Dcc;
const byte DCC_PIN = 2;
const byte LED_PIN = 13;
byte triple_desvio = 0; //1-> izquierda 2->centro 3->derecha se guarda en la posicion 0 de la memoria
const byte velocidad = 15; //velocidad a la que se mueven los servos
//////////////////////////////
#define INTERVALO_TIEMPO1 100//tiempo para evitar rebotes en el pulsador
#define INTERVALO_TIEMPO2 3000//si boton pulsado 3s posiciona los servos en 1->izq
unsigned long tiempo_1 = 0;
unsigned long tiempo_2 = 0;
///////////////////////////////
VarSpeedServo myservo1;
VarSpeedServo myservo2;
int direccion_DCC = 7; // Direccion DCC del decoder triple
byte output; // Estado del accesorio DCC: 1=on, 0=off
//definicion reles
byte rele1 = 11; // Pin de salida para rele1 para polarizar desvio
byte rele2 = 12; // Pin de salida para polarizar desvio
//definicion boton
BotonSimple boton(4);//boton en pin 4
unsigned long inicio, fin, tiempo_boton ;
//definicion servos
const int servoPin1 = 3; //pin de conexion para el servo 1
const int servoPin2 = 5; //pin de conexion para el servo 2
byte angulo;
byte setpoint;
byte anguloOff = 50; // Angulo para DCC=off
byte anguloOn = 150; // Angulo para DCC=on
boolean estado;
//definicion led para TCO
const byte led_izq = 8;
const byte led_centro = 9;
const byte led_dch = 10;
/*###################################################################################################
pines para servos y accesorios
servo 1 en pin 3 rele en pin 11
servo 2 en pin 5 rele en pin 12
led iquierdo en pin 8
Led centro en pin 9
Led derecho en pin 10
###################################################################################################
###################################################################################################*/
void activaSalida (int posicion) {
//el bucle es izquierda(1) centro_0(2) derecha(3) centro_1(4) izquierda(1)
switch (posicion) {
//1-> el desvio está en la posicion izq y pasa a la posicion centro_0, se mueve el servo1 a la izquierda
//el desvio queda en posicion 2->centro_0
case 1:
myservo1. attach (servoPin1);
myservo1.write(anguloOff , velocidad, true);
//digitalWrite (rele1, LOW);//normalmente abierto on
//digitalWrite (rele2, LOW);// normalmente abierto on
EEPROM.update(0, 2);
myservo1. detach ();
digitalWrite (led_izq, LOW);
digitalWrite (led_centro, HIGH);
digitalWrite (led_dch, LOW);
digitalWrite (rele1, HIGH);//rele off
digitalWrite (rele2, LOW);//rele on
Serial.println("centro");
break;
//2-> el desvio esta en posición centro y pasa a la posicion derecha, se mueve el servo2 a la izquierda
//el desvio queda en posicion 3->derecha
case 2:
myservo2. attach (servoPin2);
EEPROM.update(0, 3);
myservo2.write(anguloOff , velocidad, true);
myservo2. detach ();
digitalWrite (led_izq, LOW);
digitalWrite (led_centro, LOW);
digitalWrite (led_dch, HIGH);
digitalWrite (rele1, HIGH);//rele off
digitalWrite (rele2, HIGH);//rele off
Serial.println("dch");
break;
case 3:
//3-> el desvio está en posicion derecha y pasa a posicion centro_1, se mueve el servo2 a la derecha
//el desvio queda en posicion 4->centro_1
myservo2. attach (servoPin2);
EEPROM.update(0, 4);
myservo2.write(anguloOn , velocidad, true);
myservo2. detach ();
digitalWrite (led_izq, LOW);
digitalWrite (led_centro, HIGH);
digitalWrite (led_dch, LOW);
digitalWrite (rele1, HIGH);//rele off
digitalWrite (rele2, LOW);//rele on
Serial.println("centro_1");
break;
case 4:
//4-> el desvio está en posición centro_1 despues de haber efectuado una vuelta y pasa a posicion 1->izquierda
//se mueve el servo1 a la derecha
//el desvio queda en posicion 1->izuierda
myservo1. attach (servoPin1);
myservo1.write(anguloOn , velocidad, true);
EEPROM.update(0, 1);
myservo1. detach ();
digitalWrite (led_izq, HIGH);
digitalWrite (led_centro, LOW);
digitalWrite (led_centro, LOW);
digitalWrite (rele1, LOW);//rele on
digitalWrite (rele2, HIGH);//rele off
Serial.println("izq");
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
}
/*###################################################################################################
###################################################################################################*/
//////////////////////////////////////////////////////
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) {//dirección del decoder Addr Direccion 0-dch 1zq OutputPower 1 orden activar decoder
if ((OutputPower == 1) && (Addr == direccion_DCC)) { // si llega comando de activar desvio
triple_desvio = EEPROM.read(0);
// activaSalida (triple_desvio); // activa salida segun tipo
}
}
//if (( Addr == DCC_ADDRESS) && OutputPower) {
// if (Direction == 0)
// digitalWrite(LED_PIN, LOW);
// else
// digitalWrite(LED_PIN, HIGH);
//}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
delay (1000);
Serial.begin(9600);
pinMode(rele1, OUTPUT) ;
pinMode(rele2, OUTPUT) ;
digitalWrite(rele1, HIGH);
digitalWrite(rele2, HIGH);
pinMode (LED_PIN, OUTPUT);
digitalWrite (LED_PIN, LOW);
//pinMode( pinboton , INPUT) ;
Dcc.pin (digitalPinToInterrupt (DCC_PIN), DCC_PIN, 1);
Dcc.initAccessoryDecoder( MAN_ID_DIY, 1, FLAGS_OUTPUT_ADDRESS_MODE, 0);
pinMode (led_izq, OUTPUT);
digitalWrite (led_izq, LOW);
pinMode (led_centro, OUTPUT);
digitalWrite (led_centro, LOW);
pinMode (led_dch, OUTPUT);
digitalWrite (led_dch, LOW);
delay (1000);
myservo1. detach () ; //servos parados al inicio
myservo2. detach () ;
//el desvio triple comienza en la posicion izquierda,
//por lo que antes de conectar el decoder los servos deben estar situados
//para conseguir dicha posicion
//el bucle es izquierda(1) centro_0(2) derecha(3) centro_1(4) izquierda(1)
//triple_desvio = EEPROM.read(0); //lectura posicion del desvio
//if (triple_desvio == 0xFF) {//es la primera vez que se conecta
// triple_desvio = 1;
// EEPROM.update(0, triple_desvio);
// digitalWrite (led_izq, HIGH);
//}
activaSalida (0);
Serial.println(triple_desvio);
}
void loop() {
Dcc.process();
boton.actualizar();
// Si estamos apretandolo guardamos el valor al inicio de millis.
if ( boton.leer() == APRETANDOLO )
inicio = millis();
// Si estamos soltandolo tomamos el valor del final. El tiempo transcurrido entre el final
// y el inicio nos dará el tiempo que está el botón pulsado. Ese valor lo mostramos por el puerto serie.
if ( boton.leer() == SOLTANDOLO ) {
fin = millis();
tiempo_boton = fin - inicio;
if ((tiempo_boton > 200) & (tiempo_boton < 3000)) {
triple_desvio = EEPROM.read(0);
Serial.println("boton on");
activaSalida (triple_desvio);
}
if (tiempo_boton > 3000) {
EEPROM.update(0, 1);
triple_desvio = 1;
myservo1. attach (servoPin1);
myservo2. attach (servoPin2);
myservo2.write(anguloOn , velocidad, true);
myservo1.write(anguloOn , velocidad, true);
myservo1. detach ();
myservo2. detach ();
digitalWrite (led_izq, HIGH);
digitalWrite (led_centro, LOW);
digitalWrite (led_dch, LOW);
digitalWrite (rele1, LOW);
digitalWrite (rele2, HIGH);
//Serial.println(triple_desvio);
}
}
}