Pages: [1] 2   Go Down
Author Topic: libreria servo.h con servo hitec hs-785hb  (Read 1033 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"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...
« Last Edit: February 06, 2013, 09:22:49 am by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma visto che stiamo facendo dei test, iniziamo facendo un codice apposta che fa
(codice non compilato eh, magari c'è qualche errorrino)
Code:
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)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
// 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);
}
  
};
« Last Edit: February 06, 2013, 11:31:59 am by Bruschetta » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10449
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
« Last Edit: February 06, 2013, 12:35:13 pm by Bruschetta » Logged

Pages: [1] 2   Go Up
Jump to: