background image

Mateusz Fijałek 

Przemysław Fierek 

Kierunek: Informatyka 

II Rok – I Stopień 

 

 

 

Dokumentacja projektu

 

STM32 + SHT21 + CAN + BLUETOOTH via VSCP

 

( Very Simple Control Protocol )

 

 

 

 

 

 

 

background image

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. 

background image

 

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.  

 

 

 

 

 

 

 

background image

Jak to działa? 

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).

background image

Implementacja VSCP

 

 

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. 

background image

  

 

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 :: (I

2

C) 

- transceiver CAN – MCP2551 :: (CAN) 

zewnętrzny EEPROM – ATMEL 24c16 :: (I

2

C) 

background image

Przebieg projektu 

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ść 

background image

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 I

2

C. 

 

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 

background image

1-8B :: bajty danych  

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) 

background image

Budowa EXTID :: 

Identyfikator ramki CAN w jest wypełniony następującymi wartościami. 

BITY w EXTID 

0-7 

8-15 

16-24 

25 

26-28 

Adres 

Typ zdarzenia 

Klasa zdarzenia 

NicknameID 

urządzenia jest 

zakodowany na 

stałe 

Priorytet 

 

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),  

background image

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.  

 

 

 

background image

Przesyłane ramki 

Ramka 

Klasa 

Typ 

Priorytet 

Adres 

DLC 

Temperatura 

10 

0xFF 

0x85  

Wilgotność 

10 

35 

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. 

background image

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.