Mateusz Fijałek
Przemysław Fierek
Kierunek: Informatyka
II Rok – I Stopień
Dokumentacja projektu
STM32 + SHT21 + CAN + BLUETOOTH via VSCP
( Very Simple Control Protocol )
VSCP - Bardzo prosty protokół kontroli
VSCP (Very Simple Control Protocol) czyli bardzo prosty protokół kontroli.
Jak sama nazwa wskazuje jest to bardzo łatwy do zaimplementowania i nieskomplikowany protokół stworzony z myślą o programowaniu low-endowych (raczej tanich)
mikrokontrolerów.
W rzeczywistości VSCP jest więcej niż tylko protokołem. Zebrany w pakiet opisany
jako VSCP and Friends (i przyjaciele) stanowi gotowe narzędzie do monitorowania i sterowania. Protokół został umieszczony w domenie publicznej w roku 2000, kiedy projekt został uruchomiony po praz pierwszy, a zatem do wykorzystania i wdrażania dla wszystkich.
VSCP używa bardzo szczegółowo określonego formatu wiadomości i wspiera
technologię niepowtarzalnych identyfikatorów globalnych dla węzłów. Umożliwia to
rozpoznanie węzła pośród innych na całym świecie. Posiada model rejestrów aby zaoferować wspólny i uniwersalny interfejs konfiguracji węzła.
VSCP pracuje z różnymi mechanizmami transportu, takimijak Ethernet, TCP/IP,
Wireless, ZigBee, Bluetooth, GPRS, RS-232, USB.
Każda sytuacja kontroli mogą być opisywane i realizowane z wykorzystaniem VSCP.
Niektóre zalety:
•
darmowe i otwarte dla komercyjnych i innych
•
Posiada 2 poziomy. Pierwszy bardzo prosty do przesyłania
prostych komunikatów CAN . Poziom 2 może być stosowany
do TCP, UDP, RF, komunikacji sieci, itp itd.
•
unikalny identyfikator dla każdego węzła.
•
Posiada mechanizm automatycznie przypisujący unikatowy
identyfikator do nowo zainstalowanych węzłów i informujący
inne węzły i ewentualnych hostów, że nowy węzeł jest
dostępny i gotowy.
Używa "rejestrów " jako jednolitego sposobu konfiguracji
węzłów.
•
Możliwość korzystania z "macierzy decyzyjnej" do
programowania węzłom dynamicznej funkcjonalności.
•
Posiada specyfikację języka "MDF", która opisuje moduł w
jednolity sposób, tak że może być wykorzystany przez
skonfigurowane oprogramowanie.
•
Posiada oprogramowanie i sterowniki dla systemów Windows
i Linux. Aktualizowane przez cały czas.
Dlaczego kolejny protokół?
VCSP jest przeznaczony do stosowania, gdy inne rozwiązania są zbyt drogie do
wdrożenia. Z reguły inne protokoły wykorzystują większą ilości zasobów (flash / ram) na mikrokontroler co znacznie zwiększa koszty projektu.
VSCP może pracować z zarówno z typowymi najuboższymi węzłami jak seria
MCP250xx Microchip z 1K-2K flash , albo też z mikrokontrolerami o 5K pamięci flash z pełną funkcjonalnością.
VSCP jest swobodny i otwarty. Każdy może przyłączyć się do projektu i pomóc, aby
dodać funkcje do protokołu. Jest to wolne oprogramowanie i kody sterowników dostępne dla większości mikrokontrolerów, które korzystają z wielu technik komunikacji. Każdy może używać tego kodu bez obowiązku zwracania nowego kodu.
Zdarzenia (events)
VSCP bazuje na zdarzeniach systemu. Węzły generują i reagują na wydarzenia.
Zdarzenia nie są ukierunkowane a nadawane do całej magistrali. Od odbiorcy zależy czy jest zainteresowany zdarzeniem czy nie.
Wszystkie zdarzenia posiadają adres z którego są wysyłane. Jest to GUID składający się z 16 bajtów, ale zazwyczaj używane są krótsze jednobajtowe „Nicki”.
Zdarzenia są podzielone na poziomy. Poziom pierwszy jest ograniczony do maksimum
ośmiu bajtów danych, podczas gdy poziom wydarzeń II może mieć do 488 bajtów danych.
Mała liczba maksymalnych danych na poziomie I pochodzi z tego że CAN został wykorzystany wspólny mianownik. Nie ogranicza VSCP Poziomu pierwszego do tego by być używanym
tylko przez CAN.
Obydwa poziomy są podzielone na klasy i typy. Klasa definiuje grupę zdarzeń
określonego typu. Typowymi przykładami są zajęcia dla pomiarów, sterowania i informacji.
Jak wspomniano powyżej zdarzenia nie są skierowane do konkretnego odbiorcy. To
nie jest całkiem prawdą, jako że jedna klasa na każdym poziomie (CLASS1.PROTOCOL i CLASS2.PROTOCOL) posiadają zdarzenia, które są adresowane. Klasy te określa
funkcjonalność protokołu, przy połączeniu wszystkich węzłów. Przykładami mogą być tutaj typse dla programu rozruchowego dostęp do rejestru i informacji o stanie.
Większość wydarzeń może korzystać strefy/podstrefy by zdefiniować grupę różnych
węzłów należących na przykład do jednego pokoju , maszyny lub jakiegokolwiek innego modelu grupowania (geograficznych, logiczne, funkcjonalne ugrupowania wychodzące poza klasy i typy).
Przeniesienie VSCP na nową platformę nie jest bardzo trudne, lecz wymaga
wykonania kilku kolejnych czynności.
• Najpierw należy pobrać kod źródłowy ze strony projektu lub z
repozytorium SVN. Instrukcja jak to zrobić dziale download
projektu.
• Odnajdujemy folder _rmware/common folder w folderze z plikami
źródłowymi. Znajdują się w nim pliki vscp.c i vscp.h, które
umożliwiają wdrożenie praktycznie całego węzła VSCP. Folder
src/vscp/common zawiera inne ważne pliki, które są potrzebne w
przypadku pracy z systemami wyższego poziomu, poza
vscp_class.h i vscp_type.h które definiują wszystkie potrzebne
klasy i typy.
• VSCP do prawidłowego działania potrzebuje pliku inttypes.h.
Większość systemów posiada już ten plik dedykowany, ale
istnieje wersja standardowa w folderze /commons.
• Następnie należy przemyśleć organizację rejestrów procesora.
Większość węzłów potrzebuje jednej przestrzeni i co najmniej
jednej (może kilku) podprzestrzeni Wszystkie rejestry są 8
bitowe i jeśli potrzebna jest większa wartość, trzeba dane
podzielić. W tym przypadku najbardziej znaczący bit znajdować
się musi na najniższej pozycji rejestru.
• Teraz zdefiniowane powinny być zdarzenia jakie węzeł powinien
wysłać, a także zdecydować na jakie zdarzenia odpowiada i w
jaki sposób. odpowiedzi na pewne wydarzenia.
• Rozpoczynamy pisanie kodu na naszej platformie. Ustawiamy jako
czas bazowy 1 milisekundę. Sprawdzamy działanie, poprzez
stworzenie zmiennej, która podobnie jak vscp_timer jest
inkrementowana co 1ms. Jeśli w pustej pętli indeks będzie
większy niż 1000, znaczy że upłynęła sekunda.
• Każdy węzeł VSCP powinien mieć przycisk inicjalizacyjny.
Standardowo przycisk ten powinien być wciśnięty przez 2
sekundy zanim pojawią się warunki do wykonania inicjalizacji.
Informacje na ten temat przechowuje plik vscp_initbtncnt.
• Każdy węzeł VSCP powinien mieć diodę LED, która informuje o stanie
węzła. Miga w trakcie inicjalizacji i jeśli szukanie wolnego „Nicka”
się powiodło zaświeca się na stałe, a jeśli wystąpił błąd
inicjalizacji wyłącza się całkiem.
Założenia
Głównym założeniem projektu była budowa termometru wraz z pomiarem
wilgotności, pracującego jako węzeł CAN (Control Area Network), a także
umożliwiającego pomiar temperatury przez urządzenie mobilne (PocketPC -
Windows Mobile). Komunikacja z urządzeniem mobilnym zrealizowana miała być za
pośrednictwem technologii Bluetooth. Projekt oparty był o mikrokontroler z rodziny STM32. Całość kontrolowana miała być przez zaimplementowany dla tych celów
protokół VSCP.
Wykorzystane podzespoły
- zestaw uruchomieniowy oparty o STM32 – ZL31ARM
- Bluetooth – BTM-222 :: (USART)
- PocketPC – i-Mate JAMA 101 ( Windows Mobile 6.1 )
- czujnik temperatury i wilgotności – Sensirion SHT21 :: (I2C)
- transceiver CAN – MCP2551 :: (CAN)
- zewnętrzny EEPROM – ATMEL 24c16 :: (I2C)
1. Pierwszym krokiem projektu było napisanie bibliotek umożliwiających sprawne
i efektywne wykorzystanie urządzeń wykorzystywanych w projekcie. Napisane
zostały biblioteki konfigurujące mikrokontroler STM32, obsługujące czujnik SHT21
(odczyt temperatury, wilgotności a także konfiguracja czujnika), umożliwiające zapis i odczyt z EEPROM 24c16. Biblioteki zostały utworzone na podstawie materiałów
znalezionych na stronach producentów (ST, Sensirion), konfiguracja na podstawie
książki STM32 w Praktyce. Linki do materiał znajdują się na końcu dokumentu.
2. Kolejnym krokiem było przestudiowanie dokumentacji potrzebnej do
zrozumienia zasady działania protokołu VSCP. Dokumentacja znajduje się w na
stronie http://www.vscp.org/, w trakcie trwania projektu opieraliśmy się o
specyfikacje w wersji 1.7.7, a także o paczkę źródeł o nazwie kodowej Carbon
0.3.1.
3. W trakcie dalszych prac przystąpiliśmy do analizowania kodów, przykładów
dostępnych w paczce ze strony VSCP. W czasie pisania kodu wykorzystaliśmy kilka
pomysłów i fragmentów kodu z projektów „Kelvin SHT” (dla mikrokontrolera PIC), a
także projektu „Digiprobe” (dla mikrokontrolera AVR), a także przykładów
dostarczonych przez prowadzącego.
4. Mając ogólny zarys projektu przystąpiliśmy do implementacji protokołu dla
naszego projektu. W paczce ze źródłami znajdował się plik firmware_vscp.h i
firmware_vscp.c, plik zostały przezwane na odpowiednio vscp.h i vscp.c, następnie dopisaliśmy niezbędne funkcje w pliku vscp.c (których prototypy znajdowały się w
vscp.h). W przykładach na, których się wzorowaliśmy niektóre funkcje zostały
napisane tak uniwersalnie, że możliwe było ich wykorzystanie w naszym projekcie
przy niewielkich modyfikacjach.
5. W projekcie występowały funkcje wymagającej pamięci EEPROM. Ponieważ
STM32 nie posiada pamięci EEPROM, wykorzystana została zewnętrzna kość
pamięci (ATMEL 24c16). Do obsługi została napisana biblioteka zwierająca podstawowe funkcje (readEEPROM, writeEEPROM) niezbędne do działania projektu.
Nie jest to jedyne rozwiązanie, gdyż producent firma ST dostarcza biblioteki
umożliwiające emulacje pamięci EEPROM. To rozwiązanie nie zostało wykorzystane
ponieważ wraz z rozrostem projektu komórki pamięci EEPROM były nadpisywane.
Bardziej wygodny wydał się pomysł zewnętrznej pamięci podłączonej do
mikrokontrolera przy pomocy I2C.
6. Ważnym krokiem w projekcie było napisanie funkcji odpowiedzialnych za
wysyłanie i odbieranie ramki CAN z informacją o temperaturze. Za to zadanie
odpowiedzialne są d i wie funkcje getVSCPFrame i sendVSCPFrame. Funkcje te
odpowiedzialne są za wypełnienie ramki nadawanej i interpretacje otrzymanej ramki CAN (zgodnie z przyjętą metoda komunikacji w przypadku naszego projektu,
zawsze analizowana była ramka CAN). Rozszerzony nagłówek (29bit) ramki CAN
zawiera informacje dotyczące:
- klasy zdarzenia :: bity 16-23
- typu zdarzenia :: bity 8-15
- adresu węzła :: bity 0 – 7
- priorytetu :: bity 26 – 28
- nickname urządzenia :: bit 25
7. Mając gotowe podstawowe narzędzia do dalszej pracy napisaliśmy
komunikacje między urządzeniem mobilnym (PocketPC) i naszym termometrem.
Aplikacją na urządzeniu mobilnym urządzeniu wysyła ramkę CAN przez Bluetooth.
Transmisja przy pomocy protokołu RFCOMM (jest transmisja szeregową). W
dokumentacji VSCP przedstawiony jest dokładnie format takiej wiadomości.
Wysyłana jest ona w następującej postaci: (1B = 1 BAJT)
1B :: DLE
1B :: STX – początek transmisji
1B :: 0x05 – informuje system, że przesyłana jest ramka CAN
4B :: ExtID – rozszerzony nagłówek ramki CAN (29bit)
1B :: DLC – rozmiar danych przesyłanych w ramce
1B :: DLE
1B :: ETX – koniec transmisji
8. Mając gotową transmisje pomiędzy urządzeniami, przystąpiliśmy do macierzy
decyzyjnej, odpowiedzialnej za podejmowanie decyzji, która akcja powinna zostać
wykonana. W pliku vscp_actions.c znajdują się akcje wykonywane w odpowiedzi na
zapytanie wysłane przez VSCP (w przypadku naszego projektu odesłaniu ramki z
temperatura lub wilgotnością).
9. Na tym etapie, komunikacja między urządzeniami działa prawidłowo, w
związku z tym dalsze prace skupiliśmy na mniej znaczących poprawkach. Przy okazji pisania kodu napisaliśmy prosty program do interpretacji danych wysyłanych przez
Bluetooth na komputerze, którego kod źródłowy zamieszczam wraz z projektem.
Komunikacja szczegółowo
Jak odczytać temperaturę lub wilgotność?
Aby odczytać temperaturę należy wysłać ramkę z żądaniem temperatury, w naszym
projekcie zarówno w CAN jak i Bluetooth przesyłana jest ramka CAN. Zapytanie
pochodzące z CAN’u, spowoduje odesłanie odpowiedzi do CAN’u, natomiast zapytanie
pochodzące od urządzenia przesłane przy pomocy Bluetooth, powoduje odesłanie
odpowiedzi do tego urządzenia. W związku z powyższym aby odczytać temperaturę
wysyłamy następującą ramkę:
EXTID DLC DATA0 DATA1 DATA2 DATA3 DATA4 DATA5 DATA6 DATA7
EXTID – nagłówek ramki CAN
DLC – liczba przesyłanych bajtów danych (przyjmuje wartości od 0 do 8)
DATA0 - DATA7 – bajty z danymi (8bajtow)
Identyfikator ramki CAN w jest wypełniony następującymi wartościami.
BITY w EXTID
0-7
8-15
16-24
25
26-28
NicknameID
urządzenia jest
Adres
Typ zdarzenia
Klasa zdarzenia
Priorytet
zakodowany na
stałe
Adres – unikalny identyfikator w systemie, może być zakodowany na stałe lub przydzielony w procesie inicjacji węzła. Wartość 0x00 zarezerwowany dal segmentu
MASTER. 0xFF oznacza, że nickname jest nie przypisany. Węzeł nie otrzymywał
adresu przy inicjalizacji w związku z tym jego adresem był 0xFF.
Klasa zdarzenia – jest to liczba określająca zbiór konkretnych zdarzeń w
rzeczywistości, np. W projekcie wykorzystywana jest CLASS = 10 (Measurment –
pomiar). Informuje to węzeł, że interesuje nas pomiar, co będzie mierzone to określa tym zdarzenia.
Typ zdarzenia – określa konkretny typ zdarzenia w rzeczywistości np. pomiar temperatury, przyciśnięcie przycisku, otwarcie, zamknięcie, etc...
PRZYKŁAD :: Jeśli TYPE = 6 i CLASS = 10 oznacza, że interesuje nas pomiar
temperatury, natomiast jeśli TYPE = 35 i CLASS=10 interesuje nas pomiar
wilgotności.
Priorytet – przesyłanej informacji (0 – najwyższy priorytet, 7 – najniższy priorytet).
Budowa DLC ::
W protokole VSCP poza ilością danych w tym miejscu przechowywana jest flaga
VSCP_VALID_FRAME (informuje ona węzeł, że przesłana ramka jest poprawna),
przechowywana w MSB (najbardziej znaczącym bicie). MSB = 1 – ramka poprawna, MSB = 0 - ramka niepoprawna.
Budowa DATA0 ::
zawiera informacje o tym jaki jest format przesyłanych danych (byte, float, etc…), a także w niektórych przypadkach zawiera dodatkowe informacje dla określonego typu
zdarzenia. Szczegóły można znaleźć w dokumentacji str78. (rozdział :: Data coding).
Źródła zdarzeń:
Pomiar temperatury i wilgotności wykonywany jest w stały odstępach czasu, wartości przechowywane są w pamięci RAM, czas między kolejnymi pomiarami to 5s.
Zdarzenia generowane są przez zewnętrzne węzły, i mogą być przesyłane do
naszego węzła przy pomocy Bluetooth lub CAN. W projekcie zewnętrzny węzłem był
PocketPC, który generował zdarzenia pomiaru temperatury lub wilgotności w
zależności od naszej woli. Możliwe było również określenie jednostek zmierzonej
temperatury. Wszelkie zdarzenie wygenerowane przez telefon były przesyłane przez
Bluetooth zgodnie z informacjami zawartymi w dokumentacji. Każda odebrana ramka
była interpretowana, tzn. sprawdzana była flaga VSCP_VALID_FRAME i jeśli była
poprawna wywoływana była macierz decyzyjna, która powodowała reakcje na
zdarzenie i odesłanie informacji zwrotnej w postaci ramki z danymi. Dane były
transmitowane tylko jako odpowiedź na zdarzenie, informacja nie była wysyłana
ciągle. Zewnętrzne węzły, to wszystkie urządzenia które mogą wysłać ramke
zapytaniem po CAN lub Bluetooth. Termometr nie generuje zdarzeń tylko na nie
odpowiada.
Ramka
Klasa
Typ
Priorytet
Adres
DLC
Temperatura
10
6
3
0xFF
0x85
Wilgotność
10
35
3
0xFF
0x85
Zdarzenie żądające zawierało DLC = 0x81. Bajty DATA1-DATA4 były puste.
Zdarzenie zwrotne zawierało temperaturę lub wilgotność zapisana w DATA1-
DATA4, dlatego DLC = 0x85.
Wytłumaczenie ::
DLC = 0x85
DLC = 0x80 | 0x05
0x05 = 5 <- liczba bajtów danych
0x80 <- flaga VSCP_VALID_MSG. Flaga ustawiana przy przesyłaniu danych.
Podsumowanie
Wszystkie założenia projektu zostały zrealizowane, kody napisanych programów wraz z komentarzami, przekazujemy prowadzącemu. Mamy nadzieje, że zawarte w
sprawozdaniu informacje będą pomocne przy realizacji innych projektów opartych o
mikrokontrolery STM32 i protokół VSCP.
Wykorzystane Materiały
http://www.kamami.pl/dl/zl31arm.pdf - dokumentacja zestawu uruchomieniowego ZL31ARM
http://www.st.com/internet/mcu/product/164487.jsp - informacje o STM32F103RB i
datasheet.
http://www.sensirion.com/en/pdf/product_information/Datasheet-humidity-sensor-
SHT21.pdf - datasheet SHT21.
http://www.sensirion.com/en/pdf/product_information/Sample_Code_humidity-sensor-
sht21.pdf - przykład obsługi czujnika SHT21 napisany w języku ANSI C.
http://vscp.org/downloads.php - dokumentacja VSCP i paczka ze źródłami.
http://www.vgj.pl/allegro/btm222_datasheet.pdf - BTM 222 datasheet.
http://www.koders.com/c/fidE915DC25ED09E6E250CEB77020D465DD656248AB.aspx?s=crc
– przykłady dla VSCP :: (Kelvin SHT)
Materiały dostarczone przez prowadzącego.