Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

załączanie cewki dwoma przyciskami w bascomie

pio_kan 06 Nov 2008 21:13 1191 9
  • #1
    pio_kan
    Level 12  
    Witam serdecznie!



    Mam pewien problem z którym nie mogę się uporać od dłuższego czasu. Jak w temacie, chcę załączać cewkę dwoma przyciskami, z tym że ma być zrobione zabezpieczenie czasowe 1s pomiędzy naciśnięciem przycisków. W innym razie cewka nie załącza się gdy nie zostanie spełniony ten warunek czyli przyciski muszą być naciśnięte jednocześnie. Poza tym przyciski nie mogą być przytrzymane do następnego cyklu.
    Używam mikroprocesora AT89c2051.
    Program wyglądał następująco:
    --------------------------------------
    Code:
    Glowny:
    
    Do
     If P3.0=0 And P3.1=0 Then
        P1.7=0
        Wait 1
        P1.7=1
        Goto Glowny
     Else
        Goto Time1
     End if
    Loop
    End

    Time1:
       Wait 1
     If P3.0=0 And P3.1=0 Then
         P1.7=0
        Wait 1
        P1.7=1
        Goto Glowny
     Else
        Goto Glowny
     End if

    ----------------------------------------------

    To by było na tyle. Kombinowałem już na różne sposoby ale niestety program nie spisuje się tak jak bym tego chciał, chyba mam za małą wiedzę.
    Dlatego proszę Was o pomoc
  • #2
    Dr.Vee
    VIP Meritorious for electroda.pl
    Proponuję:
    1) poprawić temat,
    2) sformatować kod (znaczniki [code], wcięcia),
    3) napisać jasno i wyraźnie po polsku jak ten program ma działać, bo chyba jest to zrozumiałe tylko dla autora tematu...

    Pozdrawiam,
    Dr.Vee


    PS. Moderator podpisuję się również pod tą prośbą (punkty 1 i 2) [c_p]
  • #3
    crazy_phisic
    VIP Meritorious for electroda.pl
    Trudno nazwać zamieszczony listing programem ;). rozumiem że chodzi o pewien sposób zabezpieczenia - jak np w prasach hydraulicznych? Jeśli tak to sprawdź najpierw jeden przycisk, jeśli wciśnięty, sprawdź drugi, jeśli znów warunek spełniony włącz cewkę i odczekaj określony czas.
    Teraz czekasz na zwolnienie przycisków i procedurę powtarzasz.
    To tak w wielkim skrócie.
  • #4
    pio_kan
    Level 12  
    Witam ponownie!

    Na wstępie chcę przeprosić za niezrozumiały tekst.
    A więc zacznę od początku.

    1. W programie ma być zastosowane zabezpieczenie na przyciski dokładnie takie jak w prasach hydraulicznych, tzn. cewka załączy się tylko wtedy, gdy zostaną naciśnięte jednocześnie dwa przyciski. Dopuszczalne opóźnienie pomiędzy naciśnięciem jednego przycisku a drugiego wynosi 1s.
    Jeśli ten warunek nie zostanie spełniony, cewka nie uruchomi się.

    2. przyciski nie mogą być przytrzymywane czyli gdy ktoś przytrzyma jeden przycisk lub zewrze go na stałe i będzie chciał tylko drugim załączać cewkę to jej nie uruchomi

    3. można wykonać tylko jeden cykl, aby wykonać drugi należy puścić przyciski i przycisnąć od nowa.

    Ten cykl się dalej powtarza do momentu wyłączenia maszyny.

    Code:

    $regfile = "89c2051.dat"
    $crystal = 11059200
    $baud = 4800

    P3 = &B11111111
    P1 = &B1111100

    Glowny:
    Do
     If P3.0=0 And P3.1=0 Then
        P1.7=0
        Wait 1
        P1.7=1
        Goto Glowny
     Else
        Goto Time1
     End if
    Loop
    End

    Time1:
       Wait 1
     If P3.0=0 And P3.1=0 Then
         P1.7=0
        Wait 1
        P1.7=1
        Goto Glowny
     Else
        Goto Glowny
     End if


    A co do poprawy tematu to proszę mi wybaczyć ale niezbyt wiem jak to zrobić :cry:
  • #5
    BoskiDialer
    Level 34  
    Najprostszym rozwiązaniem wydaje mi się wygenerowanie sygnału wspólnego (tutaj mającego 3 stany: oba_puszczone, mieszany, oba_nacisniete) oraz operowanie na jednej pomocniczej zmiennej "gotowosc" - cykl zacznie się tylko wtedy, kiedy sygnał wspólny jest w stanie oba_nacisniete a układ jest gotowy - wtedy nastąpi rozpoczęcie procesu oraz skasowanie gotowości. Przejście do stanu innego niż oba_nacisniete przerywa proces, ale dopiero przejście do oba_puszczone z powrotem ustawia zmienną "gotowosc".
    Code:
    (pseudokod)
    
    zmienna gotosc;
    on_init()
    {
      gotowosc = 1;
    }
    on_change()
    {
      zmienna tmp_a, tmp_b;
      tmp_a = stan_przycisku_a;
      tmp_b = stan_przycisku_b;
      // jeśli oba przyciski są naciśnięte (oba_nacisniete) oraz układ gotowy - rozpocznij proces
      if(tmp_a == 1 && tmp_b == 1 && gotowosc == 1)
      {
        rozpocznij_proces();
        gotowosc = 0;
      }
      // jeśli jeden z przycisków jest puszczony (mieszany, oba_puszczone) - przerwij proces
      if(tmp_a == 0 || tmp_b == 0)
        przerwij_proces();
      // jeśli oba przycisku są puszczone (oba_puszczone) - wznów gotowść
      if(tmp_a == 0 && tmp_b == 0)
        gotowosc = 1;
    }
    W tym kodzie rozpoczęcie procesu może wystąpić tylko raz na cykl, ale przerwanie procesu może wystąpić dowolną liczbę razy co jest spowodowane prostymi warunkami. Jeśli nie jest to pożądane, to należy trochę kod rozbudować.

    Jeśli ma być dobudowane zabezpieczenie, że oba przyciski muszą być naciśnięte w pewnej maksymalnej odległości czasowej od siebie, to trzeba dodać licznik - ogólnie przy oba_puszczone należy licznik ustawić na pewien czas. Jeśli czas upłynie (jeden przycisk jest naciśnięty, drugi puszczony, proces się nie rozpoczyna[1.war] a timer nie jest zerowany[3.war] więc się przepełnia/dochodzi do spełnienia warunku), kasujemy zmienną gotowosc, przez co nie nastąpi rozpoczęcie procesu aż do ponownego puszczenia przycisków. Pseudokod zawierający obie poprawki:
    Code:
    zmienna gotosc, proces;
    
    on_init()
    {
      gotowosc = 1;
      proces = 0;
    }
    on_change()
    {
      zmienna tmp_a, tmp_b;
      tmp_a = stan_przycisku_a;
      tmp_b = stan_przycisku_b;
      // jeśli oba przyciski są naciśnięte oraz układ gotowy - rozpocznij proces
      if(tmp_a == 1 && tmp_b == 1 && gotowosc == 1)
      {
        rozpocznij_proces();
        proces = 1;
        gotowosc = 0;
      }
      // jeśli proces trwa oraz jeden z przycisków jest puszczony - przerwij proces
      if(proces == 1 && (tmp_a == 0 || tmp_b == 0))
      {
        przerwij_proces();
        proces = 0;
      }
      // jeśli oba przyciski są puszczone - wznów gotowść
      if(tmp_a == 0 && tmp_b == 0)
      {
        zeruj_licznik();
        gotowosc = 1;
      }
    }
    on_timer()
    {
      gotowosc = 0;
    }

    Sam kod można rozwinąć w kilku kierunkach - zamiast wywoływać on_change przy zmianie stanu można go wywoływać ciągle (w pętli). on_timer może być wywoływany nie w przerwaniach, ale po spełnieniu warunku sprawdzanego w pętli głównej. Kod można bardzo łatwo rozbudować na dowolną liczbę przycisków, gdyż sygnał wspólny z przycisków nadal będzie miał 3 stany.
  • #6
    pio_kan
    Level 12  
    Witam!

    Ogromne dzięki za pomoc. Może ten kod, który napisał BoskiDialer nie jest w tym języku, którego ja używam ale mam już jakiś wzór według którego zmodyfikuję mój program.
    Tak więc zacznę próby od nowa, zobaczę co z tego wyjdzie.
  • #7
    Dr.Vee
    VIP Meritorious for electroda.pl
    Zastanów się nad modelem Twojego systemu. Z tego co piszesz, to powinno wyglądać to tak:
    załączanie cewki dwoma przyciskami w bascomie

    w_1, /w_1 = prawda gdy przycisk jest wciśnięty, zwolniony

    Teraz wystarczy napisać implementację w bascomie :)

    Zmiany: uprościłem automat :)
    Zmiany 2: uwzględniłem uwagi BoskiegoDialera

    Pozdrawiam,
    Dr.Vee
  • #8
    BoskiDialer
    Level 34  
    Dr.Vee: Staram się jak mogę, ale mam problem ze zrozumieniem przedstawionego przez Ciebie automatu:
    - interpretując w_1 oraz w_2 jako aktualny stan, to po przejściu ready->wait może nastąpić bezpośrednie przejście wait->off
    - interpretując w_1 oraz w_2 jako zdarzenie, ciężko jest interpretować /w_2 AND /w_1, gdyż musiały by one wystąpić równocześnie.
    - nie wiem czym jest przejście opisane jako "turn_off" - przy jakich warunkach następuje

    Mój pseudokod można by zapisać jako automat o trzech stanach - ready (gotowość=1, proces=0), on(gotowość=0, proces=1) oraz block(gotowość=0, proces=0). Przejścia wyglądały by następująco:
    ready->on: przy w_1 AND w_2. wykonanie rozpocznij_proces() [warunek if(tmp_a == 1 && tmp_b == 1 && gotowosc == 1)]
    on->block: przy /w_1 OR /w_2. wykonanie przerwij_proces() [warunek if(proces == 1 && (tmp_a == 0 || tmp_b == 0))]
    ready->block: przy timeout [on_timer()]
    [block|ready]->ready: przy /w_1 AND /w_2. wykonanie zeruj_timer() [warunek if(tmp_a == 0 && tmp_b == 0)]
    Zabezpieczenie polega na tym, że w celu przejścia ready->on (przejście 1) trzeba nacisnąć oba przyciski, ale po przerwaniu procesu (przejście 2) aktualny stan to "block" a więc trzeba puścić oba przyciski (przejście 4). Zabezpieczenie przed długim trzymaniem jednego przycisku to przejście 3.
  • #9
    pio_kan
    Level 12  
    W dużym uproszczeniu tak by to wyglądało. Właśnie pracuję nad poprawkami w moim dawnym programie. Dzięki za podpowiedź
  • #10
    Dr.Vee
    VIP Meritorious for electroda.pl
    BoskiDialer: w_1 i w_2 oznaczają stany przycisków, a nie zdarzenia. Rzeczywiście, przejście wait -> off powinno następować tylko w przypadku timeout (lub ew. przy timeout OR (/w_1 AND /w_2)).

    Chyba zinterpretowaliśmy wymagania w różny sposób - u mnie przyciski kontrolują jedynie włączenie procesu, bo pio_kan nic nie wspomniał o wyłączaniu procesu. U Ciebie zwolnienie przycisku zatrzymuje proces, u mnie nie ma nic na ten temat (warunek "turn_off").

    Swoim postem chciałem zwrócić uwagę na formalne podejście do problemu, a dopiero później na kodowanie.

    Pozdrawiam,
    Dr.Vee