W końcu udało się ukończyć projekt, który rozpocząłem ponad rok temu! Jest to rejestrator parametrów - U,I,T. Głównym celem wykonania urządzenia, była możliwość monitorowania zmian napięcia, prądu i temperatury w badanym układzie wraz z zapisem na kartę SD. Założenia i koncepcja zmieniała się z biegiem czasu.
Założenia ogólne:
- Zapis danych na kartę SD;
- Pomiar napięcia do 13VDC;
- Pomiar prądu, do 0,5A;
- Pomiar temperatury z wykorzystaniem DS18B20
- Zasilanie bateryjne, bądź z zasilacza 12VDC;
- Podłączenie przejściówki RS232, modułu bluetooth - złącze RJ45 6P;
- Interfejs użytkownika w postaci wyświetlacza i 4 przycisków;
- Wyświetlanie pomiaru napięcia, prądu i temperatury na wyświetlaczu;
- Diody sygnalizujące wykonywany pomiar, oraz zapis na kartę SD;
- 2 złącza 2 pinowe do pomiaru napięcia i prądu;
- Czujnik temperatury podłączany poprzez złącze jack;
- Pozostałe kanały wyprowadzone na złącze RJ46 8P;
- Mała, przenośna obudowa.
Założenia programistyczne:
- Możliwość zmiany nazw zapisywanych plików z poziomu UI;
- Zmiana czasu dokonywania pomiarów (próbkowania);
- Włączenie/wyłączenia odpowiednich kanałów pomiarowych;
- Dane konfiguracyjne zapisywane w pamięci EEPROM;
Czytając powyższe założenia, można sobie wyobrazić ogrom pracy, jaki był, podczas wykonywania rejestratora. Gdy zabrałem się za wykonywanie projektu, myślałem że nie uda mi się wszystkich założeń wykonać tak jak planuję. Jednak udało mi się i jestem z tego efektu bardzo zadowolony.
Przedstawię krótko najważniejsze cechy i funkcjonalności urządzenia - dokładny i szczegółowy opis zająłby pewnie dużo czasu jak i objętości.
Poniżej przedstawiam schemat ideowy całego układu.
Rejestrator może być zasilany z dwóch źródeł - z baterii (na chwilę obecną jest to bateria 9V - nie nadają się one jednak do takiego zastosowania bo mają zbyt małą pojemność), bądź z zasilacza zewnętrznego. Napięcie jakie panuje w wykonanym układzie wynosi 3.3V, jest ono zapewniane przez stabilizator LM1117DT-3.3. Zastosowanie napięcie 3,3V umożliwiło bezpośrednie podłączenie karty SD do mikrokontrolera bez stosowania dodatkowych układów do translacji napięcia. Komunikacja po RS232 jak i obsługa czujnika DALLAS DS18B20 jest również możliwa przy zastosowanym napięciu.
W wykonanym urządzeniu napięciem pracy jest 3.3V, więc zastosowanie typowego wyświetlacza z sterownikiem HD44780 może skutkować tym, że napisy mogą nie być prawidłowo wyświetlane z powodu zbyt małego napięcia kontrastu. Postanowiłem więc zastosować przetwornicę napięcia ujemnego i wykonać moduł do tych wyświetlaczy. Dodatkowo taki moduł wyposażyłem w złączki które ułatwią mi podłączanie tego wyświetlacza do docelowego układu.
Jedyny problem - raczej niedogodność - który wynikł z zastosowania napięcia 3.3V dotyczy pomiaru różnicowego napięcia oraz prądu, a dokładnie maksymalnego napięcia wyjściowego w zastosowanym wzmacniaczu operacyjnym. Według noty katalogowej LM358 napięcie wyjściowe wzmacniacza operacyjnego może wynieść maksymalnie V+ -1,5V (V+ napięcie zasilające), czyli w moim przypadku dla napięcia zasilającego 3.3V maksymalne napięcie wyjściowe wyniesie 1,8V (w rzeczywistości z pomiarów wyszło mi, że maksymalne napięcie wyjściowe może wynieść 2V). Znając ten parametr musiałem tak dobrać wzmocnienie każdego wzmacniacza aby przy maksymalnej mierzonej wartości nie przekroczyć tego napięcia - o tym troszeczkę później.
Urządzenie umożliwia pomiar napięcia na 7 kanałach, oraz pojedynczy pomiar prądu. W tych 7 kanałach do pomiaru napięcia znajduje się 6 kanałów nieskonfigurowanych (nieposiadających żadnego pomiaru różnicowego - napięcie podawane jest bezpośrednio do układu scalonego i nie może ono przekroczyć napięcia 2,56V), oraz jeden kanał umożliwiający pomiar napięcia do 13V.
Do pomiaru napięcia jak i prądu - jak już wspomniałem - wykorzystałem układ różnicowy z wzmacniaczem operacyjnym. Układ ten umożliwia pomiar spadku napięcia na danym elemencie. Poprzez odpowiedni dobór rezystorów możliwe jest uzyskanie wzmocnienia w dużym zakresie - większe jak i mniejsze od 1. Jedyny największy minus tego rozwiązania to niska rezystancja wejść wzmacniacza, co może powodować zakłócenia w badanym układzie. Dlatego starałem się zastosować rezystancje jak największe, aby wpływ ten był jak najmniejszy (im większa rezystancja to tym mniejszy prąd płynący przez rezystory w układzie różnicowym - prąd który jest "pobierany" z badanego układu). Wzmocnienie w układzie do pomiaru napięcia wynosi k=7 (wartość wzmocnienia obliczonego na podstawie rezystancji wynosi 6.67, natomiast podałem wartość wzmocnienia "rzeczywistego" - rezystancja ścieżek, dokładność 5% rezystorów i lutów w tym przypadku odegrała znaczącą rolę) - czyli dla różnicowego napięcia wejściowego 13V napięcia na wyjściu wyniesie 1,85.
W pomiarze prądu został zastosowany rezystor, tzw. bocznik. Pomiar spadku napięcia na tym rezystorze umożliwia obliczenie z prawa Ohma prądu jaki przez ten rezystor płynie. Zastosowany rezystor posiada rezystancję 0.1ohma. Natomiast rezystory w układzie różnicowym definiują wzmocnienie o wartości k=41 (zastosowałem rezystory o dokładności 1%). Upraszczając - spadek napięcia jest wprost proporcjonalny do prądu płynącego przez rezystor w proporcjach 1 do 4.
Algorytm główny programu przedstawia się następująco:
Przedstawię jedynie kod pętli głównej, resztę ewentualnie na prośbę (ale w fragmencie) jeżeli ktoś by chciał.
Kod: Zaznacz cały
while(1){
backlight();
return_screen();
button_service();
DISPLAY_EVENT(1);
wdt_reset();
pomiary();
ADC_EVENT();
zapisz_dane();
UART_EVENT(uart_bufor);
sygnalizacja_led();
wdt_reset();
}Wykorzystanie zasobów mikrokontrolera ATmega32 przedstawia się następująco:
- FLASH - 27,848 kb tj. 85%
- RAM - 1,372kb tj. 67%
- EEPROM - 24b tj. 2,3%
Mikrokontroler taktowany jest kwarcem o częstotliwości 16MHz.
Komunikacja z komputerem odbywa się poprzez interfejs RS232, natomiast obsługę wykonuje się poprzez komendy AT z wykorzystaniem terminala. Poprzez komendy AT możliwa jest ta sama zmiana i konfiguracja parametrów co poprzez UI. Jedynie kalibracja wyświetlanych wartości napięcia i prądu na wyświetlaczu LCD, jest możliwa poprzez komendy AT (polecenie AT+CAL) - nie ma takiej możliwości z poziomu menu na wyświetlaczu. Dodatkowo do mikrokontrolera jest wgrany bootloader, który umożliwia wgranie nowego programu poprzez RS232 bez podłączania zewnętrznego programatora. Poniżej przedstawiam screeny z działania komunikacji przez RS232.
Wyniki odczytu napięcia i prądu są podawane jako czyste wartości ADC (również w takiej formie są zapisywane na karcie pamięci). Nie stosowałem konwersji wartości pomiarowych, aby zaoszczędzić na czasie podczas zapisu danych na kartę SD. Jedynie napięcie i prąd przedstawiane na wyświetlaczu są na bieżąco przeliczane.
Wykonane pomiary zapisywane są również na karcie SD. Przed wykonywaniem pomiarów możliwa jest zmiana nazwy pliku do jakiego będą zapisywane dane, znak oddzielający kolumny, oraz ilość próbek zapisanych w pliku. Maksymalna ilość plików wynosi 99. Po przerwaniu pomiarów, a następnie rozpoczęciu nowej serii, nowe dane pomiarowe będą zapisywane do kolejnego numeru pliku.
W plikach nie jest zapisywany czas pomiaru. Odstęp pomiędzy pomiarami jest ustawiany wcześniej, więc znane jest próbkowanie - pominąłem ten parametr, aby nie tracić dodatkowe czasu podczas samego zapisu danych na kartę SD.
W projekcie użyłem bibliotek FatFS do obsługi kart SD.
Na potrzeby projektu, stworzyłem własne biblioteki do obsługi przycisków jak i menu. Jako ciekawostkę przedstawiam:
- rejestrację nowych przycisków:
Kod: Zaznacz cały
//rejestracja klawiszy
button_register(&SW_UP, &(PIN(BUTTON_PORT)), (1<<BUTTON_UP),1,20,up_menu_button,NULL); //1
button_register(&SW_DWN, &(PIN(BUTTON_PORT)), (1<<BUTTON_DWN),1,20,down_menu_button,NULL); //4
button_register(&SW_OK, &(PIN(BUTTON_PORT)), (1<<BUTTON_OK),2,200,ok_menu_button, start_button); //2
button_register(&SW_EXIT, &(PIN(BUTTON_PORT)), (1<<BUTTON_EXIT),2,2,exit_menu_button, NULL); //3- obsługę przycisków:
Kod: Zaznacz cały
//obsługa przycisków
void button_service(void){
uint8_t i=0; //i - numer obsługiwanego przycisku,
enum b_st state=none; // state stan dla danego przycisku
for(i=0 ; i<MAX_BUTTON ; i++){
if(button_tab[i]) {
state = ds_button_serv(i);
if(state == procedure)
continue;
if(state == button_short){
if(button_tab[i]->short_push) //jeżeli została przydzielona funkcja
button_tab[i]->short_push();
break;
}
else if(state == button_long){
if(button_tab[i]->long_push) //jeżeli została przydzielona funkcja
button_tab[i]->long_push();
break;
}
}
}
}- oraz strukturę przechowującą informację o przyciskach
Kod: Zaznacz cały
typedef struct {
volatile uint8_t *PORT; //port do którego podłączony jest klawisz, np. PINB
uint8_t button_mask_pin; //pin/maska pinu do którego podłączony jest przycisk, np. (1<<PB0)
uint8_t repeat_wait_s; //czas oczekiwania na identyfikację długiego wcisniecia w s
uint8_t repeat_time_ms; //czas pomiędzy powtórzeniami w 10ms
void (*short_push)(void); //funkcja obsługująca krótkie wcisnienie
void (*long_push)(void); //funkcja obslugująca długie wcisnięcie
} DS_BUTTON;
W programie możliwa jest szybka zmiana obsługi przycisków poprzez funkcje rejestrujące. Szczerze powiem, że jestem bardzo zadowolony z tej biblioteki - nie spodziewałem się, że może mi takie coś wyjść spod moich palców
Przed przystąpieniem do pisania programu określiłem kolejność pisania kodu. Plan kodowania wygląda następująco:
- Obsługa LCD
- Menu i obsługa przycisków
- Obsługa czujnika temperatury
- Komunikacja poprzez RS232
- Obsługa karty SD
- Konfiguracja poprzez UI
- Konfiguracja poprzez komendy AT
- Obsługa ADC
- Bootloader
Tak natomiast przedstawia się wykonany Rejestrator:
Opis tego urządzenia znajdzie się też w najbliższym czasie na mojej stronie - prawdopodobnie w takiej samej formie.
Zachęcam do oceniania, komentowania i zadawania pytań.



