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

[Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

09 Sie 2011 10:21 7787 27
  • Poziom 17  
    Witam
    Od dłuższego czasu pracuję nad własnym sterownikiem bramy przesuwnej. Może ktoś pamięta jak stawiałem pierwsze kroki w tym kierunku ;)

    W zeszłym roku opracowałem teraźniejszą wersję sterownika - dodałem SOFT-START, SOFT-STOP (wykorzystując PWM). I wszystkie aktualne problemy kręcą się w zasadzie w okół tego.

    Po pierwsze, nie mogę ustawić częstotliwości PWM większej niż aktualne ok 200Hz. Efekt jest taki, że uC się prawdopodobnie resetuje (staje w miejscu brama, nie mam możliwości debugowania ;) ). Co istotne, gdy sterownik pracuje bez obciążenia (silnik podlaczony, ale działający na biegu jałowym) to wyższa częstotliwość nie wpływa na pracę. Wydaje mi się, że to problem zakłóceń, może źle prowadzonych ścieżek zasilania. Aktualny projekt płytki jest poniżej. Czy przeprojektowanie płytki, prowadzenie odpowiednio mas (z wyszczególnieniem PGM), podzielenie płytki na część sterującą i wykonawczą (większa odległość "prądów" silnika - dwie płytki połączone tulejkami w "kanapkę") czy też dodanie dodatkowych kondensatorów filtrujących?

    Drugi problem. Zacznę może od opisu zagadnienia. SOFT-STOP działa na podstawie pomiaru czasu. Mam z góry wprowadzoną ilość czasu jaką pokonuje brama. Dobrane jest to tak, aby brama ładnie przed końcem wyhamowała i delikatnie weszła w gniazdo. Czas jest odmierzany przez Timer. Problem jest taki, że po włączeniu zabezpieczenia przeciążeniowego (na podstawie ADC - włączenie polega na ustawieniu progu zadziałania innego niż maksymalny). Różnica w działaniu kodu jest w zasadzie żadna. Zanim włączę to zabezpieczenie to miga dioda led na płytce ostrzegając o wyłączonym zabezpieczeniu. Aby utrzymać "symetrię" wykonywania kodu, to po włączeniu zabezpieczenia wykonuję się bardzo podobny kod do tego odpowiedzialnego za miganie diody - dioda po prostu jest zapalana na bardzo krótki okres czasu.
    A teraz co się dzieje. Otóż po jakimś czasie (rzędu kilku uruchomień) lub tak jak do niedawna po włączeniu zabezpieczenia, sterownik zachowuje się tak jakby czas nastawy był krótszy. To znaczy - brama nie dojeżdża do końca. Zwykle jeśli zaprogramuje uC na nowo to problem znika, brama znowu działa idealnie.
    Tutaj jestem bez radny, kilka razy sprawdzałem kod czy przypadkiem to nie jego wina, ale bez rezultatu. Zdażało mi się godzinami siedzieć nad podobnymi dziwnymi problemami i okazywał się problem w kodzie, więc umieszczę go na końcu postu, dla sprawdzenia.

    Ostatni problem to uszkodzenia portu ADC. Portu ADC używam do zabezpieczenia przeciążeniowego, o którym mowa wyżej. Mierzy on napięcie na rezystorze, co daje wynik pobieranego prądu. Przy prądzie maksymalnym (w sensie, takim jaki może podać transformator) napięcie na rezystorze może dojść do niecałego 1V (w teorii - 8,33A prąd znamionowy tarfo, rezystancja 0R11 = 0,92V). Port ADC jest bezpośrednio podłaczony z punktem pomiary napięcia. Lecz sygnał ten jest w jakiś sposób zabezpieczony dzięki równolegle doprowadzonej diodzie Zenera 5,1V (jest także kondensator 100n).
    Aktualnie już drugi port mi "padł". Kolega po studiach elektronicznych twierdzi, że to jest nie możliwe - wysoka impedancja portu uniemożliwia uszkodzenie go w ten sposób. Nie bardzo wiem jak zabezpieczyć ten port.

    Schemat "trochę" niechlujny, ale lepszy taki niż żaden:
    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    Widok płytki drukowanej (masa jest np. na pinie 2 złącza EDG w górnym prawym rogu):
    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    Kod:

    Główny:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    adc.h:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Timer.h:
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Computer ControlsComputer Controls
  • VIP Zasłużony dla elektroda
    1. Jeśli jestem w stanie dobrze odczytać rysunek udający schemat (brak opisu gdzie co idzie...) brak rezystora na bramce MOSFET-a.
    2. Zabezpieczenie ADC - rezystor 4,7k w szereg na wejście. Płynące prądy są tak znikome, że raczej nie spowodują zbyt dużego błędu w odczycie.
  • Poziom 17  
    LordBlick napisał:
    1. Jeśli jestem w stanie dobrze odczytać rysunek udający schemat (brak opisu gdzie co idzie...) brak rezystora na bramce MOSFET-a.

    To akurat jest wzięte z Artykułu Tranzystory dla Początkujących cz. 23- Tranzystory polowe MOSFET (strona 39 rys. 23a) z EdW Lipiec 2000.
    http://www.elportal.pl/pdf/k01/55_08.pdf

    LordBlick napisał:
    2. Zabezpieczenie ADC - rezystor 4,7k w szereg na wejście. Płynące prądy są tak znikome, że raczej nie spowodują zbyt dużego błędu w odczycie.

    Zastosuję :)
  • Computer ControlsComputer Controls
  • VIP Zasłużony dla elektroda
    Powiem tak - można PWM do 1MHz, ale IRLZ44 na bramce 100Ω podłączony bezpośrednio do µC, żadnych dodatkowych NPN.
  • Poziom 17  
    LordBlick napisał:
    Powiem tak - można PWM do 1MHz, ale IRLZ44 na bramce 100Ω podłączony bezpośrednio do µC, żadnych dodatkowych NPN.

    Czyli układ bufora pradowego + ten mosfet mógł resetować atmege?

    Tak czy siak zastosuje ten tranzystor, bo można go "otworzyć" dzieki 5V :) szkoda, że go wcześniej nie znałem.
  • Poziom 17  
    A co w związku z dziwnie działającym timerem?
  • Użytkownik usunął konto  
  • VIP Zasłużony dla elektroda
    1MHz to taktowanie licznika od PWM, rzeczywista częstotliwość to ok. 4kHz... ;)
  • Użytkownik usunął konto  
  • Poziom 17  
    albertb napisał:
    I radiator większy trochę trzeba.

    Dlaczego? Rds(on) ma dużo mniejsze 0.077 vs. 0.028 Ohm
  • Poziom 36  
    Mariojas napisał:
    albertb napisał:
    I radiator większy trochę trzeba.

    Dlaczego? Rds(on) ma dużo mniejsze 0.077 vs. 0.028 Ohm


    Dlatego, że te wartości odnoszą się do warunków statycznych przy pełnej saturacji tranzystora.
    W warunkach dynamicznych wygląda to nieco inaczej.
    Przy załączeniu np. silnika prąd rozruchu jest dość duży, a w tym momencie Rds(on) jest jeszcze tez stosunkowo wysoki i na tranzystorze wydzieli sie pewna moc powodując jego grzanie.
    Porównaj dane dynamiczne w tabeli oraz timingi Fig.10b w datasheet:

    http://www.vishay.com/docs/91328/91328.pdf

    e marcus
  • Poziom 17  
    No to tak rozumiem. 0.028 Ohm jest tylko "w najlepszych warunkach", czyli przy pełnym otwarciu tranzystora. Ale tak na logike biorąc to skoro jest mniejsza rezystancja, czasy tr i td są zbliżone to powinno sie mniej grzać.

    Ale wracając do sedna sprawy.
    LordBlick napisał, że mogę ustawić większą częstotliwość PWM jeśli zastosuje tranzystor o którym mowa wyżej. Po przeczytaniu poradnika o MOSFETach troche nie chce mi się wierzyć, że przy takich częstotliwościach można podłączyć go bezpośrednio pod mikroprocesor. Wydaje mi się, że wydajność prądowa dla ładowania/rozładowania pojemności bramki będzie za niska.
    Aczkolwiek widząc tytuł "Zasłużony dla elektroda" miałem wrażenie, że wie co mówi.

    Problem z wyższymi częstotliwościami jest tylko taki, że Atmega mi się resetuje, więc tutaj jest moje pytanie czy zmiana tranzystora cokolwiek da. Tym bardziej, że owe resetowanie się układu występuje tylko pod obciążeniem.

    Proszę nie odebrać mojego podejścia jako ignoranta. Chciałbym zrozumieć dlaczego tak, zamiast robić to co inni każą bez przemyślenia.

    Pozdrawiam
  • Poziom 38  
    Po pierwsze- narysuj ten schemat po ludzku.
    Po drugie- prowadzenie masy i zasilania "w układzie gwiazdy".
    Od zasilacza poprowadzone oddzielnie przewody do części sterującej i wykonawczej.
    Precyzyjniej- od + i - kondensatora umieszczonego przy wyjściu prostownika a do części wykonawczej + po stabilizatorze.
    Czy "-" przed czy po stabilizatorze- to zależy czy będę mógł odczytać schemat.
    Przewody- skrętka ekranowana- takie jak do połączenia falowników z silnikiem.
    Można to wykonać chałupniczo- skręcając dwa przewody i owijając je paskiem aluminium- albo kupić gotowe prościej- lapp-kabel albo szybsza dostawa ale drożej- elfa.
    Możesz narysować schemat z ukośnie idącymi połączeniami- ale tylko wtedy gdy w ten sposób zaznaczysz że masz połączenie "w gwiazdę".
    Używanie wolnych i o małym wzmocnieniu tranzysrorów BD mija się z celem.
    Powinny być BC337/327.
    Opornik do bazy pierwszego tranzystora powinien być ok. 1kohm i równolegle do niego speed-up capacitor 100p-1nF.
    W szereg z bramką tranzystora IRF540- opornik 10-100ohm- można obliczyć.
    Przekaźniki- nie potrzeba mosfetów- ale nic więcej nie mogę z tego odczytać.
    To powinno się resetować stale- a nie co jakiś czas.
  • Poziom 17  
    janbernat napisał:
    Po pierwsze- narysuj ten schemat po ludzku.

    Na razie najistotniejsze elementy. W wolnym czasie dokończę schemat i zaprojektuję płytkę (wtedy ją wstawię do oceny).
    Jeśli chodzi o złacze P2:
    1 - +12 zasilania silnika
    2 - masa zasilania silnika
    3 oraz 4 - zaciski silnika
    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    janbernat napisał:
    Od zasilacza poprowadzone oddzielnie przewody do części sterującej i wykonawczej.

    Mam oddzielny zasilacz dla części sterującej i wykonawczej. A dokładniej silnik zasilany jest z jednego transformatora 100W 12V (podłączanego do sieci poprzez dodatkowy przekaźnik w momencie rozpoczęcia ruchu). Mikroprocesor i przekaźniki z oddzielnego zasilacza (trafo 9V + to co za złączem P1).

    Przy projekcie płytki wezmę pod uwagę wszystkie rady.

    Ponowię pytanie, czy rozdzielenie płytki na dwie, z rozdzieleniem głównie bloku sterowania oraz wykonawczego (przekaźniki + tranzysory + "mosfet") ma jakikolwiek sens? Rozdzielenie polegałoby na zaprojektowaniu dwóch oddzielnych płytek i połączeniu ich "jedna na drugiej" poprzez dystanse.

    Pozdrawiam
  • Moderator Mikrokontrolery Projektowanie
    Mariojas napisał:
    Ponowię pytanie, czy rozdzielenie płytki na dwie, z rozdzieleniem głównie bloku sterowania oraz wykonawczego (przekaźniki + tranzysory + "mosfet") ma jakikolwiek sens? Rozdzielenie polegałoby na zaprojektowaniu dwóch oddzielnych płytek i połączeniu ich "jedna na drugiej" poprzez dystanse.

    Takie działania zawsze powodują zysk w postaci większej odporności na zakłócenia, choć nie dają 100% gwarancji eliminacji zakłóceń.
  • VIP Zasłużony dla elektroda
    Mariojas napisał:
    LordBlick napisał, że mogę ustawić większą częstotliwość PWM jeśli zastosuje tranzystor o którym mowa wyżej. Po przeczytaniu poradnika o MOSFETach troche nie chce mi się wierzyć, że przy takich częstotliwościach można podłączyć go bezpośrednio pod mikroprocesor. Wydaje mi się, że wydajność prądowa dla ładowania/rozładowania pojemności bramki będzie za niska.
    Aczkolwiek widząc tytuł "Zasłużony dla elektroda" miałem wrażenie, że wie co mówi.
    Pisałem o podłączeniu bezpośrednim rezystora do bramki, nie µC... ;) Tym niemniej muszę się sam skorygować. Nieprzekraczalny max. w/g noty katalogowej to 40mA, więc 100Ω to trochę za mało. Obciążalność prądowa wyjścia PWM przy napięciu zasilania µC 5V to 20mA i tego należałoby się trzymać przy dalszych obliczeniach z użyciem pojemności bramki - rezystor 240Ω. Pojemność bramki IRLZ44 w/g noty katalogowej to około 3,3nF. Otrzymana stała czasowa nie może być większa od połowy okresu przebiegu PWM. Stała czasowa wynosi w tym przypadku 0,792 µs. daje to nam teoretyczny okres 1,584µs. Przy tym okresie mamy teoretyczną częstotliwość 631,313kHz. Uwzględniając wszelkie inne zjawiska mogące zajść, spokojnie 4kHz można gonić z µC przez rezystor 240Ω na bramce.
  • Użytkownik usunął konto  
  • Poziom 17  
    Ale stosując bufor, który sam używam to ten problem mija. Bufor mógłby dać kilkadziesiąt większy prąd niż 10mA.
  • Użytkownik usunął konto  
  • Poziom 17  
    Odrobiłem wreszcie pracę domową.

    Rozdzieliłem część sterowania od wykonawczej na dwie oddzielne płytki.

    Płytkę części sterującej zamierzam wykonać w firmie produkującej prototypowe PCB. Część wykonawczą zrobię samodzielnie.

    Proszę o ocenę pod kątem poprawności elektrycznej (poprawność schematu) oraz prowadzenia ścieżek. Chętnie wysłucham rad dotyczących estetyki prowadzenia ścieżek, ponieważ u mnie na uczelni za wiele na ten temat nie mówiono. :)

    Część sterująca:
    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    Część wykonawcza:
    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    PS. Nie bardzo wiem jak lepiej podzielić się swoją pracą, tak aby było to czytelne.
  • Poziom 21  
    Ojojoj ... myślę sobie ... :)

    Tu masz pełne sterowanie silnikiem DC za pomocą timerów i pwm :

    [Atmega8][C/AVR Studio 5] Sterownik bramy, niezrozumiałe zachowanie się uC

    Oraz kod :

    Code:

    #include <avr/io.h>
    #include <delay.h>
    /* quartz crystal frequency [Hz] */
    #define xtal 1000000L

    #define increaseButton_PRESSED           !(PIND & 0x40)
    #define increaseButton_OPEN                  (PIND & 0x40)
    #define decreaseButton_PRESSED           !(PIND & 0x80)
    #define decreaseButton_OPEN                  (PIND & 0x80)
    #define DIRECTION_FORWARD               !(PIND & 0x20)
    #define DIRECTION_REVERSE                 (PIND & 0x20)
    #define STOP_MOTOR                     TCCR1B = 0x00; TCCR1A = 0x00
    #define START_MOTOR                     TCCR1B = 0x09
    #define set_FORWARD                     TCCR1A = 0x81
    #define set_REVERSE                     TCCR1A = 0x21

    //defining macros for setting minimum and maximum PWM counter values
    //and step-size for controlling the voltage applied to MOSFETs base
    #define COUNTER_LOWER_LIMIT               0x0090
    #define COUNTER_UPPER_LIMIT               0x00f8
    #define   STEP_SIZE                     0x0008

    void port_init(void)
    {
     PORTB = 0x00;
     DDRB  = 0x06; //PWM pins OC1A & OC1B defined as outputs
     PORTC = 0x00;
     DDRC  = 0x00;
     PORTD = 0xE0; //internal pull-up enabled for three pins connected to switches
     DDRD  = 0x00;
    }

    //TIMER1 initialize - prescale:1
    //PWM Frequency: 1KHz
    void timer1_init(void)
    {
     TCCR1B = 0x00; //stop
     TCNT1H = 0xFC; //setup
     TCNT1L = 0x18;
     OCR1A  = COUNTER_LOWER_LIMIT;
     OCR1B  = COUNTER_LOWER_LIMIT;
     ICR1H  = 0x03;
     ICR1L  = 0xE8;
     TCCR1A = 0x81; //set forward; OC1A connected, OC1B disconnected
     TCCR1B = 0x09; //start Timer
    }

    //call this routine to initialize all peripherals
    void init_devices(void)
    {
     #asm("cli");//stop errant interrupts until set up
     //disable all interrupts
     port_init();
     timer1_init();

     MCUCR = 0x00;
     GICR  = 0x00;
     TIMSK = 0x00; //timer interrupt sources
     #asm("sei"); //re-enable interrupts
     //all peripherals are now initialized
    }


    //************************ main ***************************

    void main(void)
    {
     unsigned int counter = COUNTER_LOWER_LIMIT;
     unsigned char dir = 0, dir1 = 0;
     
     init_devices();
     
     while(1)
     {
       CHECK_PB:
       while(increaseButton_OPEN && decreaseButton_OPEN)   
       {                      //loop here until any push-button is pressed
         if(DIRECTION_FORWARD)      //check for Direction control switch status
             dir = 0;
         else
             dir = 1;
         if(dir != dir1)         //chenge direction if switch position has changed
         {
             STOP_MOTOR;
             delay_ms(500);
             if(dir == 0)
             set_FORWARD;
             else
             set_REVERSE;
             START_MOTOR;
          dir1 = dir;
         } 
       }   
       
       if(increaseButton_PRESSED)         //Speed-increase push-button is pressed
       {
         delay_ms(20);                    //key debouncing delay after key-pressed
         if(increaseButton_OPEN) goto CHECK_PB;
         while(increaseButton_PRESSED);     //wait here till the push-button is kept pressed
         delay_ms(20);                  //key debouncing delay after key released
         
        if(counter >= COUNTER_UPPER_LIMIT) //if speed is already maximum, don't do anything
            counter = COUNTER_UPPER_LIMIT;
        else   
          counter += STEP_SIZE;           //increase speed by a fixed step
         
        OCR1A = counter;
        OCR1B = counter;
       }
       else                                    //speed-decrease push-button is pressed
       {
         delay_ms(20);                    //key debouncing delay after key-pressed
         if(decreaseButton_OPEN) goto CHECK_PB;
         while(decreaseButton_PRESSED);     //wait here till the push-button is kept pressed
         delay_ms(20);                  //key debouncing delay after key released
         
        if(counter <= COUNTER_LOWER_LIMIT)   //if speed is already minimum, don't do anything
            counter = COUNTER_LOWER_LIMIT;
        else   
          counter -= STEP_SIZE;           //reduce speed by a fixed step
         
        OCR1A = counter;
        OCR1B = counter;
       }
         
     }
    }

    //******************************  END  ***************************************

    [img]
  • Poziom 17  
    Dzięki wielkie za chęci, ale nad mostkiem H myślałem. 4 grzejniki zamiast 1? Wole moją opcję z przekaźnikami. Soft - może coś z tego wyciągne, ale ogólnie załatwia jedynie małą część funkcjonalności, którą mam u siebie, a chcę ją jedynie doprowadzić do porządku.

    Nikt nie oceni mojej pracy? Czy jest to strzeżona wiedza, czy po prostu nikt nie jest w stanie powiedzieć jednoznacznie, że to będzie dobre rozwiązanie?
  • Poziom 21  
    1 przekaźnikiem nie zmienisz sobie polaryzacji i muszą być 2 i dodatkowo mosfet,
    aby zmieniać polaryzacje silników, pasuje dodać trzeci do odcinania zasilania
    tak więc wydaję mi się że lepiej dać 4 mosfety ...

    Piszesz o problemie niedojeżania bramy - zapisujesz wartość
    licznika z impulsatora. Sprawdź poprawność zapisu po tym czasie co się psuje

    Proponuje Ci najpierw skontrolować ten zapis zmiennej kończącej bieg bramy.
    Pasowało by też oglądnąć jak wygląda zapis z impulsatora (czy za każdym razem
    masz podobną wartość - impulsatory czasem przekłamuja i to sporo)

    AHA: nie licz czasu tylko ilość impulsów.
  • Poziom 17  
    djkomprez napisał:
    1 przekaźnikiem nie zmienisz sobie polaryzacji i muszą być 2 i dodatkowo mosfet,
    aby zmieniać polaryzacje silników, pasuje dodać trzeci do odcinania zasilania

    nie wiem czy to wytknięcie przesadzenia z przekaźnikami, ale dopiszę, że mam tak to rozwiązane i taka opcja mi odpowiada.

    djkomprez napisał:
    Piszesz o problemie niedojeżania bramy - zapisujesz wartość
    licznika z impulsatora. Sprawdź poprawność zapisu po tym czasie co się psuje

    Proponuje Ci najpierw skontrolować ten zapis zmiennej kończącej bieg bramy.
    Pasowało by też oglądnąć jak wygląda zapis z impulsatora (czy za każdym razem
    masz podobną wartość - impulsatory czasem przekłamuja i to sporo)

    AHA: nie licz czasu tylko ilość impulsów.

    W tym temacie nie pytam o to co zrobić żeby dobrze liczyło (impulsatora w pierwotnym układzie w ogóle nie ma!) tylko o to (do czego doszedłem po pewnym czasie), aby dobrze zaprojektować płytkę.
    Jak pisałem, miałem problemy z działaniem przetwornika ADC, Timerami oraz zakłóceniami w czasie pracy PWM.
  • Poziom 21  
    Ja nic Ci nie wytykam :) po prostu ja bym to zrobił inaczej ... prościej bez analogówki :)
    Masz byka do potęgi w schemacie na dzielniku napięcia na ADC - ładujesz 12v na port
    i dziwisz się że Ci się to pali ?

    Daj do masy 1k, drugi 10k = to przy 12V da CI ok 1V

    i jeszcze PS. jeśli tam na port szło pełne napięcie to mogło to
    powodować błędy pracy całej reszty
  • Poziom 17  
    djkomprez napisał:
    Masz byka do potęgi w schemacie na dzielniku napięcia na ADC - ładujesz 12v na port
    i dziwisz się że Ci się to pali ?

    Nie pytaj sie mnie czy sie dziwie, że sie pali. Pewnie to odczytałeś z najnowszego schematu. Otóż tego jeszcze nie zastosowałem. Wymyśliłem, że można by było odczytywać spadek napięcia na tranzystorze. Pytałem czy tak można. Teraz sobie zdałem sprawę że nie, bo gdy tranzystor będzie zatkany to pojawi się +12V.
    Port się pali (chyba pali, w każdym bądź razie działanie ADC się zmienia :) ) gdy mierzę napięcie na rezystorach R1 i R2, wg nowego schematu.
  • Poziom 21  
    Spadek napięcia odczytuj na rezystorze wpiętym w szereg z zasilaniem na silnik 0,1ohma 5W (oczywiście z tym dzielnikiem o którym pisałem)
    możesz to zastosować właśnie do pomiaru tzw. bezpiecznego wyłączenia po napotkaniu przeszkody :)
  • Poziom 17  
    Ależ tak właśnie czynię ;)