Witam, Próbuje napisać program do sterowania "inteligentnym" oświetleniem schodów, tzn. oświetlenie ma się zapalać w zależności od tego z której strony będzie się wchodziło na schody od dołu do góry luz z góry na dół. Moim problemem jest to, że chciałbym wykorzystać przerwania zewnętrzne INT0 i INT1 pochodzące z czujników ruchu. Nie za bardzo wiem jak to zrobić jak powinien wyglądać program obsługi tych przerwań. Czy mógłby mi ktoś pomóc i napisać jakiś prosty program obsługujący przerwania zewnętrzne z INT0 i INT1 tak zeby na wyjściu zapaliła się dioda? Pomogło by mi to w rozwiązaniu mojego problemu bo bym sobie to już potem próbował dostosować do swojej aplikacji oraz było by to pomocne dla mnie w lepszym zrozumieniu działania przerwań zewnętrznych.
|
|||
Odp. Przerwania INT0 i INT1
Nie napisałeś kolego w jakim języku chcesz to napisać. Jeśli w BASCOM to mogę Ci pomóc.
Wejścia zewnętrznych przerwań musisz w mikrokontrolerze skonfigurować czyli wybrać czy reagować mają na opadające zbocze, wzrastające czy może na cały czas gdy dany stan się utrzymuje. Zazwyczaj będzie to "Falling" czyli opadające. Impuls masy wywoła sygnał przerwania.
Potem musisz te przerwanie włączyć a na samym końcu włączyć przerwania ogólnie wszystkie.
Trzeba tez poinstruować mikrokontroler co ma zrobić gdy wykryje przerwanie. Do tego służy instrukcja OnINTx - i tu etykieta podprogramu do którego ma skoczyć.
Port pod wejście przerwania ustawiasz jako wejście i jeśli wybierasz wyzwalanie masą to podciągasz go wewnętrznym rezystorem żeby był w stanie wysokim.
Program obsługi przerwania powinien być jak najkrótszy i zawsze kończy się powrotem do miejsca w którym został wywołany. Najlepiej jeśli w obsłudze przerwania zaznaczysz tylko jakoś jego zaistnienie ustawiajac flage lub zmienną, ale do przykładu może być tak.
BARTek
Moja strona
Próbuje programować w miarę
Próbuje programować w miarę możliwości. Wykorzystuje do tego Bascoma. Dzięki wielkie za ten program jestem pewien, że jak go uruchomie i zacznę testować to mi się wiele wyjaśni.
Odp. Przerwania zawnętrzne
Tam za dużo do testowania nie ma :D Po podaniu impulsu masy na jedno z wejść INT mikrokontroler zapala odpowiednią diodę i gasi drugą. I tak na przemian.
Ważniejsze byłoby żebyś napisał na jakim mikrokontrolerze testujesz.
W nocie aplikacyjnej Twojego procesora trzeba sprawdzić na którym pinie są wejścia.
Możesz też napisać ile ma być punktów światła i jak widzisz funkcjonalne ich działanie.
Tak jak pisałem ten program u góry jest tylko dla przykładu jak włączyć przerwania zewnętrzne.
Przerwania są po to by procesor nie przeoczył jakiegoś zdarzenia gdy jest czymś zajęty, a najczęściej nie jest. Najczęściej wystarczy że z jakąś częstotliwością sprawdza stan portów.
Wydaje mi się że najwięcej czasu to zajmie logika programu :P Przemyśl jak ma się zapalać, jak gasić i co z tym gdyby ktoś zawrócił na schodach albo na schody weszły dwie osoby z dwóch stron lub jedna za drugą w odstępach czasu. Policz stopnie, zmierz czas przejścia schodów. Na wszelki wypadek przemyśl w programie "czasówke" jakby sterownik nie wykrył zejścia ze schodów.
Można podpatrzeć gotowe rozwiązania wpisując "sterowniki schodowe" w wyszukiwarke. Tu na forum jest jeden, nieskończony, projekt takiego sterownika z płynnym rozjaśnianiem się diod.
.. Pomysł jest ważny. Na pomoc w napisaniu możesz liczyć :D
BARTek
Moja strona
Testuje na Atmega8 z
Testuje na Atmega8 z wykorzystaniem płytki testowej ZL2AVR. Zakładam 8 punktów oświetlenia. Chciałem żeby się zapalały po kolei w zależności od kierunku wchodzenia/schodzenia ze schodów z jakąś zwłoką czasową. Zrobiłem pierwszą wersje programu lecz nie wykorzystuje w niej przerwań zewnętrznych. Na próby napisania programu z przerwaniami zewnętrznymi narazie nie mam czasu. W tym programie zastosowałem taką właśnie czasówkę która jest odpowiedzialna za gaszenie oświetlenia gdyby ktoś zawrócił ze schodów lub licznik zliczył więcej impulsów z czujnika przy wchodzenia niż przy schodzeniu, a co do rozwiązania kwestii jednoczesnego wchodzenia dwóch osób z dwóch stron to nie wiem jak wykonać. Gdy do takiej sytuacji dojdzie podczas trającego cyklu zapalania/gaszenia oświetlenia nie zostanie to wykryte przez to że w tym czasie nie będzie aktywny drugi czujnik. W programie wpisałem funkcję włącznika schodowego która powoduje zapalanie/gaszenie wszystkich punktów świetlnych jednocześnie. Zastosowałem fotorezystor aby nie dochodziło do załączania oświetlenia w przypadku gdy było by wystarczająco jasno.
Takim małym niedociągnięciem w tym programie jest to że wykorzystuje waitms co powoduje, że nie jest ustawiana flaga_60s po upłynięciu równych 60s. Myślałem jak by to można było poprawić i niestety nie wymyśliłem nic więcej jak to żeby wykorzystać do tego Timer2 tylko jak to zrobić w programie aby co 500ms dochodziło do zapalania/gaszenia kolejnego punktu oświetlenia. Ostatnio również przyszło mi do głowy jak zrobić taki "wyłącznik" jak by się znudziło komuś to oświetlenie i chciał korzystać tylko z oświetlenia głównego sufitowego według mnie to można to zrobić przez odłączenia od zasilania sterownika ale może jakaś możliwość programowa lub coś innego Ci przychodzi do głowy.
A to płynne rozjaśnianie się diod to jak się wykonuje bo wcześniej nie myślałem żeby to oświetlenie w ten sposób się zapalało, a teraz jak o tym myślę to wydaje mi się to ciekawe i sensowne.
"Inteligentne" oświetlenie schodów
Proszę. To szkielet sterownika oświetlenia schodów, podjazdów itp. Rozwiązanie programowego rozjaśniania i kolejnego włączania diod odgapiłem z projektu tu na forum. Mój jest pomysł na sterowanie tym. Program bazuje na tym w jakim aktualnie znajduje się stanie i na tej podstawie podejmuje działania. Jeśli więc na dole czujnik włączy oświetlenie to po kolei będzie włączał diody aż zapali wszystkie. Wtedy pamięta że uruchomiony był od dołu i w tej kolejności zgasi oświetlenie jeśli ktoś przejdzie schody lub po 120 sekundach. Analogicznie w drugą stronę. To szkielet, jak napisałem na początku. Teraz można dodać do niego mierzenie natężenia światła dziennego lub inne "ciekawostki" bo program zajmuje tylko 23% flasha.
Jeśli masz juz uruchomiony przetwornik ADC to możesz dodać potencjometr i wartość odczytaną z ADC wpisywac do Timera co da regulację szybkości rozpalania. Można w ten sposób sterować też Timeout`em.
Kluczowe wartości dla ułatwienia ich edycji są zapisane na początku listingu. Tak więc nie muszą to być "stałe" a zmienne.
Zauważ że program nie staje nigdy w miejscu i dopisując coś zrób podobnie np. dopisując jakiś status.
ADC najlepiej chyba czytać kilkakrotnie i uśredniać. Jeśli już da jakiś wynik np. "Jest dzień" to warto na jakimś programowym liczniku zrobić tak że dopiero kiedy dany odczyt powtórzył się kilkanaście razy to ma nastapić reakcja. Uchroni to przed reakcją na oświetlenie czujnika latarką lub flashem aparatu i nieprzewidzianych anomalii.
Program napewno trzeba "dopieścić". Sam nie mam takiej potrzeby, a nawet schodów :P
Może kiedys podjazd w stylu amerykanskym zrobie :D
Życzę miłego dnia. Jeśli byłoby więcej czujników to logikę można rozbudować :)
PS. W Twoim programie widać błędne podejście do ADC. Jeśli nie potrzebujesz przedstawić odczytu z ADC użytkownikowi to nie potrzebujesz tych przeliczeń ze zmienna Single. Po prostu 5V to 1024 ..więc 2,5V to około 500. To porównujesz i wystarczy ;)
EDYTOWANO : Poprawiłem kilka błedów które rzuciły mi się w oczy po zamieszczeniu kodu.
Flaga była 1 jest 0
Poprawiony dzielnik Timera0
Poprawiona kolejnośc w Case Select
Poprawiona obsługa PWM
Poprawione pod płytę ZL2AVR
BARTek
Moja strona
Super dzięki wielkie za ten
Super dzięki wielkie za ten "szkielet". Co do tego sterowania czasem zapalania oświetlenia to jeśli dobrze rozumiem to wartość nastawioną na potencjometrze mam podać na ADC i wartość odczytaną z ADC następnie przypisać do Timer2_load?
Mam pytanie co oznaczają
Mam pytanie co oznaczają cyfry po znaku równości w:
Const Oczekiwanie = 0
Const Oswietl_z_dol = 1
Const Oswietl_z_gor = 2
Const Zgas_w_dol = 3
Const Zgas_w_gore = 4
Const Oswietlone_z_dol = 5
Const Oswietlone_z_gor = 6
są to wartości które odpowiadają za coś konkretnego czy np. zmiana jakiejś wartości na inną spowoduje, że będzie to działało wtedy w jakiś inny sposób? Próbuje ogarnąć ten "szkic" i tak nie mogę zrozumieć skąd się wzięły akurat takie wartości
Sterownik schodowy
Const to stała w programie. Definiując je na początku mogę ich używać "po nazwach" co daje większą czytelność kodu dla każdego innego i dla mnie po czasie :)
Tak naprawde mógłbym napisać że "Status = 4" i tylko ja wiedziałbym co to znaczy. Status = Zgas_w_gore jest czytelniejszy a dla procesora oznacza 4. Zmiana tych wartości nic nie zmieni jeśli zawierać się bedą w przedziale do 255 i każda z nich będzie inna bo tutaj to unikatowe znaczniki. Używanie Const nic nie kosztuje a nawet własnie skraca kod gdy do jakiejś stałej odwołujemy sie więcej razy. Z każdego statusu możesz w każdym momencie przerzucić na inny i przy kolejnym przejściu pętli juz nowy bedzie brany pod uwagę. To są kolejne liczby, tu akurat, więc dopisując jakiś stan wybierz 7..8 itd.
Natomiast zmiana wartości Timeout_time u góry w programie, czyli w jednym miejscu, spowoduje że wszędzie gdzie zostanie użyta zostanie zmieniona w całym programie. Nie trzeba biegać po całym programie i szukać opóźnień. Zmieniasz raz i masz zmienione :P
Co do regulacji czasów potencjometrem.. Jeśli możesz to skompiluj to co juz jest do procka i przetestuj bo ja, prawdę powiedziawszy nie mam na czym :D
Napisz potem w jakim tempie sie rozswietlają diody, o ile chciałbys zwiększyć regulację. Właśnie Timer2_load nie powinno się ruszać bo on steruje oświetleniem a nie prędkością rozświetlania. Jeśli czas rozświetlania, czas Timeout`u i próg oświetlenia miałyby być regulowane to trzeba będzie ciut przepisać program.
BARTek
Moja strona
Ten szkic nie reaguje na
Ten szkic nie reaguje na żadne sygnały podawane z przycisków. Podejrzewam, że to może być przez to że nigdzie się nie odwołuje do zapalania poszczególnych pinów portu D. Chyba, że się mylę i gdzieś to jest w programie zapisane, a mi się wydaje, że tego nie ma
Sterownik schodowy
Program pracuje w stałej pętli, ale wyzwalany jest tylko co 100ms gdy ustawiona jest Flaga_100ms.
Flaga_100ms jest ustawiana gdy 250 razy przepełni się Timer0 który przepełnia sie co 4ms.
I tu chyba pierwszy błąd bo 250x4=1000. W przerwaniu zdejmij jedno zero ;)
Warunek ustawionej flagi tworzy "element opóźnienia" w programie.
Gdy warunek ustawionej flagi jest spełniony kontroler ma podjąć działania zależne od wartości zmiennej "Status".
Jeśli wynosi ona 0 czyli oczekiwanie to zwarcie pinu b.0 lub b.1 powoduje zmianę wartości zmiennej Status na 1 lub 2.
Przy kolejnym przejściu przez pętlę powinien wziąć już nową wartość zmiennej Status pod uwagę.
Jedyny pomysł jaki przychodzi mi teraz do głowy to to, że w funkcji Select Case wartości muszą wzrastać po kolei co jest w tym przypadku moim niedopatrzeniem.
Spróbuj zmienić ten fragment. Jeśli się nie pomyliłem to są poukładane po kolei.
Jeśli już ma zapalić diody to jak najbardziej odwołuje się do portu D ale poprzez wartość Iled każdej z diod. Wartość ta jest zwiększana przy każdym przejściu pętli. Od wielkosci tych zmiennych Iled zależy współczynnik wypełnienia który jest sprawdzany w przerwaniu Software_pwm. Wiec jeśli bedzie np. wynosił dla jakiejś diody 50 to bedzie porównywany z aktualna wartością zmiennej Licznik która tez sie zmienia od 0 do 100. Tu widze kolejny bug który należałoby sprawdzić. Teoretycznie powinno świecić ale można potem spróbowac wartość licznik zwiększyć by uzyskać większy stopień regulacji. Przerwanie Software_pwm dokonuje sie bardzo szybko więc niezauważenie zwiększa wartość zmiennej Licznik.
Najpierw spróbuj z tą kolejnością. Drugim testem może być pominięcie warunku "If Flaga_100ms = 1"
W zależności od tego czy diody na płytce uruchomieniowej sterujesz plusem lub masą to trzeba tak ustawić Set i Reset w obsłudze przerwania Software_pwm
BARTek
Moja strona
Po zmiane tej kolejności przy
Po zmiane tej kolejności przy długim trzymaniu przycisku zaczyna gasnąć powoli jedna dioda i tyle. a po usunieciu tego warunku na ustawiabie flagi podczas trzymania przycisku dioda cały czas na zmiene się włącza/ wyłącza a po puszczeniu świeci
Sterownik schodowy
Wartość Iled każdej diody po starcie wynosi 0. Nie powinny więc w ogóle świecić.
zamień na
..i tak do ósmego Ileda.
Pewnie wystarczyłoby zmienić znak "<" na ">"
Tego If`a z Flaga_100ms wstaw z powrotem. Możesz też testowo wyłączyc Timeout wstawiając "'" przed tymi liniamii
BARTek
Moja strona
Sterownik schodowy - błąd w PWM!
Kolego widze błąd kolejny :)
W obsłudze Software_pwm był błąd. Przed instrukcjami Else w każdym przypadku było Led1 zamiast kolejne diody!
Jako że mam taką możliwość to wszystkie poprawki naniosłem do pierwszego kodu. Ściągnij najlepiej nowy w całości.
BARTek
Moja strona
Program teraz już działa z
Program teraz już działa z tym, że rozświetlanie diod trwa długo ale próbowałem zmieniać wartość Timer0_load i po zmianach rozświetlanie przebiegało znacznie szybciej. Diody na mojej płytce w stanie spoczynku są lekko rozświetlone. Dla programu nie ważne ile osób wejdzie na schody bo i tak pierwsza osoba która z nich zejdzie spowoduje rozpoczęcie sekwencji gaszenia oświetlenia. Co do regulacji czasu rozświetlania za pomocą potencjometru to wartość z ADC w takim razie ma być podawana na timer0_load czy dobrze rozumiem? a żeby odmierzać wtedy ustaloną wartość czasu np. 1s to trzeba by było wykorzystać kolejny timer?
Sterownik schodowy z regulacją czasów.
Tak jak pisałem wcześniej program trzeba było trochę przepisać. Żeby zawsze liczył tak samo czasu Timera0 nie ruszałem. Jedynie program podzielony został na część która ze stałą częstotliwością jest w pętli co 100ms a część odpowiedzialna za rozświetlanie jest w podprogramie który wywoływany jest z częstotliwością zależną od nastaw potencjometru na ADC2. Czasem Timeout`u steruje ADC1, a czułością oświetlenia ADC0.
Teraz obsługa przerwania nie ustawia flagi a zajmuje się odczytem napięcia z trzech portów i zwiększaniem wartości potrzebnych do odmierzania czasów.
Odczytując napięcia robi to dziesięć razy po czym uśrednia. Maksymalnie może zrobić ponad 60 pomiarów do uśredniania i ustawiane jest to wartością Max_pomiar na początku. Zapis "
Suma(i + 1) = Suma(i + 1) + Probka
" jest dlatego że do tablic można zapisywać wartości dopiero od jedności, nie zera.Gdy już nazbiera pomiarów i je uśredni zgłasza gotowość i wtedy wartości sa przypisywane zmiennym. Można więc przyspieszyć rozświetlanie sie diod bo można zmniejszyć wartość zmiennej Speed. Regulowany jest też Timeout i badane nasłonecznienie.
Światło dzienne nie wyłacza nigdy oświetlenia a jedynie nie pozwala go włączyć. Zabezpiecza to przed zgaszeniem światła jakimś błyskiem.
Co do ilości osób na schodach to radzę Ci jej nie liczyć. Lepiej chyba zrezygnowac z gaszenia świateł po przejściu schodów, a w momencie gdy ktos jest na schodach i wchodzi kolejna osoba automatycznie odnawiać Timeout.
Daj znać jak działa ;) i jakby co napisz co jeszcze by się przydało.
PS. Diody pełnym blaskiem świeca już od wartości 100. Potem czekasz jeszcze 155 do rozpoczęcia rozświetlania kolejnej. Jeśli chcesz skrócić ten czas pomiędzy to trzeba zmienić wszystkie wartości "255" na mniejsze. To własnie byłoby dobre zastosowanie dla stałej gdyby zamiast 255 wpisac stałą. Zmieniłbyś u góry i załatwione.
BARTek
Moja strona
wszystkie diody lekko pulsują
wszystkie diody lekko pulsują w czasie gdy nic nie zadaje na przyciski. obecnie dysponuje tylko dwoma potencjometrami to nie wiem czy takie obiektywne te testy będą. Ale z tego co udało mi się zauważyć przy zastosowaniu tylko tych dwóch potencjometrów to regulacja prędkości rozświetlania jest strasznie czuła i delikatne skręcenie potencjometru powoduje duże skoki w wartości odczytywanej przez ADC. Regulacja nasłonecznienia działa raczej poprawnie. ADC2 odpowiada za to jak szybko jest wykonywany program?
Regulacje sterownika
Tak ADC2 to max 1024. Podzielone przez 40 daje max 25. Przedtem tez było własnie 25 x 4ms = 100ms. Zmniejszenie więc wartości o jeden to już wykonywanie co 96ms. Można pomyśleć nad innym rozwiązaniem albo to taki potencjometr jak ostatnio kupiłem za 25gr i przerywały :) Sa potencjometry precyzyjne jeszcze ;) Co do mrugania..to może czytanie kolejnych ADC trzeba będzie rozbić jak przy tramsmisji microwire i multipleksowanych wyświetlaczach ;)
Mam nadzieje że masz ta wersję z "Config PortC" bo w Twoim projekcie brakowało.
BARTek
Moja strona
Masz racje w moim programie z
Masz racje w moim programie z postu 4 nie ma konfiguracji portu C.
Sterownik schodowy z regulacją czasów ver.2
Przemyślałem kilka rzeczy, bo nie na wszystko wpada się od razu ;)
Teraz nie dość, że nie mierzy w przerwaniu to mierzy tylko wtedy gdy nic nie robi, czyli gdy czeka. Do tego PWM włączone jest tylko na czas rozjaśniania i ściemniania. Po zakończeniu tych operacji port przyjmuje stała wartość.
Niepotrzebny jest Bit "Zmierzono". Program dalej zajmuje 30%
Spróbuj. Diody nie mają prawa drgnać w spoczynku :D
BARTek
Moja strona
Program działa dobrze tylko
Program działa dobrze tylko słabo zauważalna jest ta regulacja szybkością rozjaśniania diod. Po za tym wszystko super wielkie dzięki za pomoc i za te programy.
Odp. Sterownik schodowy
Można jeszcze "oszukać przeznaczenie" :D
Do wartości Timer0_load dodać "w pamięci" 25.
132+25=157 i tę wartość zapisać jako stałą Timer0_load
W obsłudze przerwania zapisac tak:
Zmniejszając wartość mniej odejmujesz od wartości wstępnie ładowanej do Timera. Rozsynchronizuje to zegar tak że trzeba będzie dodac wartości Timeout.
Nie wiem też czy da się to zapisać w tej jednej linii. Może pomocnicza zmienna by się przydała. Można próbowac ;)
Można też spróbowac tak:
Skróci to odstępy pomiędzy kolejnymi diodami. Oczywiście trzeba "zakomentowac" na próbe zapis Const Iled_max = 200 i zadeklarować taką zmienną. Każdy z tych pomysłów możesz próbować odzielnie i zobaczyć który najlepiej pasuje. Razem będą chyba zbyt drastyczne :D
BARTek
Moja strona