Sto utilizzando una fotocella per realizzare una lampada crepuscolare a LED ed utilizzo la funzione map() per spalmare il valore analogico su un canale PWM in uscita che ho collegato ad un op-amp con guadagno 2 per gestire un dimmer.
Il tutto funziona molto bene e sono soddisfatto; l'unica pecca è che se in condizioni di oscurità (luce molto bassa) accendo, all'improvviso, una luce molto forte, i valori delle fotocella oscillano e fanno dei "salti" provocando una sorta di lampeggio della lampada che tenta di inseguire i cambiamenti di luce repentina.
Ad esempio, quando il valore della luminosità varia all'improvviso, i valori del PWM cambiano bruscamente per poi assestarsi dopo un certo periodo:
12
12
12
34
32
20
33
34
Mi dareste dei consigli su come controllare quando i valori analogici letti variano bruscamente?
Vorrei riuscire a rilevare i cambiamenti bruschi ed a settare il pwm in maniera opportuna ed in modo graduale.
Il codice che uso adesso è molto banale:
loop(){
//...
if (digitalRead(crepuscolare) == LOW && digitalRead(motion) == HIGH){
digitalWrite(led5, LOW);
digitalWrite(led7, HIGH);
Serial.println("Motion ON");
int pirVal = digitalRead(pirPin);
if(pirVal == LOW){ //was motion detected
Serial.println("Motion Detected");
for ( int i = 0; i < 20; i++){ // 20 secondi
photocellReading = analogRead(photocellPin);
Serial.println(i);
Serial.print("Analog reading = ");
Serial.println(photocellReading);
LEDbrightness = map(photocellReading, 0, 1023, 255, 0);
bright = LEDbrightness;
Serial.println(bright);
analogWrite(LEDpin, bright);
delay(1000);
if ( digitalRead(pirPin) == LOW ){
Serial.println("Reset, continua da zero!");
i = 0;
}
else if ( (digitalRead(crepuscolare) == HIGH && digitalRead(motion) == HIGH) || (digitalRead(crepuscolare) == HIGH && digitalRead(motion) == LOW) || (digitalRead(crepuscolare) == LOW && digitalRead(motion) == LOW) ) {
i = 1001;
}
}
}
else if(pirVal == HIGH){
Serial.println("No Motion!");
analogWrite(LEDpin, 0);
delay(1);
}
}
//..
}
Uhm.. potresti fare più letture e farti poi la media. Oppure fare una lettura e vedere lo scarto da quella precedente: se è superiore ad un certo valore, potresti prendere dei provvedimenti (inserire una correzione, scartare la lettura, ecc...).
Sono ignorante quindi magari sbaglio, potrebbe essere la fotocellula che sballa l'out per qualche ms perchè arriva luce di colpo, potresti mettere un condensatore (da non so quanto) per levellare gli sbalzi improvvisi, credo
Non sono un matematico per cui non so che tipo di media può servirti. Inizia con la classica media aritmetica e vedi se può risolvere. Fai passare qualche ms tra una lettura e l'altra, per evitare di campionare più volte la stessa lettura.
Ma che fotocellula stai usando? Potresti provare con una fotoresistenza, che ha un tempo di risposta altino ed una linearità nei valori.
Opterei anche io per un condensatore,per quanto riguarda il suo collegamento invece va in questo caso in parallelo ma come hai collegato la fotoresistenza all'ingresso arduino? In condizione di buio ti da 10k mentre di luce ti da 1k, io collegherei la fotor tra positivo ed in arduino,una R di 10k tra in di arduino e gnd ed in parallelo a questa un condensatore elettrolitico di pochi uF (2,2-4,7),il problema che ti rimane però è che la lettura che otterrai non sarà da 0 a 1023 ma da circa 512(buio) a circa 930(luce).Sono conti che ho ottenuto dal valore che assume il "partitore resistivo" in funzione della condizione di luce. Se con una capacità così piccola non risolvi il problema devi aumentarla,l'inconveniente che potrebbe darti è che ritardando la condizione di luce fino ad avere una lettura stabile ritarderai anche la condizione di buio,se questo non ti porta fastidio io proverei così.
Si, i collegamenti sono come quelli che hai detto tu, cioè con la resistenza di 10K, ma senza condensatore perchè non lo avevo considerato.
Leggo il valore con un delay(1) quindi è molto veloce anche se il tutto è all'interno di cicli if() che ad ogni loop valutano i valori di due variabili.
Quindi il consiglio è di mettere un condensatore in parallelo al resistore? E in alternativa considerare la media?
Il fatto del ritardo non so quanto potrebbe causarmi fastidi perchè dipende sempre dal valore di quest'ultimo, se è molto alto, potrebbe essere noioso.