logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

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

hanibal0 20 Lis 2010 19:13 14667 82
REKLAMA
  • #1 8768279
    hanibal0
    Poziom 11  
    Jak w temacie.
    Potrzebuję programu, 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.
    Od jednego z kolegów z forum otrzymałem kod, który niestety nie działał poprawnie, zmodyfikowałem go ale wciąż nie działa.
    Bardzo proszę kogoś o pomoc w ukończeniu tego programu:
    
    $regfile = "attiny2313.dat"
    
    'konfiguracja portow
    Config Portd = Input
    Config Portb = Output
    
    'ustawienie nazw
    Przycisk Alias Pind.0
    Dioda Alias Pinb.7
    
    'wygaszenie diod
    Przycisk = 1
    Dioda = 0
    
    'zmienne
    Dim Flaga As Byte
    Dim A As Byte
    
    'program glowny
    Do
    Flaga = 0
       If Przycisk = 0 Then
       Waitms 30
       If Przycisk = 0 Then
    Flaga = 1
       Waitms 500
    End If
       If Przycisk = 0 Then Flaga = 2
    Bitwait Przycisk , Set
    End If
    If Flaga = 1 Then Gosub Krotkie
    If Flaga = 2 Then Gosub Dlugie
    Loop
    
    '----------podprogramy-------------
    Krotkie:
    Toggle Dioda
    Return
    
    Dlugie:
    Do
    Set Dioda
    For A = 0 To 10
    If Przycisk = 0 Then
       Waitms 30
       If Przycisk = 0 Then
          Reset Dioda
          Return
       End If
    End If
       Waitms 500
    Next
    Reset Dioda
    Return
    Loop
    End
  • REKLAMA
  • #2 8768341
    piotrva
    VIP Zasłużony dla elektroda
    użyj do tego celu np. timera1
    naciskasz przycisk - start timera
    zwalniasz przycisk - stop timera
    i odczytujesz ile impulsów zliczy Ci ten Timer, i w zależności od tego odpowiedni podprogram ;-)
  • #3 8768410
    hanibal0
    Poziom 11  
    hehe no niby proste ale dla bardziej zaawansowanych bo ja jeszcze nie ruszalem timerow i nie wiem jak sie za to zabrac
  • #4 8768494
    piotrva
    VIP Zasłużony dla elektroda
    Poniższy kod działa na 100%
    
    $regfile = "2313def.dat"
    $crystal = 11059200
    $baud = 9600
    ' ...
    Config Timer1 = Timer , Prescale = 1024
    'zmień prescale na mniejsze, żeby odmierzać krótsze odcinki czasów
    Config Pind.2 = Input
    Set Portd.2
    Przycisk Alias Pind.2
    '...
    Do
    Stop Timer1
    Timer1 = 0
    Bitwait Przycisk , Reset
    Start Timer1
    Bitwait Przycisk , Set
    Stop Timer1
    If Timer1 > 5000 Then
    'im wyższa wartość tym dłużej trzeba trzymać przycisk, żeby wywołać pierwsza procedurę
    Gosub Dlugie
    Else
    Gosub Krotkie
    End If
    Waitms 250
    Loop
    '...
    Dlugie:
    Print "Long"
    Return
    Krotkie:
    Print "Short"
    Return
    
  • #5 8768564
    Freddy
    Poziom 43  
    piotrva napisał:

    ...
    Poniższy kod działa na 100%
    ...
    kod pisany na kolanie, nie testowany ale powinien działać, musisz prescale i ten drugi parametr dobrać eksperymentalnie

    To zdecyduj sie działa na 100% czy nietestowany, a nie wprowadzaj zamieszania :!:
  • #6 8768745
    hanibal0
    Poziom 11  
    kod jest nie kompletny, nie ma okreslonego portu wyjsciowego, lsd jest nie skonfigurowany a ja jestem poczatkujacy wiec bede musial nad nim troche czasu spedzic. Dlatego chcialbym wiedziec czy warto (wiem ze zawsze warto bo naucze sie czegos nowego ale obecnie nie mam zbyt wiele czasu na hobby a ten program jest mi potrzebny)

    o ile jestem w stanie mniej wiecej zrozumiec kod to nie wiem jak dobrac prescale i ilosc impulsow zeby np program dlugie zadzialal po 2 sek trzymania przycisku
  • #7 8768790
    xury
    Specjalista automatyka domowa
    Nie wytrzymałem... ,a może jeszcze zakupić uC zrobić płytkę i zaprogramować za free ?
    Skoro wiesz kolego czego brakuje to, sobie dopisz. Ty piszesz, że nie masz czasu na hobby, ktoś inny Ci za darmo pomaga, a Ty jeszcze wybrzydzasz ?
    Znasz stare polskie przysłowie - "darowanemu koniowi nie patrzy się w zęby"?
  • REKLAMA
  • #8 8768817
    hanibal0
    Poziom 11  
    xury napisał:
    Nie wytrzymałem... ,a może jeszcze zakupić uC zrobić płytkę i zaprogramować za free ?
    Skoro wiesz kolego czego brakuje to, sobie dopisz. Ty piszesz, że nie masz czasu na hobby, ktoś inny Ci za darmo pomaga, a Ty jeszcze wybrzydzasz ?
    Znasz stare polskie przysłowie - "darowanemu koniowi nie patrzy się w zęby"?


    zle mnie zrozumiales, nie wybrzydzam wrecz przeciwnie doceniam pomoc a w szczegolnosci to ze w tak krotkim czasie ktos zainteresowal sie moim problemem. Jestem wdzieczny za wszelka pomoc tylko nie umiem poslugiwac sie timerami ale skoro to taki problem to przepraszam. Forum jest dla tych ktorzy szukaja pomocy i dla tych ktorzy bezinteresownie chca pomagac, ja nie powiedzialem ze potrzebuje ten program na sprzedaz bo tak nie jest, potrzebuje go bo zona mnie denerwuje zebym wreszcie uruchomil sterownik.



    taki kod wlancza diode ale jej nie wylancza, no i dziala tylko jeden program (krotkie)
    $regfile = "2313def.dat"
    
    ' ...
    Config Timer1 = Timer , Prescale = 1024
    'zmień prescale na mniejsze, żeby odmierzać krótsze odcinki czasów
    Config Portd = Input
    Config Portb = Output
    
    Przycisk Alias Pind.0
    Dioda Alias Pinb.7
    
    Przycisk = 1
    Dioda = 0
    
    '...
    Do
    Stop Timer1
    Timer1 = 0
    Bitwait Przycisk , Reset
    Start Timer1
    Bitwait Przycisk , Set
    Stop Timer1
    If Timer1 > 5000 Then
    'im wyższa wartość tym dłużej trzeba trzymać przycisk, żeby wywołać pierwsza procedurę
    Gosub Dlugie
    Else
    Gosub Krotkie
    End If
    Waitms 250
    Loop
    '...
    
    
    Dlugie:
    Toggle Dioda
    Wait 5
    Toggle Dioda
    Return
    
    Krotkie:
    Toggle Dioda
    Return
  • #9 8769025
    omicronNs
    Poziom 21  
    Cytat:

    ja nie powiedzialem ze potrzebuje ten program na sprzedaz bo tak nie jest, potrzebuje go bo zona mnie denerwuje zebym wreszcie uruchomil sterownik.


    Za to zdanie chętnie bym ci pomógł, ale niestety nie znam bascoma :) . Przeczytaj help do bascoma.
  • #10 8769055
    hanibal0
    Poziom 11  
    dzieki, czytam go juz od kilku godz ale nie potrafie ogarnac tych timerow, tzn wlaczenie odliczanie niby rozumiem ale ustawienie czasu jaki bym chcial juz nie bardzo
  • #12 8769185
    hanibal0
    Poziom 11  
    chcialbym uzyc timer1 i czestotliwosc wewnetrznego kwarcu attiny2313, nie jestem pewien ale to chyba 4MHz. Czas jaki chcialbym uzyskac to cos ok 2sek, nie mysi byc dokladnie 2sek.

    Naprawde nie chce nikogo urazic na tym forum poniewaz duzo sie z niego ucze ale poprostu jeszcze tego nie umiem zrobic, kilkakrotnie probowalem wykorzystywac timery ale zawsze bez skutku.

    Ten kod wydaje mi sie byc ok ale niestety bez wzgledu na to ile przytrzymam przycisk to dioda sie zaswieca ale juz kolejne nacisniecie nie gasi diody :(

    $regfile = "2313def.dat"
    
    ' ...
    Config Timer1 = Timer , Prescale = 64
    'zmień prescale na mniejsze, żeby odmierzać krótsze odcinki czasów
    Config Portd = Input
    Config Portb = Output
    
    Przycisk Alias Pind.0
    Dioda Alias Pinb.7
    
    Przycisk = 1
    Dioda = 0
    
    '...
    Do
    Stop Timer1
    Timer1 = 0
    Bitwait Przycisk , Reset
    Start Timer1
    Bitwait Przycisk , Set
    Stop Timer1
    If Timer1 > 1000 Then
    'im wyższa wartość tym dłużej trzeba trzymać przycisk, żeby wywołać pierwsza procedurę
    Gosub Dlugie
    Else
    Gosub Krotkie
    End If
    Waitms 250
    Loop
    '...
    
    
    Dlugie:
    Toggle Dioda
    Wait 5
    Toggle Dioda
    Return
    
    Krotkie:
    Toggle Dioda
    Return


    wydaje mi sie ze powinno tu byc cos ok 4sek ale pewnie tylko mi sie wydaje
  • #13 8769272
    omicronNs
    Poziom 21  
    Chyba nie potrzebujesz odliczać dokładnych czasów, więc najlepiej wyliczyć ile przepełnień licznika potrzebujesz przy danej częstotliwości i danym preskalerze.

    f=fosc/p

    f - częstotliwość taktowania licznika
    fosc - częstotliwość oscylatora
    p - preskaler

    T=1/f

    t=(c*x)/f

    t - czas odmierzany
    c - pojemność licznika
    x - ilość przepełnień

    ostatecznie:

    x=(t*fosc)/(p*c)

    np.

    Odmierzamy ok. 1s fosc 8MHz licznik 8bit czyli jego pojemność = 256, preskaler 1024

    x = 30, czyli po 30 przepełnieniach licznika zostanie odmierzona ok. 1s.

    Dla licznika 16 bit licznik nawet raz się nie przepełni, więc możesz wykorzystać przerwania od porównania.

    edit:
    Jak przy częstotliwości oscylatora 4MHz i preskalerze 64 liczysz tylko do 1000 to odmierzasz marne 16ms. Dla tego preskalera i tej częstotliwości oscylatora musisz liczyć do 62500.

    Zaraz po:
    
    Bitwait Przycisk , Reset 
    

    poczekaj kilka ms.
  • #14 8769333
    hanibal0
    Poziom 11  
    jeśli dobrze zrozumiałem to przy częstotliwości 4MHz i preskalerze 64 oraz przy liczniku 8-bitowym 1s będzie odmierzona przy ok x=14648
  • #15 8769358
    omicronNs
    Poziom 21  
    Tak ale pamiętaj, że to są przepełnienia, a nie wartość licznika. Przeczytaj mój edytowany post wyżej.

    Cytat:

    Dla tego preskalera i tej częstotliwości oscylatora musisz liczyć do 62500.


    A to jest wartość licznika, i to możesz wpisać tam gdzie miałeś 1000 w programie.
    Timer1, preskaler=64, fosc=4MHz.

    Czemu zmieniłeś post? 244 przepełnienia to była dobra wartość :D, tylko musiałbyś zmienić program(bądź co bądź skomplikować go, nie wiedziałem jakiego licznika chciałeś użyć).
  • REKLAMA
  • #16 8769388
    hanibal0
    Poziom 11  
    no i znowu nie rozumiem tego 62500, mi wychodzi z obliczeń 29296

    Posty raportowane.
    Proszę poprawić pisownię w swoich postach, w tym temacie - za wyjątkiem pierwszego.
    Regulamin p.15
    [zumek]
  • #17 8769399
    omicronNs
    Poziom 21  
    Teraz nie liczysz przepełnień tylko do ilu musi doliczyć, bo nie przepełni się ani razu. Wzór jeśli nim chcesz się posługiwać będzie następujący:

    y=(t*fosc)/p

    (1*4000000)/64 = 62500

    Po prostu nie wiem dlaczego założyłem, że będziesz korzystać z licznika 8bit, a on jest zbyt mały, żeby odliczyć sekundę bez przepełnienia, stąd też należało odliczyć ilość przepełnień, a ty korzystasz z licznika 16bit, którym bez problemu odliczysz sekundę bez przepełnień.
  • #18 8769433
    hanibal0
    Poziom 11  
    omnicronNs moglibyśmy pogadać przez 10 min na gg?

    wpisałem 244 ale program wciąż nie działa.

    ok teraz chyba zrozumiałem z tym odliczaniem, przynajmniej tak mi się wydaje, wpisałem do programu 6250 jednak program wciąż nie działa poprawnie, tzn dioda tylko się zaświeca niezależnie czy przytrzymam krótko czy długo a ponowne naciśniecie nie wygasza diody.



    Cytat:
    $regfile = "2313def.dat"

    Config Timer1 = Timer , Prescale = 64
    Config Portd = Input
    Config Portb = Output

    Przycisk Alias Pind.0
    Dioda Alias Pinb.7

    Przycisk = 1
    Dioda = 0

    Do
    Stop Timer1
    Timer1 = 0
    Bitwait Przycisk , Reset
    Waitms 100
    Start Timer1
    Bitwait Przycisk , Set
    Waitms 100
    Stop Timer1
    If Timer1 > 6250 Then
    Gosub Dlugie
    Else
    Gosub Krotkie
    End If
    Waitms 250
    Loop

    Dlugie:
    Toggle Dioda
    Wait 5
    Toggle Dioda
    Return

    Krotkie:
    Toggle Dioda
    Return
  • #19 8769460
    omicronNs
    Poziom 21  
    Wpisz tam 62500 a nie 244.
  • REKLAMA
  • #20 8769470
    hanibal0
    Poziom 11  
    tak zrobiłem, zobacz na mój edytowany post wyżej
  • #21 8769476
    omicronNs
    Poziom 21  
    Nie wpisałeś tam 62500 tylko 6250 a to 10 razy mniej.
  • #22 8769736
    hanibal0
    Poziom 11  
    dzięki koledzie omicronNs zmodyfikowałem kod, jednak program wciąż nie spełnia moich oczekiwań, tzn w tym momencie program działa w ten sposób że jeśli wcisnę przycisk krótko zapali się dioda na pb7 i można ją zgasić jedynie przez długie wciśnięcie przycisku, co spowoduje wygaszenie pb7 a zaświecenie pb6, teraz znowu krótkie przyciśnięcie gasi pb6 a zaświeca pb7.

    Mi zależy aby niezależnie od tego który program został uruchomiony, krótkie wciśnięcie przycisku spowoduje zmianę stanu.

    oto mój kod:
    $regfile = "2313def.dat"
    $crystal = 4000000
    
    
    Config Timer1 = Timer , Prescale = 64
    Config Portd = Input
    Config Portb = Output
    
    Przycisk Alias Pind.6
    Dioda Alias Pinb.7
    Dioda1 Alias Pinb.6
    
    Przycisk = 1
    Dioda = 0
    Dioda1 = 0
    
    
    Do
    Stop Timer1
    Timer1 = 0
    Bitwait Przycisk , Reset
    Start Timer1
    Waitms 10
    Bitwait Przycisk , Set
    Stop Timer1
    If Timer1 > 7812 Then
    Gosub Dlugie
    Else
    Gosub Krotkie
    End If
    Waitms 250
    Loop
    
    Dlugie:
    Toggle Dioda1
    Return
    
    Krotkie:
    Toggle Dioda
    Return


    będę wdzięczny za pomoc
  • #23 8771230
    piotrva
    VIP Zasłużony dla elektroda
    1. zmień sobie $regfile na
    $regfile="attiny2313.dat"
    bo ja testowałem na 90s2313 i masz zły regfile teraz
    2. wywal to waitms 10 po bitwait - niepotrzebne...
    3. jaki masz oscylator to sobie sprawdź we feusebitach (możesz mieć wybrany 8 lub 4 MHz)
    4. nie włączasz podciągania przycisku!!
    zamiast Przycisk = 1 (czyli Pind.6 = 1) daj Portd.6=1 bo za podciąganie odpowiedzialny jest rejestr PORTn.x.
    5. do diod dawaj alias jako Dioda1 Alias Portb.7 (a nie Pinb.7)
    czyli:
    
    $regfile = "attiny2313.dat"
    $crystal = 4000000
    
    
    Config Timer1 = Timer , Prescale = 1024
    Config Portd = Input
    Config Portb = Output
    
    Przycisk Alias Pind.6
    Dioda Alias Portb.7
    Dioda1 Alias Portb.6
    
    Portd.6=1
    Dioda = 0
    Dioda1 = 0
    
    
    Do
    Stop Timer1
    Timer1 = 0
    Bitwait Przycisk , Reset
    Start Timer1
    Bitwait Przycisk , Set
    Stop Timer1
    If Timer1 > 7812 Then
    '(
    f_osc/preskaler - impulsy na sekundę czyli:
    4 000 000/1 024 = 3906.25
    impulsy na sekundę * czas = impulsy
    3906.25 * 2 = 7812.5 =~7812
    przy preskalerze=64 wszystko by Ci się wywaliło...
    ')
    Gosub Dlugie
    Else
    Gosub Krotkie
    End If
    Waitms 250
    Loop
    
    Dlugie:
    Toggle Dioda1
    Return
    
    Krotkie:
    Toggle Dioda
    Return
    
  • #24 8771531
    mirekk36
    Poziom 42  
    Panowie to nie jest żaden program. Wszystko sprowadza się tu TYLKO do obsługi jednego klawisza. A jak ktoś chce 2 albo 3 czy 5 klawiszy to co ??? to kaplica z takim rozwiązaniem i tym sposobem marnotrawienia timerów. A nie dość że zatrudniacie Timer do roboty i to aż 16bitowy !!! to jeszcze jakieś Wiatms'y widzę .... toż co to za program ??? skoro nic innego w nim nie będzie działać ? ;) no zastanówcie się trochę.

    A w ogóle "program" w którym w pętli głównej dajecie już nawet nie wait ale Bitwait - to nieporozumienie.

    Weźcie się już lepiej za porządne poczytanie na temat chociażby Debounce w Bascomie zamiast tworzyć takie "potworki" (mega obliczenia, preskalery, timery 16-bitowe na wojnę rzucacie do obsługi jednego biednego klawisza a zaraz wszystko blokujecie sobie jednym ruchem - bitwait ! .... nie wspominając już o kompletnym braku przeciwdziałania drganiom styków)
  • #25 8772922
    piotrva
    VIP Zasłużony dla elektroda
    to jest najprostsze rozwiązanie dla kolegi, prosił, żeby kod był prosty ;-)
    inaczej zrobiłbym to na 1 timerze 8-bit dla wielu przycisków...
  • #26 8773194
    hanibal0
    Poziom 11  
    panowie mi chodzi o prosty program, który będzie obsługiwał krótkie i długie naciśnięcie przycisku. Napisałem nowy kod, wydaj mi się że powinien być ok ale bascom sypie błędy z end if i nie mam pojęcia dlaczego?

    'ustawienie nazw
    Przycisk Alias Pind.0
    Dioda Alias Pinb.7
    Dioda1 Alias Pinb.6
    
    'ustawienie zmiennych
    Dim A As Byte
    
    A = 0
    Przycisk = 1
    Dioda = 0
    
    Do
       Debounce Przycisk , 0 , Menu , Sub
       If A = 1 Then Gosub Krotkie
       If A = 2 Then Gosub Dlugie
       If A = 3 Then Gosub Wylacz
    Loop
    
    Menu:
       Waitms 200
       A = 1
       If Przycisk = 1 Then
       Return
       Else
       Waitms 300
       A = 2
       Return
       End If
    
    Krotkie:
       A = 0
       If Dioda = 1 Then Gosub Wylacz
       Else
       Toggle Dioda
       Return
       End If
    
    
    
    Dlugie:
       A = 0
       If Dioda1 = 1 Then Gosub Wylacz
       Else
       Toggle Dioda1
       Return
       End If
    
    
    Wylacz:
       A = 0
       Dioda = 0
       Dioda1 = 0
       Return
    
    
    End
  • #27 8775247
    sp3ots
    Poziom 38  
    Witam !
    W tych podprogramach masz błędy:
    
    Krotkie:
       A = 0
       If Dioda = 1 Then Gosub Wylacz
       Else
       Toggle Dioda
       Return
       End If
    
    Dlugie:
       A = 0
       If Dioda1 = 1 Then Gosub Wylacz
       Else
       Toggle Dioda1
       Return
       End If 
    

    zmień na:
    
    Krotkie:
       A = 0
       If Dioda = 1 Then 
       Gosub Wylacz
       Else
       Toggle Dioda
       Return
       End If
    
    Dlugie:
       A = 0
       If Dioda1 = 1 Then 
       Gosub Wylacz
       Else
       Toggle Dioda1
       Return
       End If 
    

    Pozdrawiam. Stefan
  • #28 8776987
    hanibal0
    Poziom 11  
    dzięki Stefan, poprawiłem i program się skompilował jednak po wgraniu do procka nie działa
  • #29 8778399
    Konto nie istnieje
    Poziom 1  
  • #30 8780836
    jacekk232
    Poziom 17  
    Witam.
    Do obsługi krótkiego i długiego wciśnięcia przycisku proponuję poniższy kod. Napisałem go kiedy uczyłem się "Oślej łączki". Reakcja na krótkie wciśnięcie następuje po puszczeniu przycisku a na długie - po dwóch sekundach. Stan przycisku badany jest co 25ms więc odpadają problemy z drganiami styków. A jak ktoś nie chce stosować wait to nic nie stoi na przeszkodzie aby jakimś Timerem co 25ms ustawiać flagę a potem w pętli sprawdzać czy jest ustawiona i wtedy badać stan przycisku.
    Proste i bez zbędnych akrobacji :-)
    Dim S1a As Bit , Blokbit As Bit , Licz As Byte
    
    Do
    Waitms 25
    If Przycisk = 0 Then
       If Blokbit = 1 Then
          S1a = 1
          Incr Licz
          If Licz = 80 Then
             Gosub Dlugie
             Blokbit = 0
             S1a = 0
          End If
       End If
    Else
       Blokbit = 1
       Licz = 0
       If S1a = 1 Then
          S1a = 0
          Gosub Krotkie
       End If
    End If
    Loop

    Pozdrawiam Jacek
REKLAMA