Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Attiny2313 - krótkie i długie naciśniecie przycisku

hanibal0 24 Lis 2010 10:23 12822 82
  • #31 24 Lis 2010 10:23
    arktik1
    Poziom 27  

    Code:

    $regfile = "attiny2313.dat"

    Config Portd = Input
            Portd = &B1111111
    Config Portb = Output
            Portb = &B00000000


    Do

    Debounce Pind.0 , 0 , Dioda , Sub


    Loop
    End



    Dioda:

    Toggle Portb.0
    Wait 2

    If Pind.0 = 0 Then
    Portb.0 = 1
    Wait 5
    Portb.0 = 0
    End If

    Return


    łatwiej się już chyba nie da.

  • Pomocny post
    #32 24 Lis 2010 14:14
    mirekk36
    Poziom 42  

    arktik1 napisał:

    łatwiej się już chyba nie da.


    Sorki, ale ja bym raczej powiedział, że:

    "JUŻ GORZEJ SIĘ NIE DA :("

    Co to za rozwiązanie gdzie w środku siedzi jeszcze obrzydliwy Wait !!! brrr

    ale żeby nie być gołosłownym, który tylko krytykuje....

    Ok, panowie - widzę, że wasze zmagania spełzają na niczym, pokażę wam więc jak się powinno podchodzić do programowania. Nawet w Bascomie można Programować a nie tylko "programować" czyli sterować pinami. Trzeba tylko troszkę pomyśleć i pogłówkować.

    Żeby było ciekawiej to poza obsługą klawisza, który reaguje na krótkie i długie wciśnięcie - nie użyjemy w kodzie ANI JEDNEGO polecenia Wait czy Waitms !!!!!

    co więcej, przybliżę wam jak można stosować mechanizm timerów programowych - bo słyszycie zapewne o nich tu i tam, w jakichś często "mądrych" dyskusjach czy podpowiedziach ale każdy podchodzi do tematu jak do MEGA JEŻA uważając że to za trudne, że tego nie można w Bascomie zrobić, że tego się nie da itd itd itd ;) ..... tymczasem jak zobaczycie - to jest takie proste że aż strrrach.

    Napiszmy więc program, który poza tą omawianą obsługą klawisza będzie migał NIEZALEŻNIE dwoma diodami LED w całkowicie różnym tempie. Oczywiście wszystko można sobie regulować wg uznania a migające diody LED zastąpić wywoływaniem własnych funkcji, które będą realizowały dowolne rzeczy!!!!!

    Tylko proszę! nie zarżnijcie tego mechanizmu napisaniem funkcji, w której użycjecie znowu poleceń WAIT lub WAITMS bo cały trud pójdzie na marne ;) i nic z tego się nie nauczycie....

    Od dzisiaj zapomnijcie o takich poleceniach ;) WAIT i WAITMS ok?

    Nie będę omawiał jak to działa, proponuję się skupić i to zrozumieć skoro dostajecie już w łapki gotowca. Oczywiście sama obsługa klawisza ma pewną jeszcze mini wadę - ale wątpię żebyście ją od razu odkryli .... pisałem ten program na kolanie i uwierzcie mi że musiałem długo móżdżyć ;) bo Bascom już mi prawie wyparował z głowy ... więc wciąż na helpie siedziałem.

    Mogę tylko dodać, że skoro takie rzeczy to nawet w Bascomie - to pomyślcie, że robienie tego samego tyle że w języku C to już CZYSTA POEZJA , jest o wiele łatwiej nie mówiąc już że szybciej co ma w tym konkretnym przypadku (korzystania z timerów programowych) dosyć spore znaczenie .... no ale o tym przekonacie się wkrótce jak na dobre zrozumiecie ideę posługiwania się nimi.

    Miłej lektury i prób ;)

    Code:

    $regfile = "m8def.dat"
    $crystal = 8000000


    ' ustawiamy przerwanie na ok 100Hz
    Config Timer2 = Counter , Prescale = 1024
    Ocr2 = 78
    Dim Ptimer1 As Word                                         ' timer programowy
    Ptimer1 = 0

    Dim Ptimer2 As Word                                         ' timer programowy
    Ptimer2 = 0

    Dim Ptimer3 As Word                                         ' timer programowy
    Ptimer3 = 0

    On Timer2 Systick
    Start Timer2
    Enable Timer2


    Config Pinb.1 = Input
    Set Portb.1

    Klawisz1 Alias Pinb.1

    Config Pinb.7 = Output
    Led Alias Portb.7

    Set Led

    Config Portc.0 = Output
    Led1 Alias Portc.0

    Set Led1

    Config Portc.1 = Output
    Led2 Alias Portc.1

    Set Led2


    Dim Tmp As Word
    Tmp = 0


    Enable Interrupts



    '--------- pętla główna programu -------------------
    Do




    '********************* obsługa KLAWISZA1 *****************
    ' z eliminacją drgań styków oraz
    ' z wykorzystaniem:
    '
    '     zmiennej TMP
    '     timera programowego 1
    '
    '  reakcja na krótkie kliknięcie - w zasadzie zwolnienie przycisku
    '  reakcja na dłuższe kliknięcie - dłuższe przytrzymanie przycisku
    '
    '  osobno ustalane czasy dla SHORT i LONG CLICK
    '
       If Pinb.1 = 0 Then

          If Ptimer1 = 0 Then
             Ptimer1 = 100
          End If

          If Ptimer1 < 95 And Pinb.1 = 0 Then
                Tmp = 1
                If Ptimer1 < 80 And Ptimer1 < 10 Then
                       'Call Dlugi_klik;
                       Set Led
                       Tmp = 0
                       Ptimer1 = 10
                End If
          End If
       End If

       If Tmp = 1 And Ptimer1 < 85 And Ptimer1 > 70 Then
          If Pinb.1 = 1 Then
             'Call Krotki_klik;
              Reset Led
              Tmp = 0
              Ptimer1 = 10
          End If
       End If
    '********************* obsługa KLAWISZA1 *****************


    '----------------------- timer programowy 2
       If Ptimer2 = 0 Then
          Ptimer2 = 10
          Toggle Led1
       End If


    '----------------------- timer programowy 3
       If Ptimer3 = 0 Then
          Ptimer3 = 20
          Toggle Led2
       End If


    Loop
    '----------------- koniec pętli głównej --------------



    '=========== obsługa przerwania TYKNIĘĆ SYSTEMOWYCH - HeartBIT ===========
    Systick:

    If Ptimer1 > 0 Then Decr Ptimer1
    If Ptimer2 > 0 Then Decr Ptimer2
    If Ptimer3 > 0 Then Decr Ptimer3


    Return


    Program nie jest czysto teoretyczny , właśnie działa przede mną na moim zestawie uruchomieniowym ... żeby nie było, że mówię nieprawdę , proszę poniżej filmik.

    Zwróćcie uwagę, że dwie diody po lewej migają sobie - każda własnym "życiem" nawet w trakcie gdy klawisz jest wduszony na chwilkę lub na długo i zapala i gasi własną diodę - tę po prawej

    Attiny2313 - krótkie i długie naciśniecie przycisku

    a tu filmik akcji ... ;)
    (sorki za kiepską jakość - to wina telefonu)


    Link

  • #33 24 Lis 2010 16:33
    arktik1
    Poziom 27  

    Bez urazy MIREKK, autor napisał "potrzebuję program, który będzie działał w zależności od krótkiego i długiego naciśnięcia przycisku, tzn. krótkie naciśnięcie załącza pod program_1, a przytrzymanie tego przycisku uruchamia pod program_2.".

    Do czegoś takiego nie potrzeba chyba twojego programu.
    A sprawa jest prosta.
    Program nie musi robić nic poza obsługą przycisku i diody, dlatego zastosowałem WAIT.
    Moim zdaniem jest to najprostsze rozwiązanie tego "problemu".
    :D

  • #34 24 Lis 2010 17:28
    mirekk36
    Poziom 42  

    arktik1 wcale się nie urażam, dałem sporą dawkę wiedzy, każdy wykorzysta ją jak zechce ;) .... niestety tak jak się obawiam większość ludzi piszących tylko w Bascomie niewiele z tego wyniesie (i też przepraszam) bo nie mam tu zamiaru nikogo obrażać).

    Tak to już jest, że Bascom wyrabia tragicznie złe nawyki pseudo programowania, i jak "wam" przyrosną do rączek polecenia WAIT czy WAITMS to później już ciężko je wyplenić ze świadomości nie mówiąc już o przestawieniu umysłu na inne - prawidłowe tory.

    Piszesz, że autor potrzebuje program jak najprostszy. Tyle że jak już mówiłem, to co ty ale nie tylko ty napisałeś to nie jest niestety :( "żaden program" .... to po prostu jakieś tam i to byle jakie załatwienie sprawy. I jeszcze raz powiem, nie obrażaj się za te słowa - bo jeśli do ciebie nie przemawia taki prosty przykład z wykorzystaniem timerów programowych to jeszcze będzie niestety musiało dużo wody w rzece upłynąć zanim do tego sam dojdziesz a jeszcze więcej po drodze pytań zadasz na elektrodzie typu:

    "jak zrobić, żeby mi jednocześnie działało coś tam , do tego żeby jednocześnie działało wyświetlanie multipleskowe a do tego żeby to nie przeszkadzało w działaniu np odczytów temperatury z czujników DS"

    A na zakończenie zastanów się proszę dogłębnie co się będzie działo w twoim niestety tragicznym przykładzie, gdy ktoś wciśnie klawisz i będzie go trzymał tak te 2 sekundy ???????????? toż przecież w tym momencie na AMEN wstrzymujesz działanie pozostałych funkcji / instrukcji w pętli głównej DO LOOP .... zatem TOTALNIE bez sensu jest nawet użycie do tego funkcji Debounce.

    To już ktoś tam wcześniej dawał już nieco lepsze przykłady z tymi timerami, zdaje się piotrva - chociaż tam z kolei kolega załatwił się w tym samym aspekcie funkcją Bitwait ;)

    Reasumując, nie traktuj mojej wypowiedzi jako wyśmiewanie się z twojego kodu, tylko zwróć uwagę na to jak powinno się takie rzeczy rozwiązywać. Wtedy dużo szybciej pójdzie ci nauka programowania procków i szybciej będziesz pisał zaawansowane programy - nawet w Bascomie ;)

  • #35 24 Lis 2010 17:37
    SylwekK
    Poziom 29  

    Fajny patent z tymi programowymi timerami. Zazwyczaj moje programiki piszę tak aby nie zatrzymywały się w pętli głównej (nawyki z programowania w maszynowym na poczciwych Commodore :D ), ale czasem do łatwiejszego wyliczania przeskoków używam jakiegoś kilkumilisekundowego waitms i filozofia działania jest ta sama (tak jak tu dla migających niezależnie ledów) tylko dokładność dużo mniejsza, która zresztą do tej pory aż tak bardzo mi potrzebna nie była.
    Na co innego jednak chciałem zwrócić uwagę:

    Code:
    If Ptimer1 < 80 And Ptimer1 < 10 Then

    w takiej kombinacji warunek będzie spełniony zawsze kiedy Ptimer <10. Czy przypadkiem nie chodzi o zakres od 10 do 80 czyli:
    Code:
    If Ptimer1 < 80 And Ptimer1 > 10 Then


    Pozdrawiam

  • #36 24 Lis 2010 17:46
    mirekk36
    Poziom 42  

    SylwekK --> tak jak pisałem jest to obarczone takimi małymi błędami ale chodziło mi tylko o przekazanie IDEI, którą jak widzę podchwyciłeś ;) Super. Jak widzisz można się obyć bez waitms'ów a dokładność odliczania czasu nie jest tu w ogóle aż tak istotna. Za to mamy 3 różne fragmenty kodu, które działają w sposób absolutnie nieblokujący.

    A te warunki w kodzie - masz rację można mocno jeszcze zoptymalizować i w ogóle inaczej zorganizować do swoich potrzeb. Zauważ, że z tego kodu bardzo łatwo już zrobić sobie nawet taki fiuczer jak funkcję REPEAT po dłuższym wciśnięciu ;) .... ja i tak musiałem mocno się nagimnastykować żeby tę IDEĘ przekazać i przenieść z C do Bascoma - stąd tak topornie mogło to wyjść ale wybacz, że nie mam już siły i ochoty tego poprawiać.

    Takie osoby, które "TO" widzą to już będą wiedziały właśnie jak to wykorzystać. A dodam tylko jeszcze, że ponieważ w Bascomie bardzo łatwo przechodzi się na wstawki asemblerowe to można przepięknie kod przerwania Timera napisać właśnie w asemblerze - dosłownie kilka linijek, a przy wywołaniu przerwania użyć parametru NOSAVE

    wtedy można na prawdę dużo zyskać ;) jak na Bascoma

    nie mówiąc już o tym, że takie sprzętowe przerwanie timera można jeszcze równocześnie do całkiem innych celów/potrzeb wykorzystać i to stanowi o poważnej zalecie takiego podejścia do Programowania.

  • #37 24 Lis 2010 18:15
    arktik1
    Poziom 27  

    Rozumiem, każdy robi jak chce i w czym chce.
    Tylko chciał bym uściślić:
    "gdy ktoś wciśnie klawisz i będzie go trzymał tak te 2 sekundy"
    Wtedy program wróci do pętli głównej i będzie realizował resztę swoich zadań, mimo wciśniętego przycisku.
    Dopiero puszczenie przycisku i wciśnięcie go ponownie spowoduje następny skok.
    O jakim blokowaniu programu przez DEBOUNCE ty napisałeś?

  • #38 24 Lis 2010 18:34
    piotrva
    Moderator na urlopie...

    mirekk36 napisał:

    To już ktoś tam wcześniej dawał już nieco lepsze przykłady z tymi timerami, zdaje się piotrva - chociaż tam z kolei kolega załatwił się w tym samym aspekcie funkcją Bitwait ;)

    wiem, ale też robiłem to dlatego, żeby kolega nie narzekał że za trudne ;-)
    a poza tym, to dzięki ludziom takim jak Ty, mirekk36 zaczynamy wszyscy lepiej programować, a czasem ostra i dobitna uwaga daje nieźle do myślenia i naprowadza na właściwy tor ;-)
    dzięki temu m. in. zaczynam pożegnanie z bascomem ;-)

  • #39 24 Lis 2010 18:40
    mirekk36
    Poziom 42  

    arktik1 napisał:
    Rozumiem, każdy robi jak chce i w czym chce.

    Ależ ja tego nie neguję - masz rację, każdy zrobi jak chce.

    arktik1 napisał:
    O jakim blokowaniu programu przez DEBOUNCE ty napisałeś?


    Ale tu właśnie nie dostrzegasz istoty zagadnienia - pisania tzw funkcji, procedur "nieblokujących"

    Wyobraź sobie, że progam tego autora miałby za zadanie migać diodą LED1 (tak jak to jest w tym moim kodzie - dokładnie dioda LED1)

    I teraz gdyby użyć tej twojej funkcji Dbounce, która robi skok do podprogramu, który czeka 2 sekundy (czyli wieczność w bezczynności) to powiedz sam - czy w tym czasie ta dioda w pętli głównej będzie migała czy nie????

    Chyba dociera teraz do ciebie, że ta dioda LED1 przestanie migać na całe 2 sekundy!!!

    Tymczasem w proponowanym przeze mnie rozwiązaniu - dioda ta nadal będzie migać pomimo to czy trzymasz klawisz wciśnięty czy nie.

    teraz jaśniej ?

    co więcej - jedna dioda może migać sobie np z częstotliwością ok 80Hz a druga np z częstotliwością 20Hz czy jak tam chcesz..... i nadal każda z nich miga - specjalnie pokazałem to na filmiku, gdy drugi raz klikam klawisz i trzymam go wciśniętego przez dłuższy czas żeby zgasić tę diodę po prawej.

    Dodano po 5 [minuty]:

    piotrva napisał:
    dzięki temu m. in. zaczynam pożegnanie z bascomem ;-)


    Nie no bez przesady są tu lepsi ode mnie ;) .... ale to fakt, że warto i w pełni popieram twoją decyzję o pożegnaniu z Bascomem. Tylko jak nauczysz się C to żebyś nagle nie dostał klapek na oczach wykrzykując w niebogłosy jak to niektórzy na elektrodzie że w Bascomie nic się nie da zrobić. Bo jak widać, co pokazałem - da się zrobić - i to dużo...... dla niektórych jeśli właściwie programują to to może nawet wystarczyć, ale NA PEWNO w C da się zrobić więcej ;)

  • #40 24 Lis 2010 19:23
    arktik1
    Poziom 27  

    Ok ,po prostu inaczej zrozumiałem "na AMEN wstrzymujesz działanie pozostałych funkcji".
    Jeśli program ma robić coś jeszcze , poza pilnowaniem przycisku i diody to też zastosował bym rozwiązanie z TIMEREM lub zmienną odliczającą do X, ja nazywam to "licznikiem".
    A poza tym to:
    "dzięki temu m. in. zaczynam pożegnanie z bascomem"
    Chyba masz rację, zacznij od razu od C.
    Ja zacząłem od BASCOMa i za Chiny ludowe nie potrafię się przesiąść na C, a próbowałem już wiele razy.
    Pewnie dla tego że BASCOM jest łatwiejszy.

  • #41 25 Lis 2010 12:34
    SylwekK
    Poziom 29  

    No dobra, żeby nie być gołosłownym przytoczę tu fragment mojego kodu (wycięty z całości i okrojony tylko do zapalania i gaszenia diody) rozpoznającego przycisk krótki/długi. Do zaadoptowania go na inny procek nie powinno być problemu.
    Zaletą jest, że jest dość oszczędny (jestem maniakiem optymalizacji algorytmów - pozostałości z przeszłości ;-) ) i wykorzystuję tylko jedną zmienną pomocniczą licznikową (w zasadzie niezbędną w takich rozwiązaniach).
    Aha, mirekk36 nie złość się na tego waitms ;-) już wcześniej o tym wspominałem, że małe opóźnienie w pętli głównej nigdy mi nie przeszkadzało (w razie potrzeby moje podprogramy żyją własnym życiem) ale w powiązaniu z timerem spokojnie zamiast waitms można użyć przeskoku i po sprawie :D
    Myślę, że algorytm działania jest na tyle ciekawy, że się Wam spodoba i na tyle jasny, że tłumaczył go nie będę...
    Działa na 100% pewnie za każdym razem łącznie z uwzględnieniem drgania styków, a przycisk co ciekawe badany jest tylko raz :D

    Code:
    $regfile "attiny13.dat"
    
    $crystal = 9600000
    '--
    Config Portb.0 = Input
    Sel_p Alias Pinb.0            'selekt prawo
    Set Sel_p

    Config Portb.4 = Output
    Led Alias Portb.4
    Reset Led

    Dim L_d As Iram Byte          'licznik długiego przycisku
    L_d = 0

    '----------------------
    Do
    '--
    Waitms 25                     'opóźnienie pętli głównej (można zrealizować np. na Timer0)
    '--------
    If Sel_p = 0 Then             'klawisz
       If L_d < 255 Then Incr L_d
       If L_d = 30 Then           'czekaj około 0,7s (30x25ms=750ms)
          'długi przycisk
          Reset Led
       End If
    Else
       If L_d > 1 And L_d < 30 Then       'tu też sprawdź czy było 0,7s
          'krótki przycisk
          Set Led
       End If
       L_d = 0
    End If
    '--------



    Loop
    '--
    End


    P.S. Ktoś chce to jeszcze uprościć ? ;-)

  • #42 25 Lis 2010 12:59
    mirekk36
    Poziom 42  

    SylwekK --> ależ ja się nie złoszczę i nie mam zamiaru nikomu udowadniać, że to ja mam jakąś rację i jedyny najlepszy pomysł na zorganizowanie tegoż zagadnienia ;) .... jak pisał arktik1 , każdy zrobi tak jak uważa.

    Jednak mam nadzieję, że ty także nie będziesz się złościł jeśli wspomnę że nie zawsze maksymalne uproszczenie kodu jest celem w samym sobie i nie zawsze prowadzi do celu z punktu widzenia uniwersalnego działania całego programu. A wy lubicie się panowie widzę skupiać na jakimś wąskim wycinku czy fragmencie - bo rzekomo o to autorowi chodziło. Tymczasem z takich podpowiedzi autor nigdy się nie dowie, że można inaczej i w taki sposób, żeby jedno nie blokowało drugiego. Zatem pozostaw panie kolego swoje zaczepne pytanka typu:

    "czy ktoś chce to jeszcze uprościć" - bo nie w tym rzecz rzeby się tu ścigać kto bardziej zoptymalizuje kod tym bardziej, że pokazuję ci iż dla każdego optymalizacja kodu może oznaczać coś innego.

    Zamiast tego pokaż kod, który pozwoli obsługiwać przycisk na dwa omawiane sposoby ale jednocześnie aby pozwolić swobodnie wykonywać co najmniej dwa inne zadania w tym samym czasie. I własnie dobrym przykładem jest tu wtrącenie takiego migania dwóch przykładowych diod LED w różnym tempie. Jedna np co 10ms a druga niech będzie nawet co 1 sekundę ... a trzeba włączana i wyłączana przez krótkie i dłuższe naciśnięcie klawisza.

    Dlatego wcale nie odmawiam tobie czy innym zdania racji - bo jeśli w twoim konkretnym przypadku wystarczyło ci to do zrobienia konkretnego projektu - to nie staraj się równą miarą oceniać potrzeb innych.

    A jeśli uważasz, że wyższy priorytet w nauczeniu się programowania ma pisanie programów na mikrokontroler w sposób blokujący jak to robisz to sorki ale jeszcze do końca sam pewnych kwestii moim zdaniem nie rozumiesz. Z tym, że nie mam jak mówiłem zamiaru zarzucać ci niewiedzy żebyś zaraz się nie obruszył czy obraził..... ot po prostu musisz jeszcze nabrać troszkę praktyki i już.

    I tylko z tego powodu ja będę decydowanie polecał rozwiązania bazujące na tworzeniu procedur , funkcji czy zdarzeń nieblokujących dlatego że to jest równie łatwe a za to przynosi dużo więcej korzyści w rozbudowanym programie i lepszym ogarnięciu całości niż takie liniowe programowanie.

    Choć niewątpliwie, twój przykład jest w końcu najlepszy spośród tych, które wcześniej tu widziałem i może już być godnym polecenia. Bo nie zawiera żadnych BitWait - a ew zmniejszenie "rozdzielczości" pracy pętli głównej do 25ms , szczególnie dla początkującego nie musi być wielką albo nawet żadną przeszkodą. Tym bardziej, że już sama funkcja Debounce także opiera się na takich niewielkich opóźnieniach (chociaż tu następują one tylko w przypadku wciśnięcia klawisza i w zasadzie

    to to właśnie mógłbyś - jakbyś chciał - zoptymalizować w tym swoim sposobie bo można, a wtedy byłby jeszcze lepszy ;)

  • #43 25 Lis 2010 13:23
    SylwekK
    Poziom 29  

    :arrow: mirekk36 ja się z Tobą w 100% zgadzam odnośnie pisania nieblokujących progsów i nawet nie mam zamiaru polemizować na temat wyższości jednego czy drugiego rozwiązania tym bardziej, że bardzo cenię Cię jako programistę bo widziałem parę Twoich projektów. Optymalizację kodu stosuję dlatego, że w większości przypadków staje się on jednak bardziej przejrzysty a przede wszystkim... zawsze mi brakuje miejsca w procku :D
    W moim przykładzie nie chciałem dodawać i kopiować tego co mi się strasznie podobało w Twoim rozwiązaniu czyli programowe timery. Po prostu jest to tak łatwe do zaadoptowania, że każdy to może zrobić jeśli będzie miał taką potrzebę.

    Na koniec przeniesienie Waitms do środka pętli tak aby reakcja była tylko w momencie wduszenia przycisku. W sumie zamiast 25ms można spokojnie użyć nawet 1ms czy nawet kilkadziesiąt mikrosekund i minimalnie zmodyfikować program ale to już samemu proszę :D



    Code:
    '----------------------
    
    Do
    '--------
    If Sel_p = 0 Then             'klawisz
       Waitms 25                    'opóźnienie występuje tylko gdy wciśnięty klawisz
       If L_d < 255 Then Incr L_d
       If L_d = 30 Then           'czekaj około 0,7s (30x25ms=750ms)
          'długi przycisk
          Reset Led
       End If
    Else
       If L_d > 1 And L_d < 30 Then       'tu też sprawdź czy było 0,7s
          'krótki przycisk
          Set Led
       End If
       L_d = 0
    End If
    '--------



    Loop
    '--
    End

  • #44 25 Lis 2010 14:36
    mirekk36
    Poziom 42  

    SylwekK napisał:
    Optymalizację kodu stosuję dlatego, że w większości przypadków staje się on jednak bardziej przejrzysty a przede wszystkim... zawsze mi brakuje miejsca w procku :D


    Nie, no co by nie mówić i jak nie patrzeć to oczywiście optymalizacja własnego kodu pod takimi względami jest ZAWSZE jak najbardziej pożądana i pożyteczna, więc tu złego słowa nie można powiedzieć, wręcz przeciwnie - Bardzo DOBRZE ;)


    SylwekK napisał:
    Na koniec przeniesienie Waitms do środka pętli tak aby reakcja była tylko w momencie wduszenia przycisku. W sumie zamiast 25ms można spokojnie użyć nawet 1ms czy nawet kilkadziesiąt mikrosekund i minimalnie zmodyfikować program ale to już samemu proszę :D


    No o to mi chodziło ;) i dokładnie tak jak piszesz przerobienie tego na 1ms to już powinno być zadanie dla zainteresowanych, żeby tak w 100% wszystkiego na talerzu nie podawać. Z drugiej zaś strony ten kod w takiej postaci to już można w zasadzie uznać za "nieblokujący" i z powodzeniem zastosować nawet do wielu przycisków. Poza tym jest to właśnie przykład (ale to mówię, że tak powiem "po cichu do ciebie tylko" ;) .... gdzie użycie poleceń typu waitms jest spokojnie dopuszczalne i łatwo tolerowane, wbrew takmi moim na początku zdecydowanym zaleceniom aby ich nie używać. Tak na prawdę to jak ktoś wie JAK już poprawnie pisze się programy to nawet i użycie polecenia WAIT nie jest grzechem w pewnych sytuacjach.... tylko właśnie trzeba wiedzieć i czuć co to są za sytuacje.
    A ty widzę jednak zdajesz sobie z tego już dobrze sprawę i SUPER. Takie podejście mi się bardzo podoba i uważam, że dla osób, które nie do końca mogą jeszcze zrozumieć ideę działania "timerów programowch" oraz czym one w ogóe są i "z czym się to je" to , ten twój ostatni przykład jest teraz jednym z NAJLEPSZYCH i godnych POLECENIA! ;)

  • #45 25 Lis 2010 15:17
    SylwekK
    Poziom 29  

    Potwierdza się, że działania w grupie jednak przynoszą dobre rezultaty (burza mózgów) ;-)
    Myślę, że każdy wyciągnął z tego tematu jakieś wnioski i niby chodziło tu o obsługę głupiego przycisku, a dowiedziałem się jak fajnie można jeszcze używać Timera, z którego na razie korzystałem sporadycznie - dzięki mirekk36 :D

  • #46 27 Lis 2010 08:11
    hanibal0
    Poziom 11  

    Panowie sorry za moją nieobecność w rozmowie, jednak byłem w delegacji i nie miałem dostępu do neta, widzę że tema zainteresował nie tylko mnie i BARDZO DZIĘKUJĘ każdemu za chwilę poświęconą mojemu problemowi. Myślę że z tego wątku nie tylko ja wyniosę wiele cennych uwag na przyszłość.
    W szczególności dziękuję Tobie mirekk36 bo widzę że nie podchodzisz do nowicjuszy jak niektórzy z arogancją i ignorancją, przecież każdy kiedyś zaczynał uczyć się programować i nie od razu wiedział z czym to się je.

    Wielkie dzięki ;)

  • #47 30 Gru 2010 15:51
    zimzia@
    Poziom 12  

    SylwekK napisał:
    :arrow: mirekk36 ja się z Tobą w 100% zgadzam odnośnie pisania nieblokujących progsów i nawet nie mam zamiaru polemizować na temat wyższości jednego czy drugiego rozwiązania tym bardziej, że bardzo cenię Cię jako programistę bo widziałem parę Twoich projektów. Optymalizację kodu stosuję dlatego, że w większości przypadków staje się on jednak bardziej przejrzysty a przede wszystkim... zawsze mi brakuje miejsca w procku :D
    W moim przykładzie nie chciałem dodawać i kopiować tego co mi się strasznie podobało w Twoim rozwiązaniu czyli programowe timery. Po prostu jest to tak łatwe do zaadoptowania, że każdy to może zrobić jeśli będzie miał taką potrzebę.

    Na koniec przeniesienie Waitms do środka pętli tak aby reakcja była tylko w momencie wduszenia przycisku. W sumie zamiast 25ms można spokojnie użyć nawet 1ms czy nawet kilkadziesiąt mikrosekund i minimalnie zmodyfikować program ale to już samemu proszę :D



    Witam chciałem użyć tego sposobu do mojego termostatu ale przy krótkim sygnale układ przeskakuje do podprogramu ale w nim się blokuje i zapętla

  • #48 30 Gru 2010 17:43
    SylwekK
    Poziom 29  

    A czy zamiast END nie powinno być RETURN w podprogramach ?? (tak, tak pytanie retoryczne... :) )
    Zmień to i sprawdź czy działa. Procedurka [krótki/długi] jest sprawdzona na 100% i wykorzystuję ją na bierząco w moich progsach - jeszcze nigdy nie zawiodła...
    Pozdrawiam

    P.S. Aha, pomijam już fakt, że skaczesz z pętli programu na jego początek - ciekawe co na to stos uC... ?

  • #49 30 Gru 2010 23:10
    zimzia@
    Poziom 12  

    niestety nie mogę sobie z tym poradzić, może kolega coś zaproponuje ??

  • #50 31 Gru 2010 10:57
    SylwekK
    Poziom 29  

    Hmm, nie mam w zwyczaju podawać wszystkiego na talerzu. Na początek zapoznaj się ze składnią bascoma! Podprogramy wywoływane przez GOSUB zawsze powinny kończyć się RETURN. Jeśli w pętli będziesz ciągle skakał przez GOSUB, a nie będziesz do niej wracał przez RETURN to zawalisz cały stos w pamięci i uC będzie wariował. W dobrym tonie jest aby instrukcja END była umieszczona w programie tylko JEDEN RAZ na faktycznym końcu programu (przed podprogramami, funkcjami, danymi w DATA, itp...). Ty jej tu wyraźnie nadużywasz i zamiast RETURN wszędzie jest END. Szczerze mówiąc nawet nie chce mi się analizować tego programu puki sam nie poprawisz PODSTAWOWYCH błędów. Popraw je sprawdź może już będzie działać, a jeśli nie będzie to dopiero wtedy wrzuć listing.

  • #51 31 Gru 2010 11:20
    mirekk36
    Poziom 42  

    zimzia@ -> albo zacznij się uczyć języka C dla AVR. W tym języku nawet jak byś chciał to nie udałoby ci się popełnić tyle takich błędów ;) ..... owszem można robić inne ... no ale teraz jest szczególna okazja aby sobie zrobić np noworoczne postanowienie, że szybko nauczę się języka C. Tym bardziej, że masz dużo materiałów do nauki.

  • #52 31 Gru 2010 14:54
    LordBlick
    VIP Zasłużony dla elektroda

    Programowanie w obojętnie jakim języku jeśli ma być porządne, to jest to mozolna dłubanina. Osobom z brakiem cierpliwości odradzam.

  • #53 01 Sty 2011 18:39
    asembler
    Poziom 32  

    Ja proponuje następujące rozwiązanie:
    Podzielic program na dwa podprogramy z czego jeden bedzie odpowiadał za czytanie klawisza/klawiszy ilosc obojętna.
    Drugi zaś będzie realizował rozróżnianie czy naciskamy krótko czy długo.
    Zasada jest banalna pierwszy program umieszczamy w dowolnym przerwaniu np 100 razy sek moze to być przerwanie wykorzystujące liczenie czasu rzeczywistego na przykład. Podprogram ten jezeli wykryje nacisniety klawisz zapamietuje go w dowolnej zmiennej. (KLAW)

    Drugi podprogram czyta tą zmienną jeżeli wykryje ze zmienna zawier kod klawisza kasują odczekuje np. 20mSi odczytuje ponownie.
    Jenoczesnie uruchamiany jest licznik tych porównań. Jezeli licznik przekroczy zadaną wartosć (czas długiego nacisniecia klawisza) podprogram konczy dzialanie zwracając kod klawisza "dlugiego'.
    Jezeli nie przekroczy zwraca kod klawisza krótkiego.
    Dla rozgraniczenia czy klawisz jest "długi" czy "krótki" wszystkie kody klawiszy wykryte w podprogramie umieszczonym w przerwaniu przyporządkowyje liczbami parzystymi. Natomiast po wykryciu klawisza "długiego" dodaje jeden do kodu klawisza krótkiego co oznacza ze wyszstkie klawisze "długie" są liczbami nieparzystymi.
    Jak widac czas naciakania klawisza może byc dowolnie regulowany w granicznym przypadku można łatwo przerowbic program tak aby rozróżniał inne długości naciskania klawisza (np. reset' trzymamy klawisz przez 5 sekund)
    Dodatkową zaletą takiego rozwiazanie jest to że programem mozna sterowac "z zewnątrz" tzn wystarczy ustawic zmienną KLAW z poziomu innego podprogramu a mamy mozliwosc symulacji dzialania klawiatury bez naciskania klawiszy.

    Oczywiście załatwiony jest równocześnie problem drgania styków.

  • #54 01 Sty 2011 20:43
    SylwekK
    Poziom 29  

    @asembler w zasadzie do Twojej sugestii podziału programu za wyjątkiem zastosowania 5s trzymania do resetu, o którym wspomniałeś (chociaż przeróbka mojej procedury pod tym kątem też nie była by wcale jakaś trudna i skomplikowana) nie jest w tym przypadku potrzebna żadna dodatkowa zmienna. Można przecież wykorzystać już istniejącą w tym przypadku zmienną L_d i z jej pomocą rozpoznawać odpowiednią funkcję wykonywania programu i też spokojnie można by tym sterować z zewnątrz (pod warunkiem zewnętrznego czytania dopiero po wykonaniu badania wewnętrznego przyciśnięcia klawisza). Zwróć uwagę, że jeżeli nic nie jest wciśnięte to L_d=0, w każdym innym przypadku ma jakąś tam wartość z przedziału 1 do 255. Co do przerwań to moim zdaniem cały program jest tak prosty funkcjonalnie i niewymagający nadmiernej precyzji , że przerwania tu absolutnie nie są potrzebne. Osobiście wykorzystuję je tylko tam gdzie naprawdę są niezbędne.
    Pozdrawiam :)

  • #55 01 Sty 2011 21:34
    asembler
    Poziom 32  

    W mojej metodzie gdy nie jest nic wciśniete to tez nic nie jest zapisywane w zmiennej KLAW stąd u ciebie nie ma mozliwosci sterowania z zewnątrz gdyz gdy wymusisz "z zewnatrz" wartość KLAW to twoj program ci wyzeruje.
    Co do tego przykladu resetu to tylko był przyklad ze mozna zrobic łatwo trzeci sposob naciskania klawisza niekoniecz 5s nieszczesne.

  • #56 02 Sty 2011 10:36
    zimzia@
    Poziom 12  

    Witam
    SylwekK poprawiłem to o czym mówiłeś nie daje sobie głowy uciąć że jest poprawnie ale dalej nie działa, głównie chodzi mi o to aby reagowało tylko na krótki przycisk.

  • #57 02 Sty 2011 13:48
    SylwekK
    Poziom 29  

    Programu nie poprawiałem. W wykrzyknikach umieściłem Ci ewidentne i rażące błędy programowe. Poprawności i algorytmu nawet nie sprawdzałem - pewnie musiał bym Ci to od zera napisać, a jak wspomniałem na talerzu nic nie podaję. Jeśli dojdziesz sam to nauczysz się i zapamiętasz na przyszłość.
    Po pierwsze - dla ułatwienia staraj się korzystać z dobrodziejstwa instrukcji ALIAS wtedy program będzie czytelniejszy.
    Po drugie - naucz się pisać program blokami czyli kompletnymi fragmentami, które wykonują konkretne zadanie. U Ciebie bloki wyglądają podobnie jak wrzucenie biegu wstecznego rozpędzonym autem na autostradzie.
    Po trzecie - zapoznaj się ze składnią instrukcji Bascoma. Jeśli chcesz w tym środowisku programować to zapoznaj się z popularnym polskim helpem albo (i) kup jakąś książkę (np.Marcin Wiązania - Programowanie mikrokontrolerów w języku BASCOM)
    Po czwarte - używaj komentarzy. To się bardzo opłaca po jakimś czasie.
    Zobacz przykład jednego z moich programów: Link (program jest pod koniec postu)
    Nawet za 10 lat kiedy do niego zajrzę to nie będę miał problemów z analizą jego działania. Zwróć uwagę na poszczególne bloki z jakich się składa. To tylko mały przykład. Na elektrodzie jest dużo programów, z których można się wiele nauczyć.
    Pozdrawiam

  • #58 02 Sty 2011 18:17
    zimzia@
    Poziom 12  

    Krótki przycisk już działa błędem była niepotrzebna linijka.
    Zamieniłem Gosub na Goto w skrócie teraz wygląda tak:

    Code:
    do
    
    if 1 then
    gosub cos1
    loop
    end

    cos1:
    if 2 then
    goto cos2
    if 3 then
    return

    cos2:
    do
    if 4 then
    goto cos1
    loop


    SylwekK nie jestem pewien jednej rzeczy czy powrót z cos2 do cos1 (jeśli nie jest spełniony warunek), który następnie powraca do programu głównego przez return nie zawala stosu :?:.

  • #59 02 Sty 2011 18:38
    asembler
    Poziom 32  

    Ten program predzej czy później pójdzie w maliny albo si ę zapętli.

  • #60 02 Sty 2011 20:27
    SylwekK
    Poziom 29  

    @asembler ma rację... Pomyśl nad blokami programu i napisz ten program zupełnie od nowa z nowym algorytmem.