Sari la conținut
ELFORUM - Forumul electronistilor

PUSH BUTTON


Vizitator SPEEDYMC4YOU

Postări Recomandate

Vizitator SPEEDYMC4YOU

am facut cateva programe dar nu au mers cum am vrut eu.ce vreau este ca atunci cand apas butonul sa aprind un led sau ceva iar daca-l mai apas o data sa se stingamultumescastept idei

Link spre comentariu
  • Răspunsuri 11
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • deep-blue

    3

  • sofian

    2

  • Laci

    2

  • Abram Burel

    1

Top autori în acest subiect

Ca sa faci asa ceva trebuie sa detectezi atat apasarea, cat si eliberarea butonului. Cand il apesi schimbi starea, dar nu accepti nimic altceva pana cand nu il eliberezi. Daca algoritmul nu e scris corect, la prima trecere va trece in on, la a doua in off si tot asa. De unde apare ca "licare" cu o frecventa ce depinde de temporizarile din program. Am patit asa ceva, care insa s-a dovedi a fi un efect util: daca apasai/eliberai scurt schimba din on in off si invers, daca tineai mai mult apasat "licarea" (trebuie insa ca frecventa de "licarire" sa fie destul de mica pentru a putea lua mana de pe buton la timp).

Link spre comentariu

Ca regula generala o tasta se citeste la un interval cuprins intre 10 si 100 milisecunde.

 

Pentru un program foarte simplu poti folosi o bucla de temporizare inainte de a citi din nou pinul, ceva de genul:

 

for (i = 0; i < 50; i++){for (j = 0; j < 255; j++){_asm nop _endasm;}}

Durata de temporizare va depinde de compilator (ptr PIC am folosit SDCC), tactul sistemului, si de valorile pe care le pui in loc de 50 si 255 (iti recomand sa experimentezi/calculezi cu ele). Daca folosesti assmblerul cu atat mai bine: ca exercitiu poti sa calculezi dinainte cat timp va petrece procesorul pe bucata respectiva de cod. Valorile 50 si 255 le-am aproximat (a se citi ghicit) acum pentru un PIC la 4MHz si temporizare vreo 12 milisecunde.

Link spre comentariu

eu de obicei fac asa :

1. citesc tasta si daca nu este apasata continui programul

2. daca este apasata tasta astept 20mS si citesc din nou

3. abia acum iau decizia daca este apasata sau nu

 

define KEY PORTB,5   ;definitie tasta ptr PORTB,5btfsc KEYgoto Bcl_00wait20mS  ;sau execut ceva care sa dureze ~20mSbtfsc KEYgoto Bcl_00.....aici pun ce vreau sa faca cind apas pe butonBcl_00aici continuarea programului

tasta este legata la PORTB,5 si GND

Link spre comentariu

Ce faci daca utilizatorul tine apasata tasta? Nu e mai bine sa astepti sa faca release? Stiu ca exista si un dezavantaj, ca ramai intr-o bucla infinita cat timp e tinut apasat butonul, dar cum altfel poti asigura o singura comanda in cazul in care tasta este tinuta apasata? Sau nu musai o singura comanda, insa in cazul unui program scurt, cum faci sa nu se detecteze zeci de apasari pana dai drumul la buton? Ceva de genul, daca tine apasata tasta, programul sa incrementeze un counter dar numai de 2-3 ori pe secunda, nu de fiecare data cand trece prin bucla de scanare a tastei.

Link spre comentariu

Ce faci daca utilizatorul tine apasata tasta? Nu e mai bine sa astepti sa faca release? Stiu ca exista si un dezavantaj, ca ramai intr-o bucla infinita cat timp e tinut apasat butonul, dar cum altfel poti asigura o singura comanda in cazul in care tasta este tinuta apasata? Sau nu musai o singura comanda, insa in cazul unui program scurt, cum faci sa nu se detecteze zeci de apasari pana dai drumul la buton? Ceva de genul, daca tine apasata tasta, programul sa incrementeze un counter dar numai de 2-3 ori pe secunda, nu de fiecare data cand trece prin bucla de scanare a tastei.

Buna observatia. Cel putin eu m-am obisnuit sa citesc dintr-un task si procesez pe urma. Pana una alta omul are (avea) o problema simpla care se rezolva cel mai simplu (sincron cu detectie pe front pozitiv) asa:
if key pressed event{toggle LED statusloop wait t_debounceloop wait key release event}
wait t_debounce (ce s-a prezentat mai sus) e necesar pentru ca o eventuala stare tranzitorie sa nu fie detectata ca release event.
Link spre comentariu

daca tine apasata tasta trebuie obligatoriu si o detectie de tasta apasata, care de obicei eu o pun la sfirsitul buclei

 

define KEY PORTB,5   ;definitie tasta ptr PORTB,5Buclabtfsc KEYgoto Bcl_00wait20mS  ;sau execut ceva care sa dureze ~20mSbtfsc KEYgoto Bcl_00.....aici pun ce vreau sa faca cind apas pe butonBcl_00aici continuarea programului..........No_Keybtfss KEY  ; Astept ca tasta sa nu fie apasatagoto No_Keygoto Bucla
Link spre comentariu

ca sa nu apara la apsare 100 de oscilatii pe contact se pune paraler cu acesta un condensator de 1~20n. si oricum fara condensator problema apare si la frontul crescator si la cel descrescator. de aceea se pune condensator si la platina la dacie! ca la deschidere sau inchidere frontul sa fie strict crescator sau invers si sa nu oscileze.zic si eu.

Link spre comentariu

ca sa nu apara la apsare 100 de oscilatii pe contact se pune paraler cu acesta un condensator de 1~20n

Nu e nevoie de condesator pentru debounce. Se poate pune bineinteles dar un soft bine scris nu are nevoie de el. Si apropo de soft bine scris: am uitat o linie importanta la ultimul pseudocod
if key pressed event{toggle LED statusloop wait t_debounceloop wait key release eventloop wait t_debounce // linia uitata: asteapta linistirea liniei ca sa nu se reintre accidental in secventa curenta}
Unde am lucrat in ultimi 3 ani, managerii se uitau urat de tot la astfel de condensatoare. 0,6 eurocenti insemna o mica avere. La un milion de placi si vreo 20 de intrari rezulta o 'economie' de vreo 120 de mii de euro. Debounce-ul e defapt o filtrare software: fiecare linie are asociata o variabila. Linia e verificata periodic, de exemplu la 5 milisecunde. La fiecare verificare variabila e incrementata sau decrementata cu o anumita constanta dupa cum linia e high respectiv low. Totodata se verifica si daca variabila atinge anumite valori si daca da se considera a avut loc un eveniment de schimbare de stare pe linie. Toata treaba asta se face in sistemul de operare. Dupa caz aplicatiile declara o functie callback asociata evenimentului sau fac polling la un flag ca sa vada daca s-a intamplat ceva pe afara. Erau si cazuri cand era nevoie de un raspuns garantat intr-un interval de timp foarte strict iar linia nu avea asociata nici o intrerupere. Atunci se renunta cu totul la fitrare si se chema aplicatia corespunzatoare imediat dupa detectia unei tranzitii. Eventualele tranzitii suplimentare erau ignorate deoare aplicatia rula deja.Ei na ca am ajuns sa complic destul lucrurile :nas: .
Link spre comentariu

Asa fac si eu, folosesc o filtrare soft, nu folosesc sistem de operare ca nu am nevoie dar am un nano kernel pentru functiile I/O care are un tick de ordinul sutelor de hz. depinde si de aplicatie.pentru filtrare:#define FILTER_LEVEL 10...unsigned char key;if (apasat) { if(key>0) key--;}else key=FILTER_LEVEL;..if(key==0)set_flag(..); elsereset_flag(..);in bucla principala se poate face detectare continuu sau 1 datacontinuu:while(1){...if (flag(..)) do_foo(); //actiunea legata de apasarea butonului...//daca se tine apasat butonul se executa de mai multe ori}1 data:unsigned char key_old;...while(1){... if( flag(..) && (key!=key_old) ) do_foo(); key_old = key;...}cam asa se citesc eu un push button :)

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