Go Down

Topic: [SOLUCIONADO] Mando PS2 (Read 223 times) previous topic - next topic

Ruben17

Jul 21, 2018, 12:43 pm Last Edit: Jul 22, 2018, 05:23 pm by Ruben17
Hola muy buenas, estoy aprendiendo a usar el mando de PS2 con Arduino y me propuse una practica que consiste en activar mediante dos condicionales "if" dos bucles "void". La primea condición es presionar el botón UP para que se active un bucle y presionar el botón DOWN para que se active otro bucle. Esto lo he conseguido con este código:

Code: [Select]

#include <PS2X_lib.h> 
PS2X ps2x;

int LED = 9;

void setup()
{   
  Serial.begin(9600);
  // GamePad(clock, command, attention, data, Pressures?, Rumble?)
  ps2x.config_gamepad(13,11,10,12, true, true);
  pinMode (LED, OUTPUT);   
  Serial.print ("Preparado");
}
         
void loop()
{   
  ps2x.read_gamepad();

  if (ps2x.Button(PSB_PAD_UP))
  {
    Serial.println ("Parpadeo 1");
    Parpadeo1();
  }

  if (ps2x.Button(PSB_PAD_DOWN))
  {
    Serial.println ("Parpadeo 2");
    Parpadeo2();
  }
  delay (100);
}

void Parpadeo1 ()
{
  digitalWrite (LED, HIGH);
  delay (100);
  digitalWrite (LED, LOW);
  delay (100);
}

void Parpadeo2 ()
{
  digitalWrite (LED, HIGH);
  delay (25);
  digitalWrite (LED, LOW);
  delay (25);
}


El problema es que cuando dejo de presionar el botón el bucle deja de estar activado. Y sinceramente no se que podría escribir para arreglarlo. Seguro que el problema es muy básico pero es que aún ando perdido con la sintaxis de programación pero bueno aún no desisto.

Siento seguir usando "delay" en lugar de "millis" pero es que todavía me queda mucho por mirar de los "millis".

Esfinterman

Hola. Leyendo el código, sin ser experto y aprendiz aún, veo que es lógico que deje de funcionar. El código está hecho para que cuando esté presionado el botón en cuestión, se active un bucle, pero no dice que deba mantenerse operativo una vez que lo sueltes. Ahí tienes el problema del planteamiento!! :D

Piensa en lo siguiente. Haz un pequeño sistema para que el programa sepa si lo has pulsado o no de la siguiente manera:

-Cuando pulsas el botón, almacena un 1, por ejemplo, en una variable y con un IF, escribe la condición de que si la variable del botón es 1, que ejecute el programa.
-Cuando vuelvas a pulsar el botón, esa variable decrementará hasta 0, de modo que el bucle acaba ya que la variable ya no es uno.

No veo necesario el uso de los bucles, ya que con las variables y los IF funcionará sin problemas.

Se complica un pelín el programa, pero de esta forma, los cabezazos que nos pegamos contra el ordenador sabrán a gloria cuando el programa funcione. :D Recuerda, una pulsación, incrementa la variable, otra pulsación, si la variable es uno, pues resta 1 y vuelve a ser cero.

Espero haberte aclarado un poco la idea y haber arrojado luz a tu problema!! ;)

Ruben17

#2
Jul 21, 2018, 09:17 pm Last Edit: Jul 21, 2018, 09:18 pm by Ruben17
Si ya veo por donde vas. Intentare con lo que has comentado y ya os contare si ha resultado.

Yo lo había planteado así porque en intentos anteriores si se cumplía una condición "if" le decía que se me encendiese el LED y efectivamente cuando le daba al botón se encendía y aún soltando el botón el LED seguía encendido. Y yo como un ingenuo estaba convencido de que se mantendría activo un bucle cuando se cumplía la condición de un "if" aunque hubiese soltado el botón.

Muchas gracias por tu aportación;)

Esfinterman

De nada!! Si tienes problemas, ya sabes!! Es más, si rebusco por aquí, es muy probable que tenga un código que soluciona tu problema, pero tengo que rebuscar. ;)

Ruben17

#4
Jul 21, 2018, 11:14 pm Last Edit: Jul 22, 2018, 05:29 pm by Ruben17
A ver que tal este código:
Code: [Select]

#include <PS2X_lib.h>
PS2X ps2x;
               
int estado=0;                     

int LED = 9;

void setup()
{
  Serial.begin(9600);
  // GamePad(clock, command, attention, data, Pressures?, Rumble?)
  ps2x.config_gamepad(13,11,10,12, true, true);
  pinMode (LED, OUTPUT);   
  Serial.print ("Preparado");     
}

void loop()
{
  ps2x.read_gamepad();
  Serial.println (estado);
  delay (100);
  if(ps2x.Button(PSB_BLUE)==HIGH)
  {         
    estado=1-estado;
    delay (250);
  }
 
  if(estado==1)
  {                 
    digitalWrite (LED, HIGH);
    delay (100);
    digitalWrite (LED, LOW);
    delay (100);
  }
  else
  {                               
    estado = 0;
  }
}


Hace mas o menos lo que quiero y como base esta bien pero tengo dos problemas.
 
Primero, que hay veces que lo subo a la placa y aunque he declarado estado = 0 se me inicia el código en la placa como estado = 1 y claro, se me inicia el bucle, ya digo que hay veces que pasa esto y otras en la que el código se inicia correctamente con el estado = 0. No se si algo parecido le había pasado antes a alguien.

Segundo, que le doy al botón y no me hace caso a la primera, le tengo que dar varias veces hasta que me hace caso. Tengo entendido que es habitual este problema cuando se trabaja con botones pero también tenía entendido que se solucionaba con un "delay" para darnos el suficiente tiempo para dejar de presionar el botón y no lo he conseguido solucionar. He probado a cambiar  este "delay" pero nada.

Code: [Select]

if(ps2x.Button(PSB_BLUE)==HIGH)
  {         
    estado=1-estado;
    delay (250);
  }


Seguiré trabajando en este código y voy a intentar cambiar los "delay" por "millis" pero me gustaría saber si alguien ve lo que esta mal.

Ruben17

#5
Jul 22, 2018, 05:21 pm Last Edit: Jul 22, 2018, 05:23 pm by Ruben17
Ya tengo solucionado mi problema. Con este código he conseguido mantener activado un bucle al presionar un botón y con otro botón detener el bucle.
Code: [Select]

#include <PS2X_lib.h>
PS2X ps2x;
               
int estado=0;                     

int LED = 3;

void setup()
{
  Serial.begin(9600);
  // GamePad(clock, command, attention, data, Pressures?, Rumble?)
  ps2x.config_gamepad(13,11,10,12, true, true);
  pinMode (LED, OUTPUT); 
  estado = 0;
  Serial.print ("Estado = ");
  Serial.println (estado);
  delay (100);
  Serial.println ("Preparado");   
}

void loop()
{
  ps2x.read_gamepad();
  Serial.println (estado);
  delay (100);
 
  if (ps2x.Button(PSB_BLUE))
  {         
    estado=1;
    delay (50);
  }

  if (ps2x.Button(PSB_PAD_DOWN))
  {
    estado=0;
    delay (100);
  }
 
  if (estado==1)
  {                 
    digitalWrite (LED, HIGH);
    delay (50);
    digitalWrite (LED, LOW);
    delay (50);
  }
}

No es muy sofisticado pero hace lo que se busca. Y además no da problemas como el que proponía antes con un solo botón que tenia que darle varias veces al botón para que hiciese caso. Este código funciona perfecto sin errores.

Esfinterman

Genial!! :D Poco a poco se va aprendiendo y hay que empezar a construir la casa "ladrillo a ladrillo". Ahora, que ya tienes algún conocimiento más de almacenar estados, te queda volver a tu idea original, de pulsar arriba y activar un bucle, y volver a pulsar arriba para detenerlo. Suerte!! ;)

Go Up