Nyomógombok

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
betonbokor
Újonc
Újonc
Hozzászólások: 7
Csatlakozott: 2014. március 18. kedd, 10:27

Nyomógombok

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

Sziasztok!
Csak néhány hete kezdtem el foglalkozni a témával ezért kérlek benneteket nézzétek el a lámer kérdéseimet:-)
Meg is akadtam szinte rögtön az elején, a Nyomógomb leckében szerepel:

Ha egyszerűen egy nyomógombbal szeretnénk egy LED-et
kigyújtani, azt könnyen megtehetjük:
/*
Nyomogomb
Demonstracios program a nyomogomb - LED kapcsolathoz
60 nap alatt Arduino tanfolyam
(c) TavIR http://www.tavir.hu
*/
void setup(){
pinMode(6, INPUT);
// D6 labon kapcsolo, lab bemenet
pinMode(7, OUTPUT);
// D7 lab: LED
digitalWrite(6, HIGH);
// D6-on felhuzo bekapcsol
}
void loop() {
digitalWrite(7, digitalRead(6));
// a D6 jelszintje a D7-re kiirodik
}
Nos nálam ez épp fordítva működik, folyamatosan világít a led és a gomb nyomására alszik ki majd ha elengedem ismét világít.
Mit rontottam el?
Kérlek benneteket segítsetek:-)
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Re: Nyomógombok

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

Egy led akkor világít, ha az anódjára pozitív, a katódjára pedig negativ feszkót kapcsolsz. Vagyis a felső és az alsó oldalán is kapcsolhatod. De szerintem nálad az a kapcslás van megépítve, amikor a led direktet kap, és a vezérlés kisöntöli a ledet. Nem túl egészséges, de működik, mint látod.
kkonrad
DrótVégénSzéndarab
Hozzászólások: 24
Csatlakozott: 2014. március 1. szombat, 14:47

Re: Nyomógombok

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

Sziasztok!

Olyat szeretnék csinálni, hogy ha megnyomok egy gombot akkor hajtson végre egy utasítást, de utána amíg nem engedem el a gombot, addig ne menjen tovább a program.

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

if (digitalRead(gomb) == HIGH)   
      { 
         utasítás;
         while (digitalRead(gomb) == HIGH) {delay(1);}
      }
utasítás;
  
Ez így miért nem működik? Delay helyett valami mást kéne használnom?
Válaszokat előre is köszi! :)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Nyomógombok

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

Ez még 1 feltétel vizsgálat lesz:
Használd a: do – while hátul tesztelő ciklust.
http://arduino.cc/en/Reference/DoWhile

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

if (digitalRead(gomb) == HIGH)   
      { 
         utasítás;
        delay(1);	// Kivárjuk a gomb pergését
       Do {
        } while (digitalRead(gomb)!= HIGH) ; 	// Várunk, hogy gomb LOW legyen
      }
utasítás;
Viszont a gombot fordítva szoktuk bekötni!
Tehát megnyomásra adjon 0 (LOW) szintet.
Mivel az AVR ek bemenetén van Bekapcsolható felhúzó ellenállás (pull-up resistor) ami fiksz H (1) szintet biztosít a szakadt bemeneten.

I/O Ports
http://web.engr.oregonstate.edu/~traylo ... _ports.pdf

AVR port architecture ábra: pull-up resistor
kkonrad
DrótVégénSzéndarab
Hozzászólások: 24
Csatlakozott: 2014. március 1. szombat, 14:47

Re: Nyomógombok

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

Köszi a programot.
Viszont ezt a nyomógombos részt nem értem. Mármint azt értem, hogy hogyan kéne bekötnöm helyesen, de ennek mikor lehet haszna?
(Külső felhúzó ellenállást használok, ha ez számít.)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Nyomógombok

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

Ezt most úgy értelmezem, hogy nálad a gomb állandóan zár GND-re, és mikor meg nyomot megszakít, és a felhúzó R adja a H szintet?

Ennek az a veszélye, ha véletlen kimenetre programozod az I/O portot! Az állandó GND rövidzárlat tönkreteszi!

Viszont ha a gombot megnyomásra zárod GND-re, Az állandó Felhúz R biztosította áramkorlátozás megvédi a kimenetet.
kkonrad
DrótVégénSzéndarab
Hozzászólások: 24
Csatlakozott: 2014. március 1. szombat, 14:47

Re: Nyomógombok

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

És tényleg, így már értem köszi! :)
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: Nyomógombok

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

Sziasztok!
A következő, nem túl egyszerű feladatot szeretném megvalósítani, egy darab nyomógombbal (a projekt még csak tervezési fázisban létezik, csak néha elakadok..):
A rendszer induláskor vár addig, amíg a nyomógombon két másodperces folyamatos nyomvatartás nem történik, ekkor egy analóg bemenet értékeit írja ki SD-re egy fájlba, miközben figyeljük a nyomógombot, és ha rövid gombnyomás történik, annak az idejét is fájlba írjuk, míg ha újabb két másodpercig folyamatosan lenyomva tartjuk a gombot, a mérés befejeződik, és elkezd villogni egy LED, jelezve, hogy kész vagyunk, áramtalanításra van szükség. Odáig tiszta, hogy a rendszer állapotát egy változóban, flagben tárolom, és három állapot van: mérés előtt, mérés közben, mérés után, ettől függően mást és mást kell tenni.
A gondom a két másodperces folyamatos gombnyomással van: minden loop-lefutáskor olvassam ki a bemenetet, és tároljam el az első HIGH->LOW átmenet idejét, és ha folyamatosan LOW marad és eltelik 2 másodperc, akkor váltok állapotot? Úgy érzem, a gomb állapotát is egy változóban kell tárolnom, és ha esetleg korán elengedik a gombot, akkor elengedettbe állítom, és újra figyelem a lefutó élet, átállítom lenyomottba, eltárolom az időt, és figyelem az időkülönbséget. Jól gondolom, vagy van egyszerűbb módszer?

A másik gondom a mérés közbeni gombnyomás: itt is felmerül a prell kérdése, nyilván csak egy időpontot akartok tárolni. Viszont mivel a mintavételezés kb. 1 kHz lesz, nem tudok 5 ms-ot várni a prell lefutására, itt kondenzátorban gondolkodom a nyomógombbal párhuzamosan, jó ötlet?
Ráadásul a mérés befejezése is egy két másodperces lenyomvatartás...tehát itt el kell különítenem, ha előbb felengedik, időbélyeg kiírás a fájlba, ha tovább tart a lenyomvatartás 2 mp-nél, akkor kilépünk a mérésből...
Kritikákat, megerősítést szeretnék, hogy jó-e a gondolatmenetem, mert amíg a folyamatábra össze nem áll a fejemben, nincs értelme kódolni...köszönöm előre is!

Köszönöm az ötleteket előre is!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Nyomógombok

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

Én a nyomógombot másként oldanám meg:
Timer, megszakítás 1 ms.
Minden ms-ban meglesem a gomb állapotát:
GND - érték=érték-1, kivéve ha 0
HIGH - érték=érték+1, kivéve ha 10
Ez 10 ms gombnyomást feltételez minimum.

Nem gombot nézek, hanem ha érték=0 - gombot GNDre nyomják, ha érték=10 - gomb elengedve, ha 1...9 - éppen prelleg.

A belső millis() függvény tud eltelt időt is, mert bekapcsolás óta megy....
2 sec: millis()-millisold()>2000 - eltelt min. 2 sec.
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: Nyomógombok

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

Ez a megoldás tetszik!
Az időtartamot én is így akartam mérni, a millisold ugye változó, és a kezdetkor eltárolom bele a gombnyomás kezdetét? :)
A hosszú gomblenyomás figyelését is ezzel a timeres módszerrel gondolnád? Vagy állapotváltozókkal?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Nyomógombok

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

Arduino vagy Bascom?

Arduino alatt nyomás vissza 3 leckét. Ott volt a millis() függvény.
Én az alapelvet írtam csak le....
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: Nyomógombok

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

Robert írta:Arduino vagy Bascom?

Arduino alatt nyomás vissza 3 leckét. Ott volt a millis() függvény.
Én az alapelvet írtam csak le....
Arduino, és meg is csináltam a keretprogit, szépen működik a szimuláció alatt, prellkioltás nincs benne, azt először megpróbálom párhuzamos kondival vagy más hardveres megoldással, a későbbi analóg bemenetről olvasást, fájlba írást, fájlzárást csak megjegyzésben jeleztem (még egy olyan funkció lesz benne, hogy másodpercenként eltárol egy időbélyeget. A feldolgozó program olyan lesz, hogy ha a fájlban 0..1023 értéket talál, azt adatként értékeli, 1024 jelenti az eseményjelzést, a unixtime értéke pedig jóval nagyobb, ezt fogja időbélyegként használni.
A programban nem használtam else ágakat, mert elsőre nagyon bonyolult blokk egymásba ágyazásokat kellett volna csinálnom, és ez a Pascal-Delphis begin-end párokhoz szokott agyamnak még sok lett volna :D, viszonta CASE hiányzik...de így is vígan működik, levédtem, amit kellett :)

Kód:

// konstansok
const int buttonPin = 2; // a nyomógomb láb deklarálása
const int ledPin = 3; // a LED kivezetésének deklarációja
const int buttonDelay=2000; // ennyi ms-ig kell lenyomva tartani a gombot az állapotváltáshoz
// változók
int buttonState = HIGH; // a nyomógomb állapotának nyilvántartására használt változó
int prevButtonState = HIGH; // a nyomógomb előző állapotának nyilvántartására használt változó
int nowChanged = LOW; // ebben azt tároljuk, hogy épp most léptünk-e át a rögzítés előttiből rögzítés állapotba (mivel akkor figyelmen kívül kell hagyni a gomb elengedését)
int systemState = 0; //a rendszer állapota, 0=rögzítés előtti várakozás, 1=rögzítés, 2=rögzítés befejeződött, kapcsold ki a tápfeszt
long oldmillis;
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
buttonState = digitalRead(buttonPin); // mindenképp beolvassuk a gomb állapotát
if (systemState == 0) { //ha bekapcsolás után, de rögzítési állapot előtt vagyunk
digitalWrite(ledPin, HIGH); //világít a LED
if (buttonState == LOW && prevButtonState == HIGH) { //ha lefutó él érkezik a nyomógombon
oldmillis = millis(); //eltároljuk az idejét
prevButtonState = LOW; //és az előző állapotot átállítjuk
}
if (buttonState == HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay) { // 2 mp-nél korábbi felengedés
prevButtonState = HIGH; //elkönyveljük, h újra felengedett, más teendőnk nincs
}
if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis > buttonDelay) { // 2 mp-nél hosszabb gombnyomás
digitalWrite(ledPin, LOW); //kioltjuk a LEDet
nowChanged =HIGH; //jelezzük, h most változott az állapot, az első felfutó élnél nem kell eseményjelzés a fájlba!
oldmillis = millis(); //megjegyezzük az állapotváltás időpontját
systemState = 1; //váltunk rögzítési folyamat állapotba
}
}
if (systemState == 1) { //ha rögzítési állapotban vagyunk

//ide kerül majd az analóg bemenetről olvasás, és a fájlba írás, esetleges késleltetés (az értékes adat 0..1023 közötti, és másodpercenként lesz egy időbélyeg, ami jóval nagyobb 1024-nél

if (buttonState == LOW && prevButtonState == HIGH) { //lefutó él a nyomógombon
oldmillis = millis();
prevButtonState = LOW;
}
if (buttonState == HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == LOW) { // 2 mp-nél korábbi felengedés, de csak nem közvetlenül állapotváltás után
prevButtonState = HIGH; //elkönyveljük a felengedett állapotot
//ide kerül majd az eseményjelzés írása a fájlba, mert rövid gombnyomás volt (1024)
}
if (buttonState == HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == HIGH) { // 2 mp-nél korábbi felengedés, közvetlenül állapotváltás után
prevButtonState = HIGH; //elkönyveljük, hogy a gombot felngedték
nowChanged = LOW; // jelezzük, hogy most már nem az első felengedés jön az állapotváltás után, lehet figyelni az eseményeket
}
if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis > buttonDelay && nowChanged == LOW) { // 2 mp-nél hosszabb gombnyomás, de csak ha nem az állapotváltás utáni túl hosszú
systemState = 2; //váltunk rögzítés utáni állapotba, ide kell majd egy fájlzárás is
}
}
if (systemState == 2) { //ha rögzítés után vagyunk, kikapcsolás szükséges: LED villogás jelzi
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
}
Avatar
furbyhun
DrótVégénSzéndarab
Hozzászólások: 44
Csatlakozott: 2015. február 14. szombat, 21:18

Re: Nyomógombok

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

Így kicsit olvashatóbb...

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

// konstansok
const int buttonPin = 2;    // a nyomógomb láb deklarálása
const int ledPin =  3;      // a LED kivezetésének deklarációja
const int buttonDelay=5;    // ennyi ms-ig kell lenyomva tartani a gombot az állapotváltáshoz
// variables will change:
int buttonState = HIGH;     // a nyomógomb állapotának nyilvántartására használt változó 
int prevButtonState = HIGH; // a nyomógomb előző állapotának nyilvántartására használt változó
int nowChanged = LOW;       // ebben azt tároljuk, hogy épp most léptünk-e át a rögzítés előttiből rögzítés állapotba (mivel akkor figyelmen kívül kell hagyni a gomb elengedését) 
int systemState = 0;        //a rendszer állapota, 0=rögzítés előtti várakozás, 1=rögzítés, 2=rögzítés befejeződött, kapcsold ki a tápfeszt
long oldmillis;
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  buttonState = digitalRead(buttonPin); //  mindenképp beolvassuk a gomb állapotát
  if (systemState == 0) { //ha bekapcsolás után, de rögzítési állapot előtt vagyunk
    digitalWrite(ledPin, HIGH);  //világít a LED
    if (buttonState == LOW && prevButtonState == HIGH) { //ha lefutó él érkezik a nyomógombon
      oldmillis = millis(); //eltároljuk az idejét
      prevButtonState = LOW; //és az előző állapotot átállítjuk
    }  
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay) { // 2 mp-nél korábbi felengedés
      prevButtonState = HIGH; //elkönyveljük, h újra felengedett, más teendőnk nincs
    }
    if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis  > buttonDelay) { // 2 mp-nél hosszabb gombnyomás
      digitalWrite(ledPin, LOW); //kioltjuk a LEDet
      nowChanged =HIGH; //jelezzük, h most változott, az első felfutó élnél nem kell eseményjelzés a fájlba!
      oldmillis = millis(); //megjegyezzük az állapotváltás időpontját
      systemState = 1; //váltunk rögzítési folyamat állapotba
     } 
  }
  if (systemState == 1) { //ha rögzítési állapotban vagyunk
    
  //ide kerül majd az analóg bemenetről olvasás, és a fájlba írás, esetleges késleltetés (az értékes adat 0..1023 közötti, és másodpercenként lesz egy időbélyeg, ami jóval nagyobb
  
    if (buttonState == LOW && prevButtonState == HIGH) { //lefutó él a nyomógombon
      oldmillis = millis(); 
      prevButtonState = LOW;
    }  
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == LOW) { // 2 mp-nél korábbi felengedés, de csak nem közvetlenül állapotváltás után
      prevButtonState = HIGH; //elkönyveljük a felngedett állapotot
      //ide kerül majd az eseményjelzés írása a fájlba, mert eseményt jelzett a felhasználó (1024)
    }
    if (buttonState ==  HIGH && prevButtonState == LOW && millis()-oldmillis < buttonDelay && nowChanged == HIGH) { // 2 mp-nél korábbi felengedés, közvetlenül állapotváltás után
      prevButtonState = HIGH; //elkönyveljük, hogy a gombot felngedték
      nowChanged = LOW; // jelezzük, hogy most már nem az első felengedés jön az állapotváltás után, lehet figyelni az eseményeket
    }
    if (buttonState == LOW && prevButtonState == LOW && millis()-oldmillis  > buttonDelay && nowChanged == LOW) { // 2 mp-nél hosszabb gombnyomás, de csak ha nem az állapotváltás utáni túl hosszú
      systemState = 2; //váltunk rögzítés utáni állapotba, ide kell majd egy fájlzárás is
    }
  }
    if (systemState == 2) { //ha rögzítés után vagyunk, kikapcsolás szükséges: LED villogás jelzi
    digitalWrite(ledPin, HIGH);
    delay(200);
    digitalWrite(ledPin, LOW);
    delay(200);
  }  
}
Avatar
wedds
Újonc
Újonc
Hozzászólások: 2
Csatlakozott: 2009. augusztus 26. szerda, 6:00

Re: Nyomógombok

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

Sziasztok!
Remélem a nyomógombok közé illik a kérdésem, bár némi prell is van benne...
Szóval kezdőként szeretném számolni egy bemenet impulzusait, erre egy "if"-es kódot csináltam:

// digital pin 8 elnevezése:
int erzekelopin = 8;

void setup() {
// serial communication:
Serial.begin(9600);
// bemenet:
pinMode(erzekelopin, INPUT);
}
int kontaktusszam = 0;

void loop() {
// beolvasás:
int bejovojel = digitalRead(erzekelopin);
//int kontaktusszam = 0;

if (bejovojel == LOW) {
delay(10);
//if (digitalRead(erzekelopin) == LOW) {
//delay(50);
if (digitalRead(erzekelopin) == HIGH) {
delay(10);
//if (digitalRead(erzekelopin) == HIGH) {
//delay(50);
kontaktusszam = kontaktusszam ++ ;
}
}//}}
delay(10);
// kiíratás:
Serial.println(kontaktusszam);
delay(10);
}


(A //sorok prell miatt vannak benne)
Működés közben azonban a változó értéke nem mindig nő eggyel, pedig a tx led sebességváltozásán látszik, hogy az UNO vette a bemenet jelét.
Próbáltam a látható prellmentesítéssel, mindenféle delayértékekkel, alacsony és magas bemenet fizikai és kódbeli cserélgetésével, de nem akar stabil lenni.
A bemeneten van felhúzóellenállás.
Ha van valami ötletetek, köszönöm!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Nyomógombok

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

delay() alatt jövő jeleket nem számolod...
Elvársz min 10 msec magas szintet a jelhez. Ha nincs v. >10msec a prell - kihagyod.
Kiírás előtt/után minek a delay(10) ?
Válasz küldése