Transmisja szeregowa
Szeroko używaną metodą komunikacji jest transmisja szeregowa. Używa ona
jedną linię sygnałową (plus masę) w jedną stronę plus drugą linię
w przeciwną stronę. Tradycyjnie w komputerach PC był port szeregowy
RS-232. Taki port używa napięcia 12V i -12V które są kłopotliwe
(zbyt duże) dla mikrosterowników, toteż gdybyśmy chcieli połączyć
się przez taki port z mikrosterownikiem to potrzebujemy dodatkowy
układ do zmiany poziomu napięć. Obecnie zamiast normalych portów
szeregowych często używa się konwertorów ("kabli") z USB na
RS-232. Konwertor na RS-232 sprawia ten sam problem z napięciami
co tradycyjny port szeregowy. Na szczęście są obecnie dostępne
konwertory które logicznie dają taki sam sygnał jak RS-232, ale
używają napięć 0V i 3.3V jako sygnałów (często nazywa się to
"TTL serial port"), co typowo pozwala
na bezpośrednie łączenie z mikrosterownikami. W mikrosterownikach
często są sprzętowe porty szergowe, logicznie dające sygnał
jak RS-232, ale na poziomie napięć takim samym jak inne
wejścia/wyjścia cyfrowe procesora. W przypadku gdy sprzętowy
port nie jest dostępny ale dostępny jest stabilny zegar można
używać programową transmisję szeregową (z ograniczoną szybkością).
Transmisję szeregową i RS-232 często używa się jako synonim, ale
są to różne pojęcia. RS-232 specyfikuje użycie jednej lub dwu
(dwu gdy chcemy równoczesną transmisję w obu kierunkach) linii
sygnałowych i lini masy. Na lini sygnałowej mamy napięcie
reprezentujące sygnał. Taka linia transmisyjna ma niezbyt
dobre parametry elektryczne, co ogranicza możliwą szybkość
transmisji na większe odległości. Znacznie lepsze parametry
mają tzw. symetryczne linie różnicowe gdzie linia ma dwa
przewody, na gdy na jednym podajemy napięcie dodatnie to na
drugim symetryczne doń napięcie ujemne. Odbiornik wtedy
reaguje na różnicę napięć między przewodami co eliminuje
wiele zakłóceń. Skręcając przewody tak że w przybliżeniu
tworzą długie symetryczne spirale dodakowo znacznie ograniczamy
zakłócenia. Ponadto z zgodnie z teorią tzw. linii długich
dba się o dopasowanie nadajnika i odbiornika do linii.
Odpowiednie ustalenia są zawarte w standarcie RS-422 który
używając tą samą strukturę logiczną co RS-232 dzięki
odpowiedniej konstrukcji elektrycznej pozwala na uzyskanie
znacznie lepszego tempa transmisji na większe odległości
(dziesiątki metrów do pojedyńczych kilometrów). Od
RS-422 częściej jest używany RS-485 który mając te same
parametry szybkościowe jak RS-422 pozwala na podłaczanie
wielu nadajników i odbiorników do jednej linii (oczywiście
w danym momencie tylko jeden nadajnik może być aktywny).
RS-485 funkcjonuje jak sieć komputerowa. W porównaniu z np. Ethernetem
ma mniejszą przepustowość, tzn. czas transmisji dużego pliku po
RS-485 będzie większy niż po Ethernecie. Jednakże Ethernet
tranmituje pakiety których minimalna długość to 64 bajty.
Po RS-485 zwykle używa się znacznie mniejsze pakiety. W efekcie
do celów sterowania RS-485 może mieć konkurencyją szybkość.
Ponadto RS-485 był tańszy i stawia znacznie mniejsze wymagania
w stosunku do komunikujących się procesorów, co spowodowało
że jest on szeroko stosowany w przemyśle.
My nie mamy urządzeń RS-485, ale podstawowa obsługa jest taka
jak dla normalnego portu szeregowego.
Większość płytek które mamy zawiera interfejs USB który pozwala
na komunikację szeregową z uruchamianym procesorem. Tzn. pod
Linuxem widzimy port wirtualny szeregowy który (poprzez USB) jest
połączony z portem szeregowym uruchamianego procesora. Mamy
też oddzielne konwertory z USB na port szeregowy "TTL". Uwaga:
klasyczne konwertory RS-232 produkują napięcia niebezpieczne
dla procesorów (rzędu +-12V),
dlatego ważne jest użycie konwertora dającego odpowiedni poziom.
Procesor w Stellaris Launchpad zawiera 8 portów szeregowych, port
numer 0 jest połączony z interfejsem uruchomieniowym, pozostałe
można użyć niezależnie.
Aby wypróbować komunikację komputera PC z mikrosterownikiem
może pomóc następujący program.
Wypróbować komunikację między dwoma procesorami przy pomocy
portu szeregowego.
Uwaga: Ze względu na poziomy napięć nie należy łączyć Arduino
z MSP430 Launchpad. Połączenie procesorów tego samego typu
czy też Arduino lub MSP430 Launchpad ze Stellaris Launchpad
powinno działać.
Uwaga: Interfejs uruchomieniowy w MSP430 Launchpad zawiera
interfejs USB do portu szeregowego. Niestety, ten interfejs
ma szybkość ustaloną na 9600 i zawiesza się jeśli MSP430
transmituje a komputer PC nie odbiera. Ponadto by go
użyć z procesorem MSP430G2553 trzeba ustawić poprzecznie
zworki portu szergowego (podłużne ustawienie zamienia miejscami
linie TX i RX i odpowiada procesorowi MSP430G2452). Lepiej
działa podłączenie oddzielnego konwertora z USB na port
szeregowy "TTL", rozłączamy wtedy zworki portu szeregowego
i połączamy linię TX konwertora do RX procesora zaś RX
kowertora do TX procesora. Dodatkowo nasze konwertory
mają wyprowadzone napięcie 5V co pozwala podłączać
do MSP430 Launchpad moduły wymagające zasilania 5V
(oczywiście pod warunkiem że linie sygnałowe nie
mają zbyt dużego napięcia).
SPI
SPI
jest bardzo prostą metodą transmisji pozwalającą uzyskać niezłą
szybkość na małe odległości. Interfejs SPI łączy
urządzenie nadrzędne z jednym lub więcej urządzeniami podrzędnymi.
Sprzętowe interfejsy SPI w mikrosterownikach zwykle umożliwiają pracę
zarówno jako urządzenie nadrzędne jak i jako urządzenie
podrzędne. W środowiskach Arduino i Energia
do obsługi SPI można użyć biblitekę SPI. Implementuje ona tylko
tryb pracy jako urządzenie nadrzędne. Program
spi0.ino pokazuje proste użycie do sterowania
rejestru przesuwającego. Tą samą funkcję można zrealizować
programowo, pokazuje to soft_spi.ino.
Uwaga: Procesor w Stellaris Launchpad zawiera 4 interfejsy SPI.
Domyślny interfejs jest dostępny jako obiekt SPI i
normalnie jest to sprzętowy interfejs numer 2 (można to zmienić
wykonując metodę 'setModule' przed wywołaniem 'begin').
Domyślna konfiguracja używa
portu PA_5 do wyboru urządzenia podrzędnego. Wydaje się że
powoduje to konflikt gdy używamy interfejs numer 0. W przykładzie
nie używamy linii wyboru urządzenia podrzędnego, ale konfigurujemy
ją na PC_7 aby uniknąć konfliktu.
Uwaga: Nóżki używane przez intefejsy SPI są w pliku źródłowym
biblioteki, poniżej odpowiedni fragment:
static const unsigned long g_ulSSIConfig[4][4] =
{
{GPIO_PA2_SSI0CLK, GPIO_PA3_SSI0FSS, GPIO_PA4_SSI0RX, GPIO_PA5_SSI0TX},
{GPIO_PF2_SSI1CLK, GPIO_PF3_SSI1FSS, GPIO_PF0_SSI1RX, GPIO_PF1_SSI1TX},
{GPIO_PB4_SSI2CLK, GPIO_PB5_SSI2FSS, GPIO_PB6_SSI2RX, GPIO_PB7_SSI2TX},
{GPIO_PD0_SSI3CLK, GPIO_PD1_SSI3FSS, GPIO_PD2_SSI3RX, GPIO_PD3_SSI3TX},};
Tradycyjna terminologia (MOSI i MISO) sugeruje zmianę kierunku linii
gdy interfejs SPI zmienia rolę z nadrzędnego na podrzędny.
W Stellaris Launchpad kierunek się nie zmienia i terminologia (RX, TX)
to odzwierciedla.
Uwaga: W MSP430 nóżka P1.6 to MISO, P1.7 to MOSI zaś P1.5 to SCK.
Dodatkowo, na poziomie sprzętu nóżka P1.4 może być użyta do uktywniania
interfejsu,
w szczególności gdy MSP430 jest interfejsem podrzędnym to sygnał
na tej nóżce informuje MSP430 czy został wybrany
Niestety, przypisanie MISO do P1.6 oznacza że zieloną diodę
świecącą (podłączoną do P1.6) nie da się używać razem z interfejsem SPI.
MSP430G2553 ma jeszcze drugi interfejs SPI, który współdzieli
sprzęt z portem szeregowym. Jednakże biblioteka SPI obsługuje tylko
jeden interfejs.
Domyslnie do uaktywniania urządzenia podrzędnego biblioteka SPI
używa linię P2.0.
Interfejs SPI w MSP430 jest realizowany przez ten sam sprzęt co
interfejs I2C, dlatego nie da się użyć obu równocześnie. Dokładniej,
sprzęt pozwala na użycie interfejsu normalnie używanego przez
port szeregowy jako SPI co dałoby jedno SPI plus I2C, ale
biblioteka SPI nie implementuje takiej możliwości.
Uwaga: W Arduino nóżka 11 to MOSI, 12 to MISO zaś 13 to SCK. Ponadto
domyślnie nóżka 10 służy do wyboru urządzenia podrzędnego. Nawet
jeśli użyjemy inną linię do wyboru urządzenia podrzędnego linia 10
musi byc skonfigurowana jako wyjście (inaczej interfes przełączyłby
się w tryb podrzędny, co nie działa z biblioteką SPI). W Arduino
linia 13 podłączona jest do pomarańczowej diody świecącej, do oznacza
że nie da się użyć tej diody razem z SPI. Dokładniej, dioda będzie
świeciła zależnie od sygnału SCK.
Komentarz: SPI jest używane do komunikacji z wieloma różnymi urządzeniami.
Np. wyświetlacz Nokii 5110 w programie przykładowym jest obsługiwany
przez programowe SPI, ale lepiej by było obsłużyć go przy pomocy
sprzętowego SPI.
I2C
I2C jest prostą metodą transmisji, nieco bardziej skomplikowaną niż SPI
i dającą nieco mniejszą szybkość, ale pozwalającą na
połączenie wielu urządzeń przy pomocy tylko dwu linii sygnałowych
(plus masy). W Arduino linia SDA z I2C jest oznaczana jako A4
zaś SCL ma oznaczenie A5. W MSP430 Launchpad linia SDA jest
oznaczna przez P1.6 zaś linia SCL ma oznaczenie PA.7.
Stellaris Launchpad ma 4 interfejsy I2C, nóżki definiuje
poniższy fragment:
static const unsigned long g_uli2cConfig[4][2] =
{
{GPIO_PB2_I2C0SCL, GPIO_PB3_I2C0SDA},
{GPIO_PA6_I2C1SCL, GPIO_PA7_I2C1SDA},
{GPIO_PE4_I2C2SCL, GPIO_PE5_I2C2SDA},
{GPIO_PD0_I2C3SCL, GPIO_PD1_I2C3SDA}
};
W Stellaris Launchpad domyślny interfejs ma numer 1,
tzn. linia PA6 to SCL zaś PA7 to SDA.
Interfejs I2C obsługuje biblioteka Wire. Wypróbować komunikację
między dwoma procesorami przy pomocy tej biblioteki.
Program i2c_ex.ino ilustruje komunikację
z układem MCP23017 (tzn. ekspanderem wejścia wyjścia).
Dokumentacja układu wyjaśnia szczegóły.
Uwaga: Ze względu na poziomy napięć nie należy łączyć Arduino
z MSP430 Launchpad. Połączenie procesorów tego samego typu
czy też Arduino lub MSP430 Launchpad ze Stellaris Launchpad
powinno działać.
Komentarz: Wiele urządzeń używna interfejs I2C. Oprócz układu
MCP23017 mamy też moduły z zegarem DS1307 i pamięcią EEPROM 24C32.
Komentarz: Na bazie I2C jest zdefinowany protokuł SMBUS który
jest standartowo używany w komputerach PC do komunikacji z
czujnikami (temperatury, napiecia, obrotów wentylatorów, ...),
komunikacji z monitorami i odczytu informacji o parametrach RAM.
Ethernet
Ethernet jest standartem dla lokanych sieci komputerowych. Obecnie coraz
częściej jest używany również do komunikacji z mikrosterownikami.
Zaletą Ethernetu jest duża przepustowość i możliwość współpracy z
siecią rozległą. Mamy dwa moduły ethernetu. Jeden to Arduino
Ethernet Shield, obsługiwane przez bibliotekę Ethernet w środowisku
Arduino (teoretycznie ten moduł powinien działać z innymi sterownikami
niż Arduino, ale wymaga to trochę pracy). Drugim modułem jest
moduł na układzie ENC28J60, obsługiwany przez bibliotekę "ethercard"
w środowisku Arduino. Oryginalna biblioteka jest specyficzna dla procesorów
AVR, ale w pracowni mamy wersję która powinna działać z innemi procesorami
Oba moduły komunikują się z procesorem za pomocą SPI.
Komentarz: Bibloteka "ethercard" niby impementuje TCP/IP, ale
są poważne ograniczenia:
- potrzebna jest brama (gateway), wszystkie pakiety są wysyłane
do bramy, nie ma możliwości wysłania bezpośrednio do komputera
docelowego jeśli jest różny od bramy
- TCP obsługuje tylko połączenia gdzie dane mieszczą się w
pojedynczym pakiecie.
Moduły radiowe z nRF24L00+
W wielu przypadkach wygodna jest komunikacja radiowa. Proste
moduły do transmisji na małe odległości w paśmie 2.4 GHz
często używają układu
nRF24L00+. Moduły z tym układem w środowisku Energia
i Arduino
są obsługiwane przez bibliotekę Enrf24.
Uwaga: Procesor komunikuje się układem nRF24L00+ za pomocą SPI.
Biblioteka Enrf24 używa obiektu SPI, czyli domyślnego interfejsu.
Nóżki dla interfejsu SPI trzeba znaleźć w opisie SPI. Pozostałe
nóżki sygnałowe modułu tzn. CE, CSN, IRQ podajemy (w tej kolejności)
jako argument konstuktora obiektu klasy Enrf24.
Uwaga: Układ nRF24L00+ jest zasilany napięciem maksymalnie 3.6V.
Gdy napięcie zasilające nie przekracza 3.3V linie wejścia/wyjścia
układu tolerują napięcie 5V. Czyli podłączając moduł do MSP430
Launchpad czy Stellaris Launchpad zasilamy moduł tym samym
napięciem co procesor (nóżka Vcc w MSP430 Launchpad, nóżka 3.3V
w Stellaris Launchpad). Gdy podłączamy moduł do Arduino
zasilamy go napięciem 3.3V.
Uwaga: Układ nRF24L00+ pracuje na tym paśmie co WiFi i wiele innych
urządzeń. Oznacza to że uzyskanie połączenia może być utrudnione
ze względu na zakłócenia (interferencję) od innych transmisji.
Pasmo 2.4GHz jest podzielne na 126 kanałów po 1MHz. Układ
nRF24L00+ pracuje w jednym z nich, wybranym w trakcie konfiguracji.
Teoretycznie można zmieniać kanał pomiędzy transmisjami pakietów,
ale nadajnik i odbiornik muszą uzywać ten sam kanał więc trzeba
by jakoś synchronizować zmianę. WiFi używa bloków po 6 kanałów
(tzn. kanał WiFi to 6MHz), dla nRF24L00+ lepiej wybrać kanał
nie używany przez WiFi.
Moduły radiowe 433 MHz
Są to pary składające się z nadajnika i odbiornika. Nadajnik
ma trzy linie: zasilania, masy i sygnału. Nadaje gdy na
lini jest stan wysoki, w przeciwnym razie nie nadaje.
Odbiornik ma cztery końcówki, ale też jest to zasilanie,
masa i dwie połączone ze sobą końcówki sygnału. Stan
wysoki na wyjściu sygnału oznacza że odbiornik słyszy
sygnał, stan niski oznacza że nie słyszy. Jednakże
nie można pary nadanik-odbiornik wykożystać jako
prosty kanał do przesyłania bitów. Mianowicie, odbiornik
stara się dostosować swoją czułość do siły sygnału i jeśli
nadajemy same zera to może podniść czułość tak że będzie
łapać zakłucenia. A więc sygnał nadawany musi być tak
dobrany by odbiornik widział dostatecznie dużo jedynek.
Innymi słowy przed wysłaniem do nadajnika bity trzeba
odpowiednio zakodować a odbiornik musi je rozkodować.
Moduły mają ograniczoną szybkość (rzędu 4800 zmian sygnału
na sekundę). Sygnalizacja na paśmie 432 MHz jest często
używana do sterowania. W szczególności moduły mogą być
użyte do komunikacji z gniazdkami radiowymi. Wspiera
to biblioteka rc-switch w środowisku Arduino.
Uwaga: Odbiornik wymaga zasilania 5V i daje sygnal 5V na
wyjściu. Nadajnik powinien pracować zarówno z napięciem 3.3V
jak i 5V, ale przy 3.3V moc będzie mniejsza i sygnał może
być zbyt słaby.