comando relè + due sensori

Ciao a tutti, dopo svariati tentativi le mie conoscenze sono arrivate a limite e sono alla ricerca di suggerimenti, il codice è il seguente, non ci sono errori ma non funziona come dico io…

#include <Ultrasonic.h>
#define TRIGGER_PIN  1
#define ECHO_PIN     2
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
int P_fotoresistenza = 4;    
int P_led = 6;      
int P_relay=3;
int P_button=7;

void setup() 
{
  pinMode(P_led, OUTPUT);  
  pinMode(P_relay, OUTPUT); 
  pinMode(P_button, INPUT);

}

void loop() {
   float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  int Valore = analogRead(P_fotoresistenza);        // Legge il valore da fotoresistore    
  analogWrite(P_led, 255-(1023-Valore)/4);          
  int in=digitalRead(P_button);
  if(in==HIGH)
  {
    digitalWrite(P_relay,HIGH);
    delay(5000);
  }
  if(Valore <=0 && cmMsec >= 5.00) 
  {
    digitalWrite(P_relay,HIGH);
    delay(1000);
    digitalWrite(P_relay,LOW);
  }
  else if(Valore>2) 
  {
    digitalWrite(P_relay,LOW);
  }
  delay(150);                      

}

sto usando un HC-SR04 e una fotoresistenza, la fotoresistenza mi serve per rilevare il buio, una volta rilevato il buio deve abilitare il sensore HC-SR04, con la luce non deve funzionare nulla, il problema è il seguente, quando è buio e io passo davanti al sensore voglio fare scattare il relè per un tot di tempo per poi farlo spegnere, invece attacca e stacca all’infinito come fa un led con il programma “blink”… per questo ho provato a mettere quel delay nel secondo if…
come posso risolvere?

La logica dell'algoritmo e le tue parole parlano di due obbiettivi ben diversi.

Allora primo devi verificare se è presente luce nell'ambiente, se "c'è buio" allora invii il ping, se il ping rivela un oggetto a meno di 5 cm (a me sembrano un po pochi) allora accendi la luce attendi il tempo che vuoi dopo di che spegni la luce. semplice. Tu invece cerchi di leggere un valore da un pulsante di cui non hai parlato. Poi invii il ping senza verificare che ci sia luce o meno. Fai un sacco di confusione.

non ho parlato del pulsante perchè quello funziona, l'ho messo solo per accendere il relè manualmente senza per forza passare davanti al sensreo; è il relè che non resta acceso per un tot di tempo quando passo davanti al sensore... il funzionamento è proprio quello che hai detto tu ma non riesco a farlo funzionare in quel modo.. spiegati meglio, cosa ho sbagliato??

Prima cosa non tieni traccia del valore del pulsante, se non ho capito male se il pulsante viene premuto la luce si deve accendere, se viene premuto di nuovo deve spegnersi? oppure deve essere a tempo pure quello?

aspetta, il pulsante pensandoci mi è inutile quindi l’ho rimosso, tieni conto che ho solo i sensori per fare scattare il relè…
questo è il codice, con questo il relè si apre e si chiude sempre ma smette se la fotoresistenza rileva la luce

#include <Ultrasonic.h>
#define TRIGGER_PIN  1
#define ECHO_PIN     2
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
int P_fotoresistenza = 4;         
int P_relay=3;

void setup() {
  pinMode(P_relay, OUTPUT); 
}
void loop() {
   float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  int Valore = analogRead(P_fotoresistenza);        // Legge il valore da fotoresistore    
  if(Valore <=0 && cmMsec >= 5.00) {
    digitalWrite(P_relay,HIGH);
    delay(1000);
    digitalWrite(P_relay,LOW);
  }
  else if(Valore>2) {
    digitalWrite(P_relay,LOW);
  }
  delay(150);                      
}

invece con questo codice una volta che passo davanti al sensore hc-s04 il led resta acceso fisso e si spegne soltanto se la fotoresistenza rileva luce…

#include <Ultrasonic.h>
#define TRIGGER_PIN  1
#define ECHO_PIN     2
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
int P_fotoresistenza = 4;         
int P_relay=3;

void setup() {
  pinMode(P_relay, OUTPUT); 
}
void loop() {
   float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  int Valore = analogRead(P_fotoresistenza);        // Legge il valore da fotoresistore    
  if(Valore <=0 && cmMsec >= 5.00) {
    digitalWrite(P_relay,HIGH);
    delay(1000);
  }
  else if(Valore>2) {
    digitalWrite(P_relay,LOW);
  }
  delay(150);                      
}

Dovresti annidare gli if, lo hai mai fatto? Tieni conto di questi punti -Verifico l'assenza di luce mediante fotoresistenza... -Invio il ping, se è presente un oggetto a meno di Xcm... -Accendo la luce, attendo Y secondi, spengo la luce In quest'ordine.

no non l’ho mai fatto, potresti dirmi come fare? :slight_smile:

#include <Ultrasonic.h>
#define TRIGGER_PIN  1
#define ECHO_PIN     2
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
int P_fotoresistenza = 4;         
int P_relay=3;

void setup() {
  pinMode(P_relay, OUTPUT); 
}
void loop() {
   float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  int Valore = analogRead(P_fotoresistenza);        // Legge il valore da fotoresistore    
  if (Valore>2) { 
    digitalWrite(P_relay,LOW);
  }
  else if (Valore <=0 && cmMsec >= 5.00){
    digitalWrite(P_relay,HIGH);
    delay(1000);
    digitalWrite(P_relay,LOW);
  }
  else {
    digitalWrite(P_relay,LOW);
    }
  delay(150);                      
}

ho provato anche così ma niente :frowning:
il relè attacca e stacca sempre…

se intendi così non funziona nemmeno così, attacca e stacca sempre…

#include <Ultrasonic.h>
#define TRIGGER_PIN  1
#define ECHO_PIN     2
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
int P_fotoresistenza = 4;         
int P_relay=3;

void setup() {
  pinMode(P_relay, OUTPUT); 
}
void loop() {
   float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  int Valore = analogRead(P_fotoresistenza);        // Legge il valore da fotoresistore    
  if (Valore <= 0) 
  { 
    if (cmMsec >= 5.00)
    {
    digitalWrite(P_relay,HIGH);
    delay(1000);
    digitalWrite(P_relay,LOW);
    }
    else {
    digitalWrite(P_relay,LOW);
    }                  
}
  delay(150);   
}

Spiegare a programmare in un topic è un impresa insormontabile.

#define PIN_PHOTORESISTANCE A1
#define PIN_ULTRASONIC_TRIGGER 5
#define PIN_ULTRASONIC_ECHO 6
#define PIN_LIGHT 7

#define THRESHOLDDARK 400//Soglia analogica tra luce e buio
#define ACTIVATIONDISTANCE 5//Distanza massima per l'attivazione delle luci espressa in cm

#define ACTIVATIONTIME 10000//Tempo di accensione luci espresso in ms

void setup() {
  pinMode(PIN_ULTRASONIC_TRIGGER, OUTPUT);
  pinMode(PIN_ULTRASONIC_ECHO, INPUT);
  pinMode(PIN_LIGHT, OUTPUT);
}

void loop() {
  if(analogRead(PIN_PHOTORESISTANCE) < THRESHOLDDARK) {//Verifico che non vi sia luce
    //Invio il ping
    digitalWrite(PIN_ULTRASONIC_TRIGGER, HIGH);//Segnale alto sul pin TRIGGER del HC-SR04
    delayMicroseconds(10);//Attendo 10 microsecondi
    digitalWrite(PIN_ULTRASONIC_TRIGGER, LOW);//Segnale basso sul pin TRIGGER del HC-SR04
    
    if(0.017 * pulseIn(PIN_ULTRASONIC_ECHO, HIGH) < ACTIVATIONDISTANCE) {//Leggo la risposta del HC-SR04 sul pin pin ECHO, calcolo la distanza e verifico che sia minore di 
      digitalWrite(PIN_LIGHT, HIGH);//Accendo la luce
      delay(ACTIVATIONTIME);//Attendo
      digitalWrite(PIN_LIGHT, LOW);//Spengo la luce
    }
  }
}

Questo è l’esempio piu banale di funzionamento, presenta dei problemi ma come base dovrebbe bastarti per comprendere. Cerca di capire come funziona questo semplice codice.

cos'è 0.017??

è una costante, è la metà della velocità del suono nell'aria espressa in cm/us a 20°C. Con un sensore di temperatura ed uno di umidità si può aumentare come precisione, ma nel tuo caso è un valore che può andare bene.

ho tolto il relay e ho messo un led ed esso lampeggia, fa la stessa cosa del programma di prima ç_ç
ci ho messo tutta la buona volontà ho modificato qualcosa e mi fa sempre lo stesso difetto…

#define PIN_PHOTORESISTANCE A0
#define PIN_ULTRASONIC_TRIGGER 4
#define PIN_ULTRASONIC_ECHO 5
#define PIN_LIGHT 7

#define THRESHOLDDARK 0//Soglia analogica tra luce e buio
#define ACTIVATIONDISTANCE 3//Distanza massima per l'attivazione delle luci espressa in cm

#define ACTIVATIONTIME 2000//Tempo di accensione luci espresso in ms

void setup() {
  pinMode(PIN_ULTRASONIC_TRIGGER, OUTPUT);
  pinMode(PIN_ULTRASONIC_ECHO, INPUT);
  pinMode(PIN_LIGHT, OUTPUT);
  Serial.begin(9600);
}

void loop() {
 int val = analogRead(PIN_PHOTORESISTANCE);
  if(val <= THRESHOLDDARK) {//Verifico che non vi sia luce
    
    if(0.017 * pulseIn(PIN_ULTRASONIC_ECHO, HIGH) < ACTIVATIONDISTANCE) {//Leggo la risposta del HC-SR04 sul pin pin ECHO, calcolo la distanza e verifico che sia minore di 
      digitalWrite(PIN_LIGHT, HIGH);//Accendo la luce
      delay(ACTIVATIONTIME);//Attendo
      digitalWrite(PIN_LIGHT, LOW);//Spengo la luce
    }
  }
}

Ok spiega con precisione quello che accade. Il LED lampeggia sempre? anche in presenza di luce? con che frequenza? Se vi è qualcuno nella portata del sensore o sempre?

questo è il codice

#define PIN_PHOTORESISTANCE A4
#define PIN_ULTRASONIC_TRIGGER 1
#define PIN_ULTRASONIC_ECHO 2
#define PIN_LIGHT 3

#define THRESHOLDDARK 0//Soglia analogica tra luce e buio
#define ACTIVATIONDISTANCE 3//Distanza massima per l'attivazione delle luci espressa in cm

#define ACTIVATIONTIME 2000//Tempo di accensione luci espresso in ms

void setup() {
  pinMode(PIN_ULTRASONIC_TRIGGER, OUTPUT);
  pinMode(PIN_ULTRASONIC_ECHO, INPUT);
  pinMode(PIN_LIGHT, OUTPUT);
}

void loop() {
 int val = analogRead(PIN_PHOTORESISTANCE);
  if(val <= THRESHOLDDARK) {//Verifico che non vi sia luce
    
    if(0.017 * pulseIn(PIN_ULTRASONIC_ECHO, HIGH) < ACTIVATIONDISTANCE) {//Leggo la risposta del HC-SR04 sul pin pin ECHO, calcolo la distanza e verifico che sia minore di 
      digitalWrite(PIN_LIGHT, HIGH);//Accendo la luce
      delay(ACTIVATIONTIME);//Attendo
      digitalWrite(PIN_LIGHT, LOW);//Spengo la luce
    }
  }
}

quando rileva luce blocca il processo ed è giusto, quando invece rileva il buio in ogni caso, a qualunque distanza io sia dal sensore, il led lampeggia… la frequenza del lampeggio dipende da ACTIVATIONTIME

Ok effettua un debug via seriale dei valori di distanza e verifica se sono corretti.

La logica del programma implica che vi sia un lampeggio, te lo avevo detto che necessità di alcuni aggiustamenti.

si ok, ma secondo quale logica lampeggia?? :open_mouth:
se il blink lampeggia con
digitalWrite … HIGH
delay(1000)
digitalWrite … LOW
delay(1000)

perchè questo mio programma deve lampeggiare?
se ho messo
digitalWrite HIGH
delay
digitalWrite LOW

il programma blink se tolgo il secondo delay fa accendere il led per il tempo stabilito e poi lo spegne, perchè questo non funziona in questo modo???

Lampeggia in quanto viene rilevata la presenza si accendono le luci, aspetta un tot e spegne le luci dopo di che riesegue il controllo. Le luci rimangono spente per tutta la verifica. Più corretto sarebbe, scade il tempo invece di spegnere subito le luci rieseguo il ping in caso non rilevi più l'oggetto spegni le luci.

niente non ci arrivo :frowning:

#define PIN_PHOTORESISTANCE A4
#define PIN_ULTRASONIC_TRIGGER 1
#define PIN_ULTRASONIC_ECHO 2
#define PIN_LIGHT 3

#define THRESHOLDDARK 0//Soglia analogica tra luce e buio
#define ACTIVATIONDISTANCE 3//Distanza massima per l'attivazione delle luci espressa in cm

#define ACTIVATIONTIME 2000//Tempo di accensione luci espresso in ms

void setup() {
  pinMode(PIN_ULTRASONIC_TRIGGER, OUTPUT);
  pinMode(PIN_ULTRASONIC_ECHO, INPUT);
  pinMode(PIN_LIGHT, OUTPUT);
}

void loop() {
 int val = analogRead(PIN_PHOTORESISTANCE);
  if(val <= THRESHOLDDARK) {//Verifico che non vi sia luce 
    if(0.017 * pulseIn(PIN_ULTRASONIC_ECHO, HIGH) < ACTIVATIONDISTANCE) {//Leggo la risposta del HC-SR04 sul pin pin ECHO, calcolo la distanza e verifico che sia minore di 
      digitalWrite(PIN_LIGHT, HIGH);//Accendo la luce
      delay(ACTIVATIONTIME);//Attendo
      digitalWrite(PIN_LIGHT, LOW);//Spengo la luce
    }
    else if (0.017 * pulseIn(PIN_ULTRASONIC_ECHO, HIGH) > ACTIVATIONDISTANCE) {
    digitalWrite(PIN_LIGHT, LOW);
     
    }
  }
}

ho provato in mille modi e combinazioni il led lampeggia sempre…

Tu stai andando a tentativi, non si programma andando a tentativi. Stai cercando di dare una mente ad un computer inanimato, se lui non ci può mettere la logica questo è compito tuo! Cerca di portare avanti sketch piu semplici, impara e man mano che avrai capito come si sviluppa un algoritmo questo esercizio diventerà fattibile per te in completa autonomia.

Questo non vuol dire assolutamente arrangiati, ma si notano delle lacune nel tuo apprendimento non solo di sintassi ma proprio di stesura degli algoritmi a cui non si può porre rimedio in un post su un forum, in ogni caso se hai altre domande chiedi pure.