Jump to content
PLC Forum


Sign in to follow this  
bios85

Misurare L'illuminamento Con Fotodiodo E Microcontrollore!

Recommended Posts

bios85

Buona sera a tutti, volevo aggiornarvi su come sta andando il progetto e devo ringraziarvi per i consigli che mi hanno aiutato moltissimo..... In pratica ho sincronizzato le letture del fotodiodo con un timer ogni 10ms, dopo aver fatto 5 letture e calcolato la media vado ad intervenire aumentando ( o diminuendo) di 1 il duty in base alla soglia impostata per poi ricominciare il ciclo.... In questo modo funziona perfettamente senza tremolii e se imposto as esempio 500lux, il valore letto dal sensore oscilla tra 499-501.... direi perfetto!

L'unica pecca è che per portarsi a regime impiega tanto tempo, nel senso che, una volta stabilizzato ad esempio a 500lux, modifico la soglia a 900lux per stabilizzarsi al nuovo valore ci vogliono molti secondi.. forse più di un minuto!!! Forse è solo una mia fissazione perchè nella realtà tutto il sistema è lento, quindi anche il cambiamento di luce!

Oggi ho sostituito nella schedina il nuovo fotodiodo: http://www.abcelectronique.com/composants/telechargement_datasheet.php?id=2925611&part-number=TEMD5510FX01

adesso le misure sono coerenti con il luxmetro tranne in un caso.... mettendo la mia schedina e il luxmetro in una scatola chiusa illuminata all'interna con una lampadina a incandescenza da 21W accesa a circa il 30%, il luxmetro segnava 50lux mentre il mio circuito circa 350lux. Questa differenza io l'attribuisco alla parte infrarossa (dominante della lampadina) che il luxmetro filtra completamente mentre il fotodiodo che uso io capta con una sensibilità di circa 0.3....invece nella stanza dove sto facendo i test, illuminata con lampade ai vapori di sodio, le misurazioni sono quasi identiche... differiscono di una decina di lux.

Secondo voi il mio ragionamento è corretto?

Poi esistono dei filtrini, ad esempio in plastica come le fotocellule, che lasciano passare il visibile e bloccano completamente l'infrarosso?

Grazie ancora a tutti.

Share this post


Link to post
Share on other sites

Livio Orsini
L'unica pecca è che per portarsi a regime impiega tanto tempo..

E' normale perchè lavori solo di reazione e di integrale.

Dovresti variare direttamente il valore di duty in funzione del valore di luminosità; quasto modo di operare è conosciuto come azione di feedforward.

Inoltre potresti dare una correzione proporzionale all'errore, in altri termini realizzare un vero PI con azione di feedback e feedforward.

Share this post


Link to post
Share on other sites
bios85

Ciao e grazie ancora.... io vario direttamente il duty in funzione della luminosità nel senso che: se la luminosità > soglia diminuisco il duty e viceversa....

Potresti spiegarmi un pò meglio con un esempio? Se puoi!!!

Per quanto riguarda il filtro infrarossi sai consigliarmi?

Grazie ancora di tutto

Share this post


Link to post
Share on other sites
Livio Orsini

Semplice.

Poniamo che il duty vari tra 0 e 1000 e poiniamo che per ottenere 500 lux devi avere un duty pari a circa 300.

Ebbene poni direttamente il tuo duty a 300 e lo modifichi con la tecnica che hai descritto.

Poi, al momento di passare da 500 lux a 900 lux, contemporaneamente al cambio del valore di consegna, modifichi anche il duty portandolo, ad esempio 700. Poi la regolazione agirà per ottenere il valore preciso.

Ovviamente la corrispondenza tra riferimento (duty) e variabile controllata (luminosità) o la conosci teoricamente, perchè hai una funzione di trasferimento affidabile, o la ricavi sperimentalmente.

Più il feed forward è preciso, meno deve lavorare la correzione ed è anche più veloce l'andata a regime.

Se questo ti è chiaro, poi vediamo le altre tecniche per aumentare la velocità di risposta del sistema. Non so se te l'ho già scritto, ma tutto questo lo speigo nel mio tutorial sulle regolazioni, esempi compresi. Lo trovi nella sezione didattica sottosezione elettrotecnica.

Per il filtri IR non saprei cosa consigliarti, so che esistono, ma non ho ami approfondito l'argomento. Però se non comporta problemi di saturazione, puoi anche fregartene e depurare la lettura di questa tara.

Share this post


Link to post
Share on other sites
bios85

Grazie ancora.. piano piano sto studiando il tutorial comunque al momento non so ancora che lampada dovrò pilotare quindi per correggere questo problema devo avere prima la lampada.....

Per quanto riguarda la parte IR che il sensore capta è un problema perchè non è sempre costante credo!!! Infatti nei test che sto facendo basta cambiare tipo di lampada, ad esempio da led a incandescenza, per falsare completamente la misura rispetto al luxometro! Quindi devo compensare o con un filtro IR che non riesco proprio a trovare, oppure devo inserire un'alro fotodiodo che mi misuri solo la parte infrarossa. Io penso che tutto ciò si potrebbe evitare se l'errore introdotto dall'infrarosso fosse minimo, il problema è che con una lampada ad incandescenza il mio sensore misura circa 350 invece il luxometro (che è filtrato) circa 50... direi una enorme differenza che forse mi potrà creare problemi nell'ambiente esterno!!!

Share this post


Link to post
Share on other sites
Livio Orsini

Sicuramente le lampade ad incandescenza hanno una notevole componente IR.

Puoi usare un fotodio che ha un picco di risposta nell'infrarosso, oppure scegliere un fotodiodo che non risponda all'infrarosso.

Share this post


Link to post
Share on other sites
bios85

Salve, riprendo questa discussione sul controllo della lampada a led di un lampione stradale in quanto ho ripreso a lavorarci in questi giorno... Ricapitolando, seguendo i vostri consigli sopra ero riuscito a stabilizzare il controllo di una piccola lampada ad incandescenza, in pratica il sistema manteneva costante il valore di luminosità scelto. Ora mi è arrivata la lampada che dovrà poi essere installata sul prototipo, installo il tutto ed inizio i primi test con lampada posizionata ad una altezza di circa 4metri da terra e il sensore (fotodiodo) posto su un tavolo a circa 1metro da terra... La lampada è provvista di driver che accetta un segnale di dimmer analogico 1-10V, per questo motivo ho realizzato un filtro passa basso del quarto ordine sul segnale PWM del micro e con un'adeguata amplificazione pilota il driver senza problemi.

Il controllo funziona discretamente, perchè oscilla intorno al valore scelto di una quantità che è visibile ad occhio nudo (circa +o- 10 lux) ed è molto fastidioso....

Il sistema funziona in questo modo:

Un timer gestisce il tempo di scansione del controllo come vediamo nel codice sottostante

void Timer6_7Interrupt_10ms() iv IVT_ADDR_T7INTERRUPT{
     contatore_luminosita=contatore_luminosita+1;                                     //Incremento il contatore
     if(Flag_Comando_Luminosita==255){                                                //Verifico se ho ricevuto il comando di cambiare luminosita
          contatore_luminosita_comando=0;                                             //Azzero il contatore per iniziare a contare il tempo
          Flag_Comando_Luminosita=0;                                                  //Azzero il flag del comando ricevuto
          Flag_Fine_Comando_Luminosita=0;                                             //Setto il flag per l'inizio di un comando nuovo
          soglia_Da_Applicare=soglia_LUX_Comando;                                     //Cambio la soglia con quella ricevuta dal comando
     }else{
          if((Flag_Fine_Comando_Luminosita==0) && (contatore_luminosita_comando > Tempo_Intensita_Comando)){   //Se il comando è in atto controllo il tempo, finito il quale ritorno alla luminosità di default
               soglia_Da_Applicare=soglia_LUX;
               Flag_Fine_Comando_Luminosita=255;                                      //Indica che il tempo del comando è finito
          }
     }
     if(contatore_luminosita>=30){                                                    //trascorsi 300ms:
         leggi_luminosita();                                                          //Leggo il sensore
         converti_in_lux (luminosita);                                                //Converto il valore letto dal sensore in LUX
         Regola_intensita_lampada(soglia_Da_Applicare, lux);                          //Relolo intensita lampada cambiando il duty del PWM
         contatore_luminosita = 0;
     }
     T7IF_bit   = 0;                                                                  //Azzero Flag
}

Trascorsi i 300ms, leggo il sensore e chiamo il metodo che deve regolare il PWM. Il codice della regolazione è visibile sotto:

     //Regola il duty della lampada in funzione di LUX_desiderati
void Regola_intensita_lampada(unsigned int LUX_desiderati, unsigned int lux_medi){
  unsigned int differenza;
   //pwm_period1---> corrisponde a duty cycle pari a 1
     if((lux_medi < soglia_minima_LUX) && (pwm_duty < pwm_period1)){
          differenza = LUX_desiderati - lux_medi;
          if(differenza>100){
            if(pwm_duty < (pwm_period1-300)){
                 pwm_duty=pwm_duty+300;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=100 && differenza > 50){
            if(pwm_duty < (pwm_period1-250)){
                 pwm_duty=pwm_duty+250;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=50 && differenza > 20){
            if(pwm_duty < (pwm_period1-200)){
                 pwm_duty=pwm_duty+200;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=20 && differenza > 10){
            if(pwm_duty < (pwm_period1-25)){
                 pwm_duty=pwm_duty+25;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=10 && differenza > 4){
            if(pwm_duty < (pwm_period1-7)){
                 pwm_duty=pwm_duty+7;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(pwm_duty < pwm_period1){pwm_duty+=1;}
          PWM_Set_Duty(pwm_duty, 1);
          return;
     }
   
     if(lux_medi > LUX_desiderati){
          differenza = lux_medi - LUX_desiderati;
          if(differenza>100){       //280
            if((lux_medi > soglia_minima_LUX) && (pwm_duty > 300)){
                 pwm_duty=pwm_duty-300;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=100 && differenza > 50){   //140
            if((lux_medi > soglia_minima_LUX) && (pwm_duty > 250)){
                 pwm_duty=pwm_duty-250;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=50 && differenza > 20){  //100
            if((lux_medi > soglia_minima_LUX) && (pwm_duty > 200)){
                 pwm_duty=pwm_duty-200;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=20 && differenza > 10){
            if((lux_medi > soglia_minima_LUX) && (pwm_duty > 25)){
                 pwm_duty=pwm_duty-25;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=10 && differenza > 4){
            if((lux_medi > soglia_minima_LUX) && (pwm_duty > 7)){
                 pwm_duty=pwm_duty-7;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          
          if(pwm_duty > 0){pwm_duty-=1;}
          PWM_Set_Duty(pwm_duty, 1);
          return;
     }
     
     if(lux_medi < LUX_desiderati){
          differenza = LUX_desiderati - lux_medi;
          if(differenza>100){
            if(pwm_duty < (pwm_period1-300)){
                 pwm_duty=pwm_duty+300;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=100 && differenza > 50){
            if(pwm_duty < (pwm_period1-250)){
                 pwm_duty=pwm_duty+250;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=50 && differenza > 20){
            if(pwm_duty < (pwm_period1-200)){
                 pwm_duty=pwm_duty+200;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=20 && differenza > 10){
            if(pwm_duty < (pwm_period1-25)){
                 pwm_duty=pwm_duty+25;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          if(differenza<=10 && differenza > 4){
            if(pwm_duty < (pwm_period1-7)){
                 pwm_duty=pwm_duty+7;
                 PWM_Set_Duty(pwm_duty, 1);
                 return;
            }
          }
          
          if(pwm_duty < pwm_period1){pwm_duty+=1;}
          PWM_Set_Duty(pwm_duty, 1);
          return;
     }
}
//-------------Fine Regola luminosità lampada in moda da avere i LUX_desiderati----------

Quello che faccio è andare a calcolare la differenza tra i lux misurati e quelli desiderati, in funzione di questa differenza agisco con diverso peso sul duty in positivo o in negativo, quando la differenza è al di sotto di 4 lux aumento o diminuisco il duty di una unità.

Un problema che ho notato inizialmente è che il driver presente sulla lampada non è molto veloce ad effettuare il cambiamento di luminosità, infatti ho dovuto cambiare il tempo di campionamento da 100ms a 300ms per iniziare a vedere dei miglioramenti. Poi ho testato un'infinita di valori nell'aumentare o diminuire il duty in funzione della differenza e quelli che vedete sopra sono quelli che mi hanno funzionato meglio.

Come posso fare a migliorare questo controllo? Se io rallento di molto il tutto, funziona discretamente bene ma per specifiche di progetto, ad ogni variazione di luminosità desiderata, il sistema deve reagire in tempi "rapidi" inferiori ai due secondi....

Qualche consiglio?

Ringrazio tutti anticipatamente

Share this post


Link to post
Share on other sites
Livio Orsini
che il driver presente sulla lampada non è molto veloce ad effettuare il cambiamento di luminosità,

Non hai molte alternative devi agire sull'illuminazione. Che tipo di lamada e di driver stai usando? Le lampade ad incandescenza rispondono tranquillamente in meno di 100 ms, idem i regolatori "a taglio di fase".

Share this post


Link to post
Share on other sites
bios85

Ciao, innansitutto volevo ringraziarti per l'aiuto che mi dai su ogni discussione che apro.... gentilissimo!!!

Comunque il driver è il seguente:

http://www.ecat.lighting.philips.com/l/lighting-electronics/led-electronic-drivers/xitanium-constant-current-xtreme/929000702202_eu/

La lampada è da 150W 700mA provvista di 16 led bianchi in serie....

Quindi secondo te come potrei agire per stabilizzare il controllo, in modo che non oscilli visibilmente, anche impiegando un pò più di tempo?

Share this post


Link to post
Share on other sites
Livio Orsini

Da quello che ho letto con quel driver non puoi fare molto. Le caratteristiche son quelle che sono.

Puoi farti un altro driver sfruttando il PWM per modificare la corrente di alimentazione delle lampade.

Misura la tensone ai capi dei dei LEDs, che presumo sia abbastanza elevata perchè suppongo che ciascuno dei 12 LEDs in realtà si aun array di Leds in serie.

Una volta che conosci la tensione ai capi della lampada ti realizzi un generatore di corrente il cui riferimento arriva dal micro.

Share this post


Link to post
Share on other sites
bios85

Si non è eccezionale ma pultroppo devo usare questo, non è stata una mia scelta.... Comunque ho cercato più a fondo le caratteristiche del driver ed ho scoperto che il dimming lo esegue diminuendi la corrente di pilotaggio dei led (questo non modifica la risposta dei led?), dal 10% al 100% della corrente nominale... inoltre la curva di dimming, visibile sotto, va da 1V(10%) a 8V(100%) con incremento minimo dell'1%.

dL2gU5.jpg

Quindi ora vedrò di minurare quanti mV corrispondono ad un incremento di 1% e poi modificherò il controllo sul micro....

Share this post


Link to post
Share on other sites
Livio Orsini

Per variare la luminosità di un LED si può solo intervenire sulla sua corrente.

Se lo alimenti con un generatore di corrente, fai quiesta operazione direttamente; se usi un generatore di tensione esegui l'operazione in modo indiretto, però il risultato finale è sempre il medesimo: varia la corrente nele LED.

Il tempo di risposta di un generatore di corrente costante non è intrinsecamente superiore a quello di un generatore di tensione costante. La differenza eventuale dipende solo dalle caratteristiche dei generatori usati.

Per caratterizzare il tempo di risposta del tuo sistema devi usare un oscilloscopio a due tracce di buona qualità; dai un gradino di riferimento al generatore di corrente usato per alimentare i LEDs e verifichila variazione di corrente in uscita. Se ti sincronizzi sul fronte del gradino di riferimento hai la misura del ritardo e del modo a cui va a regime il geenratore di corrente. Solitamente si usano gradi pari al 10% del valore massimo del riferimento. Si effettuano prove con un riferimento base tra il 10% ed il 90%.

Una volta caratterizzato il comportamento dell'alimentatore, dovrai verificare la risposta del rivelatore (fotodiodo) perchè potresti avere qualche sorprsa anche da quello.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...