This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Como hacer una rampa de aceleración?
#1
Buenas a tod@s:

Estoy colaborando con un proyecto Arduino donde quieren crear un robot controlado mediante el mando de la Wii (Nunchuck).

Ayer pudimos conseguir sacar los valores del mando y mediante el acelerometro del mando hacer girar un motor. Si inclinabamos el mando hacia delante el motor giraba en un sentido, si lo manteníamos estable en una posición media se quedaba quieto y si lo inclinabamos hacia atrás giraba en el sentido contrario.

El siguiente paso es que, a medida que se vaya inclinando vaya acelerando, y que cuando vuelvas hacia la posición central (donde se queda parado), pues que vaya decelerando.

Supongo que eso se tendría que hacer mediante el bucle for.

Aquí os adjunto el código que queremos modificar:

Código:
#include "Wire.h"
#include "WiiChuck.h"

WiiChuck chuck = WiiChuck();

const int controlpin1 = 2;  
const int controlpin2 = 3;
const int enablepin = 9;

// int motorenabled = 0;
//int motorspeed = 0;
// int motordirection = 1;

int yMap = 0;

  // int yJoy = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(controlpin1, OUTPUT);
  pinMode(controlpin2, OUTPUT);
  pinMode(enablepin, OUTPUT);
  digitalWrite(enablepin, LOW);
  chuck.begin();
}

void loop()
{

    digitalWrite(enablepin, HIGH);
  
  chuck.update();
  Serial.println("-----------------------");
Serial.print("Eje X: "); Serial.print((int)chuck.readAccelX()); Serial.println();
Serial.print("Eje Y: "); Serial.print((int)chuck.readAccelY()); Serial.println();
Serial.print("Eje Z: "); Serial.print((int)chuck.readAccelZ()); Serial.println();
Serial.println();
Serial.print("Joystick X: "); Serial.print((int)chuck.readJoyX()); Serial.println();
Serial.print("Joystick Y: "); Serial.print((int)chuck.readJoyY()); Serial.println();
Serial.println();
Serial.print("Boton Z: "); Serial.print((int)chuck.zPressed()); Serial.println();
Serial.print("Boton C: "); Serial.print((int)chuck.cPressed()); Serial.println();
Serial.println();
Serial.println("-----------------------");
delay(10);

yMap = (int)chuck.readAccelY();
    if (yMap >= 0 && yMap <=100){
    digitalWrite (controlpin1, LOW);
    digitalWrite (controlpin2, LOW);
  }
  
  
  
  if (yMap <0){
    digitalWrite(controlpin1, HIGH);
     digitalWrite(controlpin2, LOW);
  }
  if (yMap > 100){
    digitalWrite(controlpin1, LOW);
     digitalWrite(controlpin2, HIGH);
  }
  
  
  
}

Sé que en lugar de HIGH tenemos que poner un valor entre 0 y 255 para calibrar la velocidad del motor y controlarlo mediante un pin PWM. Pero nunca he trabajado con el bucle for (sé más o menos su funcionamiento), pero la principal duda es como modificar el valor de la velocidad del motor en función del valor obtenido del mando de la wii.

Muchas gracias de antemano.
  Responder
#2
Yo no se de esto puesto ke soy nuevo en el mundo atduino. Pero metiendo una funcion ke vaya comparando el valor del mando cada cierto tiempo ( segundo o milisegundo)??? No se si se puede hacer.
  Responder
#3
Buenas a tod@s:

Pero creo que esto que comentas es demasiado complicado. Creo que se puede hacer más sencillo, pero no sé el como.
  Responder
#4
Tan solo tienes que restar el valor de yMap.

Ejemplo valor de Ymap es 15.

Velocidad del motor.

255 - Ymap = 240;

Si yMap cambi a 55.

255 - yMap = 200.


Saludos Jero
  Responder
#5
Buenas a tod@s:

Jero lo que quiero es que con esa parte del códgi cambiar el HIGH por un valor variable de 0-255:

Código:
if (yMap <0){
    digitalWrite(controlpin1, HIGH);
     digitalWrite(controlpin2, LOW);
  }
  if (yMap > 100){
    digitalWrite(controlpin1, LOW);
     digitalWrite(controlpin2, HIGH);
  }

No quiero cambiar el valor de yMap ya que entonces podría variar el compoartamiento que yo quiero. yo quiero cambiar el valor de:

if (yMap <0){
digitalWrite(controlpin1, HIGH);
digitalWrite(controlpin2, LOW);
}
if (yMap > 100){
digitalWrite(controlpin1, LOW);
digitalWrite(controlpin2, HIGH);
}

Los HIGH marcados en negrita quiero que tomen un valor de 0 a 255 o de 255 a 0 en función del valor de inclinación de yMap.

Thanks Guiño
  Responder
#6
Pues tendras que hacer un valor que sea la aceleracion, que vaya aumentando el PWM progresivamente con alguna funcion de rampa.... O similares, que partiendo de cualquier valor te llege a 255 o a 0 como limites
  Responder
#7
Triggerr escribió:Pues tendras que hacer un valor que sea la aceleracion, que vaya aumentando el PWM progresivamente con alguna funcion de rampa.... O similares, que partiendo de cualquier valor te llege a 255 o a 0 como limites

Buenas a tod@s:

Pero yo quiero que esa rampa de aceleración vaya en función de la inclinación del mando. Es decir que sea variable.

Por lo tanto si solo inclino un poco el mando hacia delante y lo dejo a X grados me acelere hasta X velocidad y me la mantenga. Si inclino un poco más el mando me acelera un poquito más y me mantenga la velocidad. Si inclino hacia atrás el mando me desacelere y si lo llevo hasta el punto medio se vaya desacelerando el motor hasta detenerse.

Es decir, la rampa de aceleración no tiene que ser una rampa fija, sino que tiene que ser variable en función de la posición del mando.
  Responder
#8
Dentro del if crea una variable.

Int inclinacion = 255 - yMap;
Digitalwrite(controlpin2, inclinacion);

La referencia Ymap supongo que tendrá los grados de inclinación.


Si no siempre, puedes hacer un case switch.

Estoy desde el movil, pero creo que se entiende.

Saludos
  Responder
#9
Buenas a tod@s:

Sí Jero. Gracias
  Responder
#10
facil electromecanico utiliza la funcion MAP

mira este ejemplo:

void loop() {
// lee el valor(en este caso es un potenciometro conectado en A0):
int val = analogRead(0);
// mapea el rango de salida(el valor leido anteriormente se transforma en un valor de salida que es proporcional):
val = map(val, 0, 1023, 0, 255); //(esta es la funcion de mapeo)
// cambia el valor de salida:
analogWrite(9, val);
}


en fin con esta funcion puedes cambiar el valor tomado por la inclinacion del control WII en un valor de acceleracion de salida proporcional para tu juguetito Mola

para mayor informacion lee esta pagina http://arduino.cc/en/pmwiki.php?n=Reference/Map
  Responder
#11
Buenas a tod@s:

Gracias MonoPensante. Me gusta tu código. Creo que es el que utilizaré
  Responder
#12
Si quieres poner 0 o 255 pueded usar analogWrite( ), es lo que se suele hacer para señal PWM
  Responder
#13
Andrew_10 escribió:Si quieres poner 0 o 255 pueded usar analogWrite( ), es lo que se suele hacer para señal PWM

Buenas a tod@s:

La señal PWM sé como funciona, ya he trabajado anteriormente con ella. Pero hasta la fecha siempre lo había hecho de forma estática. Se le daba un valor y listos.

En este caso, quiero que el valor PWM en función de yMap, que es la variable que guarda el valor de inclinación del mando de la Wii, haciendo que la señal PWM aumente a medida que el yMap también aumente o que a medida que la variable yMap disminuya también lo haga el señal PWM.

Creo que lo que comentó MonoPensante es lo que yo necesito ^^

Gracias.
  Responder
#14
Necesitas una interrupcion periodica con un timer.
Asi mas o menos:
Código:
PeriodicInterrupt ()  // Cada 10000us o sea 10 ms o sea 100 veces por segundo
{
   VelocidadX = VelocidadX + (Xmap * FactorX);
   VelocidadY = VelocidadY + (Ymap * FactorY);
}

void setup()
{
    SetupInterrupt (PeriodicInterrupt, 10000);  // Configura para llamar a PeriodicInterrupt cada 10000us o sea 10 ms
}

Loop ()
{
// Aqui tus cosas
}

En SetupInterrupt() tienes que configurar un timer y hacer attachinterrupt y eso..

Entonces cada 10ms, o sea 100 veces por segundo, los valores VelocidadX y VelocidadY se incrementan de acuerdo con el valor de Xmap y de Ymap y del factor de cambio FactorX y FactorY.
Por supuesto debes ajustar los datos a tu aplicación, a lo mejor es mejor 100ms (diez veces por segundo), y tienes que ver que valores para FactorX y FactorY te son mas adecuados.
  Responder
#15
void setup(){

#define motor A1
#define mando A2

}

void loop(){

byte mando_regulado = map(mando, 0, 1023, 0, 255);

analogWrite(motor, mando_regulado);

}
  Responder
#16
Buenas a tod@s:

Muchas gracias a todos Sonrisa

Como dije, ya solucioné el problema, pero está bien saber de distintas formas como se puede solucionar el mismo problema
  Responder
#17
Electromecánico escribió:Buenas a tod@s:

Muchas gracias a todos Sonrisa

Como dije, ya solucioné el problema, pero está bien saber de distintas formas como se puede solucionar el mismo problema

cual fue la solucion que ocupaste?
como sabes cualquier aporte puede servir de ejemplo a otros.

saludos
  Responder


Posibles temas similares…
Tema Autor Respuestas Vistas Último mensaje
  CONSULTA Cómo puedo hacer un colorimetro casero con arduino? erjavi_zgz 1 238 18-08-2022, 11:49 PM
Último mensaje: pano
  APORTE Como hacer un drone con Arduino paso a paso. Explicado. DroneArduino 6 2,865 30-08-2021, 06:16 PM
Último mensaje: Lab.Gluon
  CONSULTA ¿Como hacer que ejecute ultima version del IDE? AcoranTf 1 715 17-06-2020, 10:56 PM
Último mensaje: asesorplaza1
  Cómo configurar una placa Freaduino y un módulo HC-05 Bluetooth ernestot87 4 2,672 27-11-2016, 01:39 PM
Último mensaje: Iván
  buzzer hace ruido que no deberia hacer homer32 0 1,192 22-09-2016, 07:28 PM
Último mensaje: homer32