ARDUINO + sensore ultrasuoni+ sensore suono

Buongiorno a tutti,
ho concluso un mini progetto per spegnere una lampada con un sensore ultrasuono ee un sensore suono e relativo relè statico.
il problema è software …
nel senso che non riesco a fare il toggle del sensore ultrasuoni, quello realativo al sensore suono funziona ! …allego programma…mi potete dare una mano ?
grazie

// PROGRAMMA GESTIONE RELE' CON SENSORE SUONO ED ULTASUONO

int rele = 4;
int soundpin = 12;
int triggerPort = 3;
int echoPort = 2;

boolean currentState = HIGH;
boolean lastState = LOW;
boolean releState = HIGH; 

void setup() {                
  Serial.begin(9600); 
 
  pinMode(rele, OUTPUT);
  pinMode(triggerPort, OUTPUT);
  pinMode(echoPort, INPUT);
  pinMode(soundpin, INPUT);
  
}
 
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 durata = pulseIn( echoPort, HIGH );


if( durata < 600 ){

digitalWrite(rele, HIGH); 
delay (400);
              [color=red]//toggle the state of the relè
    if (releState == LOW){
      digitalWrite(rele, HIGH);
      releState = HIGH;
      delay(20);
    } else {
      digitalWrite(rele,LOW);
      releState = LOW;
      delay(20);
      }[/color]
  }

else{ 

currentState = digitalRead(soundpin);
    if (currentState == LOW && lastState == HIGH){
    delay(10);
              //toggle the state of the relè
    if (releState == LOW){
      digitalWrite(rele, HIGH);
      releState = HIGH;
      delay(10);
    } else {
      digitalWrite(rele,LOW);
      releState = LOW;
      delay(10);
      }
 }
 lastState = currentState;

  }
 }

scusate il programma è il seguente :

// PROGRAMMA GESTIONE RELE' CON SENSORE SUONO ED ULTASUONO____By MaxB

int rele = 4;
int soundpin = 12;
int triggerPort = 3;
int echoPort = 2;

boolean currentState = HIGH;
boolean lastState = LOW;
boolean releState = HIGH; 

void setup() {                
  Serial.begin(9600); 
 
  pinMode(rele, OUTPUT);
  pinMode(triggerPort, OUTPUT);
  pinMode(echoPort, INPUT);
  pinMode(soundpin, INPUT);
  
}
 
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 durata = pulseIn( echoPort, HIGH );


if( durata < 600 ){

digitalWrite(rele, HIGH); 
delay (400);
currentState = digitalRead(echoPort);
    if (currentState == LOW && lastState == HIGH){
    delay(10);
              //toggle the state of the relè
    if (releState == LOW){
      digitalWrite(rele, HIGH);
      releState = HIGH;
      delay(20);
    } else {
      digitalWrite(rele,LOW);
      releState = LOW;
      delay(20);
      }
  } 
 lastState = currentState;

  }

else{ 

currentState = digitalRead(soundpin);
    if (currentState == LOW && lastState == HIGH){
    delay(10);
              //toggle the state of the relè
    if (releState == LOW){
      digitalWrite(rele, HIGH);
      releState = HIGH;
      delay(10);
    } else {
      digitalWrite(rele,LOW);
      releState = LOW;
      delay(10);
      }
 }
 lastState = currentState;

  }
 }

Ciao,
non ho mai usato i sensori a ultrasuoni, ma mi sembra che c’è una incongruenza nel codice (vedi commenti qui sotto):

//..snip...
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 durata = pulseIn( echoPort, HIGH );


if( durata < 600 ){

digitalWrite(rele, HIGH); 
delay (400);

//Xilav: Perchè leggi qui sotto il valore digitale del sensore ultrasuoni quando hai già visto che il segnale è rimbalzato?
//       inoltre dalla descrizione di pulseIn ritorna "the length of the pulse (in microseconds) or 0 if no pulse is completed before the timeout (unsigned long)"
//       per cui se il sensore non riceve rimbalzi entar di qui lo stesso
//       Io utilizzerei un'altra variabile tipo la currentState (ad esempio currentStateUltra) e la valorizzerei a TRUE se (durata < 600) && (durata != 0), 
//       nell'altro caso la valorizzerei a FALSE e calcolrerei il fronte di salita su questa variabile...
currentState = digitalRead(echoPort); 
    if (currentState == LOW && lastState == HIGH){
    delay(10);
              //toggle the state of the relè
    if (releState == LOW){
      digitalWrite(rele, HIGH);
      releState = HIGH;
      delay(20);
    } else {
      digitalWrite(rele,LOW);
      releState = LOW;
      delay(20);
      }
  } 
 lastState = currentState;

  }

else{ 

currentState = digitalRead(soundpin);
//..snip...

Premetto che sto andando ad intuizione avendo giusto dato un’occhiata ad un tutorial di un sensore ad ultrasuoni, per cui il mio suggerimento potrebbe non essere corretto… :slight_smile:

Ciao!

grazie mille

provo a vedere stasera poi ti dico!

buona serata

ciao
ieri sera ho verificato ed ineffetti il mio problema è che ho sempre usato il digitalread (pin) ma in questo caso mi sembra che non abbia senso usare il pin ECHOPORT !!!la tua soluzione non la conosco …
mi potresti aiutare …scrivendo 2 righe di Sketch?

grazie
buona giornata
massib

Quesa è la mia idea: sicuramente è perfettibile e non so neanche se funziona (l’ho messa giù col Notepad eheheh :slight_smile: )

//...snip...
bool curStateUS = false;
boon lastStateUS = false;
//...snip...

//...snip...
unsigned long durata = pulseIn( echoPort, HIGH );
if( (durata > 0) && (durata <600) )
{
  // Intercettato ostacolo al''interno della mia area
  curStateUS = true;
}
else
{
  curStateUS = false;
}

if ( (curStateUS != lastStateUS) && (curStateUS == true) )
{
  //toggle the state of the relè
  if (releState == LOW)
  {
    digitalWrite(rele, HIGH);
    releState = HIGH;
    delay(20);
  }
  else
  {
    digitalWrite(rele,LOW);
    releState = LOW;
    delay(20);
  }
  lastStateUS = curStateUS;
}
//...snip...

Ciao!

Ah... ho appena visto che c'è un errore... ma lascio fare a te le modifiche! :D

mi sembrava!!!

stasera provo .. poi ti dico!

bye e grazie !!

massib

ciao

ho provato con il toggle da te consigliato ma non funziona!!

ritento per altra via" bye massi

hai messo la

lastStateUS = curStateUS;

fuori dall'if() ?!?

Si si.. Ma la compilazione va a buon fine.. Ma poi non esegue il toggle e cime se non ci fosse.. Bohoggi pomeriggio riprovo Graxie

ciao mi sono accorto che in realtà il software è corretto... il problema è il sensore ad ultrasuoni .. che quando passo la mano sul sensore , mi fa più letture e quindi poi eccita il relè a caso!! devo risolvere il problema delle letture del sensore .. forse con dei DELAY () !!

grazie mille per il tuo aiuto

massibal:
mi sono accorto che in realtà il software è corretto… il problema è il sensore ad ultrasuoni … che quando passo la mano sul sensore , mi fa più letture e quindi poi eccita il relè a caso!!

Devi semplicemente inserire un “tempo morto” dopo ogni commutazione del relè. Ovvero, ogni volta che accendi/spegni, per X tempo, ignori quello che succede (se non devi fare altre cose, basta anche, ad esempio, un delay(2000) e per due secondi, anche se ripassi la mano il tutto “è morto”).
Guglielmo

ci ho provato ma mi da degli strani ritardi sull’altro sensore (SENSORE SUONO) …allego programma
così se avete voglia ci date un’occhiata!:slight_smile: – forse sbaglio la posizione del DELAY()?

// PROGRAMMA GESTIONE RELE' CON SENSORE SUONO ED ULTASUONO____By MaxB

int rele = 4;
int soundpin = 12;
int triggerPort = 3;
int echoPort = 2;

boolean currentState = HIGH;
boolean lastState = LOW;
boolean releState = HIGH; 
boolean currentStateU = true;
boolean lastStateU = true;

void setup() {                
   
  pinMode(rele, OUTPUT);
  pinMode(triggerPort, OUTPUT);
  pinMode(echoPort, INPUT);
  pinMode(soundpin, INPUT);
  }
 
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 durata = pulseIn( echoPort, HIGH );

if(durata < 700 )
{
 currentStateU = true;}
 else 
 {
 currentStateU = false ;}
   
   if (currentStateU == true && lastStateU == false)
   {  
                 
    if (releState == LOW){
      digitalWrite(rele, HIGH);
      releState = HIGH;
     //currentStateU = true ;
      delay(10);
    } else {
      digitalWrite(rele,LOW);
      releState = LOW;
      //currentStateU = false ;
      delay(10);
      }
      }
       lastStateU = currentStateU  ;

currentState = digitalRead(soundpin);
    if (currentState == LOW && lastState == HIGH){
    delay(10);
              //toggle the state of the relè
    if (releState == LOW){
      digitalWrite(rele, HIGH);
      releState = HIGH;
      delay(10);
    } else {
      digitalWrite(rele,LOW);
      releState = LOW;
      delay(10);
      }
  }
 lastState = currentState;

}

... se guardi bene ho scritto "se non devi fare altre cose" ... ovvero, dato che la delay() è bloccante, in quel "tempo morto" NON puoi fare altro, quindi, è "morto" anche il sensore di suono.

Se vuoi creare un "tempo morto" per una cosa, ma non per l'altra, NON puoi usare la delay() ma devi imparare ad usare una tecnica che si avvale della funzione millis() ... dovrai quindi studiare il suo uso prima QUI, poi QUI ed infine leggi anche QUI e QUI ... e dovresti avere le idee più chiare ;)

Guglielmo

grazie mille per il consiglio!!

..provo a leggere--- se poi mi serve aiuto .. vi scrivo!!

buona giornata massib

Ciao,
prova prima così:

commenta tutti i delay e metti
if( (durata > 0 ) && (durata < 700 ) )

al posto di
if(durata < 700 )

visto che come da documentazione pulseIn ritorna "the length of the pulse (in microseconds) or 0 if no pulse is completed before the timeout (unsigned long)"

Se non va allora implementa un timer con la funzione millis(), qualcosa del tipo:

// Variabile globale
unsigned long actTime = 0;

//...snip...
  if ((millis() - actTime) > 2000) // se sono passati almeno 2 secondi dall'ultimo rilevamento
  {
    if (currentStateU == true && lastStateU == false)
    {  
      if (releState == LOW)
      {
        digitalWrite(rele, HIGH);
        releState = HIGH;
      } 
      else
      {
        digitalWrite(rele,LOW);
        releState = LOW;
        delay(10);
      }
      actTime = millis();
    }
    lastStateU = currentStateU;
  }
//...snip...

così dovrebbe andare, al limite prova a mettere lastStateU = currentStateU; fuori dall’if anche se dovrebbe essere ininfluente.

Ciao!

ciao Xilav, ho dato un'occhiata al tuo sketch ... ma con i mills() , dovendo il mio programma girare H24 perchè la mia scheda sarà sempre accesa ..non c'è problema di OVERFLOW ??

grazie bye

massibal: ho dato un'occhiata al tuo sketch ... ma con i mills() , dovendo il mio programma girare H24 perchè la mia scheda sarà sempre accesa ..non c'è problema di OVERFLOW ??

... se fai questa domanda ... NON hai letto i link che ti ho dato su millis(), ed in particolare il primo!

Guglielmo

..in realtà ho scritto a Xilav il mio dubbio, proprio dopo aver letto l'articolo ;)