SERVOMOTOR , angulo inicial

Buenas tardes, dos consultas por favor :

  1. Cuando activo un servo, en que posición parte , se centra en 90°?

Por ejemplo si yo lo estoy moviendo con un control remoto mandándole los ángulos (dirección de un auto) , cada vez que dejo de enviarle un angulo quiero que vuelva al punto inicial , ¿Cual es ese angulo de inicio?

  1. Puede haber un conflicto con ARDUINO NANO, NRF2401(y sus librerias) y Servo.H, que haga que mi servo tenga alguno tiritones. Lo tengo alimentado con 5v con circuito independiente.

saludos

Hola:

En Ardino Uno me funciona.

#include <Servo.h>
//Creamos una variable servo para poder usar las funciones con ella.
Servo miservo;
int valor = 0;
int angulo;
int x;

void setup()
{
  Serial.begin(115200); // Velocidad en baudios y configuraciçon de inicio.
  //Definimos el pin al que ira conectado el servo.
  miservo.attach(6); Como salida, el pin 6 con uso de PWM.
  //Movemos el servo al centro
  miservo.write(90);  // Coloca el servo en su posición central.
}
void loop() {


  if (Serial.available() > 0) // Espera entrada de datos de 0 a 180.
  {
    valor = Serial.read(); // Los datos leidos se almacena en la variable valor.
    if (valor > 0)
    {
      x = valor;
    }
  }
  else if ((x >= 0) && (x <= 180))
  {
    angulo = x;
    miservo.write(angulo); // Envía los comando finales de 0 a 180 al servo.
  }

Aquí un programa hecho en C# en el cual controlas el servomotor desde el PC y sus ángulos.
DescargarSaludos.

Si tiene tirones es porque usas delay. Mientras no publiques código solo imaginaremos situaciones.

Lee las normas del foro y por favor, cuando plantees algo ayúdanos aportando toda la información relevante a tu tema.

Maestro , favor sus comentarios.

Este es el codigo , no tengo delays.

// recibe datos desde modulo nrf y los reenvia a otro arduino por la puerta serial setada 4,2
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#include <Servo.h>

// para manejar con joystick doble
char Msg[13];
String Mensaje;
String Salida;
RF24 radio(9,10);

const uint64_t pipe = 0xE8E9F0F0E1LL;

Servo miServo; 
int servoPin = 6;  //Direccion delantera
int ang_X = 89;    // derecha / izquierda
int ang_ant = 89;    // derecha / izquierda

// pines motor 1
int M1ACT = 3;
int M1AVA = 7;
int M1RET = 8;

// pines motor 2
int M2ACT = 5;
int M2AVA = 4;
int M2RET = 2;

int AVARET = 2;
int DERIZQ = 2;

int vel = 0;

void setup(void){

  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
  
  pinMode(M1ACT, OUTPUT); 
  pinMode(M1AVA, OUTPUT); 
  pinMode(M1RET, OUTPUT); 
  pinMode(M2ACT , OUTPUT); 
  pinMode(M2AVA , OUTPUT); 
  pinMode(M2RET , OUTPUT); 

  pinMode(servoPin, OUTPUT);
  miServo.attach(servoPin); 
  miServo.write(ang_X); 
  Serial.print("Comenzar a recibir");

}
 
void loop(){
  if (radio.available())
  {
     radio.read(Msg, 12); 
     Serial.print("Msg     :");
     Serial.println(Msg);
     Mensaje = String(Msg);
          
     if  ( Mensaje.substring(0,1)   == "X" &&
           Mensaje.substring(5,6)   == "Y" &&
           Mensaje.substring(10,11) == "B"    ) {
     
           Serial.println("Mesaje valido");
                                               // recupera valores eje Y del Joystick
           DERIZQ = Mensaje.substring(1,5).toInt();
           AVARET = Mensaje.substring(6,10).toInt();

           Direccion();       // Movimiento de Direccion , derecha - izquierda
           Desplazamiento();  // Desplazamiento , adelante - atraz
    
      } else {
        
           Serial.println("Mesaje NO valido , detenemos");
           Detener();             
      }
      
  } else {    
    
      Serial.println("Not available , detenemos ");    
      Detener();                   
  }
  

}

void Direccion()
{
    if (DERIZQ < 490 ) {  // izquierda
      
           ang_X  = map(DERIZQ, 0, 489, 55, 90);

           if   (ang_X > 54 ) {

              miServo.write(ang_X); 

           }
           
    } else {
      
        if  (DERIZQ > 505) {   // derecha
          
              ang_X  = map(DERIZQ, 506, 1024, 90, 125);

              if   (ang_X < 126 ) {

                 miServo.write(ang_X); 

              }
              
        } else {

           if (ang_X != 89) {

              ang_X  = 89;
              miServo.write(ang_X); 

           }
        }
    }
}

void Desplazamiento()
{
    if (AVARET < 510 ) {  // avanza 
      
           vel =  map(AVARET, 509, 0, 0, 255);

           analogWrite(M1ACT, vel);      
           digitalWrite(M1AVA , HIGH);     // Motor 1
           digitalWrite(M1RET , LOW);
           
           analogWrite(M2ACT, vel);                
           digitalWrite(M2AVA , HIGH);     // Motor 2
           digitalWrite(M2RET , LOW);
   
    } else {

      if  (AVARET > 520) {   // retroce

           vel =  map(AVARET, 521 , 1024, 0, 255);

           analogWrite(M1ACT, vel);      
           digitalWrite(M1AVA , LOW);     // Motor 1
           digitalWrite(M1RET , HIGH);
           
           analogWrite(M2ACT, vel);      
           digitalWrite(M2AVA , LOW);     // Motor 2
           digitalWrite(M2RET , HIGH);
        
      } else {

           Serial.println("STOP the CAR ");  
           analogWrite(M1ACT, 0);      // Paramos Motor 1
           analogWrite(M2ACT, 0);      // Paramos Motor 2
      }
    }

}
void Detener()
{
      analogWrite(M1ACT, 0);      // Paramos Motor 1
      analogWrite(M2ACT, 0);      // Paramos Motor 2

      if (ang_X != 89) {
          ang_X  = 89;
          miServo.write(ang_X); 
      }           

}
  1. Si usas la librería Servo.h deja que la definición de que pin usa se encargue de como manejará el pin, asi que esto
 pinMode(servoPin, OUTPUT);

lo comentas porque luego usas

miServo.attach(servoPin);

que es lo mismo, pero nos aseguramos que no interferimos en el manejo del pin.

  1. map convertirá cualquier cosa recibida entre 0 y 489 a 55-90 entonces para que una condición de que si es mayor a 54. Jamás puede ocurrir que tengas un valor menor
  ang_X  = map(DERIZQ, 0, 489, 55, 90);
              miServo.write(ang_X);

No esta mal, es redundante.

Yo dejaría todo asi pero no cambia nada lo que tu has hecho, solo minimiza código

void Direccion()
{
    if (DERIZQ < 490 ) {  // izquierda
        ang_X  = map(DERIZQ, 0, 489, 55, 90); 
    } else {
        if (DERIZQ > 505) {   // derecha
            ang_X  = map(DERIZQ, 506, 1024, 90, 125);
        } else {
           if (ang_X != 89) {
              ang_X  = 89;    
           }
        }
    }
    miServo.write(ang_X);          
}

Conclusión: no veo razones en tu código para tirones.
Entonces comencemos a dudar de todo.

Lo primero sería ver que las comunicaciones esten bien. Comenta el servo y visualiza cada cambio en el monitor serie y verifica que no hay latencia (demoras entre tu orden y su recepción).
Si todo esta bien, regresemos a descomentar el servo y analiza que ocurre.
Recuerdo que varios han hecho comentarios de que el servo hasta no llegar a su posición no devuelve el control, verifica si esto es asi o estoy equivocado.

Una forma de verlo sería que pusieras una medida de tiempo antes/despues de un servo.write(ang_X) por ejemplo y mira cuanto mseg o useg demora.
Tal vez esa sea la causa.

También deberías publicar el código del emisor, tu código depende del formato de la señal recibida. Llamas a las dos funciones Direccion(), Desplazamiento() en serie, pero, para que funcione, el emisor debe enviar siempre las dos coordenadas en el mismo mensaje. Puede que este bien implementado, pero nosotros no tenemos esa información.
Saludos