Problema con posición de servos Arduino

Hola. Estoy trabajando en un proyecto de feria de mi instituto.
Es un robot humanoide de 17 servomotores, estoy utilizando Arduino UNO y el módulo PCA9865.

El problema es el siguiente:
Cuando estoy programando todo va bien, las posiciones responden bien, pero el problema viene cuando ya dejó de trabajar con el robot y desconectó y lo guardo.
Cuando vuelvo a conectar todo para continuar con la programación de la secuencia que quiero lograr, pues las posiciones no cogen el ángulo en qué estaba la otra vez, y vuelvo y subo el programa a Arduino y sigue con esa posición diferente, es como si el ángulo 50 cambiara y no es el mismo que el de la otra vez.

Con el robot lo que quiero lograr es una secuencia de movimientos para hacer una demostración de éste, ya sea que camine y salude, etc.

El código que utilizo es este.
Nota: es solo un ejemplo.
C++:
#include <Wire.h>

#include <Adafruit_PWMServoDriver.h>


Adafruit_PWMServoDriver servos = Adafruit_PWMServoDriver(0x40);


unsigned int pos0=172; // ancho de pulso en cuentas para pocicion 0°

unsigned int pos180=565; // ancho de pulso en cuentas para la pocicion 180°


void setup() {

  servos.begin();

  servos.setPWMFreq(60); //Frecuecia PWM de 60Hz o T=16,66ms

}


void setServo(uint8_t n_servo, int angulo) {

  int duty;

  duty=map(angulo,0,180,pos0, pos180);

  servos.setPWM(n_servo, 0, duty);

}


void loop() {

 

    setServo(0,30);

    setServo(2,90);

    setServo(4,180);

    setServo(6,120);

    setServo(8,0);

    setServo(10,30);

    setServo(12,90);

    setServo(14,170);

    delay(1000);

    setServo(1,30);

    setServo(3,90);

    setServo(5,180);

    setServo(7,120);

    setServo(9,30);

    setServo(11,90);

    setServo(13,180);

    setServo(15,120);

    delay(1000);

    setServo(0,120);

    setServo(2,180);

    setServo(4,90);

    setServo(6,60);

    setServo(8,45);

    setServo(10,160);

    setServo(12,170);

    setServo(14,30);

    delay(1000);

    setServo(1,120);

    setServo(3,0);

    setServo(5,90);

    setServo(7,60);

    setServo(9,120);

    setServo(11,180);

    setServo(13,0);

    setServo(15,30);

    delay(1000);

  

}
 
Última edición por un moderador:
O tendrás que usar un encoder (rotativo podría ser) en cada articulación , o tendrás que poner un final de carrera a cada movimiento de manera que al iniciar el robot éste haga los movimientos hacia los finales de carrera y desde allí pueda considerar "el cero"
 
Como te dice dosmetros, no podes esperar que un robot con los motores sin alimentacion mantenga la ultima posicion alcanzada.
Lo que hay que hacer es realizar una secuencia de inicializacion al alimentar el control, detectar los extremos del recorrido de cada articulacion y a partir de ahi encontrar la posicion central de cada eje...al menos como ejemplo
Si no sabes lo que es un codificador optico incremental para determinar la posicion de los motores, estas empezando muuuuy maaaaal y te recomiendo estudiar el tema antes de seguir.
 
Los robots no pueden estar haciendo movimientos como un cnc.
Lo podes solucionar utilizando un potenciometro como los servos de los RC entonces asocias valores de tensión al angulo de posición lo cual es mucho más racional
 
Los robots no pueden estar haciendo movimientos como un cnc.
Lo podes solucionar utilizando un potenciometro como los servos de los RC entonces asocias valores de tensión al angulo de posición lo cual es mucho más racional
Lo que se hace con los robots industriales es usar un codificador óptico con un índice en el centro del recorrido, de esa forma el brazo se ubica en la posición central sin buscar los extremos. Pero eso requiere un diseño mecánico y electrico que no tiene nada que ver con un servo, por que hay que alinear la caja reductora del motor con la marca del centro del recorrido del encoder. Nosotros hemos controlado un Bosch SR-800 y trabajaba de esa forma, pero si no hay soporte por hardware no hay otra forma de hacerlo.

Si usa "servos" es peor, por que los servos tienen potenciómetros internos pero en forma de realimentación local de posición y con señales invisibles desde el exterior. Acá hemos desarmado servos y hemos abierto el lazo de realimentación para poder usar controladores externos, pero entonces el control de los servos ya no es posible con las bibliotecas estándard de Arduino y hay que armar controladores de posición por software (fácil) y se pueden agregar controladores de velocidad (un poquito mas difícil) que los servos no tienen.

Lo que yo siempre me pregunto es: por que hay docentes que no tiene NPI de electrónica/software/robótica y les piden a sus alumnos trabajos que son casi imposibles de realizar con el nivel de formación que tienen?????

Parte 2:
Otra cosa que hay que analizar es que diablos hace el Arduino con sus bibliotecas de control de servos y como diablos es la estructura del robot. Es fácil tirar comandos en C para el Arduino, pero cuando aparecen estos problemas no hay NPI que es lo que sucede...
 
Última edición:
Además de lo que comenta el @dr-zoidberg el propio proceso de puesta a "Cero" posee su complejidad intrínseca.
Para garantizar un error despreciable del sistema mecánico se toman varias medidas del punto "0", saliendo de este y volviendo a el unas 3 veces.
Si existieran diferencias groseras entre el valor que se programó mover y el que realmente se movió, la máquina (O lo que sea se bloquea) todos se van a tomar cerveza.
Si esas diferencias se encuentran dentro de valores "Aceptables" se toma como válido de referencia de "0" el promedio de mediciones.
 
Esto no es un robot industrial, solo tomo algunas cosas, nosotros atendemos y hemos diseñado varios robot para distintas tareas.
En estos robots hay que tener en cuenta ciertas circunstancias inherente a cada caso en particular
El caso más común y muy crítico por cierto desde el punto de vista "Seguridad" y es que sucede ante una falla de energía.

En tales situaciones por ejemplo los que cargan cosas ante la falta de energía no la pueden soltar.
Los que sueldan no pueden arrancar de nuevo soldando. y así según cada tarea.
Tampoco pueden posicionarse en el medio de la escala eso no lo hace níngun robot.
Cuando un robot se apaga se va alo que se llama posición de reposo, cuando arranca va a la posición de "Inicio"
Esto se puede hacer en este caso, para no utilizar un caro encoder, con un potenciometro.
No estoy inventando nada, ya se lo hemos recomendado a otros chicos para ferias presisamente.

Hay una plataforma muy interesante, como Maximite, es semejante a arduino y muy potente
 
Tampoco pueden posicionarse en el medio de la escala eso no lo hace níngun robot.
Cuando un robot se apaga se va alo que se llama posición de reposo, cuando arranca va a la posición de "Inicio"
El el BOSCH SR-800 la posición de inicio es al medio de cada articulación, excepto la "muñeca+antebrazo" que queda en el fin de carrera superior. Es un robot básicamente posicionador.
 
Muchas gracias, algo solo para aclarar:
Yo lo que estoy haciendo con el robot es lo siguiente; en el void loop pongo una secuencia de movimientos para que se ejecuten cómo está en el ejemplo que les puse al inicio. Yo con el robot quiero lograr que este se vea ''indepentiente'' aunque sabemos que no lo es porque solo hace cosas que les puse que haga. Eso de los potenciómetros es una buena idea pero no es lo que quiero para este proyecto.

Otra cosa para aclarar: cuando mencioné que dejó de trabajar ya sea para descansar y desenergizo el proyecto completo osea los servos y la tarjeta Arduino UNO. Obviamente los servos no trabajan (ES OBVIO) Pero el problema mío viene cuando vuelvo a querer a trabajar y alimento el proyecto completo (Arduino, servos) pues la posición que puse anteriormente no está, y vuelvo y subo el código con los mismos ángulos y se queda así mismo, por ejemplo: es como que la posición que pongo ya sea angulo 50, después que apago y vuelvo es como si en físico ese no es el ángulo 50, como si el 50 es 70 osea como que cambia no sé si me explico bien.

La solución sería como hacer que cuando encienda todo pues coja un ángulo inicial y apartir de ahí se ubique correctamente para colocarse en el ángulo correcto que le programe
 
A eso me refería, una posición inicial o de reposo cuanso de termina de utilizarlo, de esa forma no necesitas cargar todo de nuevo, esa era la idea
 
Vale entiendo, dime si es como lo tengo, pongo todos los servos en una posición que el robot se quede parado, y les pongo un delay de 1 minuto, y apartir de ahí que camine, salude y vuelva a caminar etc. Y después vuelvo y lo pongo en la posición del principio osea que se quede parado,¿ Ese sería el reposo/inicial?
Osea cuando está parado
 
En el código que estoy usando con dos botones y un servomotor, los botones deben aumentar y disminuir.
El servo SG90 se mueve de 0 a 180, con los dos botones quiero controlar el ángulo inicial que es 0, es decir, al aumentar o disminuir el ángulo de inicio.
Esto se mueve automáticamente de acuerdo con ese ángulo de inicio, por ejemplo, si lo cambio con los botones a 30, el servomotor se mueve de 30 a 180 y regresa de 180 a 30.
Solo se modifica el ángulo inicial y luego quiero leerlo en el terminal en serie donde me muestra el ángulo inicial que se mueve y el ángulo final que es 180.
C++:
#include <Servo.h>

Servo myservo;

int suma=8;
int resta=4;
int pos = 0;

int inicial = 0;

void setup(){
  Serial.begin(9600);
  pinMode(suma,INPUT);
  pinMode(resta,INPUT);
  myservo.attach(9);
  myservo.write(pos);
}

void loop(){
  myservo.write(pos);

  for(int pos=inicial; pos<=180; pos++){
   myservo.write(pos);

        Serial.println(pos);

    if(digitalRead(8) == HIGH && inicial < 180){
    inicial = inicial + 1;
  }
      
  if(digitalRead(4) == HIGH && inicial > 0){
    inicial = inicial -1 ;
  }
   }
}
El problema del código es que usa un bucle for y no se lee bien con el terminal en serie y el movimiento no es de 0 a 180 y 180 a 0, obviamente cambiando el ángulo inicial de acuerdo con los botones.
¿Alguien puede ayudarme?

Gracias.
 
Como aquí se está escribiendo sobre el uso de codificadores ópticos quiero indicar la opción de usar codificadores magnéticos. Estos proven unas señales PWM de cuadratura. Son 3 señales pwm, siendo unas la del índice. Lo bueno es quer muchos controladores ARM por ejemplo tienen la funcionalidad del "quadrature encoder" que toma como entradas las 3, A, B e I. Así al iniciar se pone el impulso de "I", allí donde se tiene una posición definida.
 
Buenas, quería preguntar si alguien sabe porque me vibra un servomotor cuando le meto este codigo al rotar el potenciometro

1590720971040.png En la simulación de tinkercard me va bien, pero cuando lo engancho a un servo, como que se mueve pero se va atascando. Uso Arduino UNO.
 
Atrás
Arriba