poniedziałek, 4 kwietnia 2011

SmartPIP: Czujnik światła - opóźnienie pomiaru


Autor: Dondu

Artykuł jest częścią cyklu: SmartPIP - Elektroniczny dręczyciel

W poprzednim artykule ustaliliśmy, że będziemy odłączać rezystor od masy, by zachowywać stan ładunku w kondensatorze pomiarowym i nie tracić energii baterii na ponowne jego ładowanie.

Zwróciłem także uwagę na to, że po włączeniu czujnika powinniśmy odczekać chwilkę, by sygnał na wyjściu czujnika zdążył się ustabilizować, ponieważ mogą nastąpić trzy sytuacje, w których napięcie aktualnie ustalone przez fototranzystor i rezystor:
  1. odpowiada napięciu na kondensatorze,
  2. jest niższe od napięcia na kondensatorze,
  3. jest wyższe od napięcia na kondensatorze,.

W przypadku nr 1, można by dokonać pomiaru zaraz po włączeniu czujnika, jednak w pozostałych dwóch przypadkach (2 i 3) należy zaczekać, aż kondensator ustabilizuje napięcie na wyjściu czujnika. 

Innymi słowy jest potrzebne nam opóźnienie.





Czas trwania opóźnienia

Musimy więc ustalić, jak duże powinno być opóźnienie (czas stabilizacji) po włączeniu czujnika. Czas ten zależy jest od:
  • aktualnego ładunku zgromadzonego w kondensatorze,
  • stopnia oświetlenia fototranzystora,
  • wartości kondensatora
  • wartości rezystora,

Wnioskować więc należy, że czas stabilizacji może być różny i nie jesteśmy w stanie przewidzieć kiedy, który przypadek wystąpi. Nie pozostaje nam nic innego jak przyjąć jakiś stały odcinek czasu.

Stały odcinek czasu, ale jak długi? Możemy go spróbować obliczyć.


Ładowanie kondensatora

Dla przypadku, gdy kondensator jest rozładowany i następuje jego ładowanie przez fototranzystor czas potrzebny na naładowanie się kondensatora do stabilnej wartości napięcia odpowiadającego aktualnemu poziomowi oświetlenia czujnika, zależy właśnie od tego jak bardzo czujnik jest oświetlony. Stwierdziliśmy to na podstawie datasheet w tym artykule.

Prąd, który ładować będzie kondensator będzie z reguły wielokrotnie większy, niż ten który będzie go rozładowywał (prąd rezystora). Dlatego spokojnie możemy pominąć obliczenia dla tego przypadku.


Rozładowanie kondensatora

Dla przypadku rezystora i kondensatora (układ RC) zakładając, że kondensator jest naładowany maksymalnie, a rezystor musi go rozładować do zera musimy obliczyć stałą czasową układu RC.

Wzór stałej czasowej jest następujący:




a wyrażana jest w sekundach.

Wcześniej określiliśmy wartość rezystora na 270kΩ, a wartość kondensatora przyjąłem doświadczalnie na 4,7nF. Wyznaczamy więc naszą stałą czasową:




Co oznacza ta stała? Oznacza ona, że w czasie zbliżonym do 1,3ms (milisekundy) kondensator rozładuje się do około 37% swojej pojemności. My jednak chcemy obliczyć kiedy rozładuje on całkowicie, a nastąpi to dopiero po czasie zbliżonym do 5 wartości τ :


Rys. Wykres rozładowania kondensatora
źródło: Wikipedia

W związku z tym, nasz czas opóźnienia pomiaru powinien wynosić:




Reasumując:
  • po włączeniu czujnika należy odczekać co najmniej 6,5ms i dopiero dokonać pomiaru światła,
  • jeżeli zastosujesz inne wartości RC powinieneś zastosować inne opóźnienie pamiętając, że włączony czujnik zużywa baterię, stąd należy zastosować możliwie najkrótsze opóźnienie.





Jak zrealizujemy opóźnienie pomiaru?

Dla przypomnienia, w SmartPIP'ie wykorzystujemy Timer2 pracujący w trybie asynchronicznym, w celu odliczania 8 sekundowych odstępów czasowych i to on będzie nam dawał sygnał (przerwanie) do rozpoczęcia procedury pomiaru (włączenia czujnika).

Dla odmierzenia opóźnienia 6,5ms moglibyśmy więc wykorzystać w programie jakąś funkcję opóźnienia delay(), ale to oznaczałoby, że w tym czasie mikrokontroler jest w trybie pracy i zużywa niepotrzebnie energię baterii, pobierając ponad 1mA prądu. Tę możliwość odrzucamy definitywnie.

Należy więc znaleźć inne rozwiązanie. Widzę tutaj dwie możliwości:

Wersja 1

W momencie, w którym należy wykonać pomiar oprócz włączenia czujnika włączmy dodatkowy timer np. Timer0 i usypiamy mikrokontroler. Timer0  odliczy nam czas około 6,5ms i wybudzi mikrokontroler w celu wyłączenia samego siebie i zlecenia dokonania pomiaru światła przez ADC.

W ten sposób w czasie czekania na ustabilizowanie się napięcia mierzonego, mamy uśpiony mikrokontroler i włączony główny Timer2 oraz pomocniczy Timer0. Takie rozwiązanie zużywa znacznie mniej energii niż aktywny mikrokontroler odliczający opóźnienie za pomocą funkcji delay().


Wersja 2

Standardowo Timer2 pracując w trybie asynchronicznym jako nasz zegarek czasu rzeczywistego ustawiony byłby w tryb pracy Normal, w którym po prostu odliczałby kolejne sekundy (w pakietach po 8 sekund). Nic nie stoi jednak na przeszkodzie, by nadal będąc w trybie asynchronicznym, korzystać z innych trybów pracy jakie umożliwia ten timer. Zaglądamy więc do datasheet:




Proponuję przyglądnąć się trybowi Fast PWM, który jak zapewne już wiesz pozwala oprócz generowania przerwania w momencie przepełnienia, także na zgłaszanie drugiego przerwania w momencie, w którym licznik timera (TCNT2) zrówna się z rejestrem komparatora (OCR2).

Co nam to da?

Ustawimy Timer2 w taki sposób, by poprawnie odmierzał założone odcinki czasu, ale jednocześnie był w stanie wygenerować nam dodatkowe przerwanie, odliczając ustalone przez nasz opóźnienie niezbędne do ustabilizowania się napięcia na wyjściu czujnika.

Innymi słowy, Timer2 da nam:
  • przerwania co 8 sekund niezbędne do prawidłowego odliczania czasu rzeczywistego (zegarek),
  • przerwanie opóźnienia pomiaru po włączeniu czujnika.

W ten sposób zaoszczędzimy jeszcze więcej energii niż w pierwszej proponowanej powyżej wersji.


Jaką wartość powinien mieć rejestr OCR2?

Pozostało nam policzyć, jaką wartość powinniśmy ustawić w rejestrze OCR2, by Timer zgłosił przerwanie po upływie 6,5ms od przerwania przepełnienia timera.

Ustaliliśmy wcześniej, że ośmiobitowy Timer2 będzie pracował z kwarcem 32768Hz i z preskalerem 1024. Obliczmy więc, jaki czas przypada na jednostkę czasu odliczanego przez timer:




Czyli zmiana licznika timera o 1 wykonywana jest co 31,25ms. My natomiast potrzebowaliśmy zaledwie 6,5ms. Niestety mniej nie jesteśmy w stanie uzyskać (nie da się ustawiać ułamkowych wartości licznika) stąd czas naszej zwłoki wynosić będzie  31,25ms.

Można byłoby się zastanowić, czy z punktu widzenia oszczędzania energii lepszą opcją jest jednak wykorzystanie innego timera do odliczenia tego czasu.

Ja jednak przyjmę, że wykorzystamy tylko Timer2.


W trybie FastPWM przerwanie przepełnienia Timera2 zgłaszane jest, gdy osiągnie on maksymalną wartość:


czyli w naszym wypadku 255 (bo Timer2 jest ośmiobitowy).

Skoro więc przerwanie opóźnienia ma być jeden cykl Timera2 później, to tym momentem jest stan, w którym Timer2 jest równy zero, czyli TCNT2 = 0. W tym momencie powinno nastąpić przerwanie opóźnienia. Aby to nastąpiło rejestr OCR2 musi mieć taką samą wartość, czyli zero (OCR2=0).

Innymi słowy przerwanie odliczające odcinki czasowe co 8 sekund zostanie wywołane, gdy Timer2 będzie miał wartość 255, a przerwanie opóźnienia pomiaru, gdy będzie miał wartość 0.

Przerwanie opóźnienia, będziemy oczywiście włączać tylko wtedy, gdy będzie nam potrzebne, by niepotrzebnie nie wybudzało mikrokontrolera.


Artykuł jest częścią cyklu: SmartPIP - Elektroniczny dręczyciel

1 komentarz:

  1. Drobna uwaga odnośnie użycia innego timera do budzenia w celu wykonania pomiaru. Odpada, bo tylko timer 2 może wybudzić ze stanu uśpienia.

    OdpowiedzUsuń