Problema funcionamiento motor DC con pulsador a modo de interruptor

Hola a tod@s

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.

Prueba a ver si todo esto funcioina.

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.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.