Buongiorno a tutti gli utenti del forum.
Vorrei porre un quesito riguardante la dimmerizzazione di una lampadina a 220V con Arduino UNO.
Premetto che sono abituato a maneggiare con cautela la tensione di rete perchè ci lavoro tutti i giorni, usando le dovute precauzioni, questo per tranquillizzare chi giustamente mi allerta sulla pericolosità.
Detto questo vi spiego brevemente il mio progetto ed il relativo problema che riscontro.
Ho costruito un circuitino di zero crossing detection per intercettare l'istante preciso in cui la semionda di fase passa per lo zero ed in seguito ho utilizzato l'uscita del suddetto circuito per innescare il triac che mi accende la lampadina dopo un opportuno ritardo calcolato da arduino con una funzione che ho inserito.
L'uscita del filtro zero crossing, attraverso optoisolamento, l'ho collegata all'ingresso 2 di Arduino, mentre per innescare il triac utilizzo l'uscita 8 di arduino, anch'essa con opportuno optoisolamento.
Ora il problema che riscontro è il seguente: Se scrivo la routine di accensione del triac nel loop principale il sistema funziona egregiamente ed ottengo una regolazione tra max e minima luminosità perfetta.
Chiaramente funziona ma non può andare bene perchè se scrivo altro programma nel loop (o peggio se metto dei ritardi che sicuramente mi serviranno) il tutto influisce sui tempi di innesco del triac creando un fastidioso sfarfallio della luce.
Utilizzando un interrupt che usa il mio ingresso di zero crossing per attivarsi, lo sfarfallio c'è comunque.
E' evidente che sbaglio qualcosa nella gestione dell'interrupt, ma non riesco a capire cosa.
Posto i due codici (funzionante e non) e ringrazio anticipatamente chi vorrà aiutarmi.
Saluti a tutti
CODICE FUNZIONANTE MA CON GESTIONE NEL LOOP
int AC_LOAD=8; // uscita per innesco triac
int valore_pot;//variabile che conterrà il valore letto dal potenziometro
int ritardo;
int synk=2;
void setup()
{
pinMode(AC_LOAD, OUTPUT);
pinMode(synk, INPUT);
digitalWrite(synk,LOW);
}
void loop() {
if (digitalRead (synk)==HIGH)
{
valore_pot=analogRead(0);
ritardo=(8500/1023)*valore_pot;//ho limitato a 8500 microsecondi il massimo ritardo per evitare di scavallare alla semionda successiva (a 50Hz max 10.000 microsecondi)
// ma per sicurezza ho tenuto max 8500)
if (ritardo<500) {ritardo=500;}//serve per evitare che il tempo di innesco sia inferiore ai 500 microsecondi per non rimanere troppo vicini allo zero di fase
delayMicroseconds(ritardo);
digitalWrite(AC_LOAD, HIGH);
delayMicroseconds(10);
digitalWrite(AC_LOAD, LOW);
}
else
{
digitalWrite(AC_LOAD, LOW);
}
}
CODICE CHE FUNZIONA MALE (CON INTERRUPT MA SFARFALLIO DELLA LUCE)
int AC_LOAD=8; // uscita per innesco triac
int valore_pot; // variabile che conterrà il valore letto dal potenziometro
volatile int ritardo; //variabile che conterrà il ritardo di innesco triac rispetto allo zero crossing per determinare la luminosità della lampada
int synk=2;
void setup()
{
pinMode(AC_LOAD, OUTPUT);//
pinMode(synk, INPUT);
attachInterrupt(0, zero_crosss_int,HIGH);
digitalWrite(synk,LOW);
}
void zero_crosss_int() // interrupt per innesco triac
{
delayMicroseconds(ritardo);
digitalWrite(AC_LOAD, HIGH);
delayMicroseconds(10);
digitalWrite(AC_LOAD, LOW);
}
void loop() {
valore_pot=analogRead(0);
ritardo=(8500/1023)*valore_pot;//ho limitato a 8500 microsecondi il massimo ritardo per evitare di scavallare alla semionda successiva (a 50Hz max 10.000 microsecondi)
// ma per sicurezza ho tenuto max 8500)
if (ritardo<500) {ritardo=500;}//serve per evitare che il tempo di innesco sia inferiore ai 500 microsecondi per non rimanere troppo vicini allo zero di fase
}
Ciao Cam, scusami se ho sbagliato qualcosa nell'intervenire nel forum (sono nuovo).
Il problema è che non risco a capire cosa ho sbagliato
Abbi pietà e dimmi cosa devo fare che rimedio subito.
Forse ho sbagliato qualcosa nella presentazione??
Grazie anticipatamente.
Edo
Il progetto non è banale, io l'ho affrontato impiegando due timer di un Attiny84, programmazione a basso livello, e oscilloscopio. Il primo problema da affrontare e risolvere è hardware; serve un circuito di zerocrossing preciso a sufficienza, la precisione in questo caso riguarda la costante di risposta del circuito che non deve slittare in anticipo e posticipo. Conoscendo il tempo di risposto ed avendo constatato che è assimilabile ad una costante si può procedere allo sviluppo del software, tenendo conto che il tempo di risposta è di 80us lo si può impiegare per nei calcoli al fine di inviare l'impulso di trigger in modo preciso. Poi ci sono altre considerazioni legate al funzionamento dei triac che se non conosciuto e comprese non permettono di sviluppare una applicazione enbedded funzionale. Per dirne una: per innescare la conduzione del triac tra A e K deve scorrere una minima corrente che dipende dal tipo di triac impiegato.
Quindi il triac potrebbe fallire nel portarsi in conduzione perché hai inviato segnale di trigger troppo presto.
secondo me, queste cose vanno affrontate totalmente in hardware
farle in software significa complicarsi la vita, pero' e' anche vero
che in sw e' un esercizio di stile, su questo non ci sono dubbi
MauroTec, innanzitutto ti ringrazio per la risposta; il sistema hardware comunque funziona perfettamente in quanto utilizzando il primo applicativo che ho postato sopra ottengo una regolazione perfetta dal 100% a quasi 0 della luminosità della lampada (per intenderci quando porto a 0 il potenziometro che ho messo sull'ingresso A0, che è poi quello che mi serve per determinare il ritardo di innseco del triac, riesco ad ottenere addirittura il filamento appena appena acceso, senza tremolii o disturbi).
Per cui ritengo che dal punto di vista HW non ci sia nessun problema; quello che non riesco invece a fare è utilizzare un interrupt per gestire l'innesco della lampada (vedi secondo applicativo postato) perchè si desincronizzano gli impulsi di innesco e tremola tutto.
Del resto sono obbligato ad usare un interrupt per l'innesco perchè al loop devo far eseguire il programma principale.
Y888099:
secondo me, queste cose vanno affrontate totalmente in hardware
farle in software significa complicarsi la vita, pero' e' anche vero
che in sw e' un esercizio di stile, su questo non ci sono dubbi
Grazie per la risposta Y888099, hai centrato il problema, sono un ostinato testone zuccone, ma tutto dettato per la passione dell'argomento.
Ciao e grazie
Non puoi usare il delay() o delayMicroseconds() per generare i ritardi [EDIT] perché sono funzioni che bloccano l' esecuzione di altre parti dello sketch[/EDIT]. Per la durata del impulso va bene perché é un tempo corto.
Per le tempisitiche devi usare millis() o micros() vedi esempi del IDE: blink without delay.
Grazie per la risposta Y888099, hai centrato il problema, sono un ostinato testone zuccone, ma tutto dettato per la passione dell'argomento.
Ciao e grazie
Non è così oggi, un tempo esistevano un gran numero di circuiti integrati dedicati al controllo dell'innesco di un triac, infatti ho ancora dentro delle vecchie schede di controllo velocità impiegate nelle prime lavatrici (lavapanni) dotate di programmatore multicamma e quindi elettromeccanico. Oggi il controllo del motore universale (eccitazione serie) a spazzole viene gestito totalmente da una sola MCU 8 o 16 bit, paragonabili ad un 328 o 644 di Atmel.
Esistono triac pensati per controllare carichi altamente induttivi, ST ne ha una grande varietà.
Pertanto per controllare un motore universale, oggi è imperativo usare una MCU, e il metodo della parzializzazione di fase.
Con un Attiny84 controllo due triac (credo, non ho più il progetto), ma togliti dalla testa di farlo con arduino style.
Programma i timer interni (c'è n'è tre, più il watchdog), scrivi le routine ISR in modo che impegnino meno tempo CPU possibile, quindi niente digitalWrite, digitalRead, niente librerie e scrivi il codice cucito sulla MCU, sfruttando tutto l''hardware in modo più ingegnoso che riesci.
Ciò non di meno, con il 328 e arduino style penso ci puoi riuscire con l'aiuto del forum (e se avessi un oscilloscopio ti accorgeresti quanto poco stabile è il rilevatore ZCD), però magari questo non è il tuo caso e per fortuna o esperienza hai un ZCD affidabile e stabile, ciò è da considerare un buon punto di partenza.
PS: io per impegni personali latito il forum, ma ete, nid, uwe, ecc sapranno sicuramente guidarti verso una soluzione che soddisfi le tue necessità.