Zestaw startowy Microchip PIC16F18446 Sensor Board – demonstracja możliwości płytki, część 2
Pomiar temperatury zewnętrznej
Do pomiaru wykorzystano sensor MCP9701. Jest to typowy układ mierzący temperaturę z zakresu od 0 °C do +70 °C z dokładnością +/- 2 °C max. Sygnałem wyjściowym jest napięcie zmieniane ze współczynnikiem 19,5 mV/°C. Napięcie Vout jest podawane na wyprowadzenie RC3 (ANC3) mikrokontrolera. Napięcie początkowe dla temperatury 0 °C wynosi 400 mV. Dla temperatury pokojowej +20 °C mamy napięcie 390 mV (20*19,5 mV) plus 400 mV = 790 mV. Napięcie referencyjne dla ADCC jest uzyskiwane z modułu programowanego napięcia referencyjnego FVR_Buffer1 i ma wartość 1,024 V. To określa maksymalną mierzoną temperaturę na poziomie 1024mV-400mV= 624mV; 624mV/19,5mV = 32°C. Układ pomiaru temperatury jest pokazany na rysunku 1, a procedura pomiaru na listingu 1.
Rysunek 1. Układ pomiaru temperatury
int32_t temp10bit, temp12bit; int32_t temp10bitOffset, temp12bitOffset; void readTemperature() { uint32_t res; uint16_t i; ADREF = 0x03; // ADNREF VSS; ADPREF FVR res = 0; for(i=0; i<32; i++) { ADCC_GetSingleConversion(channel_Temperature); res += (ADCC_GetAccumulatorValue() >> 6); } res = res >> 5; temp10bit = (res & 0xFFFFFFFC) - 1600; temp10bit *= 100; temp10bit /= 78; temp12bit = res - 1600; temp12bit *= 100; temp12bit /= 78; }
Listing 1. Procedura pomiaru temperatury
Pomiar ciśnienia atmosferycznego
Czujnikiem ciśnienia atmosferycznego jest układ MP3V5050VC6U lub MP3V5050GP. Czujnik jest wykonany w technologii MEMS i mierzy różnicę ciśnień w zakresie od 0 do 50 kPa od poziomu 100 kPa. Czułość pomiaru wynosi 54 mV/kPa, czyli dla pełnego zakresu na wyjściu Vout mamy napięcie 50*54 mV = 2700 mV. Układ musi być zasilany napięciem minimum +2,7 V, typowo 3,0 V. My mamy mierzyć ciśnienie atmosferyczne o wartości 100 kPa (1000 hPa) + 50 kPa.
Listing 2 pokazuje procedurę pomiaru napięcia z rozdzielczością 12- i 10-bitową z czujnika i przeliczenie jej na wartość ciśnienia w paskalach. Dla wyświetlanego ciśnienia 1023 hPa na wyjściu czujnika zmierzone napięcie wynosi ok. 145 mV.
Rysunek 2. Układ pomiaru ciśnienia
void readPressure() { uint32_t res; uint32_t v; ADREF = 0x03; // ADNREF VSS; ADPREF FVR ADCC_GetSingleConversion(channel_Pressure); res = ADCC_GetAccumulatorValue() >> 6; v = res; v += 16602; v *= 596; v /= 100; pressure12bit = v; v = res & 0xFFFFFFFC; // 12-bit to 10-bit v += 16602; v *= 596; v /= 100; pressure10bit = v; }
Listing 2. Procedura pomiaru ciśnienia atmosferycznego
Detektor metalu
Pomiary temperatury czy ciśnienia za pomocą dedykowanych czujników to standardowe wykorzystanie modułu przetwornika ADC. Na płytce znajduje się też nietypowy, ciekawy układ do wykrywania zbliżenia przedmiotów wykonanych ze stali (ferromagnetyka). Taki czujnik można wykorzystać na przykład do wykrywania zamknięcia lub otwarcia metalowych drzwi. Głównym elementem detektora jest dość spora cewka powietrzna o indukcyjności 160 uH (rysunek 17).
Rysunek 3. Cewka detektora metalu
Rysunek 4. Schemat układu detektora metalu
Zasada działania detektora jest następująca: po uruchomieniu procesu detekcji wykonywana jest jednorazowo procedura skanowania. Na wejście układu z wyprowadzenia RC1 jest podawany przebieg prostokątny generowany przez moduł NCO. Częstotliwość tego przebiegu zmienia się w zakresie od 30 kHz do 45 kHz. Po każdej zmianie częstotliwości z ustalonym krokiem mierzone jest napięcie stałe („amplituda”) na emiterze tranzystora Q2. Program wyszukuje i zapamiętuje taką częstotliwość sterującą, przy której napięcie na emiterze Q2 jest największe. Zostało to pokazane na listingu 3.
void metalDetectorGetPeakFreq() { uint16_t scf, i; uint32_t res = 0; ADREF = 0x00; // ADNREF VSS; ADPREF VDD enableNco(); peakFreq = 0; // zerowanie czestotliwosci peakAmpl = 0; // zerowanie „amplitudy” // pętla skanowania czestotliwosci for(scf = scanFreqMin; scf < scanFreqMax; scf += scanFreqStep) { setNcoFreq(scf); //ustawienie częstotliwości NCO __delay_us(250); res = 0; //pomiar napięcia na wyjściu układu detektora for(i=0; i<8; i++) { ADCC_GetSingleConversion(channel_MetalDetector); res += ADCC_GetAccumulatorValue() >> 6; } res = res >> 3; //wyszukanie maksymalnej wartości napięcia i zapamiętanie czestotliwosci if(res > peakAmpl) { peakAmpl = res; peakFreq = scf; } } setNcoFreq(peakFreq); //ustawienie częstotliwości po skanowaniu __delay_us(250); readMetalDetector(); //odczytanie detektora md10bitOffset = md10bit; md12bitOffset = md12bit; }
Listing 3. Skanowanie częstotliwości
void setNcoFreq(uint32_t freq) { // for 32MHz System Clock freq *= 100; freq /= 1526; NCO1INCU = ((freq >> 16) & 0xFF); NCO1INCH = ((freq >> 8) & 0xFF); NCO1INCL = ((freq ) & 0xFF); }
Listing 4. Ustawianie częstotliwości generatora NCO
Cewka układu detektora jest połączona pomiędzy bazą tranzystora a masą. Przybliżanie do niej ferromagnetyka powoduje wzrost indukcyjności, a co za tym idzie zwiększenie reaktancji cewki przy stałej częstotliwości. Amplituda przebiegu na bazie tranzystora maleje. Na rysunku 5 pokazano oscylogramy przebiegów na bazie tranzystora Q2 przy cewce bez przybliżonego ferromagnetyka oraz z przybliżonym przedmiotem stalowym. Układ wejściowy działa jak filtr dolnoprzepustowy i dlatego wejściowy sygnał prostokątny generowany przez układ NCO po odfiltrowaniu harmonicznych staje się przebiegiem sinusoidalnym.
Po przybliżeniu przedmiotu stalowego amplituda zmalała z 3,1 V na 2,7 V, a napięcie stałe na wyjściu układu czujnika z 880 mV na 610 mV. Zbliżanie i oddalanie przedmiotu stalowego powoduje, że napięcie na czujniku będzie się zmieniało mniej więcej w tym zakresie. Wystarczy teraz to napięcie zmierzyć i odpowiednio zinterpretować. Procedura obsługi czujnika wyświetla na ekranie linię. Jej umiejscowienie na ekranie odzwierciedla stan napięcia na wyjściu czujnika. Jest tez możliwość sygnalizacji dźwiękowej. Przy zbliżaniu metalu do cewki rośnie częstotliwość sygnału dźwiękowego, a przy oddalaniu maleje. Pomiar napięcia wyjścia detektora wykonuje procedura readMetalDetector (listing 5).
Rysunek 5. Oscylogramy przebiegów na bazie tranzystora Q2
void readMetalDetector() { uint32_t res; uint16_t i; ADREF = 0x00; // ADNREF VSS; ADPREF VDD res = 0; for(i=0; i<32; i++) { ADCC_GetSingleConversion(channel_MetalDetector); res += (ADCC_GetAccumulatorValue() >> 6); } res = res >> 5; res = 4095 - res; md10bit = (res & 0xFFFFFFFC); md12bit = res; }
Listing 5. Pomiar napięcia z wyjścia układu czujnika metalu