Estoy comenzando con el tema de los motores DC. He montado un proyecto con un Mega2650, un transistor 2N2222 (en modo interruptor), un motor DC (el típico que viene con los kits de inicio), un pulsador y un led (que se enciende cuando el motor está en marcha).
Ha funcionado sin problemas mientras el pulsador estaba programado para que actuara como pulsador pero cuando he querido modificar el código para que actuara como un interruptor, he comenzado a tener problemas y no encuentro la razón
//Control motor CC con pulsador como interruptor
const int pulsadorPin = 2; //asignar valores a las variables
const int ledPin = 3;
const int motorPin = 9;
bool estado_pulsador = 0; //valor puesto a 0 para iniciar sin ninguna acción
void setup(){
pinMode(motorPin,OUTPUT); //configuración de pinMode
pinMode(pulsadorPin,INPUT);
pinMode(ledPin,OUTPUT);
Serial.begin(9600); //inicio puerto serie para visualizar datos en monitor
}
void loop(){
if(digitalRead(pulsadorPin)==HIGH){ //lectura del pulsador
estado_pulsador=1;
Serial.println(estado_pulsador); //muestra el valor de la variable para comprobar
delay (300); //retraso para evitar varias lecturas en una pulsación
}
while(estado_pulsador==1){
digitalWrite(motorPin,HIGH);
digitalWrite(ledPin,HIGH);
if(digitalRead(pulsadorPin)==HIGH){ //comprueba si se vuelve a pulsar el pulsador
estado_pulsador=0;
Serial.println(estado_pulsador); //muestra el valor de la variable para comprobar
delay (300); //retraso para evitar varias lecturas en una pulsación
digitalWrite(motorPin,LOW);
digitalWrite(ledPin,LOW);
}
}
}
El programa inicia correctamente, sin ninguna acción, y cuando aprieto el pulsador se enciende led y se pone en marcha el motor, pero al poco tiempo (un par de segundos como mucho) se apaga el led y el motor. Cuando monitorizo el valor de la variable estado_pulsado pasa de valor 1 a valor 0 sin saber el motivo.
Es curioso que he detectado que eliminando el motor del montaje (simplemente desconectando el pin de alimentación) todo funciona correctamente, es decir, el led se activa o se apaga después de cada pulsación y la variable cambia tras cada pulsación.
¿Qué estoy haciendo mal?
Muchas gracias por vuestra ayuda y saludo.
Bueno he hecho algunos cambios, que parecerán muchos pero ya los explico
//Control motor CC con pulsador como interruptor
const int pulsadorPin = 2; //asignar valores a las variables
const int ledPin = 3;
const int motorPin = 9;
bool estado_pulsador; //valor puesto a 0 para iniciar sin ninguna acción
bool estado_pulsadorAnterior = false;
bool accionoMotor = false;
void setup(){
pinMode(pulsadorPin,INPUT);
pinMode(motorPin,OUTPUT); //configuración de pinMode
pinMode(ledPin,OUTPUT);
Serial.begin(9600); //inicio puerto serie para visualizar datos en monitor
}
void loop(){
estado_pulsador = digitalRead(pulsadorPin);
if(estado_pulsador != estado_pulsadorAnterior){ //lectura del pulsador
Serial.println(estado_pulsador); //muestra el valor de la variable para comprobar
delay (50); //retraso para evitar varias lecturas en una pulsación
}
if (estado_pulsador && !estado_pulsadorAnterior){
accionoMotor = !accionoMotor;
if (accionoMotor) {
digitalWrite(motorPin,HIGH);
digitalWrite(ledPin,HIGH);
}
else {
digitalWrite(motorPin,LOW);
digitalWrite(ledPin,LOW);
}
}
estado_pulsadorAnterior =estado_pulsador;
}
Cuando quieres usar un pulsador como interruptor lo mejor para mi es comparar siempre el flanco cuando se presiona dicho pulsador. Y uso ese instante en el que paso del estado estable que en tu caso es LOW a HIGH que es cuando presionas.
Si yo leo en cada ciclo en que situación esta el pulsador, y además tmb conservo el estado anterior. Cuando ambos sean el mismo no se hace nada pero cuando pasamos de LOW (estadoAnterior) a HIGH (estadoActual) entonces se pone en VERDADERO esta condicion
if (estado_pulsador && !estado_pulsadorAnterior){
Observa que estado_pulsadorAnterior estaba en LOW y si lo niego con ! se transforma en HIGH
Por otro lado acabas de presionar el pulsador y estado_pulsador esta en HIGH tmb. Ambos en HIGH por lo tanto
HIGH && HIGH = HIGH
1 AND 1 = 1
1 AND 0 = 0
0 AND 1 = 0
0 AND 0 = 0
te puse las 4 posibilidades.
la primera es nuestro caso.
cada vez que haya un flanco de 0 a 1 tenemos una acción dentro del if
Y en el if que hago.. lo primero es cambiar accionoMotor al valor que tenia invertido. Si era 0 lo paso a 1, y luego a 0 y asi
cada flanco me cambia a accionoMotor como un switch
Lo que sigue es un condicional que lo pongo ahi adentro para que ejecute solo 1 vez sino en cada loop se esta ejecutando y a mi no me gusta eso en los programas.
Los programas deben ser rapidos y eficientes y si hago bien las cosas con decirlo y ejecutarlo una baste es suficiente.
Muchas gracias surbyte por tu ayuda que seguro me será muy útil.
Aunque tengo que estudiar y analizar el código que me aportas, entiendo la idea que propones porque va en la linea de la mejora que quería probar. En mi profundo desconocimiento de Arduino y su programación, ya me había dado cuenta que mi primer código sobrecarga de trabajo a la placa obligándola en cada ciclo a leer y escribir en unos pines cuando no es necesario. Me imaginaba que tenía que aplicar unos condicionales para determinar en que momento exacto debe escribir y leer esos pines.
Voy a intentar hacerlo yo mismo desde 0, creo que es la mejor forma de aprender, pero gracias a ti tengo un código que me va a servir de modelo para corregir los muchísimos errores que seguro que cometeré.
Siempre es un lujo contar con maestros como tu y un placer aprender con vuestras propuestas y enseñanzas.
Muchas gracias y un saludo.