PORFAVOR - ayuda con servos

Hola cracks,

estoy intentando controlar la posicion de un servo mediante un potenciometro con arduino mega. Un primer problema es que no me funciona la libreria servo. Asi que me voy implementando yo el programa.

Los pasos que sigo son:

1)leo el angulo
2)envio el anglo en ms
3) el servo se mueve

Lo malo es que no se mueve tal y como digo, por ejemplo lo queiro mover 45º...xo se mueve lo que quiere.

Me he leido un momnton de teoria sobre servos y no acabo de pillar el concepto.

necesito AYUDA!!

PD: El codigo que utilizo es:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 2, 3, 4, 5, 6, 7, 8, 9, 10);

float val = 0;
int spin = 13;
float temps = 0;
int vegada = 1;
float t = 0;

void setup(){}

void loop()
{
if (vegada<20) //solo lo repito una vez para
// ver solo un movimento
{
//
temps = analogRead(0); //Capto el valor del potenciometro
t = (((temps*0.15)/60)*1000); //priero lo escalo a grados y luego lo passo a ms

digitalWrite(spin, HIGH); // On motor
delayMicroseconds(t); // teoricamente ponendo el tiempo correspondienta al angulo
digitalWrite(spin, LOW); // off
delayMicroseconds(2000-t); // 20 millisecond delay is needed between pulses

vegada++;
}else{
vegada=50;}

//Muestro por pantalla
val = ((analogRead(0)*360.00)/1023.00);
//val = analogRead(0);
delay(10);
lcd.print("ANGULO: ");
lcd.print (val);
lcd.home();
// Fin - muestro por pantalla

}

GRACIAS DE NUEVO!!!

He mirado el código en plan rápido, pero...

delayMicroseconds(2000-t); // 20 millisecond delay is needed between pulses

20 milisegundos = 20.000 microsegundos. No debería ser delayMicroseconds(20000-t);??

De todas formas, no es imprescindible que los pulsos "bajos" sean exactamente de 20ms, con un delay(20); es mas que suficiente.

¿has probado la librería softwareservo? (Arduino Playground - Servo) A mi me ha funcionado muy bién, y no te deja el arduino bloqueado (como hacen los delays)

¡Suerte! Ya nos contarás que tal

Hola!

· Primero muchas gracias por contestar!!

· Segundo, teienes razon con lo de los 20000 del delay.

·Tercero, ya se cual era el problema con la libreria. El problema era que yo tengo el arduino mega, i la libreria es para el deumilenove (el normal).
Asi que buscando por el link que me pusiste, encontre la libreria "MegaServo". I si que me funciona!

No obstane me hace rabia el no haber podido regularlo por mi cuenta, ya que he dedicado muchas horas a leerme la teoria de los servos, xo no he conseguido aplicarla, y claro con la libreria funciona xo no acabo de entender como, jeje.

Muchas gracias por todo!!!

¡Bien!
Lo primero es que funcione... ahora toca lo mas divertido, averiguar porque funciona :stuck_out_tongue:

Estoy echando un vistazo a tu código...

temps = analogRead(0); //Capto el valor del potenciometro
t = (((temps*0.15)/60)*1000); //priero lo escalo a grados y luego lo passo a ms

posibles fallos:

temps está declarado como Float, pero analogRead devuelve un integer. No me fio de las conversiones a pelo, prefiero especificarlas... arduino me ha hecho cosas raras con eso
temps = float(analogRead(0));

caso 90º, potenciometroa la mitad, lectura 512
(((temps*0.15)/60)1000) = 1280 (deberia ser 1500)
caso 0º, lectura en el potenciometro 0
(((temps
0.15)/60)1000) = 1000
caso 180º, lectura en el potenciometro 1024
(((temps
0.15)/60)*1000) = 2560
los valores superior e inferior dependen del servo, pero están "descentrados", asi que no funcionaría

No acabo de entender el porque de toda esa fórmula, pero no sería mejor usar un map?
map(value, fromLow, fromHigh, toLow, toHigh)
t=map(temps,0,1024,limite_inferior_servo,limite_superior_servo) (algo asi como 1250,1750 o 1000,2000 o 750,2250 según se coma tu servo, pero centrado en 1500, que suele ser el neutral)

con eso tienes en t el tiempo en us (micro secondos, que no ms, milliseconds), así que podemos usar los delays... peeeero no hace falta trabajar en floats. Tanto analogRead como map son integer.

En fin, espero haberme explicado, que estoy en el curro. Esta noche en casa probaré el código..

buenas,

Pues tienes toda la razon. El problema es que soy novato en el mundo arduino y no me havia fijao en la instruccion "map()" jeje.

Lo que me fastidia es k no acabo de ver el funcionamiento, ya que en un principio me gustaria controlar completamente el movimento y no lo acabo de enteder.

Me he estado empoyando la teoria de servos y puedo hacer el siguiente resumen:

Haver primero hay que tener claro que los servos se mueven por impulsos. Asi que si controlamos los impulsos controlamoes el movimento del servo. Estos impulsos el servo los lee en intervalos de 20ms. Veamos una grafica.

|' ' ' ' ' ' ' '|
----| |----------------------- (digamos que esto es una
senyal quadrada)
[..TI_ON...]
[......TI_OFF............]
{.............T_total....................}

TI_ON: seria el tiempo que la senyal esta en "ON"
TI_OFF: seria el tiempo que la senyal esta en "OFF"
T_total: Tiempo total, que serian los 20ms

OK, entonces, a mas cantidad de pulsos en un intervalo de 20ms, mas posiciones se mueve el servo.
Para controlar el numero de pulsos lo podemos hacer variando el T_ON, de manera que el cuanto menor sea el tiempo que esta en On, mayor numero de pulsos cabran en 20 ms.

Muy bien, eso es lo que he entendido yo de los servos. No se si estoy en lo cierto, pero vamos...es lo que he extraido yo de la teoria.

Teniendo esto claro no acabo de entender pk no hay manera de que pueda controlar la posicion.
Tampoco entiendo los estandares que hay marcados con los tiempos de 1500 etc..Ya que estan hechos para servos de 180º, xo el mio es de 360.

La verdad es que estoy un poco perdido...

PD:Menudo rollo os he metido...xo me he kedao agusto!jeje ;D

Creo que te has confundido con la teoria de servos. Es mas bién algo asi como:
P es el tiempo del pulso, lo que controla la posición del servo. entre 1 y 2 ms habitualmente, (o 1000 y 2000 us, microsecundos), pero esos valores pueden variar. Lo que si es normal es que estén centrados en 1500us.
Ese pulso debe ser seguido por 20ms de señal baja. (Para ser estrictos, 20ms - p, pero si le pones 20 funciona igual :P)

/-------
| |
| |
| |_______________________
--p--
----------------- 20ms --------------

Un ejemplo práctico:

#include <Servo.h> 

int servoPin = 9;       // the number of the output pin for the servo
int ledPin = 13;

int angulo = 90;        // Valor inicial del servo
int ampl = 900;
int pulso = 0;
long tiempo = 0;

void setup()
{

  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  pinMode(servoPin, OUTPUT);

  digitalWrite(servoPin,LOW);
  digitalWrite(ledPin,LOW);

}

void loop()
{
  /* lanzar los pulsos que el servo necesita para controlar su posición, teniendo en cuenta que:
   *  90º = 1500us
   *  180º = 1500us + ampl
   *  0º = 1500us -ampl
   */
  pulso = map(angulo,0,180,1500-ampl,1500+ampl);
  digitalWrite(servoPin,HIGH);
  delayMicroseconds(pulso);
  digitalWrite(servoPin,LOW);
  delay(20);
  if ((millis() - tiempo) > 500)
  {
    angulo = angulo + 5;
    tiempo = millis();
    if (angulo > 180) {
      angulo = 0;
    }
  }
}

Un pequeño código que hace recorrer el servo desde 0 a 180. En este caso, los valores de pulso van de 550 a 2450.

Sobre los servos de 360º... en realidad no son servos propiamente dichos... son servos que han sido "trucados", eliminandole el "control de posición". Normalmente se usan para ruedas de robot, y su funcionamiento es algo asi como:

Si le mandas el pulso de 1500 (es decir, 90º), el servo trucado entienda que "está en posición", por lo que no hace girar la rueda.

Si le mandas una posicion mayor o menor a los 90º, el servo entiende que no está en ese angulo, así que empieza a girar para colocarse. Pero al haberse eliminado el control de posición, el pobrecillo servo nunca la alcanza, por lo que gira continuamente. A mas diferencia con los 90º, mayor velocidad de giro.

Pero en un servo de 360º no pudes decirle "ponte en 10º". Ni tienes control sobre cuantos grados ha girado, todo sea dicho. Para eso necesitas un motor paso a paso.

Buenas,

Pobrecillo servo jeje, oye me has dejado todo clarisimo!!! Te agradezco infinitamente tu aporte ya que es claro y conciso!

Ahora ya entiendo la naturaleza del servo, gracias a ti, y ahora ya se como programarlos. Evidentemente no me saldra a la primera me imagino, xo ya entiendo la filosofia que es lo mas importante!!

Muchas gracias pro tu tiempo.
Ojala este post lo lea mucha gente, porque por lo que he podido leer por el foro hay mucha gente que desconoce el funcionamiento o no le sale. Si leyeran tu explicacion les quedaria mucho mas claro!

Y repito gracias! :slight_smile: