mi spiegate come mai, con nessuno dei servo in dotazione di differente marca, riesco ad ottenere delle escursioni complete?
So bene che alcuni servo potrebbero non rispondere bene ai canonici 1000ms - 2000ms ma pur provando dei valori leggermente al di fuori dei range canonici non riesco ad ottenere gli estremi. I servo in prova sono di marca Hitech e Futaba.
Hai scritto uno sketch canonico?
Battutina a parte, se noti lo stesso comportamento con servi di marche differenti il problema potrebbe riguardare lo sketch e non i servi
Si ho scritto un sketch piuttosto canonico....lo posto qui
#include <SoftwareSerial.h>
#include <Serial.h>
//Definisci i pin TX e RX
const int SERVO_CONTROLLER_RX_PIN = 11; // The SERVO CONTROLLER'S RX PIN.
const int SERVO_CONTROLLER_TX_PIN = 12; // The SERVO CONTROLLER'S TX PIN.
const int BUTTON_UP = 2;
const int BUTTON_DOWN = 3;
int increment = 6000;
int decrement = 6000;
//Inizializza la connessione con Maestro
SoftwareSerial ServoController = SoftwareSerial(SERVO_CONTROLLER_RX_PIN, SERVO_CONTROLLER_TX_PIN);
//Definisci la funzione moveServo
void moveServo(int ServoChannel, int target)
{
byte serialBytes[4]; //Crea un array di 4 bytes
target = (map(target, 0, 180, 1000, 2000)*4); //Mappa il valore di "target" tra 4000 e 8092
//Ricorda che: un segnale di 1000ms corrisponde in quarti di microsecondo, a 4000 e 2000ms a circa 8092
serialBytes[0] = 0x84; // Il primo byte contiene il Set Target --> move servo
serialBytes[1] = ServoChannel; // Primo byte: indica su quale canale è in ascolto il servo
serialBytes[2] = target & 0x7F; // Secondo byte: selezione i 7 bit meno significativi di target (0-6)(LSB)
serialBytes[3] = (target >> 7) & 0x7F; // Terzo byte: prelevo i 7 bit più significativi di target (7-13)(MSB)
ServoController.write(serialBytes, sizeof(serialBytes)); //Scrivo l'array di byte su Maestro
}
void testLimit(int ServoChannel, int target){
byte serialBytes[4]; //Crea un array di 4 bytes
serialBytes[0] = 0x84; // Il primo byte contiene il Set Target --> move servo
serialBytes[1] = ServoChannel; // Primo byte: indica su quale canale è in ascolto il servo
serialBytes[2] = target & 0x7F; // Secondo byte: selezione i 7 bit meno significativi di target (0-6)(LSB)
serialBytes[3] = (target >> 7) & 0x7F; // Terzo byte: prelevo i 7 bit più significativi di target (7-13)(MSB)
ServoController.write(serialBytes, sizeof(serialBytes)); //Scrivo l'array di byte su Maestro
}
//Definisci la funzione servoSpeed
void servoSpeed(int ServoChannel, int target)
{
byte serialBytes[4]; //Crea un array di 4 bytes
serialBytes[0] = 0x87; // Il primo byte contiene il Set Target --> move servo
serialBytes[1] = ServoChannel; // Primo byte: indica su quale canale è in ascolto il servo
serialBytes[2] = target & 0x7F; // Secondo byte: selezione i 7 bit meno significativi di target (0-6)(LSB)
serialBytes[3] = (target >> 7) & 0x7F; // Terzo byte: prelevo i 7 bit più significativi di target (7-13)(MSB)
ServoController.write(serialBytes, sizeof(serialBytes)); //Scrivo l'array di byte su Maestro
}
void sweep(){
servoSpeed(0,0);
moveServo(0,0);
delay(500);
servoSpeed(0,0);
moveServo(0, 180);
delay(500);
}
void setServo(){
moveServo(0,90);
}
void setLeft(){
moveServo(0,0);
}
void setRight(){
moveServo(0,180);
}
void setup()
{
// Apri la connessione Seriale a 9600 baud
ServoController.begin(9600);
// while (!ServoController.) {
// ; // Aspetta fin quando non si è collegato
// }
delay(500);
Serial.begin(9600);
pinMode(BUTTON_UP,INPUT);
setServo();
}
void loop() {
// put your main code here, to run repeatedly:
//setServo();
//sweep();
//setRight();
//setLeft();
if(digitalRead(BUTTON_UP)==HIGH){
Serial.println("Pressato");
increment = increment + 100;
//decrement= decrement - 100;
Serial.print("Provo:");
Serial.println(increment);
//Serial.print(decrement);
testLimit(0, increment);
//testLimit(0, decrement);
delay(50);
}
//Serial.println("False");
delay(200);
}
Ovviamente non sto pilotando i servo direttamente da Arduino ma attraverso un servocontroller esterno che ragiona in quarti di millisecondo per cui 1000 corrisponde a passare al controllore esterno un valore pari a 4000 mentre 2000ms corrisponde a 8000 (2000*4).
In buona sostanza il fulcro della questione è qui:
target = (map(target, 0, 180, 1000, 2000)*4); //Mappa il valore di "target" tra 4000 e 8092
Premesso che non ho risolto il problema di cui la ragione di questo post, ho provato a gestire i miei servo con arduino.
Le gestione avviene correttamente con il seguente codice:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int increment = 0;
const int BUTTON_UP = 2;
const int BUTTON_DOWN = 3;
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(0);
pinMode(BUTTON_UP,INPUT);
pinMode(BUTTON_DOWN, INPUT);
Serial.begin(9600);
//while(Serial){
// ;
// }
}
void loop()
{
if(digitalRead(BUTTON_UP)==HIGH){
Serial.println("Pressato");
//decrement= decrement - 100;
//Serial.print("Provo:");
//Serial.print(decrement);
increment = increment + 20;
if(increment > 180)
increment = 180;
Serial.println(increment);
myservo.write(increment);
//testLimit(0, decrement);
delay(100);
}
if(digitalRead(BUTTON_DOWN)==HIGH){
Serial.println("Pressato");
//decrement= decrement - 100;
//Serial.print("Provo:");
//Serial.print(decrement);
increment = increment - 20;
if(increment < 0)
increment = 0;
Serial.println(increment);
myservo.write(increment);
//testLimit(0, decrement);
delay(100);
}
//for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
//{ // in steps of 1 degree
// myservo.write(pos); // tell servo to go to position in variable 'pos'
// delay(15); // waits 15ms for the servo to reach the position
// }
//for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
//{
// myservo.write(pos); // tell servo to go to position in variable 'pos'
// delay(15); // waits 15ms for the servo to reach the position
//}
}
Che non fa altro che mandare il servo avanti ed indietro a seconda se è premuto il tasto A o il tasto B. Quello che accade è che l'ultimo step che fa retrocedere il servo da 20° a 0° avviene con un delay inaccettabile; il movimento non è immediato ma avviene un attimo dopo.
Come mai è possibile? Avviene solo quando il servo passa da 20° a 0°.
Se al posto di myservo.write uso myservo.writeMicroseconds il problema non sussiste
Mah...valli a capire sti servi...
Però continuo a non capire il motivo per cui i servo non funzionano quando li piloto con il micro maestro della Pololu. Penso sia un problema legato al microcontrollore esterno piuttosto che dipendente dallo sketch come asseriva Pelletta
Ciao Pelletta,
Chiedo venia....preso dalla rabbia di quella sera ho omesso dei dettagli importanti...
Ora faccio di seguito un sunto con l'obiettivo di essere più chiari:
Gestione dei servo con arduino:
attraverso l'api myservo.write(0) ho dei problemi con il servo hitech
attraverso l'api myservo.writeMicroseconds(microsecondi) vanno bene che é un piacere
Gestione dei servo con Pololu Maestro
qui il problema è più profondo. Non riesco a far raggiungere le posizione estreme ai miei servo. Il problema è grave anche perché dovrà essere il Pololu a gestire i servo e non l'arduino. Qualcuno ha qualche idea?
grazie mille per la precisazione, anche se non mi è molto chiara.
Io uso i pin TX e RX del pololu per pilotarlo.
Difatti la comunicazione è precisa. Il problema è un altro.
I miei servo coprono un escursione 15°-75° nonostante io passi i valori di temporizzazione adeguati.
In quarti di microsecondo, se voglio inviare un impulso di 1000 microsecondi, devo inviare a pololu un valore di 4000. Di converso, se voglio inviare un impulso di 2000 microsecondi, devo inviare a pololu un valore di 8000. Tutto qui.
Ora tutti i valori intermedi tra 4000 ed 8000 funzionano perfettamente ossia fanno almeno muovere il servo, ma agli estremi non ci va:
-4000 in quarti di microsecondo corrispondono a 1000 microsecondi (1ms) che corrispondono all'incirca ad un angolo di 0°
-8000 in quarti di microsecondo corrispondono a 2000 microsecondi (2ms) che corrispondono all'incirca ad un angolo di 180°
sonique:
-4000 in quarti di microsecondo corrispondono a 1000 microsecondi (1ms) che corrispondono all'incirca ad un angolo di 0°
-8000 in quarti di microsecondo corrispondono a 2000 microsecondi (2ms) che corrispondono all'incirca ad un angolo di 180°
Sbagliato, da 1 ms a 2 ms il servo fa solo 90°, +/-45°, per andare da 0° a 180° l'impulso deve essere compreso tra 500us e 2500us, valori da aggiustare di qualche decina di us a seconda del servo utilizzato.
Difatti, con la monitor seriale di arduino e la myservo.writeMicroseconds() ho potuto constatare che i valori 500us e 2500us mi mandano a fondo scala i servo.
Questo per dire che ho provato anche i valori di cui sopra ma nulla da fare.
vi do un aggiornamento.
Lo stramaledetto Pololu, aveva settato in qualche registro del micro i valori di minimo e massimo in microsecondi che si potevano attribuire al servo.
Con l'applicazione da loro fornita ho potuto estendere i due range ed ora tutto funziona. Grazie mille