Hola necesito si alguien me puede ayudar que estoy perdido, tengo dos interruptores, no pulsadores, de ON OFF y necesito que cuando pongo el interruptor 1 en ON active el relé del motor 1, luego al ponerlo en OFF que desactive el relé del motor 1, pero la siguiente vez que ponga el interruptor 1 que active el relé del motor 2, al ponerlo en OFF, desactive el relé del motor 2 y así sucesivamente, la siguiente el 1 .....
Gracias
Mira cualquier ejemplo de pulsadores porque para el caso será lo mismo.
Si tu pulsador o switch esta en ON hará algo, y si esta en OFF hara otra cosa.
Esta plagado de ejemplos la Web.
Esta lleno de ejemplos este foro tambien.
Busca en la lupa botones switches pulsadores.
Hola necesito si alguien me puede ayudar que estoy perdido, tengo dos interruptores, no pulsadores, de ON OFF y necesito que cuando pongo el interruptor 1 en ON active el relé del motor 1, luego al ponerlo en OFF que desactive el relé del motor 1, pero la siguiente vez que ponga el interruptor 1 que active el relé del motor 2, al ponerlo en OFF, desactive el relé del motor 2 y así sucesivamente, la siguiente el 1 .....
Gracias
El tratamiento de un interruptor es igual a un pulsador (que no es más que un interruptor momentáneo).
Lo importante es que trabajes con los flancos.
O sea, no solo chequear si el interruptor está en LOW o HIGH sino compararlo con la lectura anterior (que guardas en una variable) para saber si hubo cambio de estado.
Saber si pasó de LOW a HIGH (flanco ascendente) o de HIGH a LOW (flanco descendente).
Respecto a sobre cual relé actuar, usa una variable a la cual le cambias el valor al desactivar el relé. Puedes ser una tipo bool que alternas entre true y false o una numérica (byte, int) que alternas entre 0 y 1 o entre 1 y 2 o entre cualquier par de valores que quieras.
Luego si esa variable es, por ej., false actúas sobre el relé 1, y si es true actúas sobre el relé 2.
PD: Borra el otro post antes que el moderador te llame la atención
Moderador:
He unido tus publicaciones cruzadas @ tymaor.
El doble posteo va en contra de las reglas del foro de Arduino.
La razón es que las publicaciones duplicadas hacen perder el tiempo a las personas que intentan ayudar, como ves yo respondí a una consulta tuya y otro forero lo hizo en la 2da publicación, sin saber uno del otro aunque @MaximoEsfuerzo se dió cuenta.
Alguien podría pasar mucho tiempo investigando y escribiendo una respuesta detallada sobre un tema, sin saber que alguien más ya hizo lo mismo en el otro tema.
La publicación cruzada repetida puede resultar en una suspensión del foro, comenzando por una baneo de 1 dia.
En el futuro, crea solo un tema para cada tema distinto.
Esta es la etiqueta básica del foro, como se explica en Normas del foro.
Contiene mucha otra información útil.
Por favor léelo.
Gracias de antemano por tu cooperacion.
Perdón es mi primer post en el foro, no fue mi intención duplicarlo, simplemente no lo encontraba.
Gracias
//Control de 2 motores con 2 interruptores(1 y 2) y alternancia de los mismos con el interruptor1
// interruptor1 en LOW arranca motor1, en HIGH para motor1
// interruptor2 en LOW arranca motor2, en HIGH para motor2
// si interruptor1 se vuelve a poner en LOW arranca el motor2, cuando vuelve a HIGH para motor2
const int interruptor1 = 2; //asignar valores a las variables
const int interruptor2 = 4;
int motor1 = 3;
int motor2 = 5;
bool estado_interruptor1;
bool estado_interruptor2;
bool estado_interruptor1Anterior;
bool estado_interruptor2Anterior;
void setup() {
pinMode(interruptor1, INPUT);
pinMode(interruptor2, INPUT);
pinMode(motor1, OUTPUT);
pinMode(motor2, OUTPUT);
Serial.begin(9600);
}
void loop() {
estado_interruptor1 = digitalRead(interruptor1); //lectura del interruptor1
estado_interruptor2 = digitalRead(interruptor2); //lectura del interruptor2
if (estado_interruptor1 != estado_interruptor1Anterior || estado_interruptor2 != estado_interruptor2Anterior ) {
Serial.print("estado_interruptor1: ");
Serial.println(estado_interruptor1); //muestra el valor de la variable estado_interruptor1
Serial.print("estado_interruptor2: ");
Serial.println(estado_interruptor2); //muestra el valor de la variable estado_interruptor2
delay(50);
}
if (estado_interruptor1 == 0 && estado_interruptor1Anterior == false) {
digitalWrite(motor1, HIGH);
}
else {
digitalWrite(motor1, LOW);
}
if (estado_interruptor2 == 0 && estado_interruptor2Anterior == false) {
digitalWrite(motor2, HIGH);
}
else {
digitalWrite(motor2, LOW);
}
estado_interruptor1Anterior = estado_interruptor1;
estado_interruptor2Anterior = estado_interruptor2;
}
Hola tengo este código pero no consigo pasar de aquí para conseguir mi objetivo, con el interruptor 1 arranco y paro el motor 1, y con el interruptor 2, pues arranco y paro el motor 2, pero no consigo que el interruptor 1 haga la alternancia y la siguiente vez lo que haga sea arrancar y parar el motor 2 y la siguiente el motor 1 y así sucesivamente. Si alguien pudiera echarme una mano estaría agradecido, todo lo que he intentado me da error.
Gracias
Este es el montaje:
La lógica se me hace un tanto confusa para que tener dos interruptores si con el interruptor1 se plantea el funcionamiento de ambos motores, segun lo entiendo partiria de hacer que el interruptor 1 funcione de la manera que tu pretendes, en primera se dedique a controlar el motor 1 y una vez haya terminado la secuencia del motor 1 haga la secuencia del motor 2
Puedes probar como te va con este código y enfocarte primero en sacar la función del interruptor1 para despues avanzar con lo que quieras hacer con el interuptor2
//Control de 2 motores con 2 interruptores(1 y 2) y alternancia de los mismos con el interruptor1
// interruptor1 en LOW arranca motor1, en HIGH para motor1
// interruptor2 en LOW arranca motor2, en HIGH para motor2
// si interruptor1 se vuelve a poner en LOW arranca el motor2, cuando vuelve a HIGH para motor2
const int interruptor1 = 2; //asignar valores a las variables
const int interruptor2 = 4;
int motor1 = 3;
int motor2 = 5;
int estado_inicialsw1;
int estado_finalsw1;
bool motor1_activado = false;
bool motor2_activado = true;
int flag = 0;
void setup() {
pinMode(interruptor1, INPUT);
pinMode(interruptor2, INPUT);
pinMode(motor1, OUTPUT);
pinMode(motor2, OUTPUT);
Serial.begin(9600);
}
void loop() {
estado_inicialsw1 = digitalRead(interruptor1); //lectura del interruptor1
if (estado_inicialsw1 == 0) {
flag = 1;
while (flag == 1) {
if (motor2_activado = true) {
digitalWrite(motor1, HIGH);
estado_finalsw1 = digitalRead(interruptor1);
delay(50);
if (estado_finalsw1 == 1) {
digitalWrite(motor1, LOW);
motor1_activado = true;
motor2_activado = false;
flag = 0;
}
} else if (motor1_activado = true) {
digitalWrite(motor2, HIGH);
estado_finalsw1 = digitalRead(interruptor1);
delay(50);
if (estado_finalsw1 == 1) {
digitalWrite(motor2, LOW);
motor1_activado = false;
motor2_activado = true;
flag = 0;
}
}
}
}
}
Usas variables diferentes
estado_inicialsw1 = digitalRead(interruptor1);
estado_finalsw1 = digitalRead(interruptor1);
para controlar cosas distintas? terminas haciendo lo mismo o simplemente no puedes cambiar los estados.
Hola migueratto y Surbyte , gracias por vuestra respuesta mañana intentare probarlo, la lógica de dos interruptores es que en realidad son dos presostatos(que no dejan de ser dos interruptores en lo básico) y están regulados para dos tipos de demanda de caudal diferente, el 2 calado para que arranque con una presión mas baja que el calado para el 1(vamos si el 1 no es capaz de satisfacer la demanda), la alternancia entre motores con el interruptor 1(presostato), es para intentar igualar en lo posible el trabajo de los dos motores por que de otra forma el motor 1 que es el primero que salta siempre trabajaría muchas mas horas que el segundo que solo salta si el primero no es capaz de satisfacer la demanda. Espero haberme explicado bien y darte las gracias por tu ayuda.
Hola migueratto acabo de probar tu código y no veo como modificarlo para realizar la alternancia de motores con el interruptor 1. de todas formas muchas gracias, sigo investigando a ver.
Saludos
Creo que por fin has dado una verdadera pista de qué es lo que quieres. Entendiendo que si la lectura del presostato 2 está a nivel bajo, han de estar los dos motores encendidos a la vez. Mientras que la lectura del presostato 2 está a nivel alto y la del presostato 1 está a nivel bajo, sólo uno de los dos motores ha de estar encendido. Por último, si la dos lecturas están a nivel alto, los dos motores han de estar apagado.
El problema está en que cuando ha de estar sólo un motor encendido, no quieres que siempre sea el mismo motor, sino que se vayan alternando y una vez sea el motor 1 y otra sea el motor 2. Pues aquí tienes mi propuesta de solución:
const int PIN_PRESOSTATO_1 = 2;
const int PIN_PRESOSTATO_2 = 4;
const int PIN_MOTOR_1 = 3;
const int PIN_MOTOR_2 = 5;
const bool VALOR_MOTOR_ENCENDIDO = HIGH;
const bool LECTURA_PRESOSTATO_ACTIVO = LOW;
const unsigned long TIEMPO_ANTIREBOTE = 50;
bool leTocaAlUno = true;
bool encendidoMotor1 = false;
bool encendidoMotor2 = false;
bool activoAnteriorPresostato1 = false;
bool activoAnteriorPresostato2 = false;
class PinSinRebote {
public:
PinSinRebote(uint8_t pin, uint8_t modo, uint8_t valorInicial) : pin(pin), valor(valorInicial), cambiando(false), instanteAnterior(0L) {
pinMode(pin, (modo == INPUT_PULLUP) ? INPUT_PULLUP : INPUT);
}
bool lectura() {
bool valorTemporal = digitalRead(pin);
if (valorTemporal != valor) {
if (cambiando) {
if ((millis() - instanteAnterior) >= TIEMPO_ANTIREBOTE) {
valor = valorTemporal;
}
}
else {
cambiando = true;
instanteAnterior = millis();
}
}
else {
cambiando = false;
}
return valor;
}
private:
uint8_t pin;
bool valor:1;
bool cambiando:1;
unsigned long instanteAnterior;
};
void actualizaMotores(bool enciendeMotor1, bool enciendeMotor2) {
encendidoMotor1 = enciendeMotor1;
encendidoMotor2 = enciendeMotor2;
digitalWrite(PIN_MOTOR_1, encendidoMotor1 ? VALOR_MOTOR_ENCENDIDO : !VALOR_MOTOR_ENCENDIDO);
digitalWrite(PIN_MOTOR_2, encendidoMotor2 ? VALOR_MOTOR_ENCENDIDO : !VALOR_MOTOR_ENCENDIDO);
if (encendidoMotor1 && encendidoMotor2) {
Serial.println(F("Los dos motores encendidos"));
}
else if (encendidoMotor1) {
Serial.println(F("Encendido motor 1"));
}
else if (encendidoMotor2) {
Serial.println(F("Encendido motor 2"));
}
else {
Serial.println(F("Motores apagados"));
}
}
void setup() {
Serial.begin(9600);
pinMode(PIN_MOTOR_1, OUTPUT);
pinMode(PIN_MOTOR_2, OUTPUT);
actualizaMotores(false, false);
}
PinSinRebote presostato1(PIN_PRESOSTATO_1, INPUT, !LECTURA_PRESOSTATO_ACTIVO);
PinSinRebote presostato2(PIN_PRESOSTATO_2, INPUT, !LECTURA_PRESOSTATO_ACTIVO);
void loop() {
unsigned long instanteActual = millis();
bool activoPresostato1 = (presostato1.lectura() == LECTURA_PRESOSTATO_ACTIVO);
bool activoPresostato2 = (presostato2.lectura() == LECTURA_PRESOSTATO_ACTIVO);
if (activoPresostato2) {
// Se necesita que los dos motores estén activos
if (!encendidoMotor1 || !encendidoMotor2) {
// Al menos uno de los dos está apabado, nos aseguramos que se encienden los dos
actualizaMotores(true, true);
}
}
else if (activoPresostato1) {
// Se necesita un sólo motor activo
if ((encendidoMotor1 && encendidoMotor2) || (!encendidoMotor1 && !encendidoMotor2)) {
actualizaMotores(leTocaAlUno, !leTocaAlUno);
leTocaAlUno = !leTocaAlUno;
}
}
else {
// Los dos motores han de estar apagados
if (encendidoMotor1 || encendidoMotor2) {
// Al menos uno de los dos está encendido, nos aseguramos que se apagan los dos
actualizaMotores(false, false);
}
}
}
Aclarar que si el presostato 2 está a nivel bajo, no se tiene en cuenta el presostato 1. Es decir, pueden pasar de estar los dos motores apagados a encenderse los dos a la vez ya que si la entrada del presostato 1 siempre está a nivel alto y el presostato pasa de nivel alto al bajo, se pondrán en marcha los dos motores a la vez.
Otra aclaración del código que he puesto. En el caso de que estén parado los dos motores y se ponga en marcha el 1, si se detecta que se ha de poner en marcha los dos, se encenderá el motor 2. Si luego se detecta que se ha de quedar sólo uno de ellos en marcha, será el motor 2 el que se quede en marcha, ya que antes estuvo el motor 1 funcionando solo. Resumiendo, se alternan los motores cada vez que se pase a estar uno de ellos encendido, bien sea porque los dos están apagados o porque los dos están encendidos.
Cabe la posibilidad de mejorar el programa controlando el tiempo que está cada motor encendido individualmente para que ambos lleven más o menos el mismo tiempo total de funcionamiento. La idea es que si el motor 1 se enciende por 30 segundos, se apaga, para que luego el motor 2 se encienda por 10 segundos y se apaga; la siguiente vez no sea el motor 1 el que se enciende, sino el motor 2 ya que el 1 ha estado encendido 20 segundos más que el 2. El motor 1 no se volvería a encender hasta que el motor 2 no lleve un total de al menos 30 segundos de tiempo acumulado. El único problema está en que si se apaga el Arduino, este no recordaría el tiempo que llevan de diferencia entre los motores.
En caso de duda, no duden en preguntar.
Y vuelves a usar el mismo interruptor con otra función!!
int estadoMotor = digitalRead(motor1Pin);
Deja de hacer eso @tymaor, solo te confudes a ti mismo.
Establece etiquetas claras de que hará en cada caso y sigue usándolas en todo el código pero no las renombres.
Bueno, estaba trabajando con la simulación pensando que estaba en mi cuenta y resulta que no, era la tuya y se perdió lo que hice.
Dejó acá porque se perdieron mis cambios.
Te daré algunos trucos.
No necesitas dos interruptores con 1 se hace todo.
Y no necesitas un switch, con un solo pulsador y viendo flancos se hace todo.
NOTA: Ya veo el del cambio era @IgnoranteAbsoluto.
Pocos pueden usar clases para resolverlo.
Listo tema finalizado o en breve.
Hola, muchas gracias por tu tiempo @IgnoranteAbsoluto , por un momento creí que ya estaba solucionado, pero no es así, a ver si es posible, puede que sea fácil pero yo no lo veo dada mi poca experiencia con Arduino, te cuento:
*se activa el presostato 1 y se enciende un motor,
*se activa el presostato 2 y se enciende el otro, hasta aquí perfecto,
- se desactiva el presostato 1 ( paro activado sobre los 4 bares), y.... no se para el motor 1, hay que confiar que salte el presostato 2 ( que saltará...) que si para los 2 motores, es un poco arriesgado, seria posible modificar el código para que en la parada, presostato que se desactiva motor que se para. Muchas gracias por me viene de perlas exepto por ese inconveniente.
Muchas gracias
Gracias Surbyte, perdona si sigo cometiendo los mismos errores pero no soy un experto en Arduino, intento aprender, si necesito dos interruptores por que en realidad son dos presostatos, he empezado con cosas básicas y poco a poco complicándolo un poco.
Saludos
Vamos a ver si lo entiendo. ¿Sólo se han de activar los dos motores cuando están activos los dos presostatos?
Caso 1: los dos presostatos están a nivel HIGH: los dos motores han de estar apagados.
Caso 2: el presostato 1 está a nivel LOW y el presostato 2 está a nivel HIGH: sólo un motor ha de estar encendido. No importa cual, siempre que se alternen.
Caso 3: el presostato 1 está a nivel HIGH y el presostato 2 está a nivel LOW: sólo un motor ha de estar encendido. No importa cual, siempre que se alternen.
Caso 4: los dos presostatos están a nivel LOW: los dos motores han de estar encendidos.
¿Son correcto los cuatro casos que he puesto?
Según esto, parece que en el caso de estar los dos motores encendido, se debiera de apagar el motor que se encendió junto con el presostato que se desactiva. ¿Esto es así o te vale que se apague un motor cualquiera?
Hola @IgnoranteAbsoluto , efectivamente, solo se deberían activar los dos motores si los dos presostatos están en LOW, no obstante tu código es perfecto y me podría valer, trasteando con el montaje pues veo que si se desactiva el presostato 1 los dos motores continúan a plena carga, me parece bien que si salta el presostato 2 arranquen los 2 motores por que quiere decir que la presión ha caído mucho.
Lo dicho muchas gracias.
Si me das a elegir @IgnoranteAbsoluto preferiría que se apagara el motor 1 si se apaga el presostato 1 y viceversa, solo en el caso concreto de que estén los dos en marcha a la vez.
Muchas gracias
Aquí tienes una nueva versión con un par de modificaciones. La primera es que ya no se alternan los motores uno tras otro, sino que se encenderá o se mantendrá encendido el que menos tiempo lleve en marcha desde que se inició el programa del Arduino. Es la "mejora" que comenté. Entiendo que ambos motores son iguales y hacen el mismo trabajo indistintamente, por lo que de esta manera no tendrás uno que haya trabajado mucho más tiempo que el otro. Esto significa que no se tienen porqué alternar cada vez que se encienden. Si lo pruebas y dejas un buen rato uno de ellos funcionando continuamente, verás que si luego pruebas periodos cortos, siempre se encenderá el mismo hasta que "se igualen los tiempos" que es entonces cuando cambia al que menos tiempo lleva en total. En el monitor serie se muestra en milisegundos la diferencia de tiempo entre ellos. Cuando es negativo, se pondrá en marcha uno y cuando es positivo se pondrá en marcha el otro.
El otro cambio es el que únicamete trabajan los dos motores a la vez cuando están los dos presostatos activos a la vez. Esta forma de trabajar te da la ventaja de que da igual cual de los dos presostatos es el que está calibrado a más o menos presión.
const int PIN_PRESOSTATO_1 = 2;
const int PIN_PRESOSTATO_2 = 4;
const int PIN_MOTOR_1 = 3;
const int PIN_MOTOR_2 = 5;
const bool VALOR_MOTOR_ENCENDIDO = HIGH;
const bool LECTURA_PRESOSTATO_ACTIVO = LOW;
const unsigned long TIEMPO_ANTIREBOTE = 50;
bool leTocaAlUno = true;
bool encendidoMotor1 = false;
bool encendidoMotor2 = false;
bool activoAnteriorPresostato1 = false;
bool activoAnteriorPresostato2 = false;
long diferenciaDeTiempo = 0;
unsigned long instanteCambioMores = 0;
class PinSinRebote {
public:
PinSinRebote(uint8_t pin, uint8_t modo, uint8_t valorInicial) : pin(pin), valor(valorInicial), cambiando(false), instanteAnterior(0L) {
pinMode(pin, (modo == INPUT_PULLUP) ? INPUT_PULLUP : INPUT);
}
bool lectura() {
bool valorTemporal = digitalRead(pin);
if (valorTemporal != valor) {
if (cambiando) {
if ((millis() - instanteAnterior) >= TIEMPO_ANTIREBOTE) {
valor = valorTemporal;
}
}
else {
cambiando = true;
instanteAnterior = millis();
}
}
else {
cambiando = false;
}
return valor;
}
private:
uint8_t pin;
bool valor: 1;
bool cambiando: 1;
unsigned long instanteAnterior;
};
void actualizaMotores(bool enciendeMotor1, bool enciendeMotor2) {
if (encendidoMotor1 && !encendidoMotor2) {
diferenciaDeTiempo -= (millis() - instanteCambioMores);
}
if (!encendidoMotor1 && encendidoMotor2) {
diferenciaDeTiempo += (millis() - instanteCambioMores);
}
if (encendidoMotor1 != encendidoMotor2) {
Serial.print(F("Diferencia de tiempo: "));
Serial.println(diferenciaDeTiempo);
}
encendidoMotor1 = enciendeMotor1;
encendidoMotor2 = enciendeMotor2;
digitalWrite(PIN_MOTOR_1, encendidoMotor1 ? VALOR_MOTOR_ENCENDIDO : !VALOR_MOTOR_ENCENDIDO);
digitalWrite(PIN_MOTOR_2, encendidoMotor2 ? VALOR_MOTOR_ENCENDIDO : !VALOR_MOTOR_ENCENDIDO);
if (encendidoMotor1 && encendidoMotor2) {
Serial.println(F("Los dos motores encendidos"));
}
else if (encendidoMotor1) {
Serial.println(F("Encendido motor 1"));
}
else if (encendidoMotor2) {
Serial.println(F("Encendido motor 2"));
}
else {
Serial.println(F("Motores apagados"));
}
instanteCambioMores = millis();
}
void setup() {
Serial.begin(9600);
pinMode(PIN_MOTOR_1, OUTPUT);
pinMode(PIN_MOTOR_2, OUTPUT);
actualizaMotores(false, false);
}
PinSinRebote presostato1(PIN_PRESOSTATO_1, INPUT, !LECTURA_PRESOSTATO_ACTIVO);
PinSinRebote presostato2(PIN_PRESOSTATO_2, INPUT, !LECTURA_PRESOSTATO_ACTIVO);
void loop() {
unsigned long instanteActual = millis();
bool activoPresostato1 = (presostato1.lectura() == LECTURA_PRESOSTATO_ACTIVO);
bool activoPresostato2 = (presostato2.lectura() == LECTURA_PRESOSTATO_ACTIVO);
if (activoPresostato1 && activoPresostato2) {
// Se necesita que los dos motores estén activos
if (!encendidoMotor1 || !encendidoMotor2) {
// Al menos uno de los dos está apabado, nos aseguramos que se encienden los dos
actualizaMotores(true, true);
}
}
else if (activoPresostato1 || activoPresostato2) {
// Se necesita un sólo motor activo
if ((encendidoMotor1 && encendidoMotor2) || (!encendidoMotor1 && !encendidoMotor2)) {
leTocaAlUno = (diferenciaDeTiempo >= 0);
actualizaMotores(leTocaAlUno, !leTocaAlUno);
}
}
else {
// Los dos motores han de estar apagados
if (encendidoMotor1 || encendidoMotor2) {
// Al menos uno de los dos está encendido, nos aseguramos que se apagan los dos
actualizaMotores(false, false);
}
}
}