conflitto tra LED e LDR

Ciao a tutti. Come descritto in questo post http://arduino.cc/forum/index.php/topic,63627.0.html sto realizzando una piccola applicazione che mi consenta di accendere 8 led bianchi quando un LDR rileva buio completo. Superati i problemini con lo shift register 74HC595, ora tutto funziona con questo codice:

int latchPin = 8;  //Pin connesso al ST_CP del 74HC595
int clockPin = 12;  //Pin connesso al SH_CP del 74HC595
int dataPin = 11;  //Pin connesso al DS del 74HC595

int photocellPin0 = 0; // pin analogico ldr e 10k connessi a 0
int photocellReading0;    // lettura dati analogici 
float Res0=10.0;	// resistore del sensore ldr in KOhms

void setup() {
  //settaggio dei pin output 
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
Serial.begin(9600);
}

void loop(void) {
  photocellReading0 = analogRead(photocellPin0);   // lettura pin analogico
  float Vout0=photocellReading0*0.0048828125;	// calcolo del voltaggio
  int lux0=500/(Res0*((5-Vout0)/Vout0));	     // calcolo Lux
  Serial.print("Luminosidad 0: ");		     // stampa a monitor della misura (in Lux)
  Serial.print(lux0);
  Serial.print(" Lux\t");
  Serial.print("  Voltage: ");			     // stampa a monitor del voltaggio sul pin 0
  Serial.print(Vout0);
  Serial.print(" Volts\t");
  Serial.print("Output: ");
  Serial.print(photocellReading0);		   // stampa del livello misurato al pin 0
  Serial.print("   Ligth conditions: ");		// stampa condizioni di luce rilevataPrint
  
  if (photocellReading0 < 10) {
  Serial.println("- Dark");
  }
  else if (photocellReading0 < 200) 
  Serial.println(" - Dim");
  else if (photocellReading0 < 500) 
  Serial.println(" - Light");
  else if (photocellReading0 < 800) 
  Serial.println(" - Bright");
  else {
  Serial.println(" - Very bright");
}
  if (photocellReading0 < 10){  // condizione -se-
  digitalWrite(latchPin, LOW);  // stato dello shift register
  shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
  digitalWrite(latchPin, HIGH);
  delay(1000);
  Serial.println("LED ON");
}
  else if (photocellReading0 > 10)
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);   
  digitalWrite(latchPin, HIGH);
  delay(1000);
  
}

A questo punto i led si accendono contemporaneamente quando il LDR rileva buio assoluto (secondo i parametri impostati da me). Il problema è che una volta accesi i Led, il LDR rileva la luce emessa dagli stessi Led e... si riavvia il loop per cui i Led si spengono. Io invece vorrei che una volta accesi i LED il LDR venisse escluso/spento per non dare inizio un'altra volta al ciclo. Ho provato aggiungendo a fine codice queste stringhe:

}
if (photocellReading0 < 10){
digitalWrite(photocellPin0, LOW);
Serial.println(“SENSOR LED OFF”);
}

.. ma non va. Cosa fare? Grazie a tutti in anticipo,
Siro

Usa un flag di stato.
Ossia metti una variabile a TRUE quando accendi i led.
Nella lettura dell'LDR, salta questo controllo se la variabile è a TRUE.
Quando spengi i LED, rimetti a FALSE il flag, così che puoi leggere nuovamente il sensore.

Grazie Leo72, ora non mi resta che andare a studiarmi un po' l'utilizzo del TRUE/FALSE (sono veramente a secco di C!). Qualche "dritta" da dove iniziare? grazie

  if (photocellReading0 < 10){  // condizione -se-
  digitalWrite(latchPin, LOW);  // stato dello shift register
  shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
  digitalWrite(latchPin, HIGH);
  delay(1000);
  Serial.println("LED ON");
}
  else if (photocellReading0 > 10)
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);   
  digitalWrite(latchPin, HIGH);
  delay(1000);
  
}
  1. e se fosse 10?
  2. non pensi che oltre allo shiftout non cambi poi molto?
  3. perchè se è inferiore ti dice che il led è acceso mentre se è superiore non dice nulla?
  4. usa gli operatori booleani
un'operatore booleano ha 2 valori (true/false) equivalenti a 1/0.
potresti usare un case switch oppure un if (consigliato) per controllare (che sembra tu conosca già)
if (miovalore == true) {
//segue codice
}
boolean miostato = false; //la mia variabile booleana imposto per default su false
if (miostato = false) {
Serial.println("è falso!");
}
else { //ovviamente se non è falso...
Serial.println("è vero!");
}

Ciao

Ciao Marbi. Anzitutto grazie per l'esempio di operatori booleani :slight_smile:
per rispondere a:

  1. e se fosse 10?
  2. non pensi che oltre allo shiftout non cambi poi molto?
  3. perchè se è inferiore ti dice che il led è acceso mentre se è superiore non dice nulla?
  4. usa gli operatori booleani

1 e 2: non capisco esattamente a cosa ti riferisci: 10 è il valore sotto il quale voglio si accendano tutti i led; sullo shiftout non ti seguo :roll_eyes:
3: perchè lo stato >10 per me rappresenta di fatto lo stato inerziale del ciclo (diciamo che do per scontato che il sistema non si attiva quando c'è una minima luce)
4: grazie per l'empio postato, ora provo e faccio sapere
ciao
siro

4: grazie per l'empio postato, ora provo e faccio sapere

... ovviamente era: "esempio postato"
ciao

niente... c'è qualcosa che proprio non capisco:

  1. devo agire sul LDR, quindi sul pin analogico 0. Ma se dichiaro:

boolean photocellPin0 = true
mi riporta un conflitto in quanto photocellPin0 è già dichiarato come int photocellPin0 = 0

  1. di conseguenza anche questo:

if (photocellPin0 <10) {
photocellPin0 = true;
} else {
photocellPin0 = false;
}

non mi serve a nulla...

che fare? grazie in anticipo

rieccomi... (mi son perso qualcosa?) :astonished:

tornando a noi...
era semplicemente un consiglio, in quanto c'è 1 probabilità che "esca" il 10 
in quel caso "salti" il ciclo, perchè non hai impostato nulla per quel valore.

avrei modificato in if (photocellReading0 <= 10) {

per il resto mi spiego meglio 

[code]
if (photocellReading0 < 10){  // condizione -se-
  digitalWrite(latchPin, LOW);  // stato dello shift register
  shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
  digitalWrite(latchPin, HIGH);
  delay(1000);
  Serial.println("LED ON");
}
  else if (photocellReading0 > 10)
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00000000);   
  digitalWrite(latchPin, HIGH);
  delay(1000);
  }

ossia in tutte e due eseguono gli stessi comandi (tranne lo shiftOut), quindi l'avrei impostato diversamente (se lo deve sempre fare perchè lo ricopio?

boolean LedOn = false;
String Codice; //una bella revisione perchè non so se realmente serve una variabile String

if (photocellReading0 < 10){ // condizione -se-
LedOn = true;
shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
delay(1000);

} else if (photocellReading0 > 10){
LedOn = false;
shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
delay(1000);
}
digitalWrite(latchPin, HIGH);
digitalWrite(latchPin, LOW);
if (LedOn = true) {
Serial.println("LED ON");
}
[/code]

spero adesso di esserti stato più utile, sono passato adesso alla stimata piattaforma, vengo da un'altro linguaggio di programmazione...
sto in "rodaggio" :sweat_smile:

bene... ovviamente anche io sono in pieno rodaggio :cold_sweat: e arrivo (zoppicando :slight_smile: ) da matlab...
sulla variante <= 10 hai pienamente ragione (in realtà io cerco il buio assoluto e vorrei arrivare a <= 0).
sul resto sarei d'accordo (ed effettivamente il mio post di qualche giorno fa partiva bene o male dal tuo stesso ragionamento), ma ho provato e riprovato e se non ripeti l'intera sequenza (copia-incolla tranne lo shifOut) il signor Arduino non capisce proprio quello che voglio... (misteri della tecnologia :roll_eyes:).
Mi resta il problema del sensore ldr che continua ad interagire con i led quando questi si accendono. adesso metto insieme le tue "dritte" e quelle di di leo72 e cerco di tirare fuori qualcosa di plausibile (booleaneamente parlando!)
in alternativa stavo vedendo il comando "interrupt" se può servire a qualcosa.
grazie e ciao

A questo punto i led si accendono contemporaneamente quando il LDR rileva buio assoluto (secondo i parametri impostati da me). Il problema è che una volta accesi i Led, il LDR rileva la luce emessa dagli stessi Led e... si riavvia il loop per cui i Led si spengono. Io invece vorrei che una volta accesi i LED il LDR venisse escluso/spento per non dare inizio un'altra volta al ciclo.

if LedOn è true vuol dire che i led sono accesi!!!
potresti impostare un'if all'inizio del ciclo... se sono accesi, non rilevare, o meglio se sono spenti... rileva :smiley:

se il problema è "elettronico" sono l'ultima persona che può aiutarti :frowning: sorry

Stavo pensando ad una cosa. Con il mio primo suggerimento, se accendi i LED, poi non leggerai mai più il sensore, quindi non spengerai mai più i LED. Devi perciò obbligatoriamente mettere il sensore in un punto in cui non possa in alcun modo ricevere la loro luce, altrimenti è il classico cane che si morde la coda da cui non si riesce ad uscire.

ciao leo72, scusa se rispondo così tardi. Si, effettivamente il problema è proprio questo, ma io ho necessità che il ldr sia nella stessa "scatola nera" in cui si accendono i led. Cmq - anche grazie ai vostri suggerimenti che mi hanno "oliato" un po' il cervello - alla fine ho risolto parzialmente giocando sui valori di delay. Domani torno alla carica perchè ho intenzione di metter altri ldr: almeno uno che svolga lo stesso compito di on/off per i led e almeno altri 4 che mi dicano se i valori di lux emessi dai led rientrano in un certo intervallo... ne avrete da suggerirmi! :smiley:
grazie ancora
ciao
siro

e tu fai in modo che non si vedano.
puoi aggiungere un "pannello" tra i led ed il sensore?
potresti provare a prendere un tondino di plastica (meglio se a cono con la punta rivolta verso il basso) dove al suo interno stazionerai il tuo sensore.
l'altezza del cono/tondino deve essere superiore al led ed al sensore, in questo modo non possono vedersi (perchè la luce viaggia in linea retta!:wink: )
secondo me potrebbe funzionare... veterani permettendo!!! :cold_sweat: