Go Down

Topic: E' possibile usare un sensore di prossimità come switch di elenco istruzioni? (Read 656 times) previous topic - next topic

Andrewa80

Salve a tutti, scusate se la mia domanda può essere banale. Nel mio progetto ho a disposizione un sensore di prossimità e 5 servi.
Vorrei se è fattibile utilizzare il sensore come switch di istruzioni.
O meglio dire ad arduino che se il sensore ottiene un'intervallo di distanza esempio da 0 a 3cm per un certo numero di secondi esempio 3 allora mi esegue un ciclo di istruzioni,
se accade invece che la distranza è 0-3cm x 5 secondi mi switcha ad un altro ciclo di istruzioni.
So che la funzione del calcolo interrupt può aiutarmi a scandire il tempo anche se non ho capito molto come funziona.
Confido sempre nel vostro prezioso aiuto.
Grazie mille e scusate se le domande a volte possano sembrare stupide o insensate.

leo72

Certo che lo puoi fare.
Devi scrivere semplicemente il codice che faccia ciò che hai detto. Per calcolare il tempo trascorso devi semplicemente usare la funzione millis.

Andrewa80

Ok ma il mio ciclo di istruzioni deve essere sempre lo stesso fino a quando non si riverifica l'evento distanza <3cm e tempo 5 sec. Seguendo alla lettera ciò che ho scritto mi entrerà in uno dei due cicli al momento del verificarsi dell'evento ma subito dopo uscirà. Mi sfugge qualcosa?

leo72

Ho solo precisato che per calcolare i tempi usi la funzione millis, poi il resto del codice lo devi scrivere in base alle condizioni che vuoi che si verifichino.

uwefed

Sbagli se credi che siamo veggenti, sappaimo leggere nella Tua mente o abbiamo una sfera di cristallo. Percui metti per favore tutto lo sketch, non solo una parte.

Per seconda le variabili tempo_trascorso e durata; devono essere del tipo unsigned long.

Ciao Uwe

Andrewa80

ok, sono andato avanti con il mio codice e ho trovato una soluzione "forse spartana" per ottenere quello che desideravo, ve lo posto per intero così ci capiamo meglio:

Code: [Select]

#include <Servo.h>
Servo s3;
long tempo;

int triggerPort = 10;
int echoPort = 11;

void setup() {
  s3.attach(3,500,3000);
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );
  Serial.begin( 9600 );
  Serial.println( "Sensore ultrasuoni: ");
  }

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==1)
    {
      tempo=tempo+500; 
        if (tempo>3000) {
          s3.write(90);
        }
    }

    if (r==4) {
      tempo=tempo+500;
        if (tempo>3000) {   
           if (r>4  && r<20)  { s3.write(170) ; }
           if (r>20 && r<30)  { s3.write(80)  ; }
           if (r>30)              { s3.write(10)  ; }
        }
    }
  if (r!=1 && r!=4) { tempo=0; }
  delay(500);
  }
}


Intanto le impostazioni del sensore e l'assegnazione del servo sono ok.
Dunque così come l'ho impostato il tempo mi viene registrato correttamente o meglio se la distanza è uguale a 1cm (modalità A) o a 4cm (modalità B) inizia il count del tempo altrimenti verrà settato a 0;
ciò che non riesco a capire è come far mantenere sempre lo stesso ciclo di istruzioni nel caso si entri nella modalità A o B.

Scusate se non riesco ad essere chiaro.

tuxduino

Quote
ciò che non riesco a capire è come far mantenere sempre lo stesso ciclo di istruzioni nel caso si entri nella modalità A o B.


Separa il codice che decide in quale modalità porre il programma dal codice che implementa le due modalità.
Aggiungi una variabile di stato che indica la modalità attuale del programma.

modalita_corrente = scegli modalità

switch (modalita_corrente)
    case A:
        esegui istruzioni modalita A
        break;

    case B:
        esegui istruzioni modalita B
        break


Andrewa80

grande...immaginavo fosse una cavolata ma non mi veniva...non sono un esperto programmatore...
posto il codice, accetto consigli per ottimizzare il codice:

Code: [Select]

#include <Servo.h>
Servo s3;
long tempo;
int modalita=0;

int triggerPort = 10;
int echoPort = 11;

void setup() {
  s3.attach(3,500,3000);
  pinMode( triggerPort, OUTPUT );
  pinMode( echoPort, INPUT );
  Serial.begin( 9600 );
  Serial.println( "Sensore ultrasuoni: ");
  }

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<4) { tempo=tempo+500;
      if (tempo>10000) { modalita=0;}
      Serial.print( " modalita: " );
      Serial.println( modalita );
    }
    if (r<4) { tempo=tempo+500;
      if (tempo>4000 && tempo<6000) { modalita=1;}
      Serial.print( " modalita: " );
      Serial.println( modalita );
    }
    if (r<4) { tempo=tempo+500;
      if (tempo>2000 && tempo<4000) { modalita=2;}
      Serial.print( " modalita: " );
      Serial.println( modalita );
    }
       
    if (r>4) { tempo=0;}
   
   switch (modalita) {
     case 0:
       s3.write(90);
       break;
     
     case 1:
       if (r>4  && r<20) { s3.write(0) ; }
       if (r>20 && r<30) { s3.write(45)  ; }
       if (r>30)         { s3.write(90)  ; }
       break;
     
     case 2:
       if (r>4  && r<20) { s3.write(90) ; }
       if (r>20 && r<30) { s3.write(135)  ; }
       if (r>30)         { s3.write(180)  ; }
       break;
   }
   delay(500);
  }
}

Go Up