Go Down

Topic: Duda acción pulsador (Read 9099 times) previous topic - next topic

111---111

Hola a todos,

He estado probando para hacer que un pulsador en una entrada digital, al hacer una pulsación encienda un led en otra salida digital y que esta se mantenga activa por ejemplo 5 segundos pero que si dentro de ese tiempo se pulsa otra vez el pulsador que apague directamente el led.

He probado un monton de formas pero no doy con la correcta, por eso os pido ayuda.

Saludos

learzy

haz probado con los ejemplos?

si no me equivoco, ahi debe estar uno parecido

111---111

Esto es lo único que he podido conseguir con los ejemplos, que un pulsador cada vez que pulsas encienda o apague, pero al probarlo parece que tiene bastantes rebotes y veo bastante complicado el código para simplemente encender o apagar mediante cada pulsación.

Code: [Select]
const int  buttonPin = 8;  
const int ledPin = 2;      

int buttonPushCounter = 0;  
int buttonState = 0;        
int lastButtonState = 0;    

void setup() {
 
 pinMode(buttonPin, INPUT);
 pinMode(ledPin, OUTPUT);
 
}

void loop() {
 
 buttonState = digitalRead(buttonPin);
 
 if (buttonState != lastButtonState) {
   if (buttonState == HIGH) {
     buttonPushCounter++;
   }
   lastButtonState = buttonState;
 }
 
 if (buttonPushCounter % 2 == 0) {
   digitalWrite(ledPin, HIGH);
 } else {
  digitalWrite(ledPin, LOW);
 }
 
}


De todas maneras lo que busco es lo que he comentado en el primer post pero veo que no soy capaz :'(

111---111

Bueno, pues lo primero y que supongo será mas sencillo no lo he conseguido todavía. :-[

Pero he conseguido, y esto tambien estuve buscando ejemplos durante bastante tiempo, que con una pulsación se encienda un led durante un determinado tiempo, que en este caso he puesto 5 segundos y que si en cualquier momento se pulsa de nuevo durante, en este caso, mas de 800 milisegundos apague el led directamente y como es lógico lo mantenga encendido el tiempo que esté pulsado.

De esta forma he conseguido hacer el típico boton bifuncional que con una pulsación hace una cosa y manteniendolo pulsado hace otra.
Lo dejo por aquí por si a alguien le puede ayudar ya que yo no encontré nada en su momento.

Lo que he comprobado es que cuando se mantiene pulsado mas de 5 segundos, la salida da 5 voltios y en el segundo 5 baja a 3 voltios y pico :o

Si alguien pudiera hechar un vistazo al código para hacerlo mas sencillo y/o subsanar el tema de los voltios se lo agradecería.

Saludos

111---111

Code: [Select]
const int buttonPin = 8;    
const int ledPin =  2;      

byte buttonState;            
byte lastButtonState;  

long lastButtonDelay = 0;  
long buttonDelay = 800;
long actionDelay = 5000;

void setup() {
 
 pinMode(buttonPin, INPUT);
 pinMode(ledPin, OUTPUT);
 
}

void loop() {
 
 byte reading = digitalRead(buttonPin);
 
 if (reading != lastButtonState) {
   digitalWrite(ledPin, HIGH);
   lastButtonDelay = millis();
 }
 
 if ((millis() - lastButtonDelay) > actionDelay) {
   digitalWrite(ledPin, LOW);
 }
 
 if ((millis() - lastButtonDelay) > buttonDelay) {
   buttonState = reading;
 }
 
 if (buttonState) {
 digitalWrite(ledPin, reading);
 }
 
 lastButtonState = reading;
 
}

igorreal

#5
Apr 14, 2010, 05:17 pm Last Edit: Apr 14, 2010, 05:28 pm by igorreal Reason: 1
Hola,

Una forma sencilla de resolver este tipo de problemas, es dibujarte un diagrama de estados.

Me explico:



--------------------------------------------> ESTADO 1 (Accion: Led off, al salir guardar tiempo)
¦                                                               ¦
¦                                                               ¦
¦                                                               ¦
¦                                                               ¦
¦                                                               ¦
¦                                                               ¦
¦                                                              --- (Pulsador)
---(tiempo>5sg OR pulsador)                        ¦
¦                                                                ¦
¦                                                                ¦
¦                                                               \¦/
--------------------------------------------< ESTADO 2 (Accion: Led on)



Es decir, el programa empieza en el estado 1 (condicion inicial).
Si estando en el estado 1, se me cumple la condicion de activar el pulsador, entonces cambio a estado 2. (En el momento de salir, recojo el tiempo).
Si estando en el estado 2, activo el pulsador o tiempo > 5 segundos, entonces cambio al estado 1.

Accion mientras ESTADO= 1-> Led OFF
Accion mientras ESTADO= 2-> Led ON



Pseudocodigo:
int state=1;

void loop(){

     if (state==1 && pulsador){
           delay(100); //evitar rebotes
           state=2;
           t_start=millis();
     end

     if (state==2 && (pulsador OR (millis()-t_start)>5000)){
           delay(100); //evitar rebotes            
           state=1;
     end

     switch (state){
           case 1:
                 digitalWrite(led,LOW);
                 break;
           case 2:
                 digitalWrite(led,HIGH);
                 break;
     }

}
[/color]


No es el codigo tal cual, es pseudocodigo para que se me entienda.....

Como lo ves pensandolo asi? se te hace mas facil?

(estoy en un teclado ingles, y no tengo ni acentos, ni apertura de interrogacion,....)



Saludos   ;)




Igor R.

111---111

Hola Igor, gracias por contestar, te he visto en varios posts y eres un máquina.

He intentado hacer lo siguiente pero no me funciona y no se para donde tirar.

Code: [Select]
#define pulsador 8
#define led 2

int state=1;
long t_start;
int temp=5000;

void setup() {
 
 pinMode(pulsador,INPUT);
 pinMode(led,OUTPUT);
}

void loop(){

    if (state==1 && pulsador){
          delay(100); //evitar rebotes
          state=2;
          t_start=millis();
    }
    end;

    if (state==2 && (pulsador || (millis() - t_start) > temp)){
          delay(100); //evitar rebotes            
          state=1;
    }
    end;

    switch (state){
          case 1:
                digitalWrite(led,LOW);
                break;
          case 2:
                digitalWrite(led,HIGH);
                break;
    }

}



Saludos

igorreal

#7
Apr 14, 2010, 10:37 pm Last Edit: Apr 14, 2010, 10:48 pm by igorreal Reason: 1
Hola,

Te falta leer el pulsador => pulsador=digitalRead(pin_pulsador). O bien sustituir pulsador por digitalRead(pulsador)

Saludos


Igor R.

igorreal

Otra cosa....

Code: [Select]

#define pulsador 8
#define led 2

int state=1;
long t_start;
int temp=5000;

void setup() {

 pinMode(pulsador,INPUT);
 pinMode(led,OUTPUT);
}

void loop(){

    if (state==1 && digitalRead(pulsador)){
          delay(100); //evitar rebotes
          state=2;
          t_start=millis();
    }


    if (state==2 && (digitalRead(pulsador) || (millis() - t_start) > temp)){
          delay(100); //evitar rebotes
          state=1;
    }


    switch (state){
          case 1:
                digitalWrite(led,LOW);
                break;
          case 2:
                digitalWrite(led,HIGH);
                break;
    }

}


Los if, van sin end.


;)

111---111

Hola de nuevo Igor,

a quedado algo así:

Code: [Select]
#define pulsador 8
#define led 2

int state=1;
long t_start;
int temp=5000;

void setup() {

 pinMode(pulsador,INPUT);
 pinMode(led,OUTPUT);
}

void loop(){

    if (state==1 && digitalRead(pulsador)){
          delay(100); //evitar rebotes
          state=2;
          t_start=millis();
    }
    end;

    if (state==2 && (digitalRead(pulsador) || (millis() - t_start) > temp)){
          delay(100); //evitar rebotes
          state=1;
    }
    end;

    switch (state){
          case 1:
                digitalWrite(led,LOW);
                break;
          case 2:
                digitalWrite(led,HIGH);
                break;
    }

}


Pero al compilar me dice lo siguiente:

In function 'void loop()':
error: 'end' was not declared in this scope


Saludos

igorreal

Lee mi post anterior, que hemos escrito a la vez....je,je,je


;)

111---111

#11
Apr 14, 2010, 10:50 pm Last Edit: Apr 14, 2010, 10:51 pm by 111---111 Reason: 1
Perdoname, parece que hemos posteado casi a la vez jejeje, voy a probar lo que has puesto.

Saludos

Editado: jejejej otra vez...voy a ello...

111---111

#12
Apr 14, 2010, 10:58 pm Last Edit: Apr 14, 2010, 10:59 pm by 111---111 Reason: 1
Perfecto Igor!!!

Lo único que he bajado los delay's a 50 porque hacía cosas rarillas, pero vamos, lo que te digo, eres una máquina.

Por cierto, también te agradezco que no me hallas dado todo hecho al principio para ir quemando coco y aprendiendo.

Por cierto, has visto algo raro en el otro código de pulsando o manteniendo pulsado?


Saludos ;)

igorreal

#13
Apr 14, 2010, 11:20 pm Last Edit: Apr 14, 2010, 11:22 pm by igorreal Reason: 1
La verdad que no me lo he mirado.... Lo que quería explicar es como abordar un programa de otra manera diferente a la habitual.

En mi opinión, resolver un problema pensado en programación de estados (Finite State Machine), es una manera que facilita muchísimo el ponerse luego manos a la obra y tener todos los casos acotados. A parte de ser fácil de escribir con papel y boli para pensar el algoritmo a resolver.

De hecho, en muchos autómatas (grafcet), en Matlab(Stateflow),... se usa este módelo de programación directamente (método gráfico).

Creo que hay algun proyecto para utilizarlo en Arduino...

Como te ha parecido al leerlo...¿lo has entendido? ¿Te parece más fácil de esta manera?



111---111

Desde luego, mucho mas claro, la primera vez que vi el switch case empecé a entender y a agregar mas codigo sin mucha complicación.

Go Up