libreria servo.h con servo hitec hs-785hb

Ciao a tutti,
oggi mi sono arrivati due servo della hitec hs-785hb possono ruotare fino a 3,5 giri ...

il mio problema è che con la libreria servo.h non riesco a farli funzionare ... sbarellano proprio ... potete darmi una mano? qualcuno ha già risolto questo problema?

ciao

sicuro siano dei servi analogici? se si allora prova a usare la writeMicroseconds() invece che la classica write(), con valori che magari gli passi via seriale (diciamo da 500 a 2000)

Il problema che ho già sviluppato tutta la parte di programmazione per gestire angolo min e angolo Max ... Come faccio sommo 500 al valore ?

usa la map() per passare da angolo a range, vedi il reference

Non riesco a capire come possa utilizzare la map ... Io in input ho gradi min e gradi Max ed il servo deve costantemente ruotare prima a destra e poi a sinistra di un grado alla volta ...

Con writeMicroseconds peggio di prima .....

"Detailed Specifications
Control System: +Pulse Width Control 1500usec Neutral"

quindi con wiriteMicroseconds() a 1500 dovresti vedere il servo mettersi a metà... con un valore più piccolo vedere che si muove da una parte, e più grande dall'altra. che valori hai provato?

edit:

Operating Angle: 630 Deg. one side pulse traveling 400usec

ciò cuol dire che variando da 1500 di 400 fai 630°... ciò vuol dire che 630°/400 = 1.57°, ovvero ogni incremento di 1 della microseconds ti fa cambiare di 1,5gradi. dato che la write() scrive valodi da 0 a 360, il servo "rimappa" il valore con 0 che rimane 0, ma 360 diventa 630*2=1260°...

questo perchè in realtà la write fa una map che diventa poi una chiamata a writeMicroseconds...

Ciao,
prima di tutto ti ringrazio dell'aiuto ...

non riesco a capire come possa trasformare la write in writemicroseconds ... ti allego il codice forse riesco a farmi capire :

// library:
#include <LiquidCrystal.h>
#include <Servo.h>

// Define object:
LiquidCrystal objLcd( 12 , 11 , 5 , 4 , 3 , 2);

Servo objOschi_1;

// set pin numbers:

const int OSCI_1 = 46;
const int SET = 32;
const int PIU = 33;
const int MENO = 34;
const int CONF = 35;

// variables will change:
int StatoBottone=0;
int val;
int posizione = 10;
int Numero_Pompa = 1;
int Angolazione_min = 1;
int Angolazione_max = 360;

char buffer[11];

boolean Sommo = true;

void setup() {

objOschi_1.attach(OSCI_1);

pinMode(SET, INPUT );
pinMode(PIU, INPUT);
pinMode(CONF, INPUT);
// attachInterrupt(0, SettingMode, RISING );
InitLcd();
Serial.begin(9600);
}

void loop() {

if (digitalRead(SET) == HIGH) { SettingMode(); } ;

objOschi_1.write(posizione);

if (Sommo){

posizione++;

if (posizione >=Angolazione_max) { Sommo=false; } ;
}
else {

posizione--;
if (posizione <=Angolazione_min) { Sommo=true; } ;
}

delay(15);

};

void InitLcd() {

objLcd.begin(16, 2);

objLcd.print("Connecting ...");

delay(1500);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("OsciMotion Italy");

}

void SettingMode()
{

boolean setMode = true;
boolean setNotConfirmPompa = true;
boolean setNotConfirmAngoloMin = true;
boolean setNotConfirmAngoloMax = true;
int setModeLevel = 0;
int AngoloMin = Angolazione_min;
int AngoloMax = Angolazione_max;

Numero_Pompa=1;

while ( setMode )
{

if ( setModeLevel == 0 )
{

sprintf(buffer, "Pompa N. %d", Numero_Pompa);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Scegliere Pompa");
objLcd.setCursor(0, 1);
objLcd.print(buffer);

delay(15);

while ( setNotConfirmPompa )
{
if (digitalRead(PIU) == HIGH)
{
Numero_Pompa++ ;

if (Numero_Pompa > 5) {Numero_Pompa=1;};

sprintf(buffer, "Pompa N. %d", Numero_Pompa);

objLcd.setCursor(0, 1);
objLcd.print(buffer);

delay(400);
}

if (digitalRead(MENO) == HIGH)
{
Numero_Pompa-- ;

if (Numero_Pompa < 1) {Numero_Pompa=5;};

sprintf(buffer, "Pompa N. %d", Numero_Pompa);

objLcd.setCursor(0, 1);
objLcd.print(buffer);

delay(400);
}

if (digitalRead(CONF) == HIGH)
{
setModeLevel++;

setNotConfirmPompa=false;

delay(200);
}
}
}

if ( setModeLevel == 1 )
{

sprintf(buffer, "Angolo %d", AngoloMin);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Angolo Minimo");
objLcd.setCursor(0, 1);
objLcd.print(buffer);

objOschi_1.write(AngoloMin);

delay(15);

while (setNotConfirmAngoloMin)
{
if (digitalRead(PIU) == HIGH)
{
AngoloMin++ ;

if (AngoloMin > 170) {AngoloMin=1;};

sprintf(buffer, "Angolo %d", AngoloMin);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Angolo Minimo");
objLcd.setCursor(0, 1);
objLcd.print(buffer);

objOschi_1.write(AngoloMin);

delay(250);
}

if (digitalRead(MENO) == HIGH)
{
AngoloMin--;

if (AngoloMin < 1) {AngoloMin=170;};

sprintf(buffer, "Angolo %d", AngoloMin);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Angolo Minimo");
objLcd.setCursor(0, 1);
objLcd.print(buffer);

objOschi_1.write(AngoloMin);

delay(250);
}

if (digitalRead(CONF) == HIGH)
{
setModeLevel++;

setNotConfirmAngoloMin=false;

Angolazione_min=AngoloMin;
posizione=AngoloMin;

Sommo = true;

delay(200);
}
}
}

if ( setModeLevel == 2 )
{

sprintf(buffer, "Angolo %d", AngoloMax);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Angolo Massimo");
objLcd.setCursor(0, 1);
objLcd.print(buffer);

objOschi_1.write(AngoloMax);

delay(15);

while (setNotConfirmAngoloMax)
{
if (digitalRead(PIU) == HIGH)
{
AngoloMax++ ;

if (AngoloMax > 360) {AngoloMax=1;};

sprintf(buffer, "Angolo %d", AngoloMax);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Angolo Massimo");
objLcd.setCursor(0, 1);
objLcd.print(buffer);

objOschi_1.write(AngoloMax);

delay(250);
}

if (digitalRead(MENO) == HIGH)
{
AngoloMax--;

if (AngoloMax < 1) {AngoloMax=1;};

sprintf(buffer, "Angolo %d", AngoloMax);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Angolo Massimo");
objLcd.setCursor(0, 1);
objLcd.print(buffer);

objOschi_1.write(AngoloMax);

delay(250);
}

if (digitalRead(CONF) == HIGH)
{
setModeLevel++;

setNotConfirmAngoloMax=false;

Angolazione_max=AngoloMax;
posizione=AngoloMax;

Sommo = false;

delay(200);
}
}
}

if ( setModeLevel == 3 ) {

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("Saving ...");

delay(600);

objLcd.clear();
objLcd.setCursor(0, 0);
objLcd.print("OsciMotion Italy");

setMode = false;

}

}

delay(600);

}

Come vedi ho dei valori iniziali ed il servo fa da valore minimo a valore massimo poi successivamente da valore massimo a minimo ...

Se premo il tasto Setting posso impostare il valore minimo attraverso i bottoni più e meno (man mano che premo vedo il servo che si muove) ... stessa cosa per valore massimo ...

come posso trasformare il valore posizione 1 in microseconds ?

il mio servo dovrebbe fare al max 360° mentre il servo gira 3,5 volte ...

please help

ma visto che stiamo facendo dei test, iniziamo facendo un codice apposta che fa
(codice non compilato eh, magari c'è qualche errorrino)

for (int i=1100; i<1900;i++){
   servo.writeMicroseconds(i);
   delay(1000);
}

ah il codice racchiudilo come ho fatto io tra i tag code:

[code ][/code ] (senza spazi)

niente ... si muove pochissimo e sembra quasi che sgrani e l'lcd sfarfalla!

continua a girare in un verso ... a scatti (sembra quasi che sgrani) ...

// library:
#include <LiquidCrystal.h>
#include <Servo.h>

// Define object:
LiquidCrystal objLcd( 12 , 11 , 5 , 4 , 3 , 2);

Servo objOschi_1;

// set pin numbers:

const int OSCI_1 = 9;

char buffer[11];

boolean Sommo = true;

void setup() {    
  
  objOschi_1.attach(OSCI_1); 
  
  objLcd.begin(16, 2);
  
  objLcd.print("Connecting ...");
  
  delay(1500);
  
  objLcd.clear();
  objLcd.setCursor(0, 0);
  objLcd.print("ciao");
  
  Serial.begin(9600);
}

void loop() {
  
  for (int i=1100; i<1900;i++){
   objOschi_1.writeMicroseconds(i);
   delay(1000);
}
  
};

ho abassato il delay a 15 adesso non sgrana più però fa circa 2 giri ...

togli tutto!
Il fatto che l'lcd sfarfalla può essere che il servo assorbe troppo... come l'hai collegato?

ed infatti:

Current Drain (4.8V): 8mA/idle and 230mA no load operating
Current Drain (6.0V): 8.7mA/idle and 285mA no load operating

quando si muove consuma circa 250mA (se non ha nulla da scpingere, se fa fatica molto di più!), arduino al massimo ne può dare 200, e anche l'lcd manga un bel pò!!! ti serve una fonta di alimentazione esterna per il servo, come una batteria a parte, e collegare il - della batteria al GND di arduino, e poi il + e - della batteria al servo

il collegamento del servo l'ho fatto sulla millefori col classico collegamento positivo su 5v di arduino , negativo gnd ...

comunque sia non vedo soluzione riguardo al servo ... non ci sto più capendo nulla :frowning:

sì, ma arduino non riesce a dare abbastanza potenza al servo. Quindi il + del servo lo colleghi al + di una batteria a parte, il - della batteria al GND di arduino, possibilmente insieme al - del servo.

In pratica quando il servo si muove ciuccia troppa corrente, e l'arduino si resetta, l'LCD sfarfalla, e anche l'USB del PC non sarà di certo felice

da quanto la devo mettere la batteria ... conta che se riesco a farlo funzionare dovrei collegare da 1 a 4 servi (adesso ne ho due) ...

insieme al kit mi sembra che c'era uno snap battery per una batteria da 9v (quelle quadrate per capirci) ... scusa ma sono proprio a zero!

gli Ah della batteria indicano quanto dura, a te interessa invece quanti Ampere puoi ciucciare istanataneamente.

normalmente dalle batterie normali (alkaline) puoi ciucciare meno di 200/300mA, poi iniziano a scaldare... quindi metterei un gruppo batterie per ogni servo.

Se prendi le batterie al litio o al niMh devi fare più attenzione, perchè se ciucci troppo PRENDONO FUOCO. in tal caso il produttore ti da la C di scarica: moltiplica quel valore per gli Ah della batteria e trovi quanti A istantanei può dare la batteria.

Ovviamente pwer stimare la durata della batteria in ore fai A istantanei/Ah