Go Down

Topic: libreria servo.h con servo hitec hs-785hb (Read 1 time) previous topic - next topic

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

lesto

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)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

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

lesto

usa la map() per passare da angolo a range, vedi il reference
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

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 .....

lesto

#5
Feb 06, 2013, 03:18 pm Last Edit: Feb 06, 2013, 03:22 pm by lesto Reason: 1
"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:

Quote
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...
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

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

lesto

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

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)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

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

#9
Feb 06, 2013, 05:30 pm Last Edit: Feb 06, 2013, 05:31 pm by Bruschetta Reason: 1
continua a girare in un verso ... a scatti (sembra quasi che sgrani) ...

Code: [Select]

// 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 ...

lesto

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

ed infatti:
Quote
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
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

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 :-(

lesto

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
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

#14
Feb 06, 2013, 06:31 pm Last Edit: Feb 06, 2013, 06:35 pm by Bruschetta Reason: 1
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!

Go Up