60 nap alatt Arduino #10 - Prell

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
csegebiga
Chipgyilok
Hozzászólások: 288
Csatlakozott: 2015. március 27. péntek, 21:27

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: csegebiga »

mert változatlanul nem jó helyen vannak dolgok a programban:
a long ido miért nem a setupban van?

most mit is csinálsz:

Kód: Egész kijelölése

loop
  definiálod az idő változót
  gombnyomás történt?
    igen:
       időnek a millis() értékét adod    //(ez nem nullázza az időt, kap egy pillanatnyi értéket)
       azonnal 3 vizsgálat: gomb nyomva van-e , az idő nagyobb-e 300nál, és relé állapot=high?
          relé állapot átállítása= low
       azonnal 3 vizsgálat: gomb nyomva van-e , az idő nagyobb-e 300nál, és relé állapot=low?
         relé állapot átállítása=high
loop vége
előző hszben írtam, hogy az idő nagy valszinűséggel mindig nagyobb lesz 300 nál (millis() reference)
mellesleg ha átfut a progi a loopon, és még mindig nyomva van a gomb, az idő új értéket kap a millis() függvénytől ugye?
hogyan valósul így meg a 300 ms-os késleltetés?

a másik dolog:
a két relékapcsolgatós if-ed állandó oszcillációban van, ha nyomod a gombot
csak ezt kiszedve a loopbol:

Kód: Egész kijelölése

loop
  állapot=high?
     igen: állapot=low
  állapot=low?
    igen: állapot=high
loop vége



szerintem folyamat valami iljen kellene, hogy legyen:

Kód: Egész kijelölése

loop 
  gombnyomás történt?
      igen:
         várok, míg lenyugszik a kapcsoló (300 ms)
         még mindig nyomva van?
            igen:
               relé be van húzva?
                  igen:
                     relé elenged
                  nem: //else ág
                     relé behúz
        még mindig nyomva vége
   gombnyomás vége
 loop vége  
hosszú gombnyomásnál ez is ide-oda kapcsolgat, de már "csak" 600 ms-onként húz be 300 ms-ra, nem
ezredmásodperces reléfüstölést csinál

ui: a programkódhoz érdemes a code nyomógombot használni, így jobban látszik a hozzászólásban.
gyengeb
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2015. szeptember 5. szombat, 14:55

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: gyengeb »

Köszönöm szépen.
gyengeb
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2015. szeptember 5. szombat, 14:55

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: gyengeb »

Újragondoltam a hozzászólásaidat, bekerült a kódba mikor nullázom az idő változót (remélem jó helyen van).
Stabilabb működést tapasztalok.

Kód: Egész kijelölése

int relay=2;
int buttonpin=8;
int state;
long ido=0;

void setup()
{
  pinMode(buttonpin,INPUT_PULLUP);
  pinMode(relay,OUTPUT);
  
  int state=LOW;
  
}

void loop() 
{
  if(digitalRead(buttonpin)==LOW)
  {  
     
    ido=millis(); 
    if(ido>300)
    {
      ido=0;
      if(digitalRead(buttonpin)==LOW)
      {
        if(state==LOW)
        {
          digitalWrite(relay,HIGH);
          state=HIGH;
        }
        else
        {
          digitalWrite(relay,LOW);
          state=LOW;
        }
      }
    }
  }
}
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: kapu48 »

Avatar
csegebiga
Chipgyilok
Hozzászólások: 288
Csatlakozott: 2015. március 27. péntek, 21:27

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: csegebiga »

már majdnem jó, de a millis() függvény és a kezelése még mindig nem tiszta neked

Kód: Egész kijelölése

   ido=millis();  //ez még jó. visszaadja, hogy  hány millisec telt el a legutóbbi reset óta unsigned long formában, 
    if(ido>300)    //tehát ez itt nem értelmes. ez az első 3tized sec után kb 50 napig true lesz
    {
      ido=0;  //ez miért jó ha ez ciklusváltozó lenne, hol incrementálod?

ezt javasoltam az első hozzászólásomban egy oljan formába önteni, hogy:

Kód: Egész kijelölése

while ( millis()<ido+300) { } // ciklus, amíg a pillanatnyi idő nagyobb 300-al az eredeti időnél
de ha a várakozás ideje alatt nem kell a rendszernek mást csinálni,
elég egy delay(300) is

Kód: Egész kijelölése

 if(digitalRead(buttonpin)==LOW)  //gombnyomás
  {
     delay(300); // megvárod, míg a kapcsoló megnyugszik (nem sok az a  300ms?)
     if(digitalRead(buttonpin)==LOW)  // még mindig nyomva van?
     {
      //relékezelés
     }
  }
a relékezelés if-else rész már egész jó lett :)
gyengeb
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2015. szeptember 5. szombat, 14:55

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: gyengeb »

Mostanra már leesett, hogy a millis függvényt nem tudom resetelni szoftversen. :)
Így előálltam egy új ötlettel:

Kód: Egész kijelölése

int relay=2;
int buttonpin=8;
int state=LOW;
long ido;

void setup()
{
  pinMode(buttonpin,INPUT_PULLUP);
  pinMode(relay,OUTPUT);  
}

void loop() 
{
  if(digitalRead(buttonpin)==LOW)
  {
   ido=millis();
   while(ido<(ido+50))
   {
     if(digitalRead(buttonpin)==LOW)
     {
      if(state==LOW)
      {
        digitalWrite(relay,HIGH);
        state=HIGH;
       }
      else
      {
        digitalWrite(relay,LOW);
        state=LOW;
      }
    }
   }
  }
}
Meg tennétek, hogy megnézitek?
Köszönöm. :)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: kapu48 »

Ez így végtelen hurok:

Kód: Egész kijelölése

   ido = millis();
   while(ido<(ido+50))  // Az "ido" sehol nem változik!
{

...

}

// Így a jó:
   ido = millis()+100;
   while(millis() < ido)  // Mindig újra vizsgálja az aktuális időt!

{

...

}
Avatar
csegebiga
Chipgyilok
Hozzászólások: 288
Csatlakozott: 2015. március 27. péntek, 21:27

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: csegebiga »

...és arról nem is beszélve, hogy a fenti programod pont a fordítottját csinálná, mint amit szeretnél.
ha a Kapu48 mester által javított while ciklussal operálsz is, nézzd meg, mit csinálsz éppen:

Kód: Egész kijelölése

gombnyomáskor:
 felveszed a pillanatnyi időt;
 hozzáadsz 50et;
  belépsz a ciklusba addig, míg a pillanatnyi idő nem éri el a felvett értéket
   ha a gomb nyomva  van:
      kezeled a relét;
 ciklus vége
tehát csak az első gombnyomás utáni 50 ms-os időablakban figyeled a gombot, és kapcsolgatod a relét annyiszor, ahányszor a cikluson átfut a rendszer
ez pont a fordítottja a kitűzött célnak!

mert eredetileg az lenne a feladat, hogy amíg a kapcsoló prelleg (pattognak az érintkezők ki-be-ki-be) addig az áramkör _ne_csináljon_semmit_,
majd, ha megnyugodott a kapcsoló, _és_ nyomva van, _akkor_ vezéreljük a relét.

ez a progi jelen állapotában egy egybites kvázivéletlen-generátor, mivel az 50ms alatti ciklusfutások oda-vissza negálásából kivonjuk a kapcsoló prellegése miatt kiesett ciklusokat és a végén maradunk valahol. vagy high, vagy low, a kapcsoló pattogásától függ.

kérdés: te elméleti alapon írod a programokat, vagy van hardvered, amin ki tudod próbálni?
gyengeb
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2015. szeptember 5. szombat, 14:55

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: gyengeb »

Van hardverem, ki tudom próbálni a kódot.
Tényleg nem jó ez a megoldás akkor.
Volt egy olyan próbálkozásom, hogy a számolt időt maradék nélküli osztással vizsgáltam (ido%200==0), de ugye ez minden 200 ms után igazzá válik és be-ki kapcsol a relé a gombnyomás alatt, de szerintem ez működhet ha vizsgálok még valamilyen feltételt.
Avatar
csegebiga
Chipgyilok
Hozzászólások: 288
Csatlakozott: 2015. március 27. péntek, 21:27

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: csegebiga »

...meg ha az ido változó értékét incrementálod valahogyan.
azzal, hogy egyszer adsz neki egy értéket még nem fog automatikusan változni.
ez csak a basic for-next ciklusa csinálja meg
itt, ha ciklusváltozót használsz, neked kell megoldanod a változó változtatását is
(nézd meg az itteni for ciklus megvalósítást!)

DE nagyon ingoványos talajra merészkedsz, ha ciklusszámlálós időzítést szeretnél csinálni:
mivel nem gépi kódban programozol, és nem tiszta még előttünk (a tanfolyam jelen állásában), hogy a fordító hogyan valósítja meg az általunk megírt ciklust,
így elég nehézkes egzakt időzítéseket létrehozni. maximum tapasztalati értékekkel tudsz operálni.

ezért (is) használjuk a millisecundum függvényt. nem kell az utasításidőket neked számolni, hanem a függvény értéke növekszik millisecundumonként eggyel.

és még valami:
a millis() visszatérő értéke unsigned long
te következetesen long változóba teszed.
ez most nem okoz gondot, mivel kevés a valószínűsége, hogy 25 napnál tovább futna a programod,
de ha mégis, kb a 25. napon a változód egy nagyonnagy negatív számot mutatna kb 25 napig.
lásd számábrázolás long és unsigned long
oda kell figyelni a változó típusokra. ha itt megszokod, hogy nem pongyolán kezeled őket,
később nagyon sok kellemetlenségtől megkíméled magad!
gyengeb
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2015. szeptember 5. szombat, 14:55

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: gyengeb »

Találtam egy megírt kódot amiben átírtam a saját változóimat, de lenne egy dolog ami nem világos nekem.
Teljes kód:

Kód: Egész kijelölése

const int relayPin=2;
const int buttonPin=8;

int relayState; //=LOW;
int buttonState;
int lastButtonState=HIGH;

unsigned long lastDebounceTime=0;
long debounceDelay=50;

void setup() 
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);

  digitalWrite(relayPin, relayState);
}

void loop() 
{
  int reading=digitalRead(buttonPin);
  if(reading!=lastButtonState)
  {
    lastDebounceTime=millis(); //reset the debounce timer    
  }
  if((millis()-lastDebounceTime)>debounceDelay)
  {
    if(reading!=buttonState)
    {
      buttonState=reading;
      if(buttonState==LOW)
      {
        relayState=!relayState;
      }
    }
  }
  digitalWrite(relayPin, relayState);
  lastButtonState=reading;

}
Kérdésem:

Kód: Egész kijelölése

 {
    lastDebounceTime=millis(); //reset the debounce timer    
  }
  if((millis()-lastDebounceTime)>debounceDelay)
A lastDebounceTime és a millis() ebben az esetben nem ugyanannyi?
Válaszokat köszönöm.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: Robert »

Idézni csak pontosan szépen....

Kód: Egész kijelölése

 if(reading!=lastButtonState)
  {
    lastDebounceTime=millis(); //reset the debounce timer   
  }
 if((millis()-lastDebounceTime)>debounceDelay)

Kód: Egész kijelölése

Ha a gombnyomásállapot változott az előző óta,
    akkor lastDebounceTime=millis();

 if((millis()-lastDebounceTime)>debounceDelay) ....
gyengeb
Újonc
Újonc
Hozzászólások: 12
Csatlakozott: 2015. szeptember 5. szombat, 14:55

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: gyengeb »

Ezt értem, de a két változó a kivonás pillanatában nem ugyanannyi?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: Robert »

Ha volt változás, akkor igen.
De ha nem volt változás, azaz nem prellegett éppen - akkor van időeltérés. És ha ez az időeltérés nagyobb, mint a prellidő -> biztosan beállt a gomb állapota.
Erdist87
DrótVégénSzéndarab
Hozzászólások: 15
Csatlakozott: 2017. december 18. hétfő, 4:19

Re: 60 nap alatt Arduino #10 - Prell

Hozzászólás Szerző: Erdist87 »

Bocsi nem olvastam el mind nos én if else ággal vizsgálnám meg a gomb állapotát és az szerint utasítanám ill íratnám ki pl ha van kijelző hogy a gomb állapota zárt vagy nyitott de ezt akkor érdemes ha teljesen zárt házban van a vezérlő
Válasz küldése