[PROJEKT] Moduł telemetryczny M2M na bazie zestawu FRDM-KL25Z (KINETIS L)
Fot. 11. Wygląd kompletnego systemu M2M
Opis wykonanej aplikacji
Schemat blokowy działania aplikacji przedstawiono na rysunku 12.
Rys. 12. Schemat blokowy działania aplikacji
Mikrokontroler Kinetis L swoje działanie rozpoczyna od skonfigurowania wewnętrznych zasobów sprzętowych, których użycie wymagane jest przez aplikację. Pierwszym zasobem jest przetwornik A/C. Trzy jego kanały, przyporządkowane do wyprowadzeń PTD1, PTD5 i PTD6, używane są do odczytywania poziomu napięcia na wyjściu czujników, kolejno czujnika ciśnienia atmosferycznego, czujnika temperatury powietrza oraz czujnika wilgotności powietrza. Drugi niezbędny do wykorzystania zasób sprzętowy to interfejs UART. Służy on do komunikowania się mikrokontrolera z modułem GSM/GPRS. Wyprowadzeniami wybranymi do realizacji transmisji danych przez ten interfejs są PTA1 (UART RX) oraz PTA2 (UART TX). Ostatni konfigurowany przez mikrokontroler zasób sprzętowy to porty wejścia/wyjścia. Użyto ich w sumie pięć. Pierwszym z nich jest PTE0. Za jego pomocą realizowane jest sterowanie kluczem tranzystorowym odpowiadającym za włączanie i wyłączanie dołączonych do systemu urządzeń. Pozostałe porty są używane do sterowania wyświetlaczem: PTC0 – linia RES, PTC1 – SCE, PTC2 – CLK, PTC3 – DIN. Po zakończeniu konfiguracji przetwornika A/C, interfejsu UART oraz portów wejścia/wyjścia, mikrokontroler przystępuje do przygotowania do pracy komponentów zewnętrznych: wyświetlacza i modułu GSM/GPRS. W pierwszej kolejności zainicjowany zostaje wyświetlacz LCD, po czym ustawione zostaje tło ekranu (biały kolor) oraz wyświetlone zostają nazwy mierzonych wielkości oraz ich jednostki. W następnej kolejności konfigurowany jest moduł GSM/GPRS. Odbywa się to za pomocą komend AT (skrót AT pochodzi od słowa ‘ATtention’), a więc standardowej formy sterowania modemami. Każda komenda ma następującą postać: przedrostek AT, znak plusa, nazwę instrukcji ,dodatkowe znaki zależne od danej komendy oraz znak nowej linii i znak powrotu karetki. Listę wysyłanych przez mikrokontroler do modułu M95 komend AT (zarówno w fazie konfiguracji, jak też na potrzeby wysłania wiadomości SMS) oraz ich znaczenie przedstawiono w tabeli 3.
Tab. 3. Lista komend wysyłanych do modułu M95
Komenda AT |
Znaczenie komendy AT |
AT+CNMI |
Konfiguracja sposobu informowania o odebraniu nowej wiadomości SMS |
AT+CMGF |
Ustawienie trybu SMS: tekstowy lub PDU (reprezentacja binarna zakodowana w postaci szesnastkowej) |
AT+CMGS |
Wysłanie wiadomości SMS |
Po zakończeniu tego etapu działania aplikacji mikrokontroler rozpoczyna wykonywanie operacji w nieskończonej pętli. Wewnątrz niej wyróżnić można trzy zadania. W pierwszym zadaniu wykorzystywany jest przetwornik A/C. Mikrokontroler za jego pomocą odczytuje poziom napięć wyjściowych czujników. Następnie wartości napięcia przeliczane są na wartości mierzonych wielkości. Drugie zadanie polega na wyświetlaniu obliczonych wartości na wyświetlaczu (fotografia 13). Ostatnim, trzecim zadaniem jest sprawdzanie czy moduł GSM/GPRS odebrał nową wiadomość SMS, a jeśli tak, odpowiednie na niego reagowanie. W zależności od treści odebranego SMSa, a więc znaku ‘1’, ‘2’ lub ‘3’, mikrokontroler odpowiednio włącza klucz tranzystorowy, wyłącza klucz tranzystorowy lub odsyła do nadawcy wiadomość SMS zawierającą dane z czujników (fotografia 14).
Fot. 13. Mikrokontroler wyświetla na wyświetlaczu dane z czujników
Fot. 14. Treść wysłanych przez użytkownika wiadomości SMS do systemu M2M oraz treść wiadomości SMS (odpowiedzi) wysłanej przez system M2M do użytkownika
Kod źródłowy aplikacji stworzony został przy użyciu środowiska programistycznego CodeWarrior firmy Freescale. Interfejs programistyczny do peryferiów (przetwornika A/C, interfejsu UART i portów wejścia/wyjścia) został wygenerowany przez zintegrowane w środowisku CodeWarrior narzędzie Processor Expert. Bazując na tym interfejsie napisany został kod źródłowy implementujący przewidziane systemowi funkcjonalności. Przykładowo, wygenerowany interfejs programistyczny udostępnia kilka przydatnych funkcji do obsługi przetwornika A/C: AD1_SelectSampleGroup() – funkcja do wyboru kanału przetwornika A/C, AD1_StartSingleMeasurement() – funkcja rozpoczynająca pomiar napięcia w aktywnym kanale, AD1_GetMeasuredValues() – funkcja odczytująca wartość zmierzonego napięcia w aktywnym kanale. Na bazie tych funkcji stworzony został kod źródłowy obsługujący czujniki (listing 1).
List. 1.
//pomiar wilgotnosci Error = AD1_SelectSampleGroup(MyADCPtr, 0U); Error = AD1_StartSingleMeasurement(MyADCPtr); while(AD1_GetMeasurementCompleteStatus(MyADCPtr) != TRUE); { Error = AD1_GetMeasuredValues(MyADCPtr, (LDD_TData *)&MeasuredValue); napiecie_wilgotnosc = MeasuredValue * 2.96 / 65536; wilgotnosc = (napiecie_wilgotnosc - 0.5)/0.0214; } //pomiar temperatury Error = AD1_SelectSampleGroup(MyADCPtr, 1U); Error = AD1_StartSingleMeasurement(MyADCPtr); while(AD1_GetMeasurementCompleteStatus(MyADCPtr) != TRUE); { Error = AD1_GetMeasuredValues(MyADCPtr, (LDD_TData *)&MeasuredValue); napiecie_temperatura = MeasuredValue * 2.96 / 65536; temperatura = 85.543*(1.8663 - napiecie_temperatura); } //pomiar cisnienia Error = AD1_SelectSampleGroup(MyADCPtr, 2U); Error = AD1_StartSingleMeasurement(MyADCPtr); while(AD1_GetMeasurementCompleteStatus(MyADCPtr) != TRUE); { Error = AD1_GetMeasuredValues(MyADCPtr, (LDD_TData *)&MeasuredValue); napiecie_cisnienie = MeasuredValue * 2.96 / 65536; cisnienie_float = (napiecie_cisnienie + 0.285)/0.027; }
Innym przykładem może być obsługa modułu GMS/GPRS. Interfejs programistyczny udostępnia dwie funkcje dedykowane do kontroli transmisji UART: AS1_ReceiveBlock() – funkcja odbierająca dane przez interfejs UART, AS1_SendBlock() – funkcja wysyłająca dane przez interfejs UART. Korzystając z tych funkcji mikrokontroler może komunikować się z modułem GSM/GPRS wysyłając i odbierając wiadomości SMS. Odbywa się to w następujący sposób. Wiadomość SMS od razu po odebraniu przez moduł GSM/GPRS jest przekazywana interfejsem UART do mikrokontrolera. Dane te mikrokontroler wczytuje poprzez funkcję AS1_ReceiveBlock() do 60-elementowej tablicy. Następnie w tablicy tej wyszukiwany jest koniec wiadomości – liczba 10 oznaczająca nową linię). Gdy już zostanie określony indeks końca wiadomości, sprawdzana jest wartość wiadomości, która znajduje się na pozycji o dwa mniejszej od pozycji końca wiadomości – znajduje się tam jednocyfrowa treść wiadomości (ostatni element to wspomniany znak nowej linii, przedostatni element to z kolei znak powrotu karetki). Jeśli wartość ta wynosi 3, mikrokontroler używając funkcji AS1_SendBlock() wysyła do modułu komendy AT, których skutkiem jest wysłanie SMSa zwrotnego z informacją o zmierzonych parametrach środowiskowych. Odpowiedni kod źródłowy pokazano w listingu 2.
List. 2.
char Data1[] = "AT+CNMI=3,2,0,0,0\r\n"; char Data2[] = "AT+CMGF=1\r\n"; char Data3[] = "AT+CMGS=\"693715000\"\r\n"; char Data5[] = "temperatura: oC, wilgotnosc: %, cisnienie: hPa"; char character[] = {0x1A, 0x1A}; . . . AS1_ReceiveBlock(AS1_DeviceData, receive_buffer,60); if(receive_buffer[0] != 0) { for(buffer_index = 59; buffer_index> 0; buffer_index--) { if(receive_buffer[buffer_index] == 10) { if(receive_buffer[buffer_index-2] == '1') { Wiatrak_PutVal(NULL,1); break; } if(receive_buffer[buffer_index-2] == '2') { Wiatrak_PutVal(NULL,0); break; } if(receive_buffer[buffer_index-2] == '3') { Data5[12] = temperatura_table[0]; Data5[13] = temperatura_table[1]; Data5[30] = wilgotnosc_table[0]; Data5[31] = wilgotnosc_table[1]; Data5[46] = cisnienie_table[0]; Data5[47] = cisnienie_table[1]; Data5[48] = cisnienie_table[2]; Data5[49] = cisnienie_table[3]; AS1_SendBlock(AS1_DeviceData, Data1, sizeof(Data1)-1); short_delay(); AS1_SendBlock(AS1_DeviceData, Data2, sizeof(Data2)-1); short_delay(); AS1_SendBlock(AS1_DeviceData, Data3, sizeof(Data3)-1); short_delay(); AS1_SendBlock(AS1_DeviceData, Data5, sizeof(Data5)-1); short_delay(); AS1_SendBlock(AS1_DeviceData, character, sizeof(character)-1); break; } } } }