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

Mikrokontroler sterujący pompą i przekaźnikami

HeavyGori 29 Kwi 2015 21:20 843 14
  • #1 29 Kwi 2015 21:20
    HeavyGori
    Poziom 10  

    Witam wszystkich
    Jest to mój pierwszy temat na forum, dopiero zaczynam zabawę z mikrokontrolerami i elektroniką więc proszę o wyrozumiałość, a teraz do rzeczy.

    Kolega poprosił mnie o zaprojektowanie precyzyjnego zestawu nawadniającego do szklarni w efekcie udało mi się zaprojektować (i w większości już stworzyć taki oto układ)
    Mikrokontroler sterujący pompą i przekaźnikami

    mózgiem systemu jest ATMEGA8, zdecydowałem się na zastosowanie uC aby wyeliminować efekt falowania wody (a tym samym podnoszenie i opadanie włącznika pływakowego co skutkowało kilkunastoma krótkimi włączeniami pompy przy każdym dolewaniu wody). W zbiornikach na wodę umieszczone są pływaki, jeśli wody jest za mało obwód jest zamykany i powinien być podany sygnał na uC do portu C z podciągnięciem do VCC.
    Wyjście z portu D idzie na tranzystory sterujące pracą poszczególnych przekaźników (6 przekaźników zabezpieczonych diodą przed "szpilkami" obsługuje 6 elektrozaworów 230V oraz 7 przekaźnik obsługuje pompę, która ma pracować razem z którymkolwiek z elektrozaworów) dodatkowo równolegle z przekaźnikami idą diody LED sygnalizujące pracę poszczególnych elektrozaworów.

    i teraz mam następujące pytania i problemy z tym układem:

    1. obsługi uC i elektroniki uczę się od około dwóch miesięcy amatorsko, więc czy ten układ ma sens i jest prawidłowo zaprojektowany. Wszelkie propozycje usprawnienia są mile widziane. Szczególnie interesuje mnie kwestia czy dobrze rozwiązałem podpięcie pływaków pod uC, wyczytałem że robienie "anteny" z uC to niezbyt dobry pomysł, więc długi odcinek przewodu pomiędzy pływakiem a układem obsługuje tylko tranzystor. Dodam, że opór najdłuższego odcinka wynosi max 4 ohm dla 20m przewodu w dwie strony.

    2.
    Mam problem z zaprogramowaniem układu, chciałbym uzyskać następujący efekt, w momencie gdy poziom wody opadnie pływak zamknie obwód, włączając pompę i wybrany elektrozawór. Woda w trakcie dolewania faluje i powoduje unoszenie i opadanie pływaka (kilkanaście razy pompa się wzbudza na ułamek sekundy). Rozwiązaniem problemu byłoby zaprogramowanie uC aby po pierwszym zwolnieniu przełącznika (pływak na fali do góry) układ dolewał wody jeszcze przez 4 sekundy, a potem uśpił pływak na 30-40 sekund aż woda się uspokoi i dalej będzie kontrolował poziom wody. Kod który stworzyłem jest następujący, lecz nie działa w pełni prawidłowo.

    Kod: cpp-qt
    Zaloguj się, aby zobaczyć kod


    3. mam problem z tranzystorami sterującymi przekaźnikami, sygnał wysyłany przez uC nie jest w stanie otworzyć tranzystora BC547 aby popłynęło przez niego 70mA przy 10V nawet po bezpośrednim podłączeniu wyjścia uC do bazy tranzystora, zmierzyłem prąd płynący w obwodzie przekaźnika, wynosi ~8mA a ma być 70mA. Jako ciekawostkę dodam, że gdy na bazę podam 5V bezpośrednio ze stabilizatora to przekaźniki pięknie działają - czy ktoś może mi wytłumaczyć dlaczego tak się dzieje i gdzie popełniłem błąd? natężenie wychodzące na bazę po zmierzeniu wyniosło ok 6mA więc wzmocnienie 12x na tranzystorze chyba jest osiągalne?

    To chyba tyle z moich pytań, mam nadzieje że konstrukcja się spodoba, jak skończę projekt to opisze go dokładnie w odpowiednim dziale.

    Pozdrawiam

    0 14
  • Sklep HeluKabel
  • Sklep HeluKabel
  • #3 29 Kwi 2015 22:27
    HeavyGori
    Poziom 10  

    Ok, dzięki za wytknięcie błędu ale nie pogardzę objaśnieniem co jest źle, to tylko kilka linijek kodu więc gdybyś wrzucił choć jedną napisaną poprawnie to wielce by to pchnęło sprawę do przodu,
    pozdrawiam.

    aa sorki, nie zauważyłem, że to jest link, już czytam.

    0
  • Pomocny post
    #4 30 Kwi 2015 13:43
    dondu
    Moderator Mikrokontrolery Projektowanie

    HeavyGori napisał:
    zdecydowałem się na zastosowanie uC aby wyeliminować efekt falowania wody (a tym samym podnoszenie i opadanie włącznika pływakowego co skutkowało kilkunastoma krótkimi włączeniami pompy przy każdym dolewaniu wody).

    Nie wystarczyło zastosować filtr RC?

    Dodaj na wszelki wypadek rezystor 10kΩ podciągający RESET do Vcc. Przy takich urządzeniach jak pompy i przekaźniki warto zadbać o taki szczegół.

    Rezystory R1-R6 są zbędne - włącz wewnętrzne rezystory pull-up na pinach mikrokontrolera.

    Ad. 1. nie zastanawiałeś się nad oddzieleniem zasilania i zastosowaniu optoizolacji - tak na wszelki wypadek przy tych długościach przewodów i ich umieszczeniu w szklarni?

    Ad. 2. Kol. tehaceole podał Ci link, w którym przedstawił jedno z wielu możliwych rozwiązań. Ale prosisz o wyjaśnienie więc:
    - wybierasz sobie jakiś wolny timer i ustawiasz go na przerwania np. co sekundę.

    - dla każdego czujnika masz jakąś zmienną odliczającą czasy najlepiej tablicę np. czas_czujnika[ilosc_czujnikow-1], u wypełniasz ją na początku zerami,

    - w funkcji przerwania sprawdzasz stany czujników i :

    ---- jeśli wykrywasz że czujnik sugeruje włączenie pompy, zwiększasz zmienną czujnika o jeden np.: czas_czujnika[nr_czujnika]++ i sprawdzasz:
    ------- czy zmienna osiągnęła wartość np. 3 (minęły 3 sekundy a czujnik nadal sugeruje włączenie pompy)? Jeśli tak, to włączasz pompę

    ---- jeśli wykryłeś, że czujnik zmienił stan z powrotem na "nie włączaj pompy", to zmniejszasz zmienną o jeden czas_czujnika[nr_czujnika]-- i sprawdzasz
    ------- czy zmienna osiągnęła wartość zero? Jeśli tak, to wyłączasz pompę

    ---- koniec funkcji przerwania.

    W algorytmie należy oczywiście zadbać o to, by przy długim włączeniu pompy zmienna odliczająca czas danego czujnika nie przepełniła się.

    Ad. 3. Czy wszystkie masy (GND) są podłączone razem?

    Przykład timera sterującego za pomocą przerwań diodą: http://mikrokontrolery.blogspot.com/2011/03/led-sterowany-przez-timer.html
    To będzie podstawa Twojego programu.

    Nie definiuj F_CPU w kodzie z tych powodów: http://mikrokontrolery.blogspot.com/2011/03/fcpu-gcc-gdzie-definiowac.html

    1
  • #5 30 Kwi 2015 17:39
    tehaceole

    Poziom 28  

    Unikniesz też wielu niespodzianek gdy zmienisz sposób sterowania tranzystorów na wejściach. Zamiast podawać stan wysoki przez pływak na bazę (masz piękną antenę z przewodu pływaka) podłącz rezystory bazowe na stałe do "+" a pływaki włącz pomiędzy bazy a masy. W ten sposób będziesz miał stabilny stan wysoki i układ nie będzie tak podatny na zakłócenia.

    dondu - optoizolacja to może przerost dla tego układu, ale na pewno przydałoby się zabezpieczenie napięć wychodzących poza płytkę np. bezpiecznikami polimerowymi.

    0
  • #6 30 Kwi 2015 22:13
    HeavyGori
    Poziom 10  

    Dzięki za zainteresowanie, układ wstępnie przetestowałem i póki co od strony technicznej wszystko pracuje, problemem jest jeszcze tylko napisanie odpowiedniego programu. Jak wcześniej wspominałem uC zajmuje się od 2-3 tygodni więc obsługa timerów i przerwań to jest ciągle dla mnie nowość, no ale trzeba się rozwijać :)

    Cytat:
    Nie wystarczyło zastosować filtr RC?


    uC daje większe możliwości sterowania czasem martwym i podtrzymaniem pracy pompy po napełnieniu zbiornika- tutaj będę to wyznaczał eksperymentalnie

    Cytat:
    Ad. 1. nie zastanawiałeś się nad oddzieleniem zasilania i zastosowaniu optoizolacji - tak na wszelki wypadek przy tych długościach przewodów i ich umieszczeniu w szklarni?


    jak tranzystory zawiodą to na pewno zastosuje optoizolacje, ale wbrew pozorom układ jest na tyle prosty że powinno działać prawidłowo na samych tranzystorach

    Cytat:
    Ad. 3. Czy wszystkie masy (GND) są podłączone razem?


    masy są wspólne

    Co do testowania to na razie załadowałem do uC najprostszy program przypisania wartości portu C do portu D i od strony technicznej wszystko działa, teraz tylko musze go przerobić aby występował wspomniane wcześniej opóźnienia.

    0
  • #7 30 Kwi 2015 22:28
    dondu
    Moderator Mikrokontrolery Projektowanie

    Optoizolację wskazałem jedynie jako jedno z możliwych rozwiązań, które przy cenach rzędu 0,30 zł za jeden transoptor jest niewiele droższa od tranzystora.

    HeavyGori napisał:
    Jak wcześniej wspominałem uC zajmuje się od 2-3 tygodni więc obsługa timerów i przerwań to jest ciągle dla mnie nowość, no ale trzeba się rozwijać :)
    ...
    teraz tylko musze go przerobić aby występował wspomniane wcześniej opóźnienia.

    Dasz radę - przykłady wskazaliśmy Ci - powodzenia :)

    0
  • #8 01 Maj 2015 19:23
    tehaceole

    Poziom 28  

    Nie zrażaj się Kolego początkowymi niepowodzeniami:) Każdy kiedyś zaczynał od zera. I każdy z nas w dalszym ciągu się uczy :) Przeanalizuj podrzucone materiały, wykonaj trochę ćwiczeń w oparciu o nie i zobaczysz, że to wcale nie jest takie straszne :)

    Powodzenia :)

    0
  • #9 02 Maj 2015 14:18
    HeavyGori
    Poziom 10  

    Wytrwałości mi nie brak, ale totalnie utknąłem w martwym punkcie przy błahostce, a mianowicie jak poprawnie zaprogramować uC aby PC0-PC5 był wejściami PD0 - PD5 wyjściami PB1 wyjściem i odpowiednio jeśli PC0 wciśnięty to PD0 ma stan wysoki etc... oraz PB1 ma stan wysoki zawsze gdy cokolwiek na lini PC jest wciśnięte (obojętnie czy PC0 czy PC3 czy wszystko na raz)

    kombinuje teraz w ten sposób i o ile PC i PD działa, tak PB ciągle albo jest włączone albo wyłączone (w zależności od negacji !)

    Kod: cpp-qt
    Zaloguj się, aby zobaczyć kod


    próbuje zastosować różne operacje i logiczne i bitowe ale bez pożądanego skutku, wcześniej próbowałem zastosować wielokrotne if

    Kod: cpp-qt
    Zaloguj się, aby zobaczyć kod


    w tym ustawieniu rzeczywiście PB1 pracowało razem z PC ale tylko w przypadku wciśnięcia PC5 na PB1 był "prąd maksymalny" w pozostałych przypadkach dioda lekko świeciła i prąd był o wiele za mały aby otworzył tranzystor i uruchomił przekaźnik- w tym miejscu będę wdzięczny za komentarz dlaczego PB1 działa na "pół gwizdka" i wyciąga tylko 3-4mA a jak wcisne PC5 to ~30-40mA (mierzone).

    0
  • #10 02 Maj 2015 15:59
    dondu
    Moderator Mikrokontrolery Projektowanie

    Na przykład:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    sprawdza, czy na pinie PC3 jest jedynka i jeśli tak, to ustawia stan wysoki na PB0 i stany niskie na pozostałych pinach portu B.

    Czytelniej jest tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Uruchom sobie poniższy kod w kompilatorze CManiak: http://mikrokontrolery.blogspot.com/p/cmaniak-kompilator-jezyka-c-online.html

    Kod: c
    Zaloguj się, aby zobaczyć kod


    ... i zmieniaj kod, kompiluj aż się nauczysz :)

    Możesz także prześledzić przykład dla ATmega8 który znajdziesz w kompilatorze w zakładce Przykłady.

    0
  • #11 02 Maj 2015 20:06
    HeavyGori
    Poziom 10  

    Cytat:
    sprawdza, czy na pinie PC3 jest jedynka i jeśli tak, to ustawia stan wysoki na PB0 i stany niskie na pozostałych pinach portu B.


    Z odczytaniem pojedynczego pinu i wykonaniem instrukcji nie ma problemu, to wiem jak działa, ale totalnie nie wiem jak ustawić polecenie aby sprawdzał kilka pinów (od PC0 do PC5) i wykonał polecenie w momencie gdy co najmniej jeden jest "wciśnięty".

    Tak jak sugerujesz bawiłem się funkcją if i przy budowaniu drzewka prawie działało (patrz post wyżej) natomiast jeśli próbowałem załatwić sprawę tak:

    Kod: cpp-qt
    Zaloguj się, aby zobaczyć kod


    na PB1 ciągle był sygnał 1 lub 0 (w zależności od użytego operatora, próbowałem użyć różnych i logicznych (&& ||) i bitowych (& |).

    Powyższy kod rozumiem następująco- porównuje stany PORTu C z maską 0x00, jeśli są takie same to PRAWDA, jeśli różne to FAŁSZ. Czyli gdy nic nie wciskam jest 0x00, maska ma tą samą wartość więc PRAWDA zmieniona na FAŁSZ przez ! - wykonuje polecenie PB1 0x00. Natomiast gdy wcisnę przycisk/przyciski to PORTC jest niezgodny z maską, mamy PRAWDA i wykonuje PB1 = 0x01

    Naprawdę siedzę nad tym już dobrych kilka godzin, różne kombinacje stosuje ale takiego efektu nie jestem w stanie uzyskać- żeby nie było, nie rezygnujemy :)

    0
  • #12 02 Maj 2015 20:56
    dondu
    Moderator Mikrokontrolery Projektowanie

    Widzę, że z CManiaka skorzystałeś 10 razy (10 kompilacji). Trochę mało - próbuj dalej :)

    Najlepiej to przerób sobie kurs C z CManiakiem: http://mikrokontrolery.blogspot.com/2011/02/kurs-jezyka-c-spis-tresci.html
    w szczególności if(), a przede wszystkim operacje bitowe.

    Wtedy sam dojdziesz dlaczego to :

    Kod: c
    Zaloguj się, aby zobaczyć kod

    nie wykonuje tego:

    HeavyGori napisał:
    Powyższy kod rozumiem następująco- porównuje stany PORTu C z maską 0x00, jeśli są takie same to PRAWDA, jeśli różne to FAŁSZ.


    Niestety podstawy C musisz poznać, bo za chwilę staniesz nad kolejnym błahym problemem.

    0
  • #13 03 Maj 2015 12:18
    HeavyGori
    Poziom 10  

    Hehe! zrobiłem :) co prawda na około, ale wreszcie kod działa tak jak ma być i przy każdej kombinacji płynie odpowiedni prąd.
    moja propozycja kodu to:

    Kod: cpp-qt
    Zaloguj się, aby zobaczyć kod


    Dodałem zmienne, proste dodawanie i jest ok, teraz muszę domontować do tego opóźnienia.

    0
  • #14 03 Maj 2015 12:32
    szwagros
    Poziom 30  

    Hmm..
    Nie można było po prostu:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    ?

    0
  • #15 03 Maj 2015 13:33
    HeavyGori
    Poziom 10  

    Właśnie nie mam pojęcia dlaczego, ale gdy programuje go w ten sposób, to dioda na PB1 ciągle jest zapalona, dopiero po naprawdę wielu kombinacjach, ta ze zmiennymi działa jak należy.

    0