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

Sterownik do silnika krokowego unipolarny kod c++

13 Wrz 2015 19:12 2211 45
  • Poziom 7  
    Witam,

    Od razu mówię, że jestem amatorem w elektronice. Zrobiłam płytkę z atmegą 8, sterownikiem ULN2803 i silnikiem krokowym unipolarnym. Silnik po wgraniu początkowe programu obracał się. Teraz jedynie drga. Mój kod ma na celu zaczęcie obracania silniczkiem i liczenia kroków, gdy wcisnę guzik (PINC2) silnik ma zacząć się obracać w drugą stronę z tą samą ilością kroków, i tak w kółko. Ma to się powtórzyć 10 razy. Proszę czy ktoś mógłby spojrzeć na ten kod i podpowiedzieć jakie błędy robię?
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Sklep HeluKabel
  • Pomocny post
    Poziom 12  
    Witam.

    Po pierwsze, zegar procesora definiuj w opcjach projektu, każdy tutaj na forum Ci to powie.
    Po drugie: spójrz na tę linijkę:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    program nigdy nie wejdzie w tą pętlę z paru powodów:
    liczba_cykli = 10, natomiast inicjalizacja zmiennej: zmienna = 0, co oznacza, że nigdzie nie zwiększana zmienna nigdy nie będzie równa 0. A nawet gdyby była to używasz w nawiasie operatora PRZYPISANIA =, a nie operatora PORÓWNANIA ==. Literówka, ale robi swoje.

    Idźmy z kodem dalej zakładając, że program wchodzi w tą pętlę. Mamy więc kolejny blok uwarunkowany linijką:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Niemożliwe jest, by zainicjalizowany zerem licznik2, był większy od licznik1, który to w tym bloczku:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    jest inkrementowany nawet kilkakrotnie jeśli będziesz zwlekać z przyciskiem, a nawet gdybyś nie zwlekała, to licznik1 będzie przy starcie programu równy 0, a więc warunek (licznik2>licznik1) i tak nie będzie spełniony.
    To samo masz przy kolejnym bloku:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Ten warunek także nie będzie spełniony z powodów dokładnie takich samych jak w bloczku poprzednim.

    Do tego jeszcze kilka porad:
    Formatuj kod, tak by był czytelniejszy. W tym kodzie ciężko czasem się połapać która klamra zamyka który blok i która instrukcja do którego bloku należy...
    Używaj także debuggera, lub symulacji (przez niektórych sceptyków Atmel Studio zupełnie niedocenianej ;>) to naprawdę pomaga rozwiązać większość problemów z kodem.

    Pozdrawiam :)
  • Poziom 7  
    Dziękuję za odpowiedź.
    Rzeczywiście jest różnica czy damy = czy == :). Używam AVR studio 4.

    Nie rozumiem tylko za bardzo, czemu warunki licznik2>licznik1 i licznik3>licznik1 nigdy nie będą spełnione.

    licznik1 to jest licznik kroków podczas pierwszego obrotu. Za każdym razem gdy krok zostanie wykonany zwiększa się o jeden. Gdy naciskamy guzik, przestają nam się zliczać te kroki i przechodzimy do następnej pętli która uruchomia nam silnik w drugą stronę. Też zlicza za każdym krokiem te kroki czyli licznik2 zwiększa się po każdym kroku. Gdy licznik 2 będzie już większy niż licznik1, wychodzimy z pętli, licznik2 się zeruje i idziemy do tej następnej analogicznej pętli z licznik3(kroki w przeciwną stronę). Gdy liczba zliczonych kroków licznik3 będzie większa niż licznik1, wychodzimy z pętli, licznik3 zerujemy, zmienna zwiększa się o jeden. Będzie to się tak długo wykonywała, jak liczba cykli przez nas zadana będzie równa zmiennej.

    Czy niepotrzebnie zadeklarowałam jako 0 licznik1, licznik2 i licznik3?
    Aktualnie mój ko wygląda tak (niestety silniczek dalej tylko drga)
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    Poziom 12  
    Deklaracja zmiennych na początku programu jest dobrym nawykiem, bez tego zadeklarowana zmienna będzie początkowo przechowywać nieustaloną wartość (śmieć z pamięci), więc zadeklarowanie jest ok.
    To warunek, który jest ustalony dla pętel while jest błędny. W Twoim kodzie użyty jest operator większości, więc sprawdzamy czy licznik3 (lub licznik2) jest większy od licznik1. Więc popatrz: licznik1 zwiększa się nawet kilkakrotnie (a nawet i tysiąckrotnie) a licznik3 zadeklarowany jako 0 jest z nim porównywany. Pętla się nie wykona, bo 0 nigdy nie będzie większe od licznik1. Deklaracja jest w porządku, to warunek dla pętel jest błędny. Spróbuj ustawić to na odwrót pisząc:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Warunek dla liczby cykli także jest błędny czytając założenia projektowe, nawet pomijając zły operator (= zamiast ==), który już ustaliliśmy. Sprawdzasz, czy program wykonał pętlę zadaną ilość razy, czyli należy sprawdzić, czy zmienna wciąż jest mniejsza od zadanej wartości, jeśli tak: wykonaj pętlę. Czyli:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Spróbuj zastosować te zmiany. Zamieść kod po poprawkach i przetestowaniu go.
  • Poziom 7  
    Aktualnie kod wygląda tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Jest lepiej, silniczek się obraca, ale gdy tylko delikatnie dotknę przycik to zaczyna już tylko drgać.

    Int zmieniłam na long double, ponieważ po pewnej liczbie kroków silniczek zamiast się obracań, nagle zaczynał drgać.
  • Poziom 32  
    Początek głównej pętli (tam gdzie komentarze) zapewnia ci te drgania.
    Może napisz co chcesz osiągnąć.
  • Sklep HeluKabel
  • Poziom 7  
    Ogólnie chcę, żeby silnik sie obracal np.w prawo i jak nacisne guzik to zaczął sie obracać w druga stronę lewą z ta samą liczbą kroków jakie zliczyl dopóki guzik nacisnelam, nastepnie gdy juz zrobi ta sama liczbe krokow znowu z powrotem w prawo ale juz automatycznie. I tak zalozmy lewo-prawo wykonał 10 razy. Wiec przycisniecie guzika ma zliczac ilość kroków, z którą silnik będzie sie obracał na zmianę w lewo i prawo.
  • Pomocny post
    Poziom 32  
    Coś w ten deseń?
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Uwaga, pisano "na kolanie".
  • Poziom 7  
    -psiak- co prawda jest to bardziej skomplikowany kod niż mój i wyskoczyły mi błędy podczas kompilacji które teraz próbuję naprawić ale myślę, że tak.

    Dodano po 24 [minuty]:

    -psiak-, niestety kod po zmianach coś nie działa. Wgrałam poprzedni kod co podałam. Ogólnie dziwna sprawa, bo silniczek się obraca, a gdy tylko przystawię palec blisko przycisku (nawet nie naciskam) to silniczek przestaje się obracać i zaczyna drgać.
  • Pomocny post
    Poziom 32  
    Możliwe lekkie drgania od "efektu kondensatora".
    W twoim kodzie - wytłumaczyłem czemu są te drgania.
    Co nie działa w tym kodzie co podałem?
  • Poziom 7  
    Oo ciekawe, a jak można pozbyć się "efektu kondensatora"?

    Twój program ładnie się kompiluje jak zmieniłam z byte na char (piszę w c++) ale po wgraniu na płytkę nie ma żadnego efektu.
  • Poziom 32  
    Nie pozbędziesz się. Tylko trzeba uważać na stan przycisków. W momentach wciśnięcia/zwolnienia powstają drgania.
    Można jedynie dać pewne "znieczulenie" czyli po wciśnięciu sprawdzasz stan dopóki powiedzmy 10 pomiarów pod rząd z odstępem 2 ms nie będą jednakowe.
  • Poziom 7  
    Walcze z tym kodem niestety bez skutku :( , czy może ktoś ma jeszcze jakieś pomysły ?
  • Poziom 28  
    Najlepiej pokaż obecny kod i schemat układu i co konkretnie nie działa a co chcesz uzyskać.
  • Poziom 7  
    Mój projekt to atmega 8, silnik krokowy unipolarny i sterownik ULN2803. Chce, aby silnik po włączeniu do zasilania np.8V zaczął się kręcić w prawo i zliczał kroki. Następnie po wciśnięciu guzika, następuje zmiana kierunku obracania z tą samą ilością kroków co wcześniej zliczyliśmy. Gdy wykonają sie te kroki w lewą stronę już automatycznie silnik zaczyna się obracać w drugą stronę. I tak załóżmy obróci się lewo-prawo 10 razy.

    Moje schematy:
    Sterownik do silnika krokowego unipolarny kod c++

    Kod:
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Poziom 12  
    Z tego co widzę na schemacie to:
    - Rezystor R7 i R6 są włączone raczej błędnie. Ustaw R7 tuż przed Reset i tyle, rezystor przed pinami zasilania uC nie są w ogóle potrzebne...
    - Zwarcie przycisku S2 da Ci na porcie PC2 stan niski, a nie wysoki, a Twój kod wygląda tak, jakby założenia mówiły inaczej.
    - Poza tym schemat troszkę nieczytelny... Blok z IC2 zrób jako osobny a z uC wyprowadzaj na schemacie jedynie znaczki (label), bo póki co plątanina połączeń tuż przed IC2 trochę odstrasza.

    Co do kodu...
    Unikaj typów: long double, double, float na 8-bitowych mikrokontrolerach, to przerost formy nad treścią i zupełnie zbędny w tym przypadku.
    Jak tak patrzę na kroki w dwóch ostatnich blokach dla licznika 2 i 3 to widzę, że silnik będzie obracał się ciągle w tą samą stronę, tak miało być?
    A co do "zbliżania palca do przycisku"... Czy wszystkie masy są ze sobą połączone?
  • Poziom 7  
    Ta plątanina powstała, by łatwiej się układało schemat montażowy. Rzeczywiście na przycisku powinien się pojawić stan niski, czyli powinno być:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Masy są z sobą połączone. Ogólnie gdy jest ustawione samo kręcenie się w lewo i w prawo to działa bez zarzutu płytka.
  • Poziom 32  
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Poziom 7  
    -psiak- dziękuję, niestety coś dalej nie gra - silnik nie obraca się tylko drga cały czas.
  • Poziom 32  
    Oznacza to że niepoprawnie identyfikujesz naciśnięcie przycisku.
    Zamień warunek: !(PINC&btnmask)
    na: max<33*5 (*czyli około 5 sek*)
    i zobacz co się dzieje.
  • Poziom 7  
    Jak zmieniłam warunek to niestety dalej to samo :(
  • Poziom 32  
    W takim razie podaj działający kod który obraca w jedną stronę i kod który obraca w drugą.
    Bo to co masz w wewnętrznych while - nie robią tego co oczekujesz.
  • Poziom 7  
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Dla kręcenia w drugą stronę jest analogicznie z małą zmianą:

    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Poziom 32  
    No to wstaw:
    DDRD=0xFF;
    DDRC=0x00;
    Przed pętlami do funkcji lf() i rt()
  • Poziom 7  
    Zrobiłam według twojej rady, niestety dalej silniczek tylko drga :(
  • Poziom 12  
    Silnik drga w którym momencie?
    I który kod teraz stosujesz - swój czy kolegi Psiak?
  • Poziom 7  
    Jak wpisuję kod kolegi Psiak to silniczek tylko drga. Jak swój to slinik się obraca ale gdy zblize palec do przycisku to zaczyna drgac.
  • Poziom 17  
    Od #5 postu jest różnica w sterowaniu silnikiem przed nacisnieciem przycisku - sa sterowanie tylko linie pd.4 i pd.5 . Wysunalem zapisy do portu.
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wyglada ze przed nacisnieciem jest sterowany 0x10 , 0x20 naprzemian a potem 0x10,0x20,0x40,0x80. Skoro silnik drga to moze za szybko albo pomylone linie do silnika sa.
  • Poziom 7  
    Okazało się ze przycisk był źle przylutowany :) teraz za to mam inny problem - gdy chce programować to wyskakuje mi blad w AVR studio - ISP mode error. Ciekawe jest to że wcześniej normalnie programowal juz z przylutowanym dobrze przyciskiem, niestety nie wiem co się stało bo plytka później nie byla ruszana i nagle taki komunikat zaczął wyskakiwac. Moze to coś w ustawieniach AVR studio. Będę jeszcze z tym walczyć. Bo przesledzilam i pomierzlam plytke i nie znalazlam żadnego błędu.