Librería ps2x + stepper -> velocidad máxima de lectura mando

Hola buenas.
Estoy inmerso en un proyecto en el que quiero manejar un par de motores steppers con un mando dual shock de PlayStation 2.
Estoy usando la librería ps2x y funciona correctamente.

Solo hago uso de los joystics del mando.
Cuanto más activado/inclinado esté el joystick más rápido se tiene que mover el motor stepper. Ese es el objetivo.
El problema es que haciendo código básico para leer el mando (ps2x.read_gamepad) y leyendo el número de vueltas que hace por segundo, me salen unas 60 lecturas de mando por segundo. Si en cada vuelta tengo que hacer que el stepper se mueva UN SOLO PASO con el delay que le marque en función de lo que haya leído el mando, eso quiere decir que se va a mover 60pasos *0,9 grados/paso = 54 grados. Lo cual es bastante bastante lento.
No se cómo puedo hacer que se mueva más rápido, pues si por cada vuelta del loop le meto que haga 2 o 5 pulsos, se moverá más rápido pero también se notarán trompicones. 5 pasos rápidos - lectura mando - 5 pasos rápidos - lectura mando....
E intentando entender la librería y modificarla para leer solo los joysticks y prescindir del resto de datos no lo consigo. Entre que no soy para nada experto y que no hay quien entienda lo que hace el método _gamepad_shiftinout...

Alguien me podría dar una idea de cómo harían para aumentar la velocidad de los steppers y que vaya fluido?
Muchas gracias!

Estaría bueno ver tu código, sino es tirar ideas a ciegas.

El código sería algo así, y luego lo mismo para el otro motor:

#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

int MOTOR_ALT_STEP = 3;
int MOTOR_ALT_DIR = 2;
int MOTOR_AZIM_STEP = 5;
int MOTOR_AZIM_DIR = 4;

int CLOCK = 7;
int COMMAND = 11;
int ATTENTION = 10;
int DATA = 12;

int error = 0; 
byte type = 0;
byte vibrate = 0;

void move_stepper_joystick(int pin, int32_t tiempo) {
  digitalWrite(pin, HIGH);
  delay((long)(tiempo/10000));
  digitalWrite(pin, LOW);
  delay((long)(tiempo/10000));
}

int32_t map_mio(long x, long in_min, long in_max, long out_min, long out_max)
{
  long result = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  int32_t form_result = (int32_t) result;
  return form_result;
}

void setup(){
 Serial.begin(57600);

 pinMode(MOTOR_ALT_STEP, OUTPUT);
 pinMode(MOTOR_ALT_DIR, OUTPUT);
 pinMode(MOTOR_AZIM_STEP, OUTPUT);
 pinMode(MOTOR_AZIM_DIR, OUTPUT);

 //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************
  
 error = ps2x.config_gamepad(CLOCK, COMMAND, ATTENTION, DATA, true, true);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
 
 if(error == 0){
   Serial.println("Found Controller, configured successful");
   Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
   Serial.println("holding L1 or R1 will print out the analog stick values.");
   Serial.println("Go to www.billporter.info for updates and to report bugs.");
 }
   
 else if(error == 1)
   Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
   
 else if(error == 2)
   Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
   
 else if(error == 3)
   Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
   
   //Serial.print(ps2x.Analog(1), HEX);
   
   type = ps2x.readType(); 
     switch(type) {
       case 0:
        Serial.println("Unknown Controller type");
       break;
       case 1:
        Serial.println("DualShock Controller Found");
       break;
       case 2:
         Serial.println("GuitarHero Controller Found");
       break;
     }
  
}


void loop(){
   /* You must Read Gamepad to get new values
   Read GamePad and set vibration values
   ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
   if you don't enable the rumble, use ps2x.read_gamepad(); with no values
   
   you should call this at least once a second
   */
   
  if(error == 1) //skip loop if no controller found
  return; 

  ps2x.read_gamepad(false, vibrate);

  int value_x = ps2x.Analog(PSS_LX);
  
  // movimiento en horizontal
  int desv_x = value_x - 128;
  int abs_dev_x = abs(desv_x);
  if(abs_dev_x > 30)
  {
    Serial.println("Movimiento HORIZONTAL");
    Serial.println(desv_x);
    if (desv_x > 0)
    {
      digitalWrite(MOTOR_AZIM_DIR, LOW);
    }
    else
    {
      digitalWrite(MOTOR_AZIM_DIR, HIGH);
    }
    int32_t tiempo_x = map_mio(abs_dev_x,30,128,15000,100);
  
    move_stepper_joystick(MOTOR_AZIM_STEP, tiempo_x);
    //Serial.println(tiempo_x);
  }

}

Y lo que decía, es que si yo hago esto. que básicamente es leer el mando y contar loops en un segundo, era cuando me salían 50-60 vueltas/segundo

void loop(){
   /* You must Read Gamepad to get new values
   Read GamePad and set vibration values
   ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
   if you don't enable the rumble, use ps2x.read_gamepad(); with no values
   
   you should call this at least once a second
   */
  currentMillis = millis();
  loops++; 
  if(error == 1) //skip loop if no controller found
  return; 
  
  ps2x.read_gamepad(false, vibrate);
  //int value_x = ps2x.Analog(PSS_LX);
  //int value_y = ps2x.Analog(PSS_RY);

  if(currentMillis - lastMillis > 1000){
    Serial.print("Loops last second:");
    Serial.println(loops);
    
    lastMillis = currentMillis;
    loops = 0;
  }
   
}

En move_stepper_joystick() hay un problemón

delay((long)(tiempo/10000));

tiempo puede tener un valor entre 100 y 15000 (según map_mio()) pero cualquier valor por debajo de 10000 va a hacer que el delay sea de 0 mseg.

El mayor problema que veo es que la librería usa delay(), así que es bloqueante, y te impide hacer tareas con más velocidad que las que imponen esos delays (por eso el loop() del 2do código demora unos 20 mseg).
Además tiene varios errores de concepto, como guardar millis() en una variable double por ej., siendo que el resultado de millis() es un entero largo sin signo por lo que nunca va a tener decimales.

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