Fényerő szabályozó kapcsoló

Ezt a függvényt azért írtam, mert olyan fali kapcsolóra volt szükségem, amivel fel lehet kapcsolni a világítást, és ugyanazzal a kapcsolóval a fényerőt is lehet szabályozni. Valójában a lakásunk világítás vezérlő programját írtam meg először, ami teljesen jól működik, de már én sem látom át a működését annyira bonyolult lett. Annak forrását is megtalálod, azzal 6 szobát lehet egyszerre vezérelni, és setup funkciókkal is meg lett spékelve. Beállíthatod a fel és le fényerő szabályozási időket stb. és ezt ugyanarról a nyomógombról. Túl sokat tud, ezért azt a programot leegyszerűsítettem és jó alaposan felkommenteztem, hogy más programokban is tudjam használni. Esetleg valaki másnak is hasznos lehet jelen állapotában.

Ennek a programnak (függvénynek) a funkciói:

  • rövid gombnyomással fel illetve lekapcsolja a világítást.
  • Felkapcsoláskor a fényerő fokozatosan növekszik 0-tól a legutoljára beállított szintre
  • Lekapcsoláskor fokozatosan csökken a fényerő minimum értékre, majd minimumon világít beállítható időre és csak ennek leteltekor kapcsol ki teljesen a fény. A nyomógomb megnyomásakor egy rövidet villan a világítás, hogy látható legyen, megindult a fényerő csökkentés.
  • Ha nincs bekapcsolva a világítás, akkor kapcsoló folyamatos nyomva tartásával bekapcsolódik a világítás minimum fényerőn, és folyamatosan növekszik a fényerő. Az elengedés pillanatában érvényes fényerőn világít tovább, és ez lesz a beállított fényerő.
  • Ha a világítás be van kapcsolva, a kapcsoló folyamatos nyomva tartásával a fényerő növekedni (vagy csökkenni) kezd, ha maximumra ér, akkor villan egyet, hogy lássuk elértük a maximumot. Bármikor elengedjük a kapcsolót, a fényerőt megjegyzi, és az lesz a beállított fényerő, aminél megáll a fényerő növekedés a következő felkapcsoláskor.
  • A következő folyamatos nyomva tartáskor a fényerő ellentétes irányba változik, mint az előző folyamatos nyomva tartáskor. Növelés után egy rövid kapcsoló elengedés és újbóli nyomva tartás csökkenteni fog.

A minta program tartalmazza a lampa_on_off_fenyero() függvényt, ami a fentebb leírt funkciókat megcsinálja. Ha ezt használni akarod, akkor elég sok globális változót kell deklarálni a program elején, ezek részei a függvénynek. Nagy előnye a függvénynek, hogy nem tartalmaz időzítést, így nem lassítja jelentősen a loop működését. Tetszőleges egyéb programrészek helyezhetők el a loop-ban. Természetesen azok sem tartalmazhatnak időzítést, különben ez sem fog tudni működni. Annyira gyors a működés, hogy akár egyszerre több nyomógombot is ki tud szolgálni, de ekkor a függvényből többet kell csinálni különböző neveken, különböző névvel megduplikálni a változókat is, vagy lehet egy függvényt, és tömböket használni az egyes világítások változóihoz. Utóbbi esetben a függvény belsejét még egy for ciklusba kell helyezni, hogy minden egyes világításon végigmenjen minden meghíváskor. Ezzel a technikával dolgozik az említett világítás vezérlésem.

/****************************************************************************
 * azok a változók, paraméterek melyek közvetlenül befolyásolják a működést *
 ****************************************************************************/
  int tartasi_ido=3000;        //ennyi milisec-ig tartja minimumon a fényerot a lekapcsolás után
  int klikk_ido=400;           //ennyi idő után tartjuk benyomottnak a nyomógombot, és elkezdjük a fényerő szabályozást
  byte min_fenyero=10;         //lekapcsoláskor a minimális fényerő értéke. Ezen a fényerőn tartjuk a lámpát teljes kikapcsolásig
  int fenyero=255;             //lámpa fényereje 5..255-ig. Felkapcsoláskor az ebben tárolt fényerőre kapcsolja be a lámpát. 
                               //Nyomvatartáskor ennek az értékét változtatja a program. Azért int, hogy kihasználhassuk a 
                               //max fényerőt (255), mert ha 255-höz adunk hozzá 1-et növeléskor, abból 0 lenne ha byte.
  byte valtozasi_sebesseg=8;   //ennyi milisekondumonként változtatjuk a fényerőt nyomvatartott nyomógombnál, minél kissebb, 
                               //annál gyorsabb a változás. A teljes fényerő intervallum vágig változtatása 10msec esetén: 8msec*255=2 másodperc
  byte fel_le_valt_sebesseg=5; //ennyi milisekondumonként változtatjuk a fényerőt fel és lekapcsoláskor, minél kissebb, 
                               //annál gyorsabb a változás. A teljes fényerő intervallum vágig változtatása 10msec esetén: 5msec*255=1,27 másodperc
/****************************************************************************                              
 * Kapcsoló és lámpa állapotok és egyéb futás közbeni változók              *                  
 ****************************************************************************/
  byte lamp_on=0;         //lámpa bekapcsolt állapota esetén 1, kikapcsolva 0
  byte sw_on=0;           //kapcsoló nyomvatartás alatt értéke 1
  byte nyomvatart=0;      //jelzi, hogy nyomvatarjuk a nyomógombot, amig nyomjuk éstéke 1
  byte valtozas_fel_le=1; //a fenyero változás iránya nyomvatartáskor 1-fel 0-le
/****************************************************************************                              
 * segéd változók, melyek a működéshez kellenek                             *                  
 ****************************************************************************/
  byte sw_prell=0;            //kapcsoló prell figyeléshez
  long sw_time=0;             //kapcsoló lenyomás prell figyeléshez eltelt idő az első kontaktus óta
  byte sw_prev_stat=0;        //kapcsoló előző ciklusbani állapotát tárolja. Kapcsoló lenyomás és elengedés érzékeléséhez kell
  int  fenyero_tmp=0;          //a fényerő felés leusztatááskor az éppen aktuális fényerő értéke
  long fenyero_nov_time2=0;   //fenyero novelés során segédváltozó időméréshez
  byte lamp_on_prev_stat=0;   //lámpa előző állapota bekapcsolt állapota esetén 1, kikapcsolva 0
  long fenyero_nov_time=0;    //a fenyero novelesnel az idozítés segédváltozója
  byte nyomvatart_prev_stat=0;//nyomvatartás végének észrevételéhez segédváltozó 
  long sw_tart_time=0;        //kapcsoló lenyomás és elengedés közötti időmérés segéd változója. Első lenyomáskor 
                              //indul az időmérés, és ha egy ideig nem engedjük el, akkor lenyomottnak tekintjük 
                              //a nyomógombot, ami fényerőszabályozást eredményez
  byte villan=0;              //ha elérte a fényerő maximumot a fényerő növelés, akkor villan a lámpa, 
                                                //ezt engedélyezi, alapértelmezette 1 mert alapértelmezett változási irány a növelés
  byte lekapcs_eng=1; //nyomvatartott nyomógomb esetén elengedéskor nem engedjük kikapcsolni a lámpát, hiszen fényerőszabályozás volt
                      //ilyenkor értéke 0. Ha csak megnyomtuk a nyomógombot és és lehet lekapcsolni a lámpát, akkor értéke 1.                                

void setup() {
  pinMode(3,INPUT);     //nyomógomb bemenet
  digitalWrite(3,HIGH); //felhúzó ellenállás bekapcsolása a bemeneten
  pinMode(11,OUTPUT);   //erre kötjük a led-et
} 


void loop()
{
  /*
   * Ez a függvény egy nyomógombot és egy PWM kimenetet kezel
   * Bemenő paraméter sorrendje: bemenet, PWM kimenet
   */
  lampa_on_off_fenyero(3,11);
}


void lampa_on_off_fenyero(byte bemenet, byte kimenet)
/*
 * Ez a függvény egy nyomógomb megnyomásait figyeli és egy PWM képes kimenetten fel és lekapcsol egy led-et (lámpát).
 * Felkapcsoláskor a fényerő lassan kúszik fel egy beállított fényerőre. Lekapcsoláskor a fényerő lassan csökken 
 * egy beállított minimumra, és egy beállítható ideig minimumom tartja a fényerőt, hogy ne aludjon ki egy darabig
 * a fény, ne kelljen sötétben botorkálni. Mivel a lekapcsolás lassan indul meg, és szeretnénk biztosak lenni abban, 
 * hogy megtörtént, egy villanással jelzi a fényerő csökkenés megkezdését.
 * A nyomógomb hosszan nyomvatartva változtatja a fényerőt. Elengedve és újra hosszan nyomvatartva a fényerő 
 * ellentétes irányba változik. Ha változtatás közben a fényerő maximumra ért, akkor a lámpa villan egy rövidet, 
 * jelezve, hogy nem érdemes tovább nyomvatartani. 
 * Bekapcsolás után (reset) nem lehet fényerőt szabályozni, egyszer ki és be kell kapcsolni, nem tudom a hiba okát
 */
{
 /*
  * Ez a programrész a nyomógomb prellmentesítését végzi, valamint figyeli azt, hogy mennyi ideje tartjuk nyomva a nyomógombot
  * Ha a nyomvatartási idő hosszabb mint az előre beállított konstans klikk_ido változóban megadott érték, akkor úgy tekinti
  * hogy nyomva tartjuk a nyomógombot, vagyis fényerőt akarunk szabályozni. Ha a megnyomás kezdetén még nem világított a led,
  * akkor növelni kell a fényerőt (és bekapcsolni a lámpát), de ha már világított, akkor a fel le változást is ki kell jelölniű
  * a program későbbi részeiben.
  */
  if (sw_on==0 and digitalRead(bemenet)==LOW and sw_prell==0)                   //első lenyomás érzékelése sw_prell=1 jelzi, hogy már volt egy kontaktus,
    {sw_prell=1;sw_time=millis();}                                              //és 50msec múlva már biztosan megállt a prell a kontaktuson. sw_time 
                                                                                //tárolja az első kontaktus időpontját az 50msec méréséhez
  if (sw_on==0 and digitalRead(bemenet)==LOW and sw_prell==1 and millis()>sw_time+50) // már 50msecv óta nyomva van, most már biztos, hogy lenyomták és nem prellezik
    {sw_on=1;sw_prell=0;}                                                       //sw_prell=0, mert már biztosan nem prelles
                                                                                //sw_on=1, mert a kapcsoló meg lett nyomva (épp nyomva van)
  if (sw_on==1 and digitalRead(bemenet)==HIGH and sw_prell==0)                  //első elengedés érzékelése, itt is figyelni kell, 
    {sw_prell=1;sw_time=millis();}                                              //hogy prellezik-e a nyomógomb, sw_time tárolja az elengedés pillanatát, amikortól
                                                                                //kezdősik a prellezés, tehát sw_prell=1
  if (sw_on==1 and digitalRead(bemenet)==HIGH and sw_prell==1 and millis()>sw_time+50)//már 50msecv óta elengedte a nyomógombot, most már biztos, hogy nincs prell 
    {sw_on=0;sw_prell=0;}                                                       //sw_on=0 jelzi, hogy nincs nyomva nomógomb, sw_prell=0 jelzi, hogy már nincs prell
     
  if (sw_on==1 and sw_prev_stat==0)                                             //a kapcsoló előző állapota 0, és most megnyomták, tehát felfutó él érkezett
    {sw_tart_time=millis();}                                                    //sw_tart_time tárolja a benyomás időpontját, és innen figyeljük, hogy 500msec-en
                                                                                //elengedi-e a nyomógombot. 

  if (sw_on==0 and sw_prev_stat==1 and nyomvatart==0)                           //nem nyomvatartott állapotban engedtük el a nyomógombot (lefutó él)
    {                                                                           //lehet a lámpát fel vagy lekpcsolni
    if (lamp_on==0) {lamp_on=1;}                                                //lámpa nem volt bekapcsolva, lámpa bekapcsolása,
    else {lamp_on=0;}                                                           //lámpa fel volt kapcsolva, lampa lekapcsol
    lekapcs_eng=1;                                                              //jelezzük a későbbi programrészeknek, hogy lekapcsolható a lámpa
    }                   
    
  if (sw_on==0 and sw_prev_stat==1 and nyomvatart==1)                           //nyomvatartott állapotban engedtük el a nxomógombot (lefutó él)
    {nyomvatart=0;lekapcs_eng=0;}                                               //lámpa felkapcsolva marad beállított fényerőn, mert lekapcs_eng=0
                                                                                //a következő cilusban tudnunk kell a nyomógomb előző állapotát,
                                                                                //hogy detektálni tudjuk a nyomógomb bekapcsolását, és ez csak egyszer 
                                                                                //következzen be. Ehhez használjuk a sw_prev_stat változót.     

  if (sw_on==1 and sw_prev_stat==1 and millis()>sw_tart_time+klikk_ido)         //benyomva a nyomógomb és telik az idő. Ha klikk_ido eltelt, akkor nyomvatartottnak 
    {                                                                           //vesszük, ami fényerőszabályozást eredményez
    nyomvatart=1;                                                               //a nyomvatart változó jelzi, hogy nyomva van a nyomógomb
    if (lamp_on==0)                                                             //ha még nincs bekapsolva a lámpa, akkor bekapcsoljuk (nyomvatartással is bekapcsolható
      {lamp_on=1;fenyero=min_fenyero;valtozas_fel_le=1;villan=1;                //ha nyomvatartással kapcsoltuk fel, akkor minimum fényerőről indul a szabályozás
      fenyero_nov_time2=millis();lekapcs_eng=0;}                                //valtozas_fel_le=1 jelzi, hogy növelni kell a fényerőt, engedélyezük a villanást is max fényerőnél
   }                                                                            //fenyero_nov_time2 megjegyzi a növelés elkezdésének időpontját

  sw_prev_stat=sw_on;        //megjegyezzük a nyomógomb előző állapotát, hogy a következő ciklusban észrevegyük a változást
 /******************************************************************************************************
  * Ezek a programrészek a nyomvatortott nyomógomb esetén növelik vagy csökkentik a fényerőt, valamint *
  * nyomvatartás után elengedett nyomógomb esetén váltják a csökkentés vagy növelés irányát            *
  ******************************************************************************************************/
  if (fenyero<min_fenyero+1)                             //fényerő minimumra értünk. 
    {fenyero=min_fenyero+2;}                             //Azért állunk meg előtte egy értékkel, mert így kikapcsoláskor lesz segédfény
         
  if (fenyero>255)                                       //fenyero maximumhoz értünk
    {fenyero=255;}                                       //255 fölé nem nőhet a fényerő

  if (valtozas_fel_le==1 and nyomvatart==1 and millis()>fenyero_nov_time+valtozasi_sebesseg)//nyomvatartjuk a gombot és növeljuk a fényerőt maximumig
    {
    if (fenyero<255){fenyero=fenyero+1;}                                        //ha még kisebb a fényerő mint 255, akkor növelünk
    fenyero_nov_time=millis();                                                  //a fenyerő növelés következő lépéséhez megjegyezzük a pillanatnyi időpontot
    }
         
  if (fenyero_tmp==255 and nyomvatart==1 and villan==1)                         //nyomvatartjuk a kapcsolót és elértük a maximumot megvillantjuk 
    {analogWrite(kimenet,128);fenyero_nov_time2=millis();villan=0;}             //a lámpát rövid fényerő csökkentéssel, de a további villanásokat tiltjuk
         
  if (fenyero_tmp==255 and nyomvatart==1 and millis()>fenyero_nov_time2+200)    //200msec múlva visszakapcsolojuk a fényt maximumra (nyomvatartja a 
    {analogWrite(kimenet,255);}                                                                   //kapcsolót és elértük a maximumot, villanás vége, újra max fényerő)
         
  if (valtozas_fel_le==0 and nyomvatart==1 and millis()>fenyero_nov_time+valtozasi_sebesseg) // nyomvatartjuk a gombot és csökkentjük a fényerőt
    {fenyero=fenyero-1;fenyero_nov_time=millis();}
        
  if (nyomvatart==0 and nyomvatart_prev_stat==1)                                //nyomvatartás után elengedtük a nyomógombot
    {
    if (valtozas_fel_le==1) {valtozas_fel_le=0;}                                //ha eddig "fel" irány volt, akkor most "le" jön
    else {valtozas_fel_le=1;villan=1;}                                          //ha eddig "le" irány volt, akkor most "fel" jön. Engedélyezzük a villanást is
    }                                                                           //arra az esetre, ha a következő növeléskor elérte a mximumot a fényerő
      
  nyomvatart_prev_stat=nyomvatart;     //Ha a nyomógombot nyomva tartottuk, akkor a következő ciklusban 
                                       //tudnunk kell az előző ciklus állapotát, hogy felfedezzük a változást, mert következő
                                       //nyomvatartáskor meg kell változtatni a fényerő növelés vagy csökkentés irányát
        
  /******************************************************************************************************************************  
   * Ez a programrész figyeli a lamp_on változó értékét. Ha 1, vagyis bekapcsoltuk a lámpát, akkor a fényerőt mindíg beállítja  *
   * a fenyero nevű változó értékéhez, de ezt lassan csinálj azzal, hogy valójában egy fenyerp_tmp nevű változó határozza meg   *
   * a fényerőt, és ennek értékét fokozatosan növeli vagy csökkenti fenyero változó értékére.                                   *
   ******************************************************************************************************************************/
  if (lamp_on==1 and millis()>fenyero_nov_time2+fel_le_valt_sebesseg)   //Ha felkapcsoltuk a lámpát akkor a fenyero változóig növeljuk a fényerőt, 
                                                                        //ehhez minden ciklusban megnézzük eltel-e már fel_le_valt_sebesseg változóban 
                                                                        //megadott konstans idő. Ha igen, akkor megnézzük, hogy fenyero_tmp és fenyero 
                                                                        //változók között van-e különbség. Ha igen, akkor változtatjuk fenyero_tmp értékét.
                                                                        //Így a fenyero_tmp változó csak követi fenyero változó erteket, a fel_le_valt_sebesseg
                                                                        //változóban beállított sebességgel. A nyomógombbal fenyero változó értékét változtatjuk,
                                                                        //illetve bekapcsoláskor ez 255, kikapcsoláskor 0. Ezért kúszik fel és le a fényerő.
    {                                                  
    if (fenyero_tmp>=255) {fenyero_tmp=255;}      //fenyero_tmp nem nőhet 255 fölé,mert az a max fényerő, de ez a programban máshol előfordulhat, ezért kell figyelni
    if (fenyero_tmp<fenyero)                      //még nem értük el a szükséges fényerőt a fenyero változóban meghatározott fényerőt
      {fenyero_tmp=fenyero_tmp+1;                 //növeljük fenyero_tmp értékét                 
       fenyero_nov_time2=millis();                //tároljuk fenyero_nov_time2-ben az aktuálisidőt, mert ehhez hasonlít következő ciklusban 
       analogWrite(kimenet,fenyero_tmp);}              //beállítjuk a fényerőt fenyero_tmp értékére
            
    if (fenyero_tmp>fenyero)                      //ha a fényerő nagyobb mint a beállított fényerő, akkor elkezdjük csökkenteni
      {fenyero_tmp=fenyero_tmp-1;                 //csökkentjük fenyero_tmp értékét, mert a fenyero változóban megszabott fenyerőnél nagyobb afényerő
       fenyero_nov_time2=millis();                //tároljuk fenyero_nov_time2-ben az aktuálisidőt, mert ehhez hasonlít következő ciklusban 
       analogWrite(kimenet,fenyero_tmp);}              //beállítjuk a fényerőt fenyero_tmp értékére
   }
      
  /******************************************************************************************************************************  
   * Ez a programrész figyeli a lamp_on változó értékét. Ha 0, vagyis lekapcsoltuk a lámpát, akkor a fényerőt 0-ra állítja      *
   * de ezt lassan csinálj azzal, hogy valójában egy fenyero_tmp nevű változó értékét csökkenti időnként. Ha egy beállított     *
   * minimumra ért a fenyero_tmp értéke, akkor egy időre megál a csökkentéssel (tartasi_ido változó), és csak aztán kapcsolja   *
   * le teljesen a fényerőt. Amikor érzékeljük, hogy lekapcsoltuk a lámpát, egy rövid időre lecsökkentjük a fényerőt 0-ra,       *                                                                                                     
   * És ezzel jelezzük, hogy megindult a lekapcsolái folyamat                                                                   *
   ******************************************************************************************************************************/
  if (lamp_on==0 and millis()>fenyero_nov_time2+fel_le_valt_sebesseg and lekapcs_eng==1)       //lekapcsoltuk a lámpát, csökkenteni kell a fénmyerőt 0-ig 
    {                                                                                          //ebbe minden fel_le_valt_sebesseg értékével meghatározott időnként bele megy
    if (fenyero_tmp==min_fenyero and millis()>fenyero_nov_time2+tartasi_ido)                   //Ha már minimum fényerőn van, akkor még tartasi_ido értékig tartja a min fényerőt
      {analogWrite(kimenet,0);fenyero_tmp=0;}                      
            
    if (fenyero_tmp>min_fenyero)                                                               //még nem értük a el a minimum fenyerőt 
      {fenyero_tmp=fenyero_tmp-1;fenyero_nov_time2=millis();analogWrite(kimenet,fenyero_tmp);}      //csökkentjük a fényerőt, megjegyezzük a pillanatnyi időt a köv. csökkentéshez
    }  
  if (lamp_on==0 and lamp_on_prev_stat==1)                                                     //lampa lekapcsoláskor csökkemnteni fogjuk a fenyerőt egy rövid időre, 
    {analogWrite(kimenet,0);fenyero_nov_time2=millis()+70;}                                         //hogy lássul elkezdődött a lekapcsolás

  lamp_on_prev_stat=lamp_on;                                                                   //led állapotának tárolása a változás megállapításához
} 

Mennyire volt hasznos amit olvastál?

Kattints egy csillagra az értékeléshez!

Sajnálom, hogy amit olvastál nem volt hasznos számodra!

Szeretném ha elégedett lennél!

Írd le kérlek, hogy mi nem tetszett!?