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

Sterownik silnika krokowego na RC5 - optymalizacja kodu

wojlej 25 Kwi 2010 23:08 3222 21
  • #1 25 Kwi 2010 23:08
    wojlej
    Poziom 17  

    Witam.
    Zbudowałem i zaprogramowałem układ do sterowania silnikiem krokowym przez RC5. Prosiłbym jeśli to możliwe o optymalizacje mojego kodu. Chciałbym zauważyć, że program działa poprawnie już załadowany do Atmegi, chodzi mi tylko o samą optymalizacje, żeby działał tak samo, jeśli się da to szybciej itd.

    Układ jest wyposażony w ULN2003, wyjścia z Atmegi do ULNa są oznaczone jako Aliasy C1 - C4 (Cewki), Układ posiada dwa przyciski na płytce S1 i S2 umożliwiające sterowanie silnikiem bez pilota, posiada dwa wejścia na krańcówki X1 i X2. Diody, zieloną Ledz i czerwoną Ledc i wyjście na sterowanie silnikiem prądu stałego Dc1 i Dc2.

    Idea działania:

    Można sterować sterownikiem z przycisków na płytce. Po przyciśnięciu przycisku i przytrzymaniu przez 3s program wykonuje podprogram silnik_up, po ponownym wciśnięciu przycisku kończy działanie podprogramu. Po wciśnięciu drugiego przycisku program wykonuje podprogram Silnik_down. I tak samo. Po przytrzymaniu obu przycisków przez 5s, program wykonuje podprogram kalibracja_up odpowiedzialny za zapamiętanie komendy z pilota RC5 odpowiadającej za ruch silnika do góry. Najpierw miga zielona dioda LED i program czeka na wciśnięcie przycisku na pilocie, Potem odbywa się skok do podprogramu Kalibracja_down, i miga czerwona dioda i program czeka na wciśnięcie przycisku na pilocie odpowiedzialnego za ruch silnika w dół. Jeśli ten sam przycisk został wciśnięty jako silnik w górę i w dół to znopwu następuje przeskok do podprogramu kalibracja_up. Jeśli są różne przyciski to program wraca do programu głównego i po wciśnięciu odpowiedniego przycisku na pilocie załącza podprogram Silnik_up lub Silnik_down.

    Mam nadzieje, że wszystko jasne. poniżej przedstawiam program:

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

    Config Rc5 = Pind.2

    Dim Adres As Byte
    Dim Komenda As Byte
    Dim Togglebit As Bit
    Dim A As Byte , B As Byte
    Dim C As Byte , D As Byte
    Dim K As Byte , P As Byte

    Ddrc = 255
    Ddrb = 255
    Portc = 0
    Portb = 0
    Config Pind.0 = Input
    Config Pind.1 = Input
    Config Pind.5 = Output
    Config Pind.6 = Output

    Ledz Alias Portd.5
    Ledc Alias Portd.6
    S1 Alias Pind.0
    S2 Alias Pind.1
    X1 Alias Portc.0
    X2 Alias Portc.1
    Dc1 Alias Portb.3
    Dc2 Alias Portb.4

    C1 Alias Portc.5
    C2 Alias Portc.4
    C3 Alias Portc.3
    C4 Alias Portc.2

    Set Portd.0
    Set Portd.1


    Enable Interrupts



    Do
    Begin:
    P = 1
    K = 1

    If S1 = 0 And S2 = 0 Then
    Wait 5
    If S1 = 0 And S2 = 0 Then

    Gosub Kalibracja_up
    Waitms 500

    End If
    End If


    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then




          If Komenda = C And Adres = A Then
             Waitms 500
             Gosub Silnik_up
             Wait 1
          End If

          If Komenda = D And Adres = B Then
             Waitms 500
             Gosub Silnik_down
             Wait 1
          End If

       End If

    If S1 = 0 And S2 = 1 Then
       Wait 3
          If S1 = 0 And S2 = 1 Then
             Waitms 200
             Set Ledz
             Waitms 300
             Reset Ledz
             Waitms 500
             Gosub Silnik_up
          End If
    End If

    If S1 = 1 And S2 = 0 Then
       Wait 3
          If S1 = 1 And S2 = 0 Then
             Waitms 200
             Set Ledc
             Waitms 300
             Reset Ledc
             Waitms 500
             Gosub Silnik_down
          End If
    End If

    Loop
    End


    '*******************************************************************************
    Kalibracja_up:

    For K = 1 To 200
    Set Ledz
    Waitms 500
    Reset Ledz
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          A = Adres
          C = Komenda
          P = 1
          Waitms 500
          Set Ledz
          Wait 2
          Reset Ledz
          Waitms 100
          Gosub Kalibracja_down

       End If
    Next K
    If K = 200 Then K = 1


    '*******************************************************************************
    Kalibracja_down:

    For P = 1 To 200
    Set Ledc
    Waitms 500
    Reset Ledc
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          B = Adres
          D = Komenda
          Waitms 500
          Set Ledc
          Wait 2
          Reset Ledc
          Waitms 100
          If C = D Then
          Gosub Kalibracja_up
          End If
          Goto Begin

       End If
    Next P
    If P = 200 Then P = 1

    '*******************************************************************************
    Silnik_up:
    If X1 = 1 Then
    Set Ledz
    Waitms 500
    Reset Ledz
    Return
    End If

    Reset Ledc
    Set Ledz
    Set Dc1
        Do
          Getrc5(adres , Komenda)
             Togglebit = Komenda.7
             Komenda = Komenda And &B01111111
       If Adres <> 255 Then
          If Komenda = C And Adres = A Then
             Reset Dc1
             Reset Ledz
             Return
          End If
       End If

           Reset C1
           Reset C2
           Reset C3
           Reset C4
           Set C1
           Waitus 100
           Reset C1
           Set C2
           Waitus 100
           Reset C2
           Set C3
           Waitus 100
           Reset C3
           Set C4

           If S1 = 0 And S2 = 1 Then
             Waitms 50
             If S1 = 0 And S2 = 1 Then
                Reset Dc1
                Reset Ledz
                Return
             End If
           End If

       Loop Until X1 = 1
    Reset Ledz
    Reset Dc1
    Return


    '*******************************************************************************
    Silnik_down:
    If X2 = 1 Then
    Set Ledc
    Waitms 500
    Reset Ledc
    Return
    End If

    Reset Ledz
    Set Ledc
    Set Dc2
        Do
           Getrc5(adres , Komenda)
            Togglebit = Komenda.7
            Komenda = Komenda And &B01111111
       If Adres <> 255 Then
          If Komenda = D And Adres = B Then
             Reset Dc2
             Reset Ledc
             Return
          End If
       End If
           Reset C1
           Reset C2
           Reset C3
           Reset C4
           Set C4
           Waitus 100
           Reset C4
           Set C3
           Waitus 100
           Reset C3
           Set C2
           Waitus 100
           Reset C2
           Set C1

            If S1 = 1 And S2 = 0 Then
             Waitms 50
             If S1 = 1 And S2 = 0 Then
                Reset Dc2
                Reset Ledc
                Return
             End If
           End If

       Loop Until X2 = 1
    Reset Ledc
    Reset Dc2
    Return


    Pozdrawiam i z góry dzięki za wszelką pomoc i rady

    Przeniesiono z Programowanie Ogólne. - arnoldziq

    0 21
  • #2 28 Kwi 2010 22:11
    misiek1994
    Poziom 17  

    Nie chce cię martwić, ale w bascomie to specjalnie kodu nie zoptymalizujesz. Jeżeli działa to dobrze, a nawet jeżeli byś przyspieszył procek o te pare ns to cie za bardzo nie urządza.
    Czytałem, że w niektórych sytuacjach polecenie "case" jest bardziej optymalne od "if".
    Prędzej czy później prawdopodobnie będziesz musiał przesiąść się na C lub asm, więc proponuje już teraz zacząć naukę któregoś z nich.
    Pzdr misiek

    0
  • #3 29 Kwi 2010 22:11
    kots
    Poziom 11  

    Cytat:
    Nie chce cię martwić, ale w bascomie to specjalnie kodu nie zoptymalizujesz. Jeżeli działa to dobrze, a nawet jeżeli byś przyspieszył procek o te pare ns to cie za bardzo nie urządza.


    W tym przypadku nie problemem nie jest czas wykonywania kodu i nawet po przepisaniu go na assembler czas ten niewiele się zmieni. Chyba że problemem jest to że kod nie mieści się w pamięci, to zamiana na assembler pomoże.

    Problem tkwi w konstrukcji programu, widzę w nim wiele instrukcji czekania, jeżeli program wejdzie w taką pętlę, to przez zadany czas nie może nic innego (poza obsługą przerwań0 zrobić i to chyba jest problemem.

    W Bascom bardzo łatwo wplata się assembler. Ja piszę w bascomie i dopiero jak potrzeba coś zoptymalizować, to zamieniam na assembler, np procedury przerwań.

    KotS

    0
  • #4 30 Kwi 2010 16:16
    wojlej
    Poziom 17  

    No, powiedzmy sobie szczerze, na razie jestem amatorem w programowaniu. Układ działa ale nie do końca. Otóż w podprogramach Silnik_up i Silnik_down występuje składnia GetRC5 itd. Przez to silnik porusza się skokowo. Najpierw wykona GetRc5, potem silnik zrobi pełen cykl zasileń cewek od 1 do 4, potem się zatrzymuje bo jest GetRc5 i znowu. Mam problem jak to zrobić tak, żeby jednak się nie zatrzymywał. Próbuje jakoś z przerwaniem ale za cholere nie wychodzi. Mógłby mi ktoś pomóc?

    Code:

    Do
          Getrc5(adres , Komenda)
             Togglebit = Komenda.7
             Komenda = Komenda And &B01111111
       If Adres <> 255 Then
          If Komenda = C And Adres = A Then
             Reset Dc1
             Reset Ledz
             Return
          End If
       End If

           Reset C1
           Reset C2
           Reset C3
           Reset C4
           Set C1
           Waitus 100
           Reset C1
           Set C2
           Waitus 100
           Reset C2
           Set C3
           Waitus 100
           Reset C3
           Set C4

    0
  • #5 01 Maj 2010 13:33
    janbernat
    Poziom 38  

    Nie używa się wait do sterowania silników krokowych.
    W czwartym "podobnym temacie" znajdziesz program do sterowania silnikiem który po pewnych przeróbkach się nada.
    To co jest w pętli głównej należy przenieść do przerwania od TIMER2- bo Timer0 jest zajęty przez RC5- i wywoływać co jakiś czas.
    Zrób to najpierw na przyciskach a dopiero potem wstaw RC5.

    To jest tak:
    Znajdź w tym czwartym podobnym temacie kod w którym jest "rotate".
    Dokładnie go przeczytaj i postaraj się zrozumieć.
    To jest kod do sterownika który wysyła STEP i DIR- z komputera.
    A w Toim przypadku STEP ma być wysyłany z tego samego procesora.
    Jeśli zrobisz tak:
    On Timer2 krok

    krok:
    'tu kod z głównej pętli
    return
    To będziesz prawie miał.
    Oczywiście z ustawieniem odpowiednim Timera2.
    Może z tego zrobię "gotowca"- ale najpierw musiałbym skonfigurować płytkę, program i sprawdzić czy wszystko chodzi.

    0
  • #6 06 Maj 2010 20:30
    wojlej
    Poziom 17  

    Zrobiłem coś takiego:

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

    Config Rc5 = Pind.2

    Config Timer2 = Timer , Prescale = 1024

    On Timer2 Silnik_up

    Dim Adres As Byte
    Dim Komenda As Byte
    Dim Togglebit As Bit
    Dim A As Byte , B As Byte
    Dim C As Byte , D As Byte
    Dim K As Byte , P As Byte
    Dim X As Byte
    X = 00000001

    Ddrc = 255
    Ddrb = 255
    Portc = 0
    Portb = 0
    Config Pind.0 = Input
    Config Pind.1 = Input
    Config Pind.5 = Output
    Config Pind.6 = Output

    Ledz Alias Portd.5
    Ledc Alias Portd.6
    S1 Alias Pind.0
    S2 Alias Pind.1
    X1 Alias Portc.0
    X2 Alias Portc.1
    Dc1 Alias Portb.3
    Dc2 Alias Portb.4

    C1 Alias Portc.5
    C2 Alias Portc.4
    C3 Alias Portc.3
    C4 Alias Portc.2

    Set Portd.0
    Set Portd.1


    Enable Interrupts



    Do
    Begin:
    P = 1
    K = 1


    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then
          If Komenda = C And Adres = A Then
             Waitms 500
             Gosub Silnik_up
             Wait 1
          End If



    Loop
    End


    '*******************************************************************************
    Kalibracja_up:

    For K = 1 To 200
    Set Ledz
    Waitms 500
    Reset Ledz
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          A = Adres
          C = Komenda
          P = 1
          Waitms 500
          Set Ledz
          Wait 2
          Reset Ledz
          Waitms 100
          Gosub Kalibracja_down

       End If
    Next K
    If K = 200 Then K = 1


    '*******************************************************************************
    Kalibracja_down:

    For P = 1 To 200
    Set Ledc
    Waitms 500
    Reset Ledc
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          B = Adres
          D = Komenda
          Waitms 500
          Set Ledc
          Wait 2
          Reset Ledc
          Waitms 100
          If C = D Then
          Gosub Kalibracja_up
          End If
          Goto Begin

       End If
    Next P
    If P = 200 Then P = 1

    '*******************************************************************************
    Silnik_up:
    Rotate X , Left
    Select Case X
          Case 1
             Portd = &B11111100
          Case 2
             Portd = &B11111001
          Case 4
             Portd = &B11110011
          Case 8
             Portd = &B11110110
          Case 16
             Portd = &B11111100
          Case 32
             Portd = &B11111001
          Case 64
             Portd = &B11110011
          Case 128
             Portd = &B11110110
       End Select

    Return
    Return


    Prosiłbym o pomoc mi w wyjściu z podprogramu za pomocą RC5

    0
  • #7 06 Maj 2010 21:09
    janbernat
    Poziom 38  

    Mam prośbę- wyrzuć z kodu kalibrację na początek- potem ją dodasz.
    Dodaj Enable Timer2.
    Skasuj podwójny return.
    W silnik_up wklej cały kod- a nie tylko fragment.
    Można wykasować sprawdzanie kierunku- DIR.
    No i Silnik_up to nie jest podprogram- to jest obsługa przerwania.
    Sam wychodzi jak nie ma następnego przerwania.

    0
  • #8 07 Maj 2010 19:42
    wojlej
    Poziom 17  

    Coś takiego? Nie wiem ale chyba nie o to chodzi

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

    Config Rc5 = Pind.2

    Config Timer2 = Timer , Prescale = 1024

    On Timer2 Silnik_up

    Dim Adres As Byte
    Dim Komenda As Byte
    Dim Togglebit As Bit
    Dim A As Byte , B As Byte
    Dim C As Byte , D As Byte
    Dim K As Byte , P As Byte
    Dim X As Byte
    X = 00000001

    Ddrc = 255
    Ddrb = 255
    Portc = 0
    Portb = 0
    Config Pind.0 = Input
    Config Pind.1 = Input
    Config Pind.5 = Output
    Config Pind.6 = Output

    Ledz Alias Portd.5
    Ledc Alias Portd.6
    S1 Alias Pind.0
    S2 Alias Pind.1
    X1 Alias Portc.0
    X2 Alias Portc.1
    Dc1 Alias Portb.3
    Dc2 Alias Portb.4

    C1 Alias Portc.5
    C2 Alias Portc.4
    C3 Alias Portc.3
    C4 Alias Portc.2

    Set Portd.0
    Set Portd.1


    Enable Interrupts

    Enable Timer2



    Do
    Begin:
    P = 1
    K = 1


    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then
          If Komenda = C And Adres = A Then
             Waitms 500
             Gosub Silnik_up
             Wait 1
          End If



    Loop
    End



    '*******************************************************************************
    Silnik_up:
    Do

       If Step = 0 And Dir = 0 Then
          If Temp_0 = 0 Then      'sprawdzenie
            Rotate X , Left

              If Pinb.2 = 0 Then
                Gosub Pol_kroczek
              Else
                Gosub Kroczek
              End If

            Temp_0 = 1            'zablokowanie powtórnego wykonania kroku
           End If                 'dopóki nie zmieni się stan Pin.0
        Else
          Temp_0 = 0              'jeśli stan pinb.0=1 to przy ponownym pojawieniu
        End If                    ' się stanu pinb.0=0 może wykonać sie następny STEP

       If Step = 0 And Dir = 1 Then
          If Temp_1 = 0 Then
             Rotate X , Right

               If Pinb.2 = 0 Then
                 Gosub Pol_kroczek
               Else
                 Gosub Kroczek
               End If

             Temp_1 = 1
           End If
        Else
          Temp_1 = 0
        End If

    Loop

    Kroczek:

       Select Case X
          Case 1
             Portd = &B11111100
          Case 2
             Portd = &B11111001
          Case 4
             Portd = &B11110011
          Case 8
             Portd = &B11110110
          Case 16
             Portd = &B11111100
          Case 32
             Portd = &B11111001
          Case 64
             Portd = &B11110011
          Case 128
             Portd = &B11110110
       End Select

    Return

    Pol_kroczek:

       Select Case X
          Case 1
             Portd = &B11111110
          Case 2
             Portd = &B11111100
          Case 4
             Portd = &B11111101
          Case 8
             Portd = &B11111001
          Case 16
             Portd = &B11111011
          Case 32
             Portd = &B11110011
          Case 64
             Portd = &B11110111
          Case 128
             Portd = &B11110110
       End Select



    Return



    '*******************************************************************************

    0
  • #9 07 Maj 2010 20:28
    janbernat
    Poziom 38  

    Code:

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

    Config Portb = Input
    Portb = 255
    Config Portd = Output
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
    Config Timer1 = Timer , Prescale = 64
    On Timer1 Krok
    Enable Ovf1
    Enable Interrupts
    Dim X As Byte
    X = 00000001
    Dir Alias Pinb.1                                  'albo sygnał z RC5- kierunek
    'dim X as word' jeśli X będzie z RC5


    Cls
    Lcd "START"
    Waitms 500

    Do
                                                     'Tu można odbierać sygnał z RC5

    Loop

    Kroczek:

       Select Case X
          Case 1
             Portd = &B11111100
          Case 2
             Portd = &B11111001
          Case 4
             Portd = &B11110011
          Case 8
             Portd = &B11110110
          Case 16
             Portd = &B11111100
          Case 32
             Portd = &B11111001
          Case 64
             Portd = &B11110011
          Case 128
             Portd = &B11110110
       End Select

    Return

    Pol_kroczek:

       Select Case X
          Case 1
             Portd = &B11111110
          Case 2
             Portd = &B11111100
          Case 4
             Portd = &B11111101
          Case 8
             Portd = &B11111001
          Case 16
             Portd = &B11111011
          Case 32
             Portd = &B11110011
          Case 64
             Portd = &B11110111
          Case 128
             Portd = &B11110110
       End Select

    Return

    Krok:

    If Dir = 0 Then
       Rotate X , Left

       If Pinb.2 = 0 Then
           Gosub Pol_kroczek
        Else
           Gosub Kroczek
        End If
    End If

    If Dir = 1 Then
       Rotate X , Right

       If Pinb.2 = 0 Then
          Gosub Pol_kroczek
       Else
          Gosub Kroczek
       End If
    End If
    'timer1=X 'Też z RC5- im większy X tym szybciej się kręci
    Return

    To działa-bez RC5- bo nie mam odbiornika.
    Sprawdź na przyciskach a potem z RC5.

    0
  • #10 21 Maj 2010 12:00
    wojlej
    Poziom 17  

    Ok, program ładnie działa. Silnik niestety bardzo powoli się kręci i też przerywa. Jak podzieliłem timer na 1024 to w ogóle się nie ruszył. Teraz musze dołożyć sterowanie przyciskami lewo prawo a potem RC5.

    Dodano po 1 [godziny] 28 [minuty]:

    Nasmarowałem coś takiego:

    Code:

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

    Config Portd = Input
    Portd = 255
    Config Portc = Output
    Config Timer1 = Timer , Prescale = 64
    On Timer1 Krok
    Enable Ovf1
    Enable Interrupts
    Dim A As Byte
    Dim X As Byte
    X = 00000001
    Lewo Alias Pind.0
    Prawo Alias Pind.1                               'albo sygnał z RC5- kierunek
    'dim X as word' jeśli X będzie z RC5


    A = 1

    Do

    If Lewo = 1 And Prawo = 0 Then
       Waitms 40
          If Lewo = 1 And Prawo = 0 Then

             Incr A
             If A > 2 Then A = 1
          End If
    End If

    If Lewo = 0 And Prawo = 1 Then
       Waitms 40
          If Lewo = 0 And Prawo = 1 Then

             Decr A
             If A < 0 Then A = 1
          End If
    End If                                           'Tu można odbierać sygnał z RC5

    Loop

    Kroczek:

       Select Case X
          Case 1
             Portc = &B0001111
          Case 2
             Portc = &B0100111
          Case 4
             Portc = &B0110011
          Case 8
             Portc = &B0011011
          Case 16
             Portc = &B0001111
          Case 32
             Portc = &B0100111
          Case 64
             Portc = &B0110011
          Case 128
             Portc = &B0011011
       End Select

    Return



    Krok:

    If A = 0 Then
       Rotate X , Left

       Gosub Kroczek

    End If

    If A = 2 Then
       Rotate X , Right

       Gosub Kroczek

    End If
    'timer1=X 'Też z RC5- im większy X tym szybciej się kręci
    Return


    Ale nie chce to działać tak jak powinno. Otóż silnik nie chce się kręcić w drugą stronę. I strasznie sie grzeje.

    0
  • #11 21 Maj 2010 13:12
    janbernat
    Poziom 38  

    To że w ogóle się kręci- to jest dopiero dziwne.
    Przy sterowaniu pełnokrokowym muszą być w każdym kroku wysterowane dokładnie dwa uzwojenia- a nie trzy.
    No i to sprawdzanie warunków wciśnięcia przycisków- chyba czasem A będzie =0 ale nigdy =2.

    0
  • #12 21 Maj 2010 13:17
    wojlej
    Poziom 17  

    To jest PORTC, więc PORTC6 to Reset, dlatego on zawsze jest 0. Silnik jest podłączony od 5 do 2.

    Dlaczego nie będzie 2? Przecież dopiero jak jest większe od 2 to przyrównuje do 1

    0
  • Pomocny post
    #13 21 Maj 2010 14:08
    janbernat
    Poziom 38  

    To którymi pinami sterujesz?
    I stanem niski czy wysokim?
    Poprawka:
    A nigdy nie będzie <0
    P.S.
    Daj prescale=8 na razie.

    Code:

    Do

    If Lewo = 1 And Prawo = 0 Then
       Waitms 40
          If Lewo = 1 And Prawo = 0 Then
              A=0

          End If
    End If

    If Lewo = 0 And Prawo = 1 Then
       Waitms 40
          If Lewo = 0 And Prawo = 1 Then
             A=2
             
          End If
    End If                                           

    Loop

    No i zrób jakiś warunek żeby wcale się nie kręcił.
    Silnik krokowy zwykle się grzeje.
    Temperatura nie powinna przekraczać ok.80st.
    P.S.2
    Dla 1024 też się kręci.
    Krok co ok.8s.
    Trzeba czekać ok. pół godziny na pełen obrót.

    0
  • #14 21 Maj 2010 14:41
    wojlej
    Poziom 17  

    OK. Jeśli A = 2 to silnik stoi. Chociaż to i tak różnie działa. Powinno być tak, że jak wcisne pierwszy przycisk to zaczyna kręcić się w jedną stronę. Potem jak wcisnę jeszcze raz ten sam albo drugi to powinien się zatrzymać. I tak samo w drugą stronę. A czasami jest tak, że jak wcisne lewo to kreci w lewo, a jak wcisne prawo to sie nie zatrzyma tylko zacznie sie od razu krecic w prawo. Ale może to przez krótki czas po wait. Może za długo trzymam. Teraz spróbuje wsadzić jeszcze RC5. Na razie dzięki. Dałem pomógł

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

    Config Portd = Input
    Portd = 255
    Config Portc = Output
    Config Timer1 = Timer , Prescale = 8
    On Timer1 Krok
    Enable Ovf1
    Enable Interrupts
    Dim A As Byte
    Dim X As Byte
    X = 00000001
    Lewo Alias Pind.0
    Prawo Alias Pind.1                               'albo sygnał z RC5- kierunek
    'dim X as word' jeśli X będzie z RC5


    A = 2

    Do

    If Lewo = 1 And Prawo = 0 Then
       Waitms 80
          If Lewo = 1 And Prawo = 0 Then

             Incr A
             If A = 4 Then A = 2
          End If
    End If

    If Lewo = 0 And Prawo = 1 Then
       Waitms 80
          If Lewo = 0 And Prawo = 1 Then

             Decr A
             If A = 0 Then A = 2
          End If
    End If                                           'Tu można odbierać sygnał z RC5

    Loop

    Kroczek:

       Select Case X
          Case 1
             Portc = &B0001111
          Case 2
             Portc = &B0100111
          Case 4
             Portc = &B0110011
          Case 8
             Portc = &B0011011
          Case 16
             Portc = &B0001111
          Case 32
             Portc = &B0100111
          Case 64
             Portc = &B0110011
          Case 128
             Portc = &B0011011
       End Select

    Return



    Krok:

    If A = 1 Then
       Rotate X , Left

       Gosub Kroczek

    End If

    If A = 3 Then
       Rotate X , Right

       Gosub Kroczek

    End If
    'timer1=X 'Też z RC5- im większy X tym szybciej się kręci
    Return

    0
  • #15 22 Maj 2010 17:43
    wojlej
    Poziom 17  

    Program działa. Poniżej przedstawiam całokształt. Wielkie dzięki za pomoc koledze Janbernat. Myślę, że można zamknąć temat

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

    Config Rc5 = Pind.2

    Config Pind.0 = Input
    Config Pind.1 = Input
    Config Pind.5 = Output
    Config Pind.6 = Output
    Portd = 255
    Config Portc = Output
    Config Timer1 = Timer , Prescale = 8
    On Timer1 Krok
    Enable Ovf1
    Enable Interrupts
    Dim Adres As Byte
    Dim Komenda As Byte
    Dim Togglebit As Bit
    Dim A As Byte
    Dim B As Byte
    Dim C As Byte
    Dim K As Byte
    Dim P As Byte
    Dim X As Byte
    X = 00000001
    Lewo Alias Pind.0
    Prawo Alias Pind.1
    Ledc Alias Portd.5
    Ledz Alias Portd.6                               'albo sygnał z RC5- kierunek
    'dim X as word' jeśli X będzie z RC5
    Set Portd.0
    Set Portd.1

    A = 2

    Do
    Begin:
    P = 1
    K = 1

    If Lewo = 0 And Prawo = 0 Then
    Wait 3
    If Lewo = 0 And Prawo = 0 Then
    Gosub Kalibracja_up
    Waitms 500

    End If
    End If

    If Lewo = 1 And Prawo = 0 Then
       Waitms 200
          If Lewo = 1 And Prawo = 0 Then

             Incr A
             If A = 4 Then A = 2

             Set Ledz
             Waitms 500
             Reset Ledz

          End If
    End If

    If Lewo = 0 And Prawo = 1 Then
       Waitms 200
          If Lewo = 0 And Prawo = 1 Then

             Decr A
             If A = 0 Then A = 2

             Set Ledc
             Waitms 500
             Reset Ledc
          End If
    End If

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then
          If Komenda = B Then
             Incr A
             If A = 4 Then A = 2

             Set Ledz
             Waitms 500
             Reset Ledz
          End If

          If Komenda = C Then
             Decr A
             If A = 0 Then A = 2

             Set Ledc
             Waitms 500
             Reset Ledc
          End If
       End If                                        'Tu można odbierać sygnał z RC5

    Loop

    Kroczek:

       Select Case X
          Case 1
             Portc = &B0001111
          Case 2
             Portc = &B0100111
          Case 4
             Portc = &B0110011
          Case 8
             Portc = &B0011011
          Case 16
             Portc = &B0001111
          Case 32
             Portc = &B0100111
          Case 64
             Portc = &B0110011
          Case 128
             Portc = &B0011011
       End Select

    Return



    Krok:

    If A = 1 Then
       Rotate X , Left

       Reset Ledz
       Set Ledc

       Gosub Kroczek

    End If

    If A = 3 Then
       Rotate X , Right

       Reset Ledc
       Set Ledz

       Gosub Kroczek

    End If

    If A = 2 Then

       Reset Ledz
       Reset Ledc

    End If
    'timer1=X 'Też z RC5- im większy X tym szybciej się kręci
    Return

    '*******************************************************************************

    Kalibracja_up:

    For K = 1 To 200
    Set Ledz
    Waitms 500
    Reset Ledz
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          B = Komenda
          P = 1
          Waitms 500
          Set Ledz
          Wait 2
          Reset Ledz
          Waitms 100
          Gosub Kalibracja_down

       End If
    Next K
    If K = 200 Then K = 1


    '*******************************************************************************
    Kalibracja_down:

    For P = 1 To 200
    Set Ledc
    Waitms 500
    Reset Ledc
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          C = Komenda
          Waitms 500
          Set Ledc
          Wait 2
          Reset Ledc
          Waitms 100
          If C = B Then
          Gosub Kalibracja_up
          End If
          Goto Begin

       End If
    Next P
    If P = 200 Then P = 1

    0
  • #16 22 Maj 2010 18:16
    janbernat
    Poziom 38  

    Gratulacje.
    A tak dla zaspokojenia mojej ciekawości- gdybyś zamiast sub kroczek wstawił sub polkroczek i opisał swoje wrażenia.
    I nie korci Cię żeby program poprawiać?
    Bo mnie zawsze korci.
    Tylko czasem zapominam zapisać działającą wersję.

    0
  • #17 23 Maj 2010 12:37
    wojlej
    Poziom 17  

    Gdybym dodał Półkroczek to bym uzyskał większą precyzje sterowania. Może i tak. Ale zastanawia mnie jeszcze jedno. Otóż Silnik ma być zastosowany do sterowania roletami. I nie chcę zaprzęgać krańcówek do układu, wolałbym liczyć kroki i po zrobieniu iluś kroków silnik miałby się zatrzymać. Muszę nad tym pomyśleć.

    0
  • #18 23 Maj 2010 15:18
    snow
    Poziom 28  

    wojlej napisał:
    I nie chcę zaprzęgać krańcówek do układu, wolałbym liczyć kroki i po zrobieniu iluś kroków silnik miałby się zatrzymać. Muszę nad tym pomyśleć.


    Sterowanie krokami to sterowanie w ciemno. Jeżeli coś ci zablokuje silnik to kroki ze sterowania będą zliczane a silnik nie będzie wykonywał kroku co w efekcie spowoduje rozjechanie się twoich pozycji rolety. Poza tym warto by było zabezpieczyć silnik nad prądowo przed tym że coś zostanie połamane gdy podejdzie pod roletę.

    0
  • #19 24 Maj 2010 00:52
    janbernat
    Poziom 38  

    Liczenie kroków, półkroków itd. jest bardzo podobne.
    Ale- jak napisał snow- jest to sterowanie "w ciemno".
    Bez krańcówek to jest niebezpieczne.
    Chyba że silnik ma taki zapas momentu że nie zgubi kroków.
    Coś za coś- proste sterowanie albo skomplikowane ale pewniejsze.

    0
  • #20 24 Maj 2010 01:12
    utak3r
    Poziom 25  

    Robiłem kiedyś rolety - uwierz, tutaj potrzebne są krańcówki... zawsze coś stanie na drodze rolet (np. na parapecie).

    0
  • #21 24 Maj 2010 11:58
    wojlej
    Poziom 17  

    Pewnie i racja. DLatego najprawdopodobniej zastosuje krańcówki. Ale dla samej nauki spróbuje zrobić z liczeniem kroków. Pozdrawiam

    0
  • #22 27 Maj 2010 17:40
    wojlej
    Poziom 17  

    Skończyłem.

    Dodałem do programu liczenie kroków czyli zmienna D, jak i obsługę krańcówek. Program ładnie działa. Poniżej zamieszczam schemat jak i listing programu.

    Sterownik silnika krokowego na RC5 - optymalizacja kodu

    Program zajmuje 23% Flash:



    Code:

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

    Config Rc5 = Pind.2

    Config Pind.0 = Input
    Config Pind.1 = Input
    Config Pind.5 = Output
    Config Pind.6 = Output
    Config Pinb.3 = Output
    Config Pinb.4 = Output
    Portd = 255
    Config Portc = Output
    Config Pinc.0 = Input
    Config Pinc.1 = Input
    Config Timer1 = Timer , Prescale = 8
    On Timer1 Krok
    Enable Ovf1
    Enable Interrupts
    Dim Adres As Byte
    Dim Komenda As Byte
    Dim Togglebit As Bit
    Dim A As Byte                                    'zmienna odpowiedzialna za kierunek
    Dim B As Byte                                    'zmienna przechowywująca komendę w prawo
    Dim C As Byte                                    'zmienna przechowywująca komendę w Lewo
    Dim D As Integer                                 'zmienna licząca kroki
    Dim K As Byte                                    'pętla FOR NEXT w kalibracji
    Dim P As Byte                                    'pętla FOR NEXT w kalibracji
    Dim X As Byte                                    'obrót silnika
    X = 00000001
    Lewo Alias Pind.0                                'przycisk w Lewo
    Prawo Alias Pind.1                               'przycisk w Prawo
    K1 Alias Pinc.0                                  'Krańcówka 1
    K2 Alias Pinc.1                                  'Krańcówka 2
    Dc1 Alias Portb.3                                'Wyjście DC
    Dc2 Alias Portb.4                                'Wyjście DC
    Ledc Alias Portd.5                               'dioda czerwona
    Ledz Alias Portd.6                               'dioda zielona

    Set Portd.0
    Set Portd.1
    Set Portc.0
    Set Portc.1

    A = 2
    D = 0
    '**********************Pętla Główna*********************************************
    Do
    Begin:
    P = 1
    K = 1
    Reset Ledz
    Reset Ledc

    If Lewo = 0 And Prawo = 0 Then                   'wejście w tryb kalibracji
    Wait 3
    If Lewo = 0 And Prawo = 0 Then
    Gosub Kalibracja_up
    Waitms 500

    End If
    End If

    If Lewo = 1 And Prawo = 0 Then
       Waitms 200
          If Lewo = 1 And Prawo = 0 Then

             Incr A
             If A = 4 Then A = 2

             Set Ledz
             Waitms 500
             Reset Ledz

          End If
    End If

    If Lewo = 0 And Prawo = 1 Then
       Waitms 200
          If Lewo = 0 And Prawo = 1 Then

             Decr A
             If A = 0 Then A = 2

             Set Ledc
             Waitms 500
             Reset Ledc
          End If
    End If

    Getrc5(adres , Komenda)                          'odczyt komendy z pilota

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then
          If Komenda = B Then
             Incr A
             If A = 4 Then A = 2

             Set Ledz
             Waitms 500
             Reset Ledz
          End If

          If Komenda = C Then
             Decr A
             If A = 0 Then A = 2

             Set Ledc
             Waitms 500
             Reset Ledc
          End If
       End If                                        'Tu można odbierać sygnał z RC5

    Loop

    '***************Podprogram Kroczek**********************************************
    Kroczek:

       Select Case X
          Case 1
             Portc = &B0001111
          Case 2
             Portc = &B0100111
          Case 4
             Portc = &B0110011
          Case 8
             Portc = &B0011011
          Case 16
             Portc = &B0001111
          Case 32
             Portc = &B0100111
          Case 64
             Portc = &B0110011
          Case 128
             Portc = &B0011011
       End Select

    Return


    '***************Podprogram Krok - TIMER*****************************************
    Krok:

    If A = 1 Then
       Rotate X , Left

       Reset Ledz


       If D < 288 And K1 = 1 Then                    'liczenie
          Set Dc1
          Set Ledc
          Incr D
          Gosub Kroczek
       Else
          A = 2
       End If



    End If

    If A = 3 Then
       Rotate X , Right

       Reset Ledc


       If D > 1 And K2 = 1 Then                      'liczenie
          Set Dc2
          Set Ledz
          Decr D
          Gosub Kroczek
       Else
          A = 2
       End If



    End If

    If A = 2 Then

       Reset Ledz
       Reset Ledc
       Reset Dc1
       Reset Dc2

    End If
    'timer1=X 'Też z RC5- im większy X tym szybciej się kręci
    Return

    '*******************************************************************************

    Kalibracja_up:

    For K = 1 To 200
    Set Ledz
    Waitms 500
    Reset Ledz
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          B = Komenda
          P = 1
          Waitms 500
          Set Ledz
          Wait 2
          Reset Ledz
          Waitms 100
          Gosub Kalibracja_down

       End If
    Next K
    If K = 200 Then K = 1


    '*******************************************************************************
    Kalibracja_down:

    For P = 1 To 200
    Set Ledc
    Waitms 500
    Reset Ledc
    Waitms 500

    Getrc5(adres , Komenda)

    Togglebit = Komenda.7
       Komenda = Komenda And &B01111111
       If Adres <> 255 Then

          C = Komenda
          Waitms 500
          Set Ledc
          Wait 2
          Reset Ledc
          Waitms 100
          If C = B Then
          Gosub Kalibracja_up
          End If
          Goto Begin

       End If
    Next P
    If P = 200 Then P = 1


    P.S Zakupiłem książkę o programowaniu AVRów w C. Więc chyba będę powoli przechodził w język C

    Dzięki wszystkim.

    Pozdrawiam

    0