Lo script intero è molto più grande l'ho ridotto per facilitare la lettura, dunque ciò che non riesco a fare e ricollegare con attach il servo. Quindi funziona tutto ma c'è qualcosa che sbaglio nel momento in cui devo fare l'attach. Spero possiate aiutarmi.
Un saluto.
Difficile, secondo me, fare la verifica di un programma scritto da un altro (quindi bisogna analizzarlo e capire cosa volevi fare) senza averlo completo.
Ok ve lo posto completamente e vi spiego cosa dovrebbe fare:
#include <Servo.h>
Servo s1;
Servo s2;
Servo s3;
Servo s4;
Servo s5;
long tempo;
int modalita=1;
int i=1;
int led=8;
boolean mod0=false;
boolean mod1=false;
boolean mod2=false;
boolean spenti=false;
int triggerPort = 9;
int echoPort = 8;
void setup() {
s1.attach(7, 510, 3100);
s2.attach(6, 525, 3100);
s3.attach(5);
s4.attach(4, 560, 3100);
s5.attach(3, 570, 3100);
pinMode(led, OUTPUT);
pinMode( triggerPort, OUTPUT );
pinMode( echoPort, INPUT );
Serial.begin( 9600 );
}
void spegni() {
s1.detach();
s2.detach();
s3.detach();
s4.detach();
s5.detach();
spenti=true;
}
void accendi() {
s1.attach(7, 510, 3100);
s2.attach(6, 525, 3100);
s3.attach(5);
s4.attach(4, 560, 3100);
s5.attach(3, 570, 3100);
}
void loop() {
//porta bassa l'uscita del trigger
digitalWrite( triggerPort, LOW );
//invia un impulso di 10microsec su trigger
digitalWrite( triggerPort, HIGH );
delayMicroseconds( 10 );
digitalWrite( triggerPort, LOW );
long duration = pulseIn( echoPort, HIGH );
long r = 0.034 * duration / 2;
Serial.print( tempo );
Serial.print( " durata: " );
Serial.print( duration );
Serial.print( " , " );
Serial.print( "distanza: " );
//dopo 38ms è fuori dalla portata del sensore
if( duration > 38000 ) Serial.println( "fuori portata");
else {
Serial.print( r ); Serial.println( "cm" );
if (r>3 && r<15 && !mod0) {
if (spenti) { accendi(); }
s1.write(70);
s2.write(140);
s3.write(120);
s4.write(70);
s5.write(70);
mod0=true;
mod1=false;
mod2=false;
spegni();
}
if (r>15 && r<30 && !mod1) {
if (spenti) { accendi(); }
s1.write(90);
s2.write(108); //valore di base 108
s3.write(85);
s4.write(90);
s5.write(90);
mod0=false;
mod1=true;
mod2=false;
spegni();
}
if (r>30 && !mod2) {
if (spenti) { accendi(); }
s1.write(110);
s2.write(75);
s3.write(60);
s4.write(110);
s5.write(110);
mod0=false;
mod1=false;
mod2=true;
spegni();
}
break;
}
delay(500);
}
Cosa dovrebbe fare: i servi si muovono ad un angolazione rispetto alla distanza del sensore, esempio se la distanza è tra 15 e 30 cm il servo avrà l'angolazione di 60°. Se quindi lo stato non cambia, e si rimane sempre nello stesso range, vorrei che i servi fossero staccati. Ho creato 2 funzioni accendi() e spegni() e un controllo booleano che parte da false (o meglio servi accesi).
Entrato in una delle condizioni alla fine del processo dovrebbe fare il detach() e lo esegue correttamente, ma cambiando condizione i servi non si riattivano, quindi il comando attach() non funge.
Spero sia tutto più chiaro.
Se non mi sbaglio spenti ad un certo punto lo metti a true.
Ma poi non lo metti mai in nessun posto a false. Per il tuo programma spenti=true e rimane per sempre.
Un consiglio per le tre modalità. A me sembra un pò complicato gestire 3 variabili mod0,mod1,mod2 booleane per sapere la modalità.
Sarebbe più semplice una variabile numerica dove 0=statoA 1=statoB e 2=statoC.
#define STATOA 0 // ovvero mod0=false/mod1=false/mod2=false
#define STATOB 1 // ovvero mod0=true /mod1=false/mod2=false
#define STATOC 2 // ovvero mod0=false/mod1=true /mod2=false
#define STATOD 3 // ovvero mod0=false/mod1=false/mod2=true
unsigned char stato=STATOA; // ovvero mod0=false/mod1=false/mod2=false
... nel codice dove setti a vero mod0:
stato=STATOB;
etc.
si rimane per sempre true ma se vedi bene la funzione accendi viene chiamata se spenti è uguale a true. La variabile spenti servirebbe solo per un controllo iniziale perchè il setup li accende già. Non mi serve che sia "false".
Una cosa che non capisco. A me non compila il tuo programma.
A che serve quella istruzione break; ? Si usa solo per forzare uscita da cicli o switch
A parte quello, a me il tuo codice sembra giusto. Non ci vedo nulla di strano. Non capisco dove possa esserci l'inghippo.
Io proverei una cosa stupida ma che potrebbe farci capire se c'e' qualcosa di strano nell'attach/detach
Nella loop, commenta tutto e metti semplicemente
accendi();
delay(1000);
spegni();
delay(1000);
accendi();
delay(5000); // qui spegni tutto, serve solo il sopra per capire
C'è la possibilità che esegui due volte il detach. Secondo me questo incasina il tutto perché esegui un detach senza servo attaccato.
Se i servi sono spenti devi saltare tutta la parte del codice.
da così