Sari la conținut
ELFORUM - Forumul electronistilor

Dimmer AC - nelamurire


rlodina

Postări Recomandate

Salut,

Atasat este partea de cod din intrerupere

void interrupt() {unsigned char dummy;  //if (INTCON.INT0IF) { fall=1;INTCON.INT0IF=0;}      if((INT0IE_bit==1)&&(INT0IF_bit==1)){INT0IF_bit=0;fall=1;    out=0;    out1=0;    out2=0;    out3=0;    flag_out=0;    TMR0IF_bit=0;    TMR0=249;    TMR0IE_bit=1;    contor_tmr0=0;    }    if((TMR0IE_bit==1)&&(TMR0IF_bit==1)){        //out=1;        //DELAY_uS(1);        //out=0;        TMR0IF_bit=0;        TMR0=249;        contor_tmr0=contor_tmr0+1;        if(contor_tmr0==dim){out=1;}        if(contor_tmr0==dim1){out1=1;}        if(contor_tmr0==dim2){out2=1;}        if(contor_tmr0==dim3){out3=1;}    }   GIE_bit=1;}

Poate ca exista si o varianta mai eleganta de scriere, dar nu prea ma pricep la scris coduri placute la vizualizare.

Schema, momentan nu o am, voi face rost de ea curand.

Toate bune.

Editat de costi002
Link spre comentariu
  • Răspunsuri 38
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

pentru inspiratie, te-ai uitat aici ?

in fond, problema ta nu e atat de grava. iti citeste corect, poti gestiona din soft situatia, ca timp ai destul (ma refer la pulse)

 

PS: nu cred sa fie problema in HAA1X. e destul de raspandit, si in ultima vreme se foloseste EL, in loc de punti...

 

pentru teste incearca codul asta

//Arduino NANO#define IN_A 5volatile boolean zero_cross=0;void setup(){  	 pinMode(IN_A, OUTPUT);    attachInterrupt(0, onZeroCross, RISING);      }void onZeroCross() {  zero_cross = true;  digitalWrite(IN_A, 0);  }void loop()  {  if(zero_cross == true) {      digitalWrite(IN_A, 1);					  	   zero_cross=false;  }}
Editat de Vizitator
Link spre comentariu

@AW Genetix :

  - "pentru inspiratie, te-ai uitat aici ?"  (http://playground.arduino.cc/Main/ACPhaseControl) : da - dar mi-a trecut repede - codul nu-i prea adaptabil la 12 dimări simultane.

 

 - "cu ce faci splash-urile alea smechere tare ?"  - dacă te referi la acele capturi de ecran adnotate - folosesc exclusiv aplicațiile native din sistemul de operare (macOS).

Captura cu Grab, adnotări cu Preview . 

 

Nu mai folosesc windows (decat pe la servici ca încă nu ma pot despărți de Visual Studio) de aprox 5 ani (folosesc macOS si linux (CentOS - fara interfata grafica)).  Atunci a fost un gest de revoltă (relativ la MS) - acum sunt mai indiferent. Oricum a fost una dintre cele mai bune decizii pe care le-am luat (daca vrei ma explic). 

 

 

Link spre comentariu

nu vreau sa explici. singura problema o ai cu multimedia, si adesea cu driverele. pe Linux ma refer. eu am o problema cu tot ce tine de apple de cand pe pielea mea am suportat măgăriile lor de îngrădire a drepturilor utilizatorului care atenție: cumpara produsul. in opinia lor, daca cumperi un produs ești condamnat la restricționarile lor. as prefera un pc cu android totuși. ma rog tot linux e..scuze de off-topic.ps: sa ma anunți daca testezi codul ala. curand trebuie sa fac un dimmer+softstart la aspirator, deci urmează sa vad si eu care e treaba cu problema care o întâmpini tu acum.

Editat de Vizitator
Link spre comentariu

imi veni o intrebare stupida, totusi nu are legatura cu problema asta.

e critica pozitionarea fazei in circuit ? adica o sa mai functioneze triacul normal, pentru ca la un aspirator...te miri cand e faza cand e nulul pe pozitia ACL. dupa mintea mea nu conteaza asa mult dar totusi...

Editat de Vizitator
Link spre comentariu
Vizitator andreyfitza

imi veni o intrebare stupida, totusi nu are legatura cu problema asta.

e critica pozitionarea fazei in circuit ? adica o sa mai functioneze triacul normal, pentru ca la un aspirator...te miri cand e faza cand e nulul pe pozitia ACL. dupa mintea mea nu conteaza asa mult dar totusi...

Pozitionarea fazei nu este critica.

 

Pt initiator: E posibil ca tu sa detectezi zero crossing point-ul inainte ca el sa existe fizic. Daca e asa, Arduino face detectia si deschide triacul care apoi este inchis chiar de trecerea prin zero crossing point-ul pe care doreai sa-l detectezi. Ca sa vezi daca e asa, incearca sa pui in firing angle de 45-90 de grade (20-50 ms delay intre zero crossing point detection si deschiderea tiristorului).

Link spre comentariu

Pozitionarea fazei nu este critica.

 

Pt initiator: E posibil ca tu sa detectezi zero crossing point-ul inainte ca el sa existe fizic. Daca e asa, Arduino face detectia si deschide triacul care apoi este inchis chiar de trecerea prin zero crossing point-ul pe care doreai sa-l detectezi. Ca sa vezi daca e asa, incearca sa pui in firing angle de 45-90 de grade (20-50 ms delay intre zero crossing point detection si deschiderea tiristorului).

 

What?!?

 

O perioada a frecventei retelei este de 20msec iar o semiperioada (astea ne intereseaza pe noi) sau mai exact durata de timp intre doua treceri prin zero este de 10msec.

De unde ai scos delay de 20-50msec?

Pt 90° unghi de deschidere iti trebuie un delay de ~5msec.

 

Pt initiator: ca sa testezi ideea lui Andrey, pune un delay de 1-2 msec pina in 5 msec. La 50msec deja ai delay de citeva perioade.

Editat de sesebe
Link spre comentariu
Vizitator andreyfitza

What?!?O perioada a frecventei retelei este de 20msec iar o semiperioada (astea ne intereseaza pe noi) sau mai exact durata de timp intre doua treceri prin zero este de 10msec.De unde ai scos delay de 20-50msec?Pt 90° unghi de deschidere iti trebuie un delay de ~5msec.Pt initiator: ca sa testezi ideea lui Andrey, pune un delay de 1-2 msec pina in 5 msec. La 50msec deja ai delay de citeva perioade.

My bad, ai dreptate. Delay de 20-50 ms l-am scos din ora 3 dimineata :)). Am vrut sa zic 2-5 ms. Editat de andreyfitza
Link spre comentariu

@sesebe, @andreyfitza, @all - problema s-a rezolvat.

 

Sincer nu-mi dau seama ce s-a întâmplat atunci/acolo (cu acele semnale). Am refăcut (pe bradboard) circuitul și a mers din prima.

 

Am și pregătit câteva materiale (poze, capturi, documentații) despre acest subiect - din păcate sunt un pic mai prins în aceste zile și nu am avut timp sa le finalizez.

 

Revin cu detalii (probabil sâmbătă).

Link spre comentariu

Revin cu detalii și schema actualizată (cu denumirile componentelor corecte):

 

Posted Image

În principiu schema este gândită să funcționeze cu un microcontroler:

  - pe o întrerupere (cu ajutorul circuitului de ZCD (zero cross detection) - deasupra liniei albastre) detectăm trecerea prin zero a tensiunii AC (220v) - R1 și R2 trebuie sa fie un pic mai strong (eu am pus de 3W - asta deși curentul prin led = ~4 mA)  - probabil din de aceea se pun 2 rezistori nu unul. 

  - după un interval de timp (intre 0 ..10ms de la trecerea prin zero) aplicam tensiune pe CH-A -> triacul va conduce până la următoarea trecere prin zero. Evident putem sa avem mai multe canale (consumatori) pe care să aplicăm dimmări (reglare a intensității luminoase) diferite.

 

 

Posted Image

 

Un exemplu de program (Arduino) care exploatează povestea de mai sus:

#define CHANEL_A  5   //Triac canal Avolatile boolean zero_cross=0;//dupa cat timp de la trecerea prin zero deschidem triacul int t_dimm = 5000; //microsecvoid setup() {    Serial.begin(9600);     pinMode(CHANEL_A, OUTPUT);        pinMode(2, INPUT);      pinMode(2, INPUT_PULLUP);      attachInterrupt(0, onZeroCross, FALLING);      }void onZeroCross() {  zero_cross = 1;  }void loop() {            if (Serial.available()){        int newDimm = Serial.parseInt();         t_dimm = newDimm;            Serial.println(t_dimm);      }        if(zero_cross) {        zero_cross=0;                  delayMicroseconds(t_dimm);          digitalWrite(CHANEL_A, 1);          delayMicroseconds(10);          digitalWrite(CHANEL_A, 0);                                             }}

 - ZERO-CROSS   - conectat la pin 2

 - CH-A - la pin 5

 

Printr-un terminal se pot transmite valori la factorul de dimare (0 ... 10000) microsecunde.

Eventual se poate mapa acest interval pe 0% ..100% sau 0...255 - cu observația că această mapare nu trebuie făcută liniar - este o sinusoidă totuși (vezi detalii în link-urile de mai jos).

 

Evident se poate modifica (relativ simplu) programul sa suporte mai multi consumatori fiecare cu propria dimare.

 

Din păcate acestă abordare nu funcționează bine - sau mai corect spus : acest mod de implementare (soft) nu este cea mai corectă.

 

Mă explic:

Este foarte important ca codul de comada a deschiderii triacului (din funcția loop) să se execute in intervalul alternanței care a generat zero-cross :

if(zero_cross) {    zero_cross=0;              delayMicroseconds(t_dimm);      digitalWrite(CHANEL_A, 1);      delayMicroseconds(10); //așteptăm ca triacul să se deschidă     digitalWrite(CHANEL_A, 0);                                         }

Ex: Avem t = 9500 microsec - aproape de minim (ex: 10 V)  Dacă în acel moment, din varii motive MC face altceva, codul de mai sus nu se executa decât la următoarea rularea a buclei loop și dacă acel moment depășește alternanța curentă se obține un mic efect de stroboscop.

Evident se poate un pic îmbunătății ideea ex: în întreruperea de zero cross să păstrăm microsec de la start (funcția micros)) și la în loop la deschidere triac să verificăm dacă nu a trecut cumva 10 ms și să nu mai amorsăm triacul în acest ciclu - însă .... 

 

Soluția corectă (folosită și de costi002) este ca și secvența de deschidere triac să fie executată tot cu ajutorul unei întreruperi.

 

Un exemplu este si pe site-ul Arduino: ACPhaseControl - cu obs. ca codul este pt. 60Hz.

 

Exemple pe care le-am mai găsit pe net relevante :

  - Reflow - codul sursa aici - f. bine organizat codul.

  - Triac bloc - sursa aici.

 

În cele din urmă am folosit biblioteca Arduino Dimmer dezvoltata de cei de la Circuitar  - ex :

/** * Arduino Fade -  Circuitar * This software is released under the MIT license. See the attached LICENSE file for details. */#include <Dimmer.h>Dimmer dimmers[] = {  Dimmer(5, DIMMER_RAMP),  Dimmer(6, DIMMER_RAMP)};void setup() {       Serial.begin(9600);     for(int i = 0; i < sizeof(dimmers) / sizeof(Dimmer); i++) {        dimmers[i].begin();    }}void loop()  for(int i = 0; i < sizeof(dimmers) / sizeof(Dimmer); i++) {    dimmers[i].set(100);  }  delay(1500);  for(int i = 0; i < sizeof(dimmers) / sizeof(Dimmer); i++) {    dimmers[i].set(0);  }    delay(1500);}

Pentru un mic proiect eu trebuie să dezvolt un modul controlabil prin I2C care să permită dimarea a 10-12 becuri. Dacă mai este cineva interesat de subiect pot posta în acest thread proiectul final și/sau eventualele etape.

 

Mulțumesc tuturor pt. suport. 

 

 

 

 

 

 

 

 

Link spre comentariu
Vizitator andreyfitza

@sesebe, @andreyfitza, @all - problema s-a rezolvat.

 

Sincer nu-mi dau seama ce s-a întâmplat atunci/acolo (cu acele semnale). Am refăcut (pe bradboard) circuitul și a mers din prima.

 

Am și pregătit câteva materiale (poze, capturi, documentații) despre acest subiect - din păcate sunt un pic mai prins în aceste zile și nu am avut timp sa le finalizez.

 

Revin cu detalii (probabil sâmbătă).

Ai schimbat si componentele? In screenshot-ul din analizatorul logic pe care l-ai pus initial, interruptul accela pt zero crossing point dureaza prea mult, ceea ce ma facea sa cred ca punctul real de trecere era undeva la jumatatea acelui semnal.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări