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.

Bascom - optymalizacja kodu i...

stoper17 11 Kwi 2013 23:06 2427 18
  • #1 11 Kwi 2013 23:06
    stoper17
    Poziom 20  

    Witam.
    Wykonuję niewielki manipulator na bazie silników krokowych, sterowany padem.
    Kod wyszedł mi trochę duży, jakby ktoś mógł mi go zoptymalizować, to było by super.
    Poza tym nie wiem jak rozwiązać problem:
    zdeklarowane kroki i czas dla silnika 1 2 3 z osobna działają wyśmienicie, ale gdy te zadeklarowane parametry chcę by działały jednocześnie, czyli po naciśnięciu guzika ruszają 3 silniki z różnymi prędkościami, obowiązkowo JEDNOCZEŚNIE, to w efekcie wszystkie obracają się tak samo. ;(
    Proszę o pomoc.

    Cały kod

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod



    W tym odcinku kodu zadeklarowałem wszystkie 3 silniki

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0 18
  • #2 11 Kwi 2013 23:13
    piotrva
    Moderator Mikrokontrolery

    Po pierwsze, żebyś w ogóle ruszył, rzucę hasło: Timery.
    Sterowanie silnikami krokowymi powinno być zrealizowane z wykorzystaniem Timera i jego przerwania - niedopuszczalne jest wręcz stosowanie w takiej sytuacji jakichkolwiek instrukcji oczekiwania blokujących działanie programu (tj. jakiekolwiek Wait...).

    0
  • #3 12 Kwi 2013 16:04
    SylwekK
    Poziom 28  

    W zasadzie tu prawie wszystko trzeba zoptymalizować... Jak wspomniał kolega @piotrva instrukcje WAIT wywalić w trybie natychmiastowym i zapoznać się z timerami. Następnie ruch silnika najlepiej zdefiniować w liniach Data i wybierać w odpowiedniej kolejności w zależności od kierunku po czym przypisać do odpowiednich portów. Jedna tabela wystarczy dla wszystkich silników. To na początek...

    0
  • #4 15 Kwi 2013 12:19
    stoper17
    Poziom 20  

    A była by możliwość by podać mi przykład konfiguracji timera, lub programu dla (chyba) tej opcji licznika?Rozumiem muszę zmusić by timer liczył impulsy. Kiedyś bawiłem się tą funkcją z wykorzystaniem PWM- realizowałem wówczas opcję zwiększania i zmniejszania sygnału wyjściowego, czyli dioda rozjaśniała i przygasała. Z helpa bascoma nie wyciągnąłem nic pomocnego.

    0
  • #5 15 Kwi 2013 17:52
    SylwekK
    Poziom 28  

    Chodzi o to, że timer ustawiasz aby co pewien odcinek czasowy skakał wywoływał przerwanie, w którym możesz umieść np. liczniki programowe do odliczania opóźnień.

    W temacie
    https://www.elektroda.pl/rtvforum/viewtopic.php?t=2232417&highlight=
    jest programik, który po analizie powinien Ci trochę rozjaśnić przerwania, liczniki, itp....

    0
  • #6 22 Kwi 2013 00:17
    stoper17
    Poziom 20  

    Mniej więcej wiem jak działa timer0, tylko nie wiem jak go wykorzystać w programie.
    W prostych programach, podają jak załatwić sprawę przy 1 diodzie, a ten program z linku jeszcze jest dla mnie za trudny

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    próbowałem tymi przerwaniami kontrolować diodę w ten sposób jak niżej.Ale droga którą obrałem jest chyba błędna

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    czy mógłby mi ktoś pokazać, co wstawić by zapalać 4 diody po kolei z wykorzystaniem przerwań???

    0
  • Pomocny post
    #7 22 Kwi 2013 12:59
    SylwekK
    Poziom 28  

    To Ci będzie sterować kolejno czterema diodami na pinach od B0 do B3.
    Zalecam wnikliwą analizę, zanim zalejesz mnie pytaniami :)
    Timery zawsze rób na odliczanie w dół do 0, w przeciwnym wypadku po wpisaniu nowej wartości w trakcie odliczania możesz mieć niezły kwas - pomyśl dlaczego :)
    Pozdrawiam


    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #8 22 Kwi 2013 22:14
    stoper17
    Poziom 20  

    Super super ;) pytań tylko aż jedno :D jak ograniczyć ruch diody dosłownie na 4 pinach. Tu mamy przesuwanie 2 diodek - "00010001" a jak ustawie " 00000001" dioda po całym porcie lata;P. zastosowałem coś w stylu

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    ale to tylko pogorszyło sytuacje ;( zapala co 4tą i nadal na całym porcie;(
    Reszta zrozumiała

    0
  • Pomocny post
    #9 23 Kwi 2013 09:43
    SylwekK
    Poziom 28  

    Hehe, przeanalizuj dokładnie Twój ostatni programik i odpowiedz sobie jeszcze raz na pytanie jak on właściwie działa :)

    Cytat:
    ...jak ograniczyć ruch diody dosłownie na 4 pinach. Tu mamy przesuwanie 2 diodek - "00010001"...


    Wkradł mi się mały błędzik :) W swoim programie pobierałem dane z linii Data i były to tylko bity 0...3 dla silnika bipolarnego natomiast 4...7 były zerami stąd sekwencja instrukcji z AND OR była prawidłowa natomiast tu z rozpędu zapomniałem dopisać obcięcia tych bitów dla zmiennej Stan. Tak powinna wyglądać cała sekwencja:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Oczywiście trzeba jeszcze na początku zadeklarować zmienną Xs jako Byte.

    Dzięki takiemu rozwiązaniu spokojnie możesz wykorzystać pozostałe piny portu (B4...B7) do dowolnych celów. Wyjątkową sytuacja może być jedynie zmiana stanu tych portów w przerwaniu kiedy akurat przerwanie zostało by wywołane miedzy wykonującymi się właśnie linią zapamiętania stanu portu, a linią aktualizacji (zapisu do) portu.

    0
  • #10 23 Kwi 2013 23:58
    stoper17
    Poziom 20  

    Kwestia samego wyliczenia, bo chyba mam z tym problem:
    Kwarc: 8000000
    przeskalowanie: 64

    8000000:64=125000HZ = 125kHz
    Timer jest 8 bitowy
    czyli 256-125= 131
    131- tyle musi zliczyć bitów, by łączny czas dał 1ms. Zliczenie od 0 do 1 trwa 8µs
    To gdy zastąpię "131" liczbą "255" teoretycznie czas powinien wynosić 19ms czyli dłużnej niż 131,a na symulatorze bascoma pracuje szybciej
    I kolejna zmiana, zamiast "131" wpisuje "1" to jak wyżej niby powinno być 8µs czyli szybciutko, a jednak jest dużo dłużej niż 255;////

    I nie wiem jak wyliczyć opóźnienie;/ skąd wiemy by dać 100ms

    0
  • Pomocny post
    #11 24 Kwi 2013 06:25
    emarcus
    Poziom 34  

    stoper17 napisał:
    Kwestia samego wyliczenia, bo chyba mam z tym problem:
    Kwarc: 8000000
    przeskalowanie: 64

    8000000:64=125000HZ = 125kHz
    Timer jest 8 bitowy
    czyli 256-125= 131
    131- tyle musi zliczyć bitów, by łączny czas dał 1ms. Zliczenie od 0 do 1 trwa 8µs
    To gdy zastąpię "131" liczbą "255" teoretycznie czas powinien wynosić 19ms czyli dłużnej niż 131,a na symulatorze bascoma pracuje szybciej
    I kolejna zmiana, zamiast "131" wpisuje "1" to jak wyżej niby powinno być 8µs czyli szybciutko, a jednak jest dużo dłużej niż 255;////

    I nie wiem jak wyliczyć opóźnienie;/ skąd wiemy by dać 100ms


    Wygląda ze masz bardzo duży problem z tymi rachunkami.
    np:
    Cytat:

    131- tyle musi zliczyć bitów, by łączny czas dał 1ms.

    Nie, taką wartośc należy wpisac do timera0, od której będzie liczył w górę do 255 (do przepełnienia) czyli 125 'ticków' co w sumie da:
    125 * 8µS (rozdzielczośc) = 1mS
    Pozostałe obliczenia i tok analizy rachunków jest również błędny.
    Wpisując do timera '1' oznacza że będzie on liczył (jak zawsze w górę) az do przepełnienia - 255 ticków czyli cały zakres.
    Troche odmiennie wygląda przebieg pracy oraz configuracja timerów w innych trybach pracy.
    Bardzo pomocne jest (przynajmniej na poczatek), posługiwac sie jakims calculatorem.
    Tu poniżej masz kilka linków, które możesz downlolad 'Free' i posługiwac się nimi do woli. Każdy z nich jest dobry...

    by Ian Dobson; ver:1.25
    http://mail.planet-ian.com/bascom/avrtimerbeta.zip
    by Kevin Rosenberg
    http://www.b9.com/elect/avr/kavrcalc/
    by Jack Tidwell
    http://www.avrfreaks.net/index.php?module=Freaks%20Files&func=viewFile&id=353

    e marcus

    0
  • #12 24 Kwi 2013 08:30
    stoper17
    Poziom 20  

    OK dzięki, po pracy zapoznam się z programami. A co z opóźnieniem 100ms?

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    do naszej 1[ms] + 100[ms]=101[ms]? czyli 0.101[s]???
    To zamiast 100 trzeba by wstawić 1000[ms] by osiągnąć cykl co 1.01[s]??????

    0
  • Pomocny post
    #13 24 Kwi 2013 10:45
    SylwekK
    Poziom 28  

    W zasadzie kolega @emarcus powiedział już wszystko odnośnie pracy timera. Dodam jeszcze że mógłbyś użyć wyliczonej wartości 125 wykorzystując zamiast Counter0...itd., instrukcję "Load Timer0, 125" - osobiście jej nie lubię i rozwiązanie, które Ci podałem jest dokładniejsze.


    Z tym Lo1 to jest tak w tym przypadku, że ile wpiszesz tyle milisekund będzie odliczonych.
    Po prostu natychmiast po aktualizacji zmiennej Lo1 zaczyna być ona w przerwaniach zmniejszana. Faktycznie może być sytuacja, o której piszesz, że w sumie doliczy 1ms, a w zasadzie minimalnie mniej, bo akurat trafi na aktualizację tuż po wykonaniu przerwania. W większości przypadków nie ma to jednak większego znaczenia, bo w dokładniejszych pomiarach używa się timerów bez pośredników pokroju Lo1.
    Dla 1s (1000ms) będzie to tak jak piszesz wartość 1000. Specjalnie dobrałem Ci taki timing, żebyś łatwo mógł się z tym zapoznać.

    0
  • #14 24 Kwi 2013 10:56
    stoper17
    Poziom 20  

    Elegancko. Teraz postaram się zmodernizować swój programik z pierwszego posta i zobaczę, co z tego wyjdzie. ;D

    0
  • #15 24 Kwi 2013 19:37
    emarcus
    Poziom 34  

    SylwekK napisał:
    Dodam jeszcze że mógłbyś użyć wyliczonej wartości 125 wykorzystując zamiast Counter0...itd., instrukcję "Load Timer0, 125" - osobiście jej nie lubię i rozwiązanie, które Ci podałem jest dokładniejsze.


    W tej części tematu akurat, nie miałem na celu wskazania lepszej, dokladniejszej, ulubionej lub preferowanej metody wpisu do timera, lecz chciałem wyprowadzic go z błędnego rozumowana że liczba (wartośc) wpisana do rejestru timera nie jest ilością ticków wyznaczoną do odliczenia, lecz wartością od której będzie następowało incrementiwanie timera aż do jego przepełnienia.
    Ne wiem czy on to 'zaskoczył'.

    Poza tym, obie metody sa równoważne. Tę drugą łatwiej zrozumiec na poczatek i zdaje sie to było przyczyna i wynikiem jego konfuzji.

    e marcus

    0
  • #16 24 Kwi 2013 20:02
    stoper17
    Poziom 20  

    Cytat:
    Ne wiem czy on to 'zaskoczył'.

    Zaskoczył i wiedział że timer dąży do przepełnienia aby doszło do przerwania itd:)Tylko musiał to sobie wszystko poukładać, a raczej zobaczyć jak to wygląda w praktyce :) A że programowanie to tylko bonus bo całym dniu, stąd problem z "fachowymi" i prawidłowymi określeniami... u niego :);P

    Do dziś dziś dzień wszystko co robiłem opierało się na poleceniu wait. Ciesze się że taki problem stanął na drodze, bo mam parę pomysłów, do których timer pasuje jak ulał :D Ale to na przyszłość zostawie

    0
  • #17 24 Kwi 2013 21:40
    SylwekK
    Poziom 28  

    Hehe, zapomnisz o Wait tak jak ja zapomniałem :) - już nie pamiętam kiedy go używałem.
    Powinieneś też wiedzieć, że korzystając z przerwań drastycznie odbija się to na dokładności instrukcji Wait - najczęściej opóźnienie nie ma już nic wspólnego z tym co tam wpisujesz. Oczywiście zależy to od "gęstości" wywoływania przerwania - czym częściej wywołanie tym bardziej Wait się w praktyce wydłuża.

    0
  • #18 25 Kwi 2013 00:14
    stoper17
    Poziom 20  

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Próbuje w trakcie trwania programu zadeklarować left, right, czyli te słowa to niewiadoma z
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    i teraz to moje "z" muszę zadeklarować jako string czy byte???

    0
  • #19 25 Kwi 2013 07:24
    SylwekK
    Poziom 28