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

[C][ATmega32]Sterowanie silnikiem krokowym bipolarnym

adam_mocny87 24 Sty 2010 00:30 4306 9
  • #1 7581835
    adam_mocny87
    Poziom 10  
    Posty: 11
    Witam,

    Mam problem z wysterowaniem silnika bipolarnego (4 przewody idące do cewek). Dokładnie jest to aktuator liniowy.

    Program, który napisałem powinien działać, ale niestety nie działa, jak to w życiu bywa... Nie wiem, czy problem w sprzęcie, czy jednak...w moim programie.

    Generalnie w skrócie: mam 5 wejść do układu scalonego odpowiedzialnego za sterowanie aktuatorem: ENABLE (włącz/wyłącz silnik), DIR (kierunek lewo/prawo), CLK (zegar nadający prędkość silnikowi), STEP0/STEP1 (określenie na 2 bitach rodzaju pracy: full step, half step itd).
    STEP0 oraz STEP1 sobie darowałem i mam ustawione bez podłączenie do zasilania, co daje mi na stałe logiczne zera - wystarcza mi praca full step, więc faktycznie używam wejść sterujących ENABLE, DIR oraz CLK.

    Pod tym linkiem dokumentacja układu A3967, który służy do sterowanie moim silnikiem
    http://www.datasheetcatalog.org/datasheet/allegromicrosystems/3967.pdf

    a to kod programu do sterowania silnikiem:
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/delay.h>
    
    int main (void)
    {
    
    while(1)
    {
    DDRD = 0xE0; 
    
    PORTD |= 0<<PD7; //ENABLE
    
    PORTD |= 1<<PD6; //obrót w lewo
    _delay_us(100);
     
      for(int i = 0; i < 4000; i++)  //generowanie zegara - obrót w jedną stronę
      {
        PORTD |= 0<<PD5; 
    	_delay_ms(100); 
        PORTD |= 1<<PD5;
        _delay_ms(100);   
      }
      
    PORTD |= 0<<PD6;  //obrót w prawo
    _delay_us(100);
    
      for(int i = 0; i < 4000; i++)  //generowanie zegara - obrót w drugą stronę
      {
        PORTD |= 0<<PD5;
    	_delay_ms(100); 
        PORTD |= 1<<PD5;
        _delay_ms(100); 
      }
    
    }
    }


    Tak w skrócie - ten "cudowny" układ A3967 ma w sobie wbudowany translator, dzięki czemu nie muszę przejmować się bezpośrednim wysterowywaniem cewek jedna po drugiej.

    Z góry wielkie dzięki za pomoc od doświadczonych kolegów :)

    Pozdrawiam

    Poprawiłem tytuł, dodałem znaczniki [code].
    [zumek]
  • #2 7581882
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 50
    Enable chyba powinien mieć stan niski.
  • #3 7583772
    adam_mocny87
    Poziom 10  
    Posty: 11
    Dziękuję za wskazówkę, rzeczywiście... ENABLE, jak teraz doczytałem dokumentację musi mieć stan niski, a więc... testuję i napiszę, jakie dało to efekty.

    Dodano po 16 [minuty]:

    Fakt faktem, to na pewno był jeden z błędów, ale mimo tego, program nadal nie steruje moim silnikiem.
    Po załączeniu zasilania, silnik, który trzymam w dłoni, tak jakby "kopie", czyli coś tam ten program realizuje, tylko już sam nie wiem dlaczego to nie rusza...
    Z tego co analizuję kod, to raczej nie ma w nim więcej błędów...
  • #4 7584530
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 50
    Teraz zamień miejscami końcówki jednego z uzwojeń silnika.
    P.S.
    Masz 4 czy 6 wyprowadzeń?
  • #5 7584868
    adam_mocny87
    Poziom 10  
    Posty: 11
    Mam 4 wyprowadzenia. Aktualnie jestem poza domem, jak tylko znajdę się w zasięgu "sprzętu" pozamieniam kolejność cewek i zobaczę, czy pomoże...

    Dodano po 1 [godziny] 18 [minuty]:

    Niestety... zmiana cewek też daje taki sam efekt :/ Generalnie silnik ma ładnie opisane pary cewek, więc popełniania błędów w połączeniu cewek rzadko mi się zdarzają. Nie wiem co może jeszcze pomoc. Będę wdzięczny za jakikolwiek inny pomysł. Z góry dziękuję:)
  • #6 7585703
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 50
    Ale nie zamiana cewek tylko zamiana końcówek jednej cewki.
    Zrób to "ab ovo":
    Czy masz kondensator 220- 1000uF na zasilaniu A3967?
    Czy kilkakrotnie sprawdziłeś które kable należą do tego samego uzwojenia?
    Miernikiem!
    Czy dobrze podłączone- nie skrzyżowane- do dobrych końcówek układu?
    Czy zasilanie A3967 ma chociaż 12V- dobrze byłoby 24V albo więcej?
    Czy zasilacz daje dość prądu?
    ENABLE na stałe do -.
    DIR podłącz na stałe do + lub -.
    Na STEP daj sygnał prostokątny - masz 50Hz- trochę mało ale powinien działać.
    P.S.
    Jakie oporniki masz na SENS?
  • #7 7585969
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 51
    adam_mocny87 napisał:
    ...Mam problem z wysterowaniem silnika bipolarnego...
    
    //...
      for(int i = 0; i < 4000; i++)  //generowanie zegara - obrót w jedną stronę
      {
        PORTD |= 0<<PD5; 
    	_delay_ms(100); 
        PORTD |= 1<<PD5;
        _delay_ms(100);   
      }
    //...


    Proponuję cofnąć się do podstaw języka C i przypomnieć sobie, jak powinny wyglądać operacje ustawiania/kasowania bitów.
  • #8 7586670
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 50
    Zumek, daj link do swoich poprzednich porad.
    Bo były.
    Ma być:
    PORTD|=_BV(PD5); // ??
    Czy inaczej?
    Bo wygląda że adam_mocny87 zmieniał kierunek (DIR) a ENABLE i tak było 0.
  • #9 7586788
    adam_mocny87
    Poziom 10  
    Posty: 11
    Więc tak:

    Nie zmieniałem jeszcze kolejności cewek, a skupiłem się na szybkiej zmianie programu sterującego. Przypomniałem sobie podstawy C, a szczerze to skorzystałem z makra, które uwolniło mnie od konieczności wpisywania bezpośredniego ustawiania bitów w porcie. U góry zdefiniowałem makra "sbi" dla ustawiania oraz "cbi" dla kasowanie bitów pojedynczych.

    Poniżej kod zmodyfikowanego programu:

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/delay.h>
    
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    
    int main (void)
    {
    
    while(1)
    {
    
    DDRD = 0xE0; 
    DDRC = 0xFF;
    
    sbi(PORTD, PD7); // PORTD 
    cbi(PORTC, PC7); // PORTC 
    cbi(PORTC, PC6); // PORTC 
    
    sbi(PORTD, PD6); // PORTD
    _delay_us(100);
     
      for(int i = 0; i < 4000; i++)  //generowanie zegara - obrót w jedną stronę
      {
        cbi(PORTD, PD5); //PORTD 
    	_delay_ms(50); 
        sbi(PORTD, PD5); //PORTD 
        _delay_ms(50);   
      }
      
    cbi(PORTD, PD6); //PORTD 
    _delay_us(100);
    
      for(int i = 0; i < 4000; i++)  //generowanie zegara - obrót w drugą //stronę
      {
        cbi(PORTD, PD5); //PORTD 
    	_delay_ms(50); 
        sbi(PORTD, PD5); //PORTD  
        _delay_ms(50); 
      }
    
    }
    }
    


    Efekt działania programu jest dziwny... Silnik coś "wyłapuje" na cewkach - jak biorę go w dłonie, to tak jakby... "mruczy", nie wiem jak to określić. Drga, jakby chciał zaskoczyć, ale tylko drga, bez jakiegokolwiek obrotu w prawo/bądź w lewo.

    Dziękuję za ewentualnie kolejne wskazówki.

    Przede wszystkim, ENABLE, tak jak być powinno, jest w stanie 0. Zmniejszyłem też opóźnienia ze 100 ms na 50 ms, więc częstotliwość też jest dwukrotnie większa niż na początku - tak dla pewności.

    Pozdrawiam

    Dodano po 9 [minuty]:

    janbernat napisał:
    Ale nie zamiana cewek tylko zamiana końcówek jednej cewki.
    Zrób to "ab ovo":
    Czy masz kondensator 220- 1000uF na zasilaniu A3967?
    Czy kilkakrotnie sprawdziłeś które kable należą do tego samego uzwojenia?
    Miernikiem!
    Czy dobrze podłączone- nie skrzyżowane- do dobrych końcówek układu?
    Czy zasilanie A3967 ma chociaż 12V- dobrze byłoby 24V albo więcej?
    Czy zasilacz daje dość prądu?
    ENABLE na stałe do -.
    DIR podłącz na stałe do + lub -.
    Na STEP daj sygnał prostokątny - masz 50Hz- trochę mało ale powinien działać.
    P.S.
    Jakie oporniki masz na SENS?


    - Zmieniałem te cewki, efektu brak :/
    - Mam na wejściu zasilania przed stabilizatorem kondensator 470uF, potem konden. 100nF, za stabilizatorem mam 100uF a jeszcze za nim równolegle kolejny 100nF
    - Kable sprawdzałem już nie raz, miernikiem również
    - podłączone do dobrych końcówek układu
    - silnik ma parametry: zasilanie 5V przy prądzie 450 mA, a mój zasilacz ma 6V przy 800 mA (wartość graniczna dla mojego silnika to 850 mA)
    - Przy SENS-ach mam oporniki o wartości 0,68 R
    ...
  • #10 7591050
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 50
    W programie pisanym w C to ja nie pomogę.
    Ale rozbij problem na kawałki.
    Najpierw sprawdź sprzęt.
    Odłącz od procesora i potem:
    Jak już napisałem- ale powtórzę- może nie zwróciłeś uwagi:
    ENABLE na stałe do -
    DIR podłącz na stałe do + lub -.
    Na STEP daj sygnał prostokątny kiladziesiąt-kilkaset Hz z generatora prostokątnego.
    Generator zaprogramuj na procesorze albo zrób na NE555 albo na bramkach.
    Generator ma być pewny- sprawdzona amplituda, częstotliwość i wypełnienie ok 50%.
    Ja tak robię- w domu zwykle programuję procesor jako generator, sprawdzam na oscyloskopie przebieg( na wszelki wypadek) i sprawdzam układ sterujący silnikiem.
    W "plenerze" używam generatora na NE555 przestrajanego potencjometrem.
    Bo szukanie jednocześnie błędów w sprzęcie i w programie to jest dla masochistów.
    Jak sprawdzisz że silnik kręci i określisz przy jakiej częstotliwości "gubi" kroki to możesz zacząć szukać ew. błędów w programie.

Podsumowanie tematu

✨ W dyskusji poruszono problem z wysterowaniem silnika krokowego bipolarnego (aktuator liniowy) przy użyciu układu A3967. Użytkownik miał trudności z poprawnym działaniem programu, mimo że wprowadził zmiany w kodzie, takie jak użycie makr do ustawiania bitów. Uczestnicy sugerowali różne rozwiązania, w tym sprawdzenie stanu sygnału ENABLE (powinien być niski), zamianę końcówek cewek silnika, a także upewnienie się, że zasilanie układu A3967 wynosi co najmniej 12V. Podkreślano również znaczenie testowania sprzętu oddzielnie od programu oraz użycia generatora prostokątnego do sygnału STEP. Użytkownik był zachęcany do dokładnego sprawdzenia połączeń oraz parametrów zasilania.
Wygenerowane przez model językowy.
REKLAMA