Mikrokontrolery - Jak zacząć?

... czyli zbiór praktycznej wiedzy dot. mikrokontrolerów.
Pokazywanie postów oznaczonych etykietą EPP. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą EPP. Pokaż wszystkie posty

poniedziałek, 4 kwietnia 2011

SmartPIP: Czujnik światła - testowanie


Autor: Dondu


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

Nadszedł czas na przetestowanie opracowanego czujnika światła. Schemat układu testowego ograniczymy do niezbędnego minimum:

SmartPIP: Układ testowy czujnika światła.


Do powyższego schematu należy dodać jedną z wersji interfejsu RS-232, które znajdziesz tutaj: RS-232: Komunikacja ATmega8 z komputerem. Na schemacie zaznaczyłem etykietami MIKR-RXD oraz MIKR-TXD piny, które należy połączyć z pinami interfejsu RS-232 oznaczonych tymi samymi etykietami.

Zamiast RS-232 możesz wykorzystać wyświetlacz LCD, ale to już opracuj we własnym zakresie.

Dioda LED dodana jest wyłącznie w celach  testowych (np. gdyby terminal nie wyświetlał danych), więc nie musi być zamontowana. Jeżeli ją zamontujesz, to w kierunku zgodnym z powyższym schematem, by nie pobierała prądu z pinu mikrokontrolera. Rezystor diody LED oznaczony jako R2 jest nieco większy niż standardowy, ponieważ chcemy ograniczyć skoki prądu w czasie testów. Najlepszym rozwiązaniem będzie usunięcie diody w czasie, gdy terminal będzie prawidłowo odbierał dane.

Schemat naszego układu testowego w zakresie minimalnych podłączeń odpowiada wersji totalne minimum. Dlaczego stosujemy wersję "totalne minimum"? Ponieważ spokojnie wystarczy nam rozdzielczość pomiarowa 8-bitów, a dodatkowy kondensator na pinie AREF, to dodatkowa upływność, której nie chcemy w naszym SmartPIP'ie.




Opis algorytmu


Program przygotowany jest (jak w każdej części cyklu o SmartPIP'ie) w wersji wieloplikowej z podziałem na funkcjonalności:
  • pomiar światła,
  • komunikacja RS-232,
  • program główny.

W programie na razie nie wykorzystujemy jeszcze licznika czasu, a opóźnienie między pomiarami wykonujemy za pomocą funkcji _delay_ms(x). Jest to celowy zabieg uproszczenia programu testowego, który w wersji wieloplikowej jest i tak (na pierwszy rzut oka) wystarczająco skomplikowany :-). Licznik czasu będziemy używać już w następnym artykule, gdzie dokonywać będziemy pierwszych pomiarów dobowych.

Do testowania czujnika będziemy dokonywać pomiarów światła z uwzględnieniem wykorzystania usypiania mikrokontrolera do trybu ADC Noise reduction, który jak już ustaliliśmy będziemy wykorzystywać w celu zwiększenia dokładności pomiaru i redukowania pobieranego prądu z baterii.

Dla potrzeb tego testu na stałe włączymy elementy czujnika światła (zasilanie czujnika i masę rezystora).

Wyniki pomiarów będziemy obserwować za pośrednictwem komputera podłączonego do mikrokontrolera za pomocą prostego interfejsu RS-232. Algorytm wysyłania opracowany jest dla wersji opartej o przerwania i tablicę bufora tekstu w pamięci SRAM mikrokontrolera.






dd_swiatlo.c
dd_swiatlo.h


Pliki te zawierają funkcjonalności dot. pomiaru światła za pomocą naszego czujnika z wykorzystaniem przetwornika ADC.


dd_swiatlo_adc_ini()

Funkcja odpowiedzialna za przygotowanie do pomiarów, czyli:

Włączenie czujnika - ustawienie odpowiednich stanów na pinach zasilania fototranzystora oraz masy rezystora, według ustalonych wcześniej zasad.

Inicjalizacja przetwornika ADC - ustawienie parametrów przetwornika ADC realizowane jest przez funkcję:
  • ustawiamy kanał wejściowy ADC1 (PC1) zgodnie ze schematem,
  • włączamy zasilanie czujnika światła oraz masę jego rezystora,
  • ponieważ używamy tylko ośmiu najbardziej znaczących bitów, stąd wykorzystujemy dostępne w tym przypadku wyrównanie wyniku do lewej (ADLAR). 
  • preskaler ADC ustawiamy go na 8, co daje nam częstotliwość taktowania przetwornika ADC równą 125kHz (przy taktowaniu mikrokontrolera wewnętrznym generatorem RC o częstotliwości 1MHz).
  • włączamy przerwania zakończenia pomiaru ADC, by móc wykorzystać tryb ADC Noise reduction oraz przygotowujemy odpowiedni tryb snu.

dd_swiatlo_adc_pomiar_start()

Funkcja ta zawiera jedynie rozkaz uśpienia mikrokontrolera dlatego, że tę funkcję będziemy rozbudowywać w dalszych artykułach o SmartPIP'ie.

ISR(ADC_vect)

Funkcja przerwania wywoływana po zakończeniu pomiaru przez przetwornik ADC jest pusta, a przyczyna wyjaśniona w komentarzu w kodzie. Podobnie jak funkcja powyżej, także i ta będzie rozbudowywana w dalszych artykułach.


Plik dd_swiatlo.c:
/*************************************************************************
* SmartPIP - Elektroniczny dręczyciel
* 
* Data:  kwiecień 2013
* Autor: Dondu
* www:   http://mikrokontrolery.blogspot.com/2011/04/SmartPIP-elektroniczny-dreczyciel-spis-tresci.html
* 
* Plik:  dd_swiatlo.c
* Opis:  Funkcjonalności dot. pomiaru światła
**************************************************************************/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#include "dd_main.h"
#include "dd_swiatlo.h"


//-------------------------------------------------------------------------

void dd_swiatlo_adc_ini(void){

 //Funkcja włącza czujnik światła oraz inicjuje przetwornik ADC

 //KROK 1 - włącz czujnik światła
 //włącz zasilanie fototranzystora
 ADC_PIN_ZAS_DDR  |= (1<<ADC_PIN_ZAS_NAZWA); //wyjście
 ADC_PIN_ZAS_PORT |= (1<<ADC_PIN_ZAS_NAZWA); //załącz napięcie
 //włącz masę rezystora pomiarowego
 ADC_PIN_REZ_DDR  |=  (1<<ADC_PIN_REZ_NAZWA);//wyjście
 ADC_PIN_REZ_PORT &= ~(1<<ADC_PIN_REZ_NAZWA);//załącz masę (zero)


 //KROK 2 - przygotuj przetwornik ADC
 //korzystamy tylko z 8 najbardziejznaczących bitów (wyrównanie do lewej)
 //częstotliwość ADC = 1MHz + preskaler 8 = 125kHz
 //ustaw pin pomiarowy ADC
 ADC_PIN_POM_DDR   &=   ~(1<<ADC_PIN_POM_NAZWA); //wejście
 ADC_PIN_POM_PORT  &=   ~(1<<ADC_PIN_POM_NAZWA); //wyłącz pull-up
 //inicjuj przetwornik ADC
 ADMUX  =      (1<<REFS0)        //VCC jako napięcie referencyjne
             | (1<<ADLAR)        //wyrównaj pomiar do lewej
             | ADC_PIN_POM_MUX;  //przełącz na kanał wybranego pinu ADC
 ADCSRA =      (1<<ADEN)         //włącz ADC
             | (1<<ADIE)         //włącz przerwania 
             | (1<<ADPS0)        //preskaler 8
             | (1<<ADPS1);

 //ustaw tryb snu ADC Noise Reduction
 set_sleep_mode(SLEEP_MODE_ADC); 
 sleep_enable();
}


//-------------------------------------------------------------------------

void dd_swiatlo_adc_pomiar_start(void){

 //Funkcja odpowiedzialna za rozpoczęcie pomiaru światła
 //rozpocznij pomiar światła poprzez uśpienie mikrokontrolera
 sleep_cpu();  
}


//-------------------------------------------------------------------------

ISR(ADC_vect){

 //Przerwanie ADC - pomiar zakończony
 //Funkcja pusta ponieważ odczyt ADC dokonujemy w main()
 //tej funkcji nie można usunąć po nieważ pomiar światła
 //dokonywany jest w trakcie snu mikrokontrolera
 //a pomiar kończy się przerwaniem
}


Plik dd_swiatlo.h:
/*************************************************************************
* SmartPIP - Elektroniczny dręczyciel
* 
* Data:  kwiecień 2013
* Autor: Dondu
* www:   http://mikrokontrolery.blogspot.com/2011/04/SmartPIP-elektroniczny-dreczyciel-spis-tresci.html
* 
* Plik:  dd_swiatlo.h
* Opis:  Plik nagłówkowy pliku dd_swiatlo.c
*************************************************************************/


//Definicje pinów czujnika światła oraz ustawienia kanału multipleksera ADC
//pin pomiarowy
#define ADC_PIN_POM_DDR   DDRC
#define ADC_PIN_POM_PORT  PORTC
#define ADC_PIN_POM_NAZWA PC1
#define ADC_PIN_POM_MUX   (1<<MUX0) //kanał multipleksera
//pin zasilania czujnika
#define ADC_PIN_ZAS_DDR   DDRC
#define ADC_PIN_ZAS_PORT  PORTC
#define ADC_PIN_ZAS_NAZWA PC0
//pin masy rezystora
#define ADC_PIN_REZ_DDR   DDRC
#define ADC_PIN_REZ_PORT  PORTC
#define ADC_PIN_REZ_NAZWA PC2


//--- Funkcje -------------------------------
extern void dd_swiatlo_adc_ini(void);
extern void dd_swiatlo_adc_pomiar_start(void);




dd_usart.c
dd_usart.h

Obserwacja wyników za pomocą RS-232 i terminal zrealizujemy, wykorzystują opisane wcześniej rozwiązanie wraz z omówieniem obsługi programu terminala Realterm. W związku z tym, nie będę tutaj opisywał dokładnie jak działa transmisja RS-232. Dodam jedynie tę część programu by można było ją przeanalizować.


Plik dd_usart.c:
/*************************************************************************
* SmartPIP - Elektroniczny dręczyciel
* 
* Data:  kwiecień 2013
* Autor: Dondu
* www:   http://mikrokontrolery.blogspot.com/2011/04/SmartPIP-elektroniczny-dreczyciel-spis-tresci.html
* 
* Plik:  dd_usart.c
* Opis:  Funkcje komunikacji RS-232
*************************************************************************/


#include <avr/io.h>
#include <avr/interrupt.h>

#include "dd_usart.h"

//USART - tablica bufora wysyłki oraz zmienna indeksu tablicy
char usart_bufor[USART_BUFOR_DLUGOSC] = "Testowanie czujnika swiatla:"; 
volatile unsigned int usart_bufor_ind;


//--------------------------------------------------------------

void usart_inicjuj(void)
{
 //definiowanie parametrów transmisji za pomocą makr zawartych w pliku
 //nagłówkowym setbaud.h. Jeżeli wybierzesz prędkość, która nie będzie 
 //możliwa do realizacji otrzymasz ostrzeżenie: 
 //#warning "Baud rate achieved is higher than allowed"

 #define BAUD 9600         //tutaj podaj żądaną prędkość transmisji
 #include <util/setbaud.h>  //linkowanie tego pliku musi być 
                            //po zdefiniowaniu BAUD
 
 //ustaw obliczone przez makro wartości
 UBRRH = UBRRH_VALUE;  
 UBRRL = UBRRL_VALUE;
 #if USE_2X
    UCSRA |= (1 << U2X);
 #else
    UCSRA &= ~(1 << U2X);
 #endif

 //Ustawiamy pozostałe parametry moduł USART
 //zobacz: http://mikrokontrolery.blogspot.com/2011/04/Pulapki-AVR-Rejestry-pod-tym-samym-adresem.html 
 UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);   //bitów danych: 8
                                                 //bity stopu:   1
                                                 //parzystość:   brak
 //włącz nadajnik
 UCSRB |= (1<<TXEN);
}


//--------------------------------------------------------------

void usart_wyslij_bufor(void){

 //funkcja rozpoczyna wysyłanie, wysyłając pierwszy znak znajdujący się
 //w tablicy wynik[]. Pozostałe wyśle funkcja przerwania, 
 //która zostanie wywołana automatycznie po wysłaniu każdego znaku.

 //Dodaj do tekstu wyniku znaki końca linii (CR+LF), by na 
 //ekranie terminala wyniki pojawiały się w nowych liniach
 unsigned int z;
 for(z=0; z<USART_BUFOR_DLUGOSC; z++){
  if(usart_bufor[z]==0){   //czy to koniec tekstu w tablicy
   //tak znaleziono koniec tekstu, dodajemy znaki CR i LF
   usart_bufor[z]    = 13; //znak powrotu karetki CR (Carrige Return)
   usart_bufor[z+1]  = 10; //znak nowej linii LF (Line Feed)
   usart_bufor[z+2]  = 0;  //znak końca ciągu tekstu w tablicy
   break;                  //przerwij pętlę for()
  }
 }

 //Zaczekaj, aż bufor nadawania będzie pusty
 while (!(UCSRA & (1<<UDRE))); 

 //następny znak do wysyłki to znak nr 1
 usart_bufor_ind = 0;

 //włącz przerwania pustego bufora UDR, co rozpocznie transmisję
 //aktualnej zawartości bufora 
 UCSRB |= (1<<UDRIE);

}


//--------------------------------------------------------------

ISR(USART_UDRE_vect){

 //przerwanie generowane, gdy bufor nadawania jest już pusty, 
 //odpowiedzialne za wysłanie wszystkich znaków z tablicy usart_bufor[]
 //z wyjątkiem pierwszego

 //static unsigned char znak = 1;

 //sprawdzamy, czy bajt do wysłania jest znakiem końca tekstu, czyli zerem
 if(usart_bufor[usart_bufor_ind]!= 0){
  //załaduj znak do rejestru wysyłki i ustaw indeks na następny znak
  UDR = usart_bufor[usart_bufor_ind++]; 
 }else{
  //osiągnięto koniec napisu w tablicy usart_bufor[]
  UCSRB &= ~(1<<UDRIE); //wyłącz przerwania pustego bufora nadawania
 }
}


Plik dd_usart.h:
/*************************************************************************
* SmartPIP - Elektroniczny dręczyciel
* 
* Data:  kwiecień 2013
* Autor: Dondu
* www:   http://mikrokontrolery.blogspot.com/2011/04/SmartPIP-elektroniczny-dreczyciel-spis-tresci.html
* 
* Plik:  dd_usart.h
* Opis:  Plik nagłówkowy pliku dd_usart.c
*************************************************************************/

//USART - tablica bufora wysyłki oraz zmienna indeksu tablicy
#define USART_BUFOR_DLUGOSC  30    //rozmiar bufora
extern char usart_bufor[USART_BUFOR_DLUGOSC]; //bufor
extern volatile unsigned int usart_bufor_ind; //indeks bufora

//Funkcje
extern void usart_inicjuj(void);
extern void usart_wyslij_bufor(void);





dd_main.c
dd_main.h

Program główny zawiera jedynie funkcję main() wraz z niezbędnymi definicjami w pliku nagłówkowym.

Zadania:

  • dobre praktyki w zakresie dbania o to, by każdy pin miał wymuszony poziom napięcia,
  • wywołanie funkcji przygotowujących mikrokontroler do pracy,
  • wysłanie początkowego napisu do terminala,
  • inicjowanie pomiarów,
  • przetwarzanie wyniku,
  • inicjowanie wysłania wyniku do terminala.

Sądzę, że nie trzeba tutaj omawiać dokładnie każdego z powyższych punktów, bo są opisane w kodzie programu.

Fusebity

Należy wspomnieć, że poniższy program pracuje poprawnie z domyślnymi ustawieniami fusebitów (fabrycznymi), czyli:
  • low: 0xE1
  • high: 0xC9
W celu przyspieszenia wybudzenia mikrokontrolera można ustawić fusebity także tak:
  • low: 0xC1
  • high: 0xC9
O docelowym ustawieniu fusebitów zadecydujemy w następnym artykule.

Plik dd_main.c:
/*************************************************************************
* SmartPIP - Elektroniczny dręczyciel
* 
* Data:  kwiecień 2013
* Autor: Dondu
* www:   http://mikrokontrolery.blogspot.com/2011/04/SmartPIP-elektroniczny-dreczyciel-spis-tresci.html
* 
* Plik:  dd_main.c
* Opis:  Testowanie czujnika światła
*
* Mikrokontroler:  ATmega8A
* Fusebity:        low:  0xC1
*                  high: 0xC9
* Kompilator:    GCC
* 
* W opcjach projektu należy ustawić:  zegar:         1000000Hz
*                                     optymalizację: -Os
*************************************************************************/


#include <avr/io.h> 
#include <stdio.h>  
#include <util/delay.h> 
#include <avr/interrupt.h> 
#include <avr/sleep.h>

#include "dd_main.h"
#include "dd_usart.h"
#include "dd_swiatlo.h"


//-------------------------------------------------------------------------

int main(void) 
{ 

 //--- Dobre praktyki ---
 //Po resecie (włączeniu zasilania) piny ustawione są domyślnie jako 
 //wejścia. Włączamy rezystory pull-up. To bardzo istotne w projektach
 //zasilanych z baterii! Dla ATmega8A włączamy wszystkie z wyjątkiem
 //pinu RESET ponieważ mamy tam podłączony zewnętrzny rezystor pull-up
 //szczegóły: http://mikrokontrolery.blogspot.com/2011/04/zakocenia-w-pracy-mikrokontrolerow.html
 PORTB  = 0xff; 
 PORTC  = 0xff;
 PORTD  = 0x3f;

 //jeżeli włączony tryb testowy (szczegóły w pliku dd_main.h)
 #ifdef  TRYB_TEST
  //Ustaw pin LED jako wyjście
  LED_TEST_DDR |= (1<<LED_TEST_PIN_NAZWA);
  LED_TEST_ON;
 #endif

 //przygotuj moduł USART do transmisji danych do komputera
 usart_inicjuj();

 //włącz przerwania globalne
 sei(); 

 //wysyłamy napis początkowy domyślnie umieszczony w tablicy usart_bufor[]
 //patrz plik: dd_usart.c
 usart_wyslij_bufor();
 //opóźnienie na poprawne wysłanie napisu startowego
 _delay_ms(1000); 

 //przygotuj czujnik światła oraz przetwornik ADC
 dd_swiatlo_adc_ini();


 //pętla główna
 while(1){ 

  //wykonaj pomiar
  dd_swiatlo_adc_pomiar_start();

  //konwertuj wynik na ciąg znaków i umieść w tablicy usart_bufor[]
  sprintf(usart_bufor, "%u", ADCH);

  //wyślij dane do komputera
  usart_wyslij_bufor();
  
  #ifdef  TRYB_TEST
   //zmień stan LED na przeciwny
   LED_TEST_TOGGLE;
  #endif

  //opóźnienie między kolejnymi pomiarami
  _delay_ms(2000);
 } 
}



Plik dd_main.h:
/*************************************************************************
* SmartPIP - Elektroniczny dręczyciel
* 
* Data:  kwiecień 2013
* Autor: Dondu
* www:   http://mikrokontrolery.blogspot.com/2011/04/SmartPIP-elektroniczny-dreczyciel-spis-tresci.html
* 
* Plik:  dd_main.h
* Opis:  Plik nagłówkowy pliku dd_main.c
*
*************************************************************************/


//======= TESTOWE =====================
//Definicje do fragmentów programu wykorzystywanych do testów
#define TRYB_TEST 1 //zakomentowanie tej linijki wyłącza tryb testowy
#ifdef  TRYB_TEST
 //definicje dot. testowej diody LED
 #define LED_TEST_DDR        DDRB
 #define LED_TEST_PORT       PORTB
 #define LED_TEST_PIN_NAZWA  PB0
 #define LED_TEST_ON         LED_TEST_PORT &= ~(1<<LED_TEST_PIN_NAZWA)
 #define LED_TEST_OFF        LED_TEST_PORT |=  (1<<LED_TEST_PIN_NAZWA)
 #define LED_TEST_TOGGLE     LED_TEST_PORT ^=  (1<<LED_TEST_PIN_NAZWA)
#endif






Do pobrania

Poniżej link do spakowanego:
  • projektu AVR Studio 4,
  • plików .c oraz .h
  • pliku .hex skompilowanego dla 1MHz i fusebitów określonych powyżej.

Plik: SmartPIP_Czujnik_testowanie.zip





Wyniki pomiarów

W przypadku mojej wersji czujnika światła i powyższego programu zgodnie z założeniami, czujnik na oświetlenie reaguje w sposób bardzo "agresywny",  co przejawiać się będzie stromymi zboczami na wykresie pomiarów, gdyż już przy niewielkim oświetleniu wartości pomiarów szybko rosną.

Taka charakterystyka czujnika jest podyktowana wymogiem oszczędzania baterii i w niczym nam nie będzie przeszkadzać, a wręcz pomagać podczas analizy wyników przez program.

Efekt jaki powinieneś zobaczyć na terminalu Realterm, jest następujący:

SmartPIP: Terminal Realterm (RS-232) - parametry transmisji oraz pierwsze dane.


Specjalnie pokazuję zakładkę Port, abyś wiedział jak ustawić parametry odbioru. Po ich ustawieniu kliknij przycisk Change. W prawym dolnym rogu są (w skrócie) pokazane aktualne ustawienia terminala - muszą być identyczne, by program działał poprawnie.

Pierwszy pomiar

Na powyższym ekranie możesz zauważyć, że pierwszy pomiar znacząco odbiega od pozostałych. Jest to związane z faktem, że po zmianie ustawień ADC (wybór napięcia odniesienia) pierwszy pomiar może być nieprawidłowy.

Informację w tej sprawie znajdziesz w dalszej części tego cyklu.

W zakładce Display, możesz włączyć opcję Ansi, co wyłączy pokazywanie znaków specjalnych:


Terminal Realterm (RS-232): Zakładka Display - usunięcie znaków specjalnych (ansi).


Więcej o ustawieniach terminala Realterm pisałem tutaj.





Podsumowanie

Mamy już przetestowany i działający czujnik światła, o dość agresywnej charakterystyce. Jest on prosty i zużywa bardzo mało energii z baterii. Powinniśmy teraz przetestować jakie straty poniesiemy, na kondensatorze pomiarowym i o tym będzie kolejny artykuł.


Artykuł jest częścią cyklu: SmartPIP - Elektroniczny dręczyciel
Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

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

Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

SmartPIP: Czujnik światła - oszczędzamy energię


Autor: Dondu

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


Pamiętasz, jak brzmi nasze główne motto?:

Oszczędzamy energię "na maksa"!

Mamy już wybrany schemat układu zamiany światła otoczenia na napięcie wraz z wartościami elementów, który zostałby podłączony do mikrokontrolera na przykład tak:




Pinem pomiarowym będzie więc pin ADC1 (PC1).

Czy można jednak na tym fragmencie schematu SmartPIP'a, zaoszczędzić trochę energii?
Można i należy to zrobić!


1. Odłączamy zasilanie czujnika 

W naszym układzie czujnika, gdy fototranzystor będzie dobrze oświetlony, prąd pobierany przez czujnik będzie wynosił nie więcej niż 10µA niezależnie od tego, czy w danym momencie dokonujemy pomiaru, czy też mikrokontroler śpi w najlepsze.

W okresie letnim przez większą część doby w pomieszczeniu będzie jasno (słońce w dzień, a światło sztuczne wieczorem). Zimą z reguły proporcja czasu, gdy w pomieszczeniu jest jasno do czasu, gdy jest w nim ciemno będzie oczywiście inna (z reguły mniejsza), ale i tak w znacznej części doby w pomieszczeniu będzie jasno.

Oznacza to, że czujnik przez znaczną część doby będzie zużywał energię pomimo, że z niego korzystać będziemy raz na kilka minut.

Wniosek: Warto wyłączać czujnik, gdy nie jest używany, ponieważ to zbędny pożeracz energii :-)

Zgodnie z założeniami projektu, mamy minimalizować ilość użytych elementów elektronicznych, a także wielkość i koszt urządzenia. W związku z tym, najprostszym rozwiązaniem jest wykorzystanie pinu mikrokontrolera, jako klucza włączającego i wyłączającego zasilanie czujnika.

Możemy sobie na to pozwolić, ponieważ czujnik pobiera zaledwie 10µA, a pin tego mikrokontrolera, może spokojnie dostarczyć 20mA, a nawet 40mA.


Schemat może wyglądać więc na przykład tak:




Czyli aby włączyć czujnik ustawimy pin PC0 jako wyjście i ustawimy na nim stan wysoki, czyli jedynkę logiczną.

Powinniśmy sobie jednak zadać pytanie, jaki będzie faktyczny poziom napięcia zasilania czujnika, gdy pin mikrokontrolera będzie miał ustawioną jedynkę logiczną, zasilając w ten sposób nasz układ pomiarowy?

Zerkamy do datasheet do tabelki z parametrami elektrycznymi pinów i odnajdujemy odpowiedni parametr:




W naszym przypadku (zasilanie z 3V) tabelka DC Characteristics informuje nas, że możemy się spodziewać co najmniej 2,2V, ale niestety nie jest podane ile typowo powinno być. Jednakże zauważamy, że parametr ten podany jest dla prądu pinu wynoszącego aż 10mA. W naszym przypadku mamy prąd 1000 razy mniejszy, bo zaledwie 10µA.

Intuicja mówi nam, że powinniśmy poszukać bardziej szczegółowej informacji. Zaglądamy więc do części z wykresami, gdzie znajdujemy wykres zależności napięcia od prądu, dla pinu ustawionego jako wyjście z jedynką logicznym (source current), przy zasilaniu 3,0V:




Okazuje się więc, że dla naszego prądu 10µA, na wyjściu pinu otrzymamy nie 2,2V, ale pełne 3,0V, co jest dla nas bardzo istotne i oznacza, że przy takim prądzie pin działający jako klucz włączający zasilanie czujnika spełni swoją rolę "idealnego klucza"  i nie będzie wprowadzał zmian do naszych obliczeń.

Algorytm pomiaru będzie więc następujący:
  1. włączamy czujnik ustawiając pin PC0 jako wyjście i podajemy na niego jedynkę logiczną,
  2. czekamy chwilkę na ustabilizowanie się napięcia na kondensatorze,
  3. dokonujemy pomiaru pinu ADC1,
  4. po zakończonym pomiarze wyłączamy czujnik poprzez ustawienie pinu w stan wysokiej impedancji, czyli jako wejście z wyłączonym rezystorem pull-up.

W ten sposób będziemy włączać czujnik tylko wtedy, gdy jest nam potrzebny, minimalizując straty energii z baterii.






2. Odłączamy rezystor 

Można coś jeszcze zaoszczędzić?
Zastanówmy się co się dzieje z energią zgromadzoną w kondensatorze, gdy zakończyliśmy pomiar i  wyłączyliśmy zasilanie czujnika:




Prosta sprawa - wredny rezystor rozładuje nam kondensator :-)

Co to oznacza?

Za każdym razem (z wyjątkiem ciemności), będziemy ponownie ładować kondensator od zera, a po dokonaniu pomiaru rezystor nam go rozładuje. To znowu duża strata!

Jeżeli więc damy radę przechować chociażby część ładunku w kondensatorze, to będzie to zyskiem zmniejszającym zużycie ładunku baterii.

Co należy zrobić, by rezystor nie rozładowywał nam kondensatora do zera? Trzeba go odłączyć, a możemy zrobić to podobnie jak z zasilaniem czujnika, czyli wykorzystać następny pin mikrokontrolera:





W ten sposób w czasie, gdy wyłączymy zasilanie oraz masę rezystora, nie będzie on rozładowywał kondensatora.


UWAGA!

W dalszej części tego cyklu artykułów będziemy posługiwać się powyższym schematem, ale narysowanym nieco inaczej:


Jeżeli się przyglądniesz, ten i poprzedni schemat są dokładnie takie same.


Podobnie jak w przypadku odłączania zasilania czujnika, także i w tym przypadku powinniśmy sobie zadać pytanie, jaki będzie faktyczny poziom napięcia na pinie sterującym rezystorem, gdy pin ten będzie miał ustawione zero logiczne, czyli zwierał rezystor do masy?

Zerkamy do datasheet do tej samej tabelki z parametrami elektrycznymi pinów i odnajdujemy parametr:




W naszym przypadku (zasilanie z 3V) tabelka DC Characteristics informuje nas, że możemy się spodziewać aż 0,6V. Skoro aż tyle, to nasze obliczenia wykonane powyżej należałoby skorygować. Ponownie zauważamy, że parametr ten podany jest dla prądu pinu wynoszącego aż 10mA, a w naszym przypadku mamy przecież prąd 1000 razy mniejszy.

Po nabraniu doświadczenia z punktu 1 wiemy, że powinniśmy poszukać bardziej szczegółowej informacji na wykresach. Znajdujemy więc wykres dla pinu I/O ustawionego jako wyjście z zerem logicznym (sink current), przy zasilaniu 3,0V:




Ponownie okazuje się, że dla naszego prądu 10µA, na wyjściu pinu nie będziemy mieli spodziewanego 0,6V, ale 0V, co jest dla nas bardzo istotne i oznacza, że przy takim prądzie pin działający jako klucz włączający masę, nie będzie wprowadzał zmian do naszych obliczeń.

Uzupełniamy nasz algorytm pomiaru:
  1. włączamy czujnik ustawiając pin PC0 jako wyjście i podajemy na niego jedynkę logiczną,
  2. włączamy masę rezystora ustawiając PC2 jako wyjście i podajemy na niego zero logiczne,
  3. czekamy chwilkę na ustabilizowanie się napięcia na kondensatorze,
  4. dokonujemy pomiaru pinu ADC1,
  5. po zakończonym pomiarze wyłączamy czujnik poprzez ustawienie pinów zasilania i masy rezystora w stan wysokiej impedancji, czyli jako wejście z wyłączonym rezystorem pull-up.






Podsumowanie pkt. 1 i 2

Dzięki zastosowaniu rozwiązań opisanych w punktach 1 i 2 zminimalizowaliśmy do granic możliwości zużycie energii w tej części schematu SmartPIP'a.

Należy jednak wspomnieć tutaj o zjawisku upływności:
  • kondensatora,
  • pinów mikrokontrolera.

W przypadku kondensatora upływność można znaleźć w datasheet tego, który zastosujesz.

W przypadku naszego mikrokontrolera ATmega8A, upływność pinu ustawionego jako wejście, określona jest w datasheet następująco:




Jak widać, jest to wartość maksymalna w dodatku podana dla napięcia 5V. Możemy się więc spodziewać, że w naszym przypadku będzie to znacznie mniej niż 1µA na jeden pin. Tutaj niestety nic już nie policzymy, więc należałoby dokonać pomiarów.

Czas trwania stabilizacji sygnału czujnika

Należy tutaj wspomnieć jeszcze o tym, że gdy załączymy czujnik i od razu rozpoczniemy pomiar, to możemy narazić się problem otrzymania niewłaściwego pomiaru, co jest związane z czasem trwania stabilizowania się napięcia na wyjściu czujnika. Dlatego:

Po włączeniu czujnika (zasilanie + rezystor) należy zaczekać na ustabilizowanie się napięcia na wyjściu czujnika tym bardziej, gdy zastosujemy kondensator stabilizujący.

Jak to zrealizujemy opiszę w następnym artykule.





3. Wyłączamy ADC, gdy tylko jest to możliwe


Przetwornik analogowo-cyfrowy (ADC), który używamy do pomiarów światła także zużywa energię, a jest nam potrzebny zaledwie co kilka minut i w dodatku tylko na ułamek sekundy. Należy więc zadbać o to, by niepotrzebnie nie generował nam strat energii baterii.

W przypadku mikrokontrolera ATmega8 mamy w tym zakresie dwie możliwości:
  • włączania i wyłączania przetwornika,
  • specjalnego trybu pomiaru "ADC Noise Reduction".


Dlaczego włączanie i wyłączanie przetwornika ADC jest istotne?

Zobaczmy w dokumentacji jaki prąd pobiera przetwornik ADC. Znajdziesz tam wykres dla przypadku, który zastosujemy, czyli gdy napięcie referencyjne AREF (napięcie odniesienia) będzie równe napięciu zasilania mikrokontrolera Vcc:




Na wykresie zaznaczyłem jest fragment, w którym pracować będzie nasz SmartPIP, czyli dla napięć zasilania przede wszystkim z przedziału od 2,7V do 3V, ponieważ taką baterię wybraliśmy. Dla uproszczenia przyjmijmy, że prąd ten będzie równy 150µA.

Malutko prawda? Ale czy aby na pewno?

W poprzednim artykule ustaliliśmy, że w czasie snu przy działającym Timer2 odliczającym czas, mikrokontroler będzie pobierał zaledwie 10µA. Włączony ADC pobierać będzie więc:



... 15 razy więcej prądu niż mikrokontroler w czasie snu i odliczania czasu!

Wniosek jest oczywisty:

Należy bezwzględnie wyłączać przetwornik ADC pomiędzy kolejnymi pomiarami, gdyż pobiera on strasznie dużo ładunku z baterii.

Tryb pomiaru ADC Noise Reduction

Drugą możliwością w zakresie oszczędności uzyskanych z przetwornika ADC jest skorzystanie podczas pomiarów światła ze specjalnego trybu snu ADC Noise Reduction mode.

Tryb ten został zaprojektowany przede wszystkim po to, by zmniejszyć ilośc szumów generowanych przez wewnętrzne układy mikrokontrolera, które mogą przenosić się na wejście przetwornika ADC w czasie trwania pomiaru. Dla nas oczywiście jest to także istotne.

Jednakże naszym zyskiem jest dodatkowo fakt, iż w trybie tym spada zapotrzebowanie na energię co związane jest z zatrzymaniem pracy niektórych wewnętrznych układów. Niektórych, czyli?:


Niestety w tym zakresie nie jesteśmy w stanie stwierdzić na podstawie datasheet jakie z tego tytułu będą oszczędności, ale na pewno będą spore patrząc na to, co jest wyłączone :-)






Podsumowanie

Sądzę, że po analizie niniejszego artykułu stwierdzisz, że oszczędzanie energii wcale nie jest trudne i nie są to jakieś magiczne zaklęcia. Ot po prostu kombinowanie i logiczne myślenie poparte sprawdzaniem datasheet.

Jednakże zawsze możesz trafić na moment, w którym będziesz miał wątpliwości lub w datasheet nie znajdziesz odpowiednich informacji. Wtedy pozostaje droga empiryczna w postaci eksperymentu.

Najprostszym jest więc symulowanie pracy przy zasilaniu z naładowanego kondensatora. Jak taki eksperyment wygląda możesz zobaczyć na przykładzie pokazanym przez inżynierów ATmel'a.

W następnych artykułach przetestujemy nasz czujnik i dokonamy testowych dobowych pomiarów.


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


Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

SmartPIP - Czujnik światła - obliczenia


Autor: Dondu

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


Nadszedł moment, w którym powinniśmy dokonać obliczeń dla naszego układu pomiarowego wybranego w poprzednim artykule. W obliczeniach możemy pominąć kondensator i wejście przetwornika ADC:




Prąd płynący przez fototranzystor będzie zwierany do masy przez rezystor. Skoro wiemy, że nasz mikrokontroler oraz układ czujnika światła będą zasilane z baterii 3V, to możemy spróbować obliczyć wartość rezystora przyjmując wartość prądu fototranzystora taką, jakiej nie chcielibyśmy przekraczać, niezależnie od rodzaju źródła i natężenia światła oświetlającego czujnik.

Aby policzyć wartość rezystora musimy znać napięcie jakie się na nim "odłoży" przy danej wartości prądu. Napięcie to będzie wynikało ze wzoru:




Istotnym jest więc ustalenie, jaki napięcie przy wybranym przez nas prądzie będzie występowało na złączu kolektor-emiter fototranzystora (UFT).

Zaglądamy do datasheet fototranzystora i w tabelce odnajdujemy parametr Collector Emitter Saturation Voltage, czyli napięcie kolektor-emiter w czasie jego nasycenia:


Niestety wszystkie parametry z tabeli podane są dla napięcia zasilania wynoszącego 5V, a ten parametr dodatkowo podany jest dla prądu kolektora równego 10mA, a w naszym przypadku będziemy starali się, by prąd ten był 1000 razy mniejszy.

Nie ma także żadnego wykresu, z którego moglibyśmy odczytać jak zachowywać się będzie ten parametr dla innych napięć zasilania. Dlatego nie pozostaje nam nic innego, tylko do obliczeń przyjąć wartość 0,4V.


Rezystor

Zaczniemy od przyjęcia, że chcemy aby prąd płynący przez tranzystor miał wartość 10µA.

Dlaczego akurat tyle? Musimy oszczędzać, a fototranzystor, który wybrałem, umożliwia nam pracę z takim prądem co ustaliliśmy już wcześniej.

Dane do obliczeń:
  • napięcie zasilania: 3V
  • napięcie emiter-kolektor: 0,4V
  • żądany prąd fototranzystora: 10µA

Najpierw obliczymy spadek napięcia na rezystorze:




a następnie skorzystamy z prawa Ohma dla układu:



i policzymy wartość rezystora:




i na koniec ustalamy, że z szeregu rezystorowego wybieramy rezystor 270kΩ.


Kondensator

Zadaniem kondensatora jest stabilizowanie poziomu sygnału z fototranzystora, który mierzymy przetwornikiem ADC. Im większy będzie kondensator tym stabilniejsze będą pomiary.

Niestety z punktu widzenia oszczędzania energii, powinniśmy minimalizować jego wartość, ponieważ każde naładowanie i rozładowanie kondensatora to strata energii z baterii.

Dlatego jeśli się da, to można zrezygnować z kondensatora tym bardziej, że będziemy stosować programowe uśrednianie wyników.

Warto jednak przewidzieć ewentualnie miejsce na płytce PCB, żeby w razie konieczności wlutować kondensator.

Jaką więc wartość wybrać, gdy kondensator będzie potrzebny?

Odpowiedź jest prosta - sprawdzić doświadczalnie jak "pływają" pomiary z różnymi wartościami kondensatora i wybrać najmniejszy możliwy kondensator zapewniający w miarę stabilne pomiary. Może to być mocno zależne od rodzaju oświetlenia, przede wszystkim sztucznego. Ja testowałem różne, a mój kompromis znalazłem na poziomie 4,7nF.


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

Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

SmartPIP - Czujnik światła - fototranzystor


Autor: Dondu

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


Przyszedł czas na wybór odpowiedniego fototranzystora. Wyboru możemy dokonać na zasadzie "mam jakiś w szufladzie" - tak było i w moim przypadku, ponieważ miałem sporo fototranzystorów: KPS-3227SP1C (datasheet)

Jest to fototranzystor przeznaczony do pomiaru światła otoczenia (ang. ambient light). Podstawowe parametry:



Najistotniejszym parametrem, który determinuje, czy fototranzystor nadaje się do wykorzystania w naszym projekcie jest zakres długości fali światła, dla którego został zaprojektowany. Nas interesuje oczywiście światło widzialne (Wikipedia), czyli w zakresie 400-700nm.

Sprawdzamy więc odpowiednie parametry w datasheet:




Na podstawie tabelki ustalamy, że fototranzystor jest przeznaczony dla zakresu 390-700nm, z maksymalną czułością dla 580nm, a to oznacza, że idealnie nadaje się do pomiarów światła widzialnego. Dodatkowo w datasheet możemy znaleźć wykres jego czułości w zależności od długości fali światła (rysunek powyżej).


Kąt detekcji (widzenia, obserwacji)

Istotnym dla nas parametrem jest także kąt  pod jakim "widzi" fototranzystor. Kąt ten określony został przez producenta w następujący sposób:




W tabelce podano, iż kąt obserwacji dla połowy jego czułości wynosi 120º. Oznacza to, że mamy szerokie pole widzenia, co w naszym przypadku jest pożądane ze względu na to, że podkładając ofierze SmartPIP'a, nie będziemy musieli "celować" czujnikiem we właściwym kierunku.

Dla porównania inny fototranzystor przeznaczony do pomiaru światła otoczenia TEPT4400 (datasheet):




Dość ciekawy "walentynkowy :-)" kształt pola widzenia czujnika, jakże odmienny od poprzednika. Z wykresu wynika, że kąt detekcji czujnika TEPT4400 wynosi około 60º. Potwierdzeniem tego jest kąt określony w tabelce, gdzie podano kąt ±30º:




Znak ± oznacza, że kąt ten należy pomnożyć przez 2, by uzyskać faktyczny kąt widzenia czujnika. Jest to zgodne z rysunkiem powyżej, czyli 60º.

Wniosek jest oczywisty, fototranzystor ten nadaje się do naszego urządzenia, ale należy być świadomym wartości parametru kąta widzenia, który jest dwukrotnie mniejszy niż pierwszego fototranzystora.


Prąd fototranzystora vs natężenie oświetlenia

Teraz należy zastanowić się nad doborem elementów w układzie czujnika światła. Musi on pobierać w miarę możliwości jak najmniejszy prąd w czasie pracy. Jednocześnie sam fototranzystor musi poprawnie pracować w szerokim zakresie oświetlenia.

Zerkamy więc do datasheet w poszukiwaniu istotnych w tym zakresie parametrów. Zostawiłem tylko te, które nas będą interesować:



Zwróć uwagę na notatki pod tabelką, które są odnośnikami do numerków w nawiasach kwadratowych w kolumnie Conditions i oznaczają one:
  1. oświetlenie fluorescencyjne (6200K),
  2. standardowe domowe oświetlenie żarówką wolframową (2856K),
  3. oświetlenie światłem słonecznym (4600K).

Przyda się nam znajomość definicji:

Luks [lx] - to jednostka układu SI służąca do określenia natężenia oświetlenia wytworzonego przez strumień świetlny jednego lumena [lm] równomiernie rozłożony na powierzchni jednego metra kwadratowego [m2].


Lumen [lm] - to strumień świetlny wysłany w jednostkowy kąt bryłowy (steradian) przez izotropowe punktowe źródło światła o światłości jednej kandeli umieszczone w wierzchołku tego kąta.


Steradian [sr]- to kąt bryłowy o wierzchołku w środku kuli, wycinający z powierzchni tej kuli pole równe kwadratowi jej promienia.

oraz wiedza na temat barwy światła (Wikipedia).


W tabelce producent operuje luksami, więc by było łatwiej zrozumieć dalszą część artykułu przedstawimy definicję luksa za pomocą wzoru:



Zerkamy na parametry z tabelki:

Collector dark current
To prąd, który płynie przez tranzystor w momencie, gdy jest ciemno, czyli poziom oświetlenia fototranzystora wynosi 0lx. Z tabelki wynika, że powinniśmy się spodziewać zaledwie 10nA, maksymalnie 100nA. To bardzo mało, ale należy pamiętać, że w pomieszczeniu ofiary zapewne nie będzie idealnie ciemno. Trudno więc przyjmować, że faktycznie będzie tylko 10nA.


Light Current(1),(2),(3),(4)
To prąd, który płynie przez fototranzystor w momencie, gdy jest oświetlony określonym światłem (rodzaj i strumień światła). W kolumnie conditions rodzaj światła określony jest numerkiem w nawiasach kwadratowych, a jego natężenie podane w luksachMożemy się więc spodziewać nawet 950µA (czyli prawie 1mA) przy oświetleniu światłem żarowym o natężeniu 1000lx. Dla nas oczywiście tak duży prąd jest nie do zaakceptowania i będziemy go ograniczać rezystorem.



Ile to jest 100lx?

Powinniśmy sobie zadać pytanie, jak jasne jest światło o natężeniu 100lx, które według powyższej tabelki warunkuje nam osiągnięcie prądu 6µA dla światła fluorescencyjnego (patrz: light current 1). Sama liczba nie daje nam pojęcia, jaki to jest poziom oświetlenia czujnika.

Najprościej będzie porównać się do standardowej żarówki o strumieniu światła równym 100 lumenów. Żarówką, która emituje oświetlenie o natężeniu 100lm jest zwykła żarówka o mocy 15W:


Źródło: Paulmann Licht GmbH

czyli:



Zapewne jesteś świadomy, jak mało światła daje standardowa żarówka o mocy 15W.

Wyobraź sobie, że cały strumień świetlny tej żarówki (czyli 100lm) skierujesz za pomocą bezstratnego zwierciadła równomiernie na wycinek sfery kuli o powierzchni 1m2 (patrz: steradian (Wikipedia)). W ten sposób zgodnie z powyższą definicją i wzorem, natężenie oświetlenia na tej powierzchni będzie miało 100 luksów:



Następnie na tym wycinku powierzchni sfery (1m2) umieszczasz nasz malutki fototranzystor o wymiarach 2 x 2mm. Światło, które będzie go oświetlało będzie miało natężenie także 100lx.


Wartości pośrednie i zależności od rodzaju źródła światła

Teraz popatrzmy na wykres zależności prądu fototranzystora od natężenia i rodzaju oświetlenia zawarty w datasheet naszego fototranzystora. Niestety producent tak przygotował ten wykres, że za pomocą zamieszczonej do niego legendy nie można stwierdzić, która linia symbolizuje światło fluorescencyjne, a która standardowe żarowe.

Zaznaczyłem więc kolorami wartości natężenia światła z tabelki, czyli 100lx oraz 1000lx:



Odczytując poziomy prądu wyjściowego fototranzystora dla poszczególnych przypadków z tabelki możemy zidentyfikować poprawnie obie linie, co oznaczyłem strzałkami.

Zauważ, że prądu poniżej 10µA dla oświetlenia żarowego (30lx) oraz 5µA dla fluorescencyjnego (80lx), oznaczone są na wykresie linią przerywaną, a nie ciągłą jak pozostała ich część. Możemy więc się domyślać, że w tym zakresie pracy fototranzystora producent nie gwarantuje, że zależność prądu od oświetlenia czujnika będzie nadal liniowa i przewidywalna.

Zauważyć należy także, że ten fototranzystor znacznie lepiej reaguje dla światła żarowego niż fluorescencyjnego.



Podsumowanie

Mamy wybrany fototranzystor oraz ustalone jego parametry możemy więc przejść do obliczeń, o czym piszę w następnym artykule.


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

Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

SmartPIP - Czujnik światła - wstępne decyzje


Autor: Dondu

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


Na początek powinniśmy podjąć decyzje w dwóch tematach:
  1. schemat układu pomiarowego czujnika światła,
  2. dokładność pomiarów.



1. Schemat pomiarowy

W tym zakresie właściwie sprawa jest prosta. Budujemy czujnik światła na bazie elementu światłoczułego (fotorezystor, fototranzystor, fotodioda),  który zamieni poziom oświetlenia na odpowiadające mu napięcie. Następnie tak otrzymane napięcie będziemy mierzyć przetwornikiem analogowo-cyfrowym.


Kondensator "wygładzający"

Na poniższych schematach zastosujemy dodatkowy kondensator, którego zadaniem będzie "wygładzanie" sygnału wyjściowego z czujnika światła po to, by pomiary dokonywane przez przetwornik analogowo-cyfrowy, nie były "zaszumione" niewidocznymi dla ludzkiego oka zmianami natężenia oświetlenia. W szczególności jest to istotne przy oświetleniu sztucznym. O kondensatorze piszę także w dalszej części tego cyklu artykułów.


Układ pomiarowy

Ponieważ z założeń wynika, że mamy minimalizować ilość użytych elementów elektronicznych, skorzystamy z możliwie najprostszego schematu pomiarowego jakimi jest zastosowanie fototranzystora pracującego wraz z rezystorem w układzie dzielnika napięcia dla układów wspólnego emitera (WE) lub wspólnego kolektora (WC).


Układ pomiarowy WE

Układ pomiarowy WE (wspólny emiter) ma istotne dla nas zalety, ale także i wady. Podstawowy układ pomiarowy WE w naszym przypadku wyglądałby następująco:


Schemat 1 - Układ pomiarowy ze wspólnym emiterem.


Dla naszego projektu zaletą takiego układu jest fakt, że jako rezystor R (zewnętrzny pull-up) moglibyśmy wykorzystać dostępny w mikrokontrolerze wewnętrzny rezystor pull-up (o ile mikrokontroler umożliwia jego włączenie, gdy pin jest ustawiony jako wejściowy przetwornika ADC). Stąd nasz układ pomiarowy moglibyśmy ograniczyć do następującego:


Schemat 2 - Układ pomiarowy wykorzystujący wewnętrzny
rezystor pull-up mikrokontrolera.


To najprostsza możliwa wersja układu pomiarowego wraz ze wstępnym wygładzaniem sygnału mierzonego. Jednakże w naszym przypadku, użycie wewnętrznego rezystora pull-up generuje problem większego niż będziemy oczekiwali zużycia ładunku baterii.

Dlaczego?
Sprawdźmy jaką rezystancję ma wewnętrzny rezystor w mikrokontrolerze, który wybraliśmy:



Widzimy, że rezystor ten ma od 20kΩ do 50kΩ (spory rozrzut). Dla nas oznacza to, że prąd płynący przez rezystor i tranzystor (pomijając w obliczeniach spadek napięcia na złączu kolektor emiter) przy zasilaniu układu z 3V będzie wynosił około:

- gdy rezystor pull-up będzie miał blisko 20kΩ:



- gdy rezystor pull-up będzie miał blisko 50kΩ:



Wydaje się, że to niewiele, ale w następnym artykule dowiesz się, że celujemy w zaledwie 10µA stosując zewnętrzny rezystor pull-up o znacznie większej wartości.

W związku z tym i tak musimy zastosować zewnętrzny rezystor, czyli (w przypadku układu WE) układ pomiarowy ze schematu 1.




Układ pomiarowy WC

Innym rozwiązaniem, jest zastosowanie układu pomiarowego o wspólnym kolektorze.




W przypadku wykorzystania mikrokontrolera z wewnętrznym rezystorem pull-down (ATmega8 takich nie posiada), można oczywiście rozpatrywać jego użycie podobnie jak w przypadku układu WE.


Który układ wybrać - WE, czy WC?

Z naszego punktu widzenia nie będzie to miało znaczenia, a dlaczego dowiesz się w następnym artykule. Ja wybrałem układ WC.





2. Dokładność pomiarów światła


Powinniśmy się zastanowić nad dokładnością z jaką chcemy dokonywać pomiarów światła. Pisząc o dokładności należy rozumieć przez to:
  • rozdzielczość uzyskanego pomiaru,
  • odstępy czasowe pomiędzy kolejnymi pomiarami.

Przetwornik ADC mikrokontrolera ATmega8 pozwala na pomiary w rozdzielczości 10 bitów. Nam jednak taka rozdzielczość pomiarów nie jest potrzebna. Mamy właściwie wykrywać jedynie:
  • ciemność (noc i zimowe wieczory),
  • jasność dnia,
  • jasność oświetlenia sztucznego.

Nie oznacza to jednak, że nasz przetwornik powinien mieć rozdzielczość zaledwie 2 bitów, ze względu na warunki oświetlenia w jakich będzie musiał pracować. Należy więc wybrać jakiś kompromis.

Podobnie z szybkością otrzymywania kolejnych pomiarów, które mogą być realizowane przez ten mikrokontroler w odstępach ułamków sekund. Nam wystarczy, że odstęp pomiędzy pomiarami będzie wynosił kilka minut.

Ważniejsze więc od parametrów ADC jest dla nas inne ograniczenie, którym jest chęć analizy dość długich okresów czasu. Pomiary będziemy umieszczać w pamięci RAM,  której nie mamy zbyt dużo do dyspozycji (zaledwie 1kB). Dlatego też na rozdzielczość i odstęp czasowy między kolejnymi pomiarami, mają wpływ nie możliwości przetwornika ADC, ale ilość dostępnej pamięci RAM, w której będziemy przechowywać wyniki pomiarów.

Skoro więc to ilość pamięci RAM decyduje o dokładności pomiarów światła, to w ciemno można przyjąć, że w zupełności wystarczy nam 8 bitowa rozdzielczość przetwornika ADC, a co do odstępów czasu pomiędzy kolejnymi pomiarami zadecydujemy później.

Takie podejście zapewni nam wystarczający poziom dokładności pomiarów światła przy akceptowalnej zajętości pamięci RAM - czyli mamy nasz kompromis.

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


Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

Działy
Działy dodatkowe
Inne
O blogu




Dzisiaj
--> za darmo!!! <--
1. USBasp
2. microBOARD M8


Napisz artykuł
--> i wygraj nagrodę. <--


Co nowego na blogu?
Śledź naszego Facebook-a



Co nowego na blogu?
Śledź nas na Google+

/* 20140911 Wyłączona prawa kolumna */
  • 00

    dni

  • 00

    godzin

  • :
  • 00

    minut

  • :
  • 00

    sekund

Nie czekaj do ostatniego dnia!
Jakość opisu projektu także jest istotna (pkt 9.2 regulaminu).

Sponsorzy:

Zapamiętaj ten artykuł w moim prywatnym spisie treści.