far muovere un servo un grado alla volta ad ogni pressione

Premettendo che non ho molta esperienza con la programmazione, vorrei far muovere il mio servomotore un grado alla volta ogni volta che premo un bottone.
Mi spiego meglio, tutte le volte che premo il bottone deve aumentare di un grado o alla pressione di un secondo bottone diminuire di un grado, però quando lo tengo premuto questo continui ad aggiungere 1 e ad aumentare o diminuire.
Magari se per fare ciò servono due programmi ( uno che ad ogni pressione aumenti di uno, ed un'altro che finchè premo questo ruota) mi piacerebbe che qualche buon anima riuscisse a spiegarmi le differenze.
Io fin ora ho pensato di usare un' if che quando il bottone viene premuto scriva pos = pos + 1 (per posizione intendo la posizione del servo), ma ho visto che non funziona e fa tutt'altro.
Ringrazio in anticipo tutti quelli che si interessano e mi danno una mano!!!
Speranzoso che qualcuno risponda presto!

posta il codice!!!

#include <PS2X_lib.h>  //for v1.6
#include <Servo.h> 
PS2X ps2x; // create PS2 Controller Class

Servo myservo;
Servo myservo2;
int error = 0;
int pos;


void setup(){
 Serial.begin(57600);

 //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************
  
  error = ps2x.config_gamepad(6,10,9,11, true, true);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
  myservo.attach(2);
  
}
 void loop() {
   
   ps2x.read_gamepad();          
     if( ps2x.ButtonPressed(PSB_BLUE)){
       pos = pos + 1;
   myservo.write(pos);
   delay(15);
     }
       if( ps2x.ButtonPressed(PSB_PINK)){
       pos = pos - 1;
   myservo.write(pos);
   delay(15);
       }
 }

Lascia perdere i codici del mio joystick :sweat_smile: lo controllo tramite il mio controller wireless della play station 2 ma fai finta che sono 2 bottoni normalissimi! lui li vede come tali! come se dico button = HIGH per intenderci...
il mio problema è che non riesco a fargli fare una cosa come: mettiamo caso che si trova a 20 gradi, io voglio che premendo un bottone aggiunga, che ne so, +10 gradi! e passi a 30 poi ripremendo a 40 e con un'altro bottone invece di fare la somma faccia la sottrazione dei 10!

il codice va bene ma devi fare attenzione che pos sia sempre compreso tra 0 e 360.

in oltre delay(15); mi sembrano pochi, (15 millisecondi, la reazone umana si aggira sui 100, fai conto che 30ms sono la durata di un frame di un video a 30FPS, ovvero la TV più o meno)

Ho fatto varie prove di velocità cambiando il ritardo e ho messo quella più normale che non fosse troppo veloce ma neanche troppo lenta, i miei sono servi che hanno valori da 0 a 180 non sono a giro.

il codice va bene ma devi fare attenzione che pos sia sempre compreso tra 0 e 360.

Cosa intendi? Che devo scrivergli nel programma che il valore pos è compreso tra 0 e 180 nella parentesi dell'if?

aaaah che tu intendessi che se il ritardo è molto basso non ho nemmeno il tempo di premere il bottone?! ok ora ho capito cosa intendevi, il problema è che anche con un ritardo di un secondo mi fa la stessa cosa, cioè: sia che io premo un bottone sia che premo l'altro parte e va a zero, come se gli dicessi di andare al valore zero.
Non riesco a capire il motivo :expressionless: .

Ferro:
Cosa intendi? Che devo scrivergli nel programma che il valore pos è compreso tra 0 e 180 nella parentesi dell'if?

sì, in realtà esiste una funzione constrain(x, min, max) (vedi il reference: constrain() - Arduino Reference) che fa tutto con una chiamata sola.

in pratica se non fai questo controllo prima, rischi di dare alla write del servo un valore grandissimo o piccolossimo (compreso tra -32768 e +32766, i limiti della variabile int), e capisci che sia normale che il tuo povero servo non capisca una mazza di cosa deve fare :smiley:

Ma il servo come lo alimenti? che servo è?
hai provato a sostituire il tasto "remoto" con un normale tasto? (solo per debug)

Anche se inserisco il comando che mi hai detto non funziona il risultato é uguale :frowning: .
É un semplice microservo da 180°, alimentato esternamente a 5V Siccome può lavorare da 4.5V a 6V.

codice? come alimenti il servo? come alimenti arduino? hai provato a collegare il + e - del servo ad una batteria esterna, e il - della batteria al gnd dell'arduiono? magari arduino non riesce a dare abbatanza potenza e il codice/servo impazzisce

Il codice è sempre quello che ho già postato però ho cambiato il ritardo e inserito la cosa che mi hai scritto tu.
Il servo viene alimentato da una batteria esterna da 9 V che viene portata con un regolatore a 5V, arduino è indifferente posso alimentarlo da il pc ma anche con una batteria esterna sempre da 9V( un'altra), ho già fatto codici con i servomotori e li so utilizzare perchè con altri codidi funzionano alla perfezione.
Il problema è proprio il codice che non riesco a scrivere correttamente molto probabilmente e non so come uscirne :~ .
Io ho pensato di assegnare al valore di pos iniziale un servo.read() così che quando va a fare pos = pos + 1; il pos nell'operazione sia il valore che legge dal servo, peccato non sappia come scrivere il programma :roll_eyes:

coapisco che hai aggiunto solo quello che ho detto io, ma il punto è anche DOVE lo hai aggiunto :slight_smile:

sicuro di aver collegato il GND della batteria all'arduino?

Hai provato così?

#include <PS2X_lib.h>  //for v1.6
#include <Servo.h> 
PS2X ps2x; // create PS2 Controller Class

Servo myservo;
Servo myservo2;
int error = 0;
int pos;


void setup(){
 Serial.begin(57600);

 //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************
  
  error = ps2x.config_gamepad(6,10,9,11, true, true);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
  myservo.attach(2);
  
}
 void loop() {
   
   ps2x.read_gamepad();          
     if( ps2x.ButtonPressed(PSB_BLUE) && pos>=0 && pos <=180){
       pos = pos + 1;
   myservo.write(pos);
   //delay(15);
while(ps2x.ButtonPressed(PSB_BLUE)){}
     }
       if( ps2x.ButtonPressed(PSB_PINK) && pos>=0 && pos <=180){
       pos = pos - 1;
   myservo.write(pos);
   //delay(15);
while(ps2x.ButtonPressed(PSB_PINK)){}
       }
 }

che motivo ha il delay se poi fai while(ps2x.ButtonPressed(PSB_BLUE)){}?

non ti assicuri che val sia un valore valido, vedi qualche messaggio fa

IDENTARE IL CODICE! CTRL+T sull'ide, et voilà... (almeno prima di postare... poi come scrivete per i cavoli vostri sono cavoli vostri)

lesto:
non ti assicuri che val sia un valore valido, vedi qualche messaggio fa

si me ne sono accorto dopo, l'ho corretto mentre scrivevi...

lesto:
IDENTARE IL CODICE! CTRL+T sull'ide, et voilà... (almeno prima di postare... poi come scrivete per i cavoli vostri sono cavoli vostri)

l'ho modificato da qua stesso, senza passare dall'ide, in ogni caso non sapevo questa cosa... adesso che lo so starò più attento... :sweat_smile:

cambierei in

if( ps2x.ButtonPressed(PSB_BLUE) pos <=180){
       pos = pos + 1;

e

if( ps2x.ButtonPressed(PSB_PINK) && pos>=0){
       pos = pos - 1;

così se per qualch assurdo caso pos diventa un valore invalido, giochicchiare con i tasti prima o poi lo risporta ad un valore valido :slight_smile:

lesto:
cambierei in

if( ps2x.ButtonPressed(PSB_BLUE) pos <=180){

pos = pos + 1;




e



if( ps2x.ButtonPressed(PSB_PINK) && pos>=0){
      pos = pos - 1;




così se per qualch assurdo caso pos diventa un valore invalido, giochicchiare con i tasti prima o poi lo risporta ad un valore valido :)

si così è ancora meglio! :slight_smile:

Potresti aggiungere il valore iniziale di pos in

int pos = 90;

e nel setup dopo l'attachinterrupt inserire

myservo.write(pos);
delay(1000);

In questo modo all'accensione il servo si mette a 90°. :astonished:
Poi con i pulsanti lo muovi da una parte o dall'altra.

Se all'accensione non si muove, l'errore è nei collegamenti.

Grandissimi è venuto!!! Grazie mille!!! Siete dei grandi!!!posto il programma corretto.

#include <PS2X_lib.h>  //for v1.6
#include <Servo.h> 
PS2X ps2x; // create PS2 Controller Class

Servo myservo;
Servo myservo2;
int error = 0;
int pos = 90;


void setup(){
 Serial.begin(57600);

 //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************
  
  error = ps2x.config_gamepad(6,10,9,11, true, true);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
  myservo.attach(3);
  
}
 void loop() {
   
   ps2x.read_gamepad();
      
     if( ps2x.Button(PSB_BLUE) && pos <= 180){
       pos = pos + 10;
   myservo.write(pos);
   delay(100);
     }
       if( ps2x.Button(PSB_PINK) && pos >= 0){
       pos = pos - 10;
   myservo.write(pos);
   delay(100);
       }
       delay(15);
 }

Bisognava dare un valore iniziale a pos per poter fare l'operazione iniziale :smiley: .