Cel ćwiczenia Programowanie mikroprocesorów w systemie Arduino Instrukcja do ćwiczenia laboratoryjnego Patryk Strankowski, Jarosław Guziński, Marcin Morawiec, Arkadiusz Lewicki ver. 2.2 2016 r. Celem ćwiczenia jest zapoznanie się z platformą programowania Arduino oraz systemem mikroprocesorowym Intel Galileo. Wprowadzenie Arduino jest platformą oprogramowania przeznaczoną dla komputerowych systemów wbudowanych wykorzystujących mikroprocesory zamontowane na pojedynczym obwodzie drukowanym. Oprogramowanie i rozwiązania sprzętowe są typu Open-Source a źródła dostępne są w internecie. Platforma Arduino jest przeznaczona do szybkiego programowania metod sterowania, bez konieczności dokładnej znajomości używanego mikrokontrolera. Zazwyczaj programowanie nowego mikrokontrolera jest czasochłonne, z uwagi na różnice w architekturze, czy też inne oznaczenia elementów, np. liczników lub portów wejść-wyjść, które muszą być dokładnie znane, aby umożliwić prawidłowe programowanie. Platforma Arduino służy przede wszystkim do przygotowania aplikacji, które nie wymagają szybkich reakcji procesora. Układ programuje się w języku C, stosując zmienne, które na każdym procesorze są oznaczone tak same lub bardzo podobne. Platforma sprzętowa używana na ćwiczeniach to Intel Galileo, która wyposażona jest w 32 bitowy procesor klasy Pentium typu Intel Quark SoC X1000 rys.1. Rys. 1. Platforma sprzętowa Intel Galileo Platforma Intel Galileo oferuje możliwość rozbudowania o układy peryferyjne, np. łączności WiFi, wyświetlacz LCD, moduł GSM lub sterownik silnika krokowego. Peryferia instalowane są jako dodatkowe płytki, tzw. Arduino-Shield, które dołączane są do wejść platformy Galileo (czerwone prostokąty na rys. 1). 1
Układ Galileo programowany jest w języku C, jednakże struktura programu jest nieznacznie zmieniona. Główna funkcja main() jest zastąpiona funkcją {}, która działa jak pętla nieskończona. Wszystkie deklaracje zmiennych, portów, timerów itp. powinny być umieszczone w funkcji {}. Funkcja ta jest jednokrotnie wykonywana przy uruchomieniu programu mikrokontrolera. Poza tymi zmianami, składnia i polecenia są identyczne jak w języku C. Dokumentacja programowania, dokładny opis składni oraz wszystkie wspierane funkcje są dostępne na stronie: http://arduino.cc/en/reference/homepage. 1. Pierwszy przykład Działanie platformy Galileo wymaga podłączenia dedykowanego zasilacza oraz kabla mikro USB do komputera z zainstalowanym oprogramowaniem Arduiono. UWAGA! Płytkę Galileo należy NAJPIERW ZASILANIĆ A DOPIERO NASTĘPNIE PODŁĄCZYĆ DO PORTU USB. Inna kolejność podłączenia może prowadzić do uszkodzenia płytki! Aby sprawdzić działanie platformy Galileo, należy skompilować i załadować pierwszy program. Potrzebne będzie do tego: IDE (z ang. Integrated Development Environment) Arduino - rys. 2. Rys. 2. Okno programu IDE Arduino Program podstawowy realizujący miganie diody LED jest dostępny pod: File -> Examples->Basics->Blink. Kod programu jest następujący: 2
// Deklaracja zmiennych int led = 13; // Oznaczenie tzw. Cyfrowego portu. PORT 13 to dioda na płytce // Deklaracja portu. Funkcja będzie raz przetwarzana { } //Port jako wyjście pinmode(led, OUTPUT); // Funkcja główna loop { digitalwrite(led, HIGH); // Włączaj diodę-> PORT = HIGH delay(1000); // Delay jest podany w ms, czyli 1s digitalwrite(led, LOW); // Wyłączaj diodę ->PORT = LOW delay(1000); // Czekaj sekundę } Do kompilacji przykładu należy nacisnąć (skrót Ctr+R). Aby załadować program do procesora należy: sprawdzić czy ustawiony jest poprawny port: Tools ->Serial Port -> COM, sprawdzić czy ustawiona jest prawidłowa płytka Galileo: Tools -> Board -> Intel Galileo. Następnie program można załadować naciskając (skrót Ctr+U). O pomyślniej kompilacji i załadowaniu programu do procesora informuje konsola w dolnej części środowiska Arduino oraz migająca dioda na płytce Galileo. 3
2. Ustawianie częstotliwości migania diody za pomocą potencjometru Zadanie polega na przygotowaniu programu od odczytu wartości analogowej z portu A0. Należy zaimplementować procedurę (zgodnie z algorytmem pokazanym na rys. 3), w której częstotliwość migania diody ma być proporcjonalna do nastawy potencjometru podłączonego na wejście analogowe A0. Porty cyfrowe należy zadeklarować poleceniem pinmode(led, OUTPUT). W przypadku portów analogowych nie jest konieczna taka deklaracja. Do programowania będą potrzebne następujące zmienne i funkcje programu 1 : int sensorpin=a0; int analogread(sensorpin); pinmode(led, OUTPUT); digitalwrite(led, HIGH); delay(ms); Wejście analogowe Odczyt wejścia analogowego Deklaracja portu, jako wyjścia (nie jest wymagane przy A0) Wyjście portu 1= HIGH, 0= LOW Opóźnienie w milisekundach zmiennych ADC0, LEDPORT Wyczytaj wartość z analogowego wejścia Włączaj diodę Czekaj proporcjonalnie wartości analogowej Wyłączaj diodę Czekaj proporcjonalnie wartości analogowej Rys. 3. Procedura U~f_led 1 Opisy poleceń są dostępne pod: http://arduino.cc/en/reference/homepage. 4
3. Modulacja szerokości impulsów Kolejne zadanie polega na generowaniu napięcia na wyjściu portu mikrokontrolera za pomocą modulacji szerokości impulsów (ang. PWM Pulse Width Modulation). Nie wszystkie wyjścia obsługują funkcje PWM. Należy sprawdzić na jakich portach dostępna jest funkcja modulacji i zainicjalizować odpowiedni port. Schemat oraz opis portów jest podany w załączniku. Zmiana napięcia jest widoczna przez zmianę jasności diody LED podłączonej do sterowanego wyjścia. zmiennych ADC0, LEDPORT Do realizacji zadania potrzebna będzie funkcja: analogwrite(led, val); Generowanie napięcia przez PWM dla określonego wyjściu Wyczytaj Wczytaj wartość wartość z analogowego analogowego wejścia wejścia Wydaj wartość do funkcji analogwrite() Rys. 4. Procedura PWM 5
4. Wyznaczenie pozycje potencjometru za pomocą czterech diod Celem zadania jest wykorzystanie czterech diod LED do wizualizacji wartości napięcia wejścia analogowego. Diody mają być podzielone na cztery poziomy, np. 0% 25 %, 26%... 50%, 51%... 75% oraz 76%...100%. Struktura programu jest pokazana na rys.5. zmiennych ADC0, LEDPORT Wczytaj wartość z analogowego wejścia Wyłączaj 1. diode Nie Tak > 0? Włączaj 1. diode Wyłączaj 2. diode Nie Tak > 25 %? Włączaj 2. diode Wyłączaj 3. diode Nie Tak > 50 %? Włączaj 3. diode Wyłączaj 4. diode Nie Tak > 75 %? Włączaj 4. diode Rys. 5. Wartość wejścia analogowego przedstawiona za pomocą diod LED 6
5. Sterowanie diodą za pomocą wejścia cyfrowego Do realizacji ćwiczenia trzeba użyć płytki rozszerzeń (schemat w załączniku). W Jeden port Arduino zainicjalizowany ma być jako wyjście a drugi jako wejście. Wyjściowy port należy ustawić na wysoki poziom. Za pomocą przewodu należy ręcznie połączyć port wyjściowy z portem wejściowym. Przy takiej konfiguracji stan portu wyjściowego będzie mógł być odczytywany na porcie wejściowym. Stan portu wejściowego ma być wystawiany na diodzie LED. Procedura przedstawiona jest na rys.6. zmiennych ADC0, LEDPORT Do realizacji zadania potrzebna będzie funkcja: pinmode(in, INPUT); Deklaracja portu jako wejście Wyczytaj Wczytaj wartość wartość z wejścia z analogowego cyfrowego wejścia Włączaj diode Rys. 6. Procedura wejścia i wyjścia cyfrowego 7
6. Licznik czterobitowy Zadanie polega na programowaniu licznika czterobitowego, którego wartość ma być wyświetlana na czterech diod LED umieszczonych na płytce rozszerzeń. Licznik ma pracować w pętli głównej programu i zliczać liczby od 0 do 15. Prędkość zliczania ma być ustawiana być za pomocą potencjometru. Realizacja zadania wymaga zrozumienia konwersji zmiennej typu integer (zmienna całkowita) na odpowiednią liczbę binarną. W języku C zmienne integer oznaczane są słowem kluczowym int i w systemie Arduino są zapisywane jako 16-bitowa liczba binarna. Przykład: int var = 1537; var jako liczba binarna to: 000011000000001 Do opracowania programu potrzebne jest zapoznanie się ze sposobem maskowania bitów. artykuł można o tym przeczytać, np. w artykule: https://www.arduino.cc/en/tutorial/bitmask zmiennych ADC0, LEDPORT Wyczytaj Wczytaj wartość wartość z analogowego analogowego wejścia wejścia Czekaj proporcjonalnie do wartości analogowej Proponowany algorytm rys. 7 programu pokazano na Licznik +1 Licznik > 15? Tak Licznik=0 Wydaj wartość licznika zapisując go do stanów diod Rys. 7. Procedura licznika czterobitowego 8
7. Podgląd pozycji potencjometru za pomocą terminala PuTTy i komunikacji szeregowej Następne zadanie polega na opracowaniu programu do odczytu stanu wejścia analogowego z wykorzystaniem komunikacji szeregowej USB PC i terminala portu szeregowego. Do komunikacji terminalowej będzie potrzebne wejście USB oraz program PuTTy (wybrany tryb połączenia Serial). Można wykorzystać też wbudowany do Arduino monitor portu szeregowego (menu Narzędzia, skrót Ctrl_Shift+M), Uwaga - jednoczesne korzystanie z USB w dwóch programach (Putty i Arduino) nie jest możliwe. Algorytm programu przedstawiono na rys. 8. Do realizacji zadania potrzebne są funkcje: zmiennych zmiennych LEDPORT Baudrate, LEDPORT ADC0 Serial(baud); Serial.begin(baudrate); Inicjalizacja portu szeregowego, (baudrate to prędkość transmisji, np. 9600) Serial.available() Wynik=1 jeśli odebrany został znak z portu szeregowego, jeśli nie to wynik=0 Serial.print(c[i]) Wysłanie znaku na port szeregowy Serial.println((char)13); Znak Enter, nowa linia Wczytaj wartość z analogowego wejścia i zapisz Wyslji wartość do terminału Czekaj 500ms Rys. 8. Procedura podglądu pozycji potencjometru w terminalu 9
8. Ustawianie jasności diody za pomocą terminala PuTTy i komunikacji szeregowej Podobnie jak w punkcie 3. jasność diody LED ma być ustawiona z wykorzystaniem funkcji PWM oraz komunikacji szeregowej. Za pomocą programu PuTTy wczytany ma być jeden znak ASCII (z ang. American Standard Code for Information Interchange) do procesora, którego wartość ma wpływać na jasność diody LED. Wartości znaków ASCII jest podana w załączniku. Struktura programu jest przedstawiona na rys.9. zmiennych zmiennych LEDPORT Baudrate, LEDPORT ADC0 Do realizacji zadania potrzebna będzie funkcja: Serial.read(); Odczyt znaku (jednego bajtu) z portu szeregowego Serial(baud); Wczytaj wartość znaku ASCII z terminału Wyslji wartość napięcia na diode Rys. 9. Procedura PWM przez terminal 10
9. Ustawianie częstotliwości migania diody za pomocą terminala PuTTy i komunikacji szeregowej Następne zadanie polega na opracowaniu programu do sterowania częstotliwością migania diody LED z wykorzystaniem komunikacji szeregowej USB PC i terminala portu szeregowego. Podobnie jak w punkcie 2 należy zaimplementować procedurę, która będzie sterowała częstotliwością migania diody. W tym przypadku należy odczytać cztery cyfry (liczba ms), które odpowiadają okresowi migania diody. Algorytm programu przedstawiono na rys. 10. Do realizacji zadania potrzebne są funkcje: zmiennych zmiennych LEDPORT LEDPORT Baudrate Serial(baud); Serial.begin(baudrate); Inicjalizacja portu szeregowego, (baudrate to prędkość transmisji, np. 9600) pinmode(led, OUTPUT); Inicjalizacja wyjścia cyfrowego o numerze led Serial.available() Wynik=1 jeśli odebrany został znak z portu szeregowego, jeśli nie to wynik=0 Serial.print(c[i]) Wysłanie znaku na port szeregowy atoi(c) Konwersja znaku ASCII na liczbę całkowitą digitalwrite(led, HIGH) Wyjście portu 1= HIGH, 0= LOW delay(delay_ms) Opóźnienie w milisekundach Serial.println((char)13); Znak Enter, nowa linia Serial.read(); Odczyt znaku (jednego bajtu) z portu szeregowego Tak Nie Jest znak? Tak Zapisz byte i przepisz jako char oraz wyślij do terminalu Czwarty znak? Tak Nie Przekształć znaki do jednego int, dodaj Enter do terminału Jest znak? Nie Włącz diodę Czekaj ms Wyłącz diodę Czekaj ms Rys. 10. Procedura T_Led sterowania diodą LED przez terminal PuTTy i komunikacji szeregowej 11
10. Kalkulator czterobitowy Zadanie polega na opracowaniu programu kalkulatora czterobitowego. Program ma działac tak, że przez łącze szeregowe maja być wysyłane dwie liczby oraz operator. Wynik operacji należy zwrócić do programu terminala oraz wyświetlić za pomocą czterech diod LED. Struktura programu przedstawiona jest na rys.11. zmiennych zmiennych LEDPORT Baudrate, LEDPORT ADC0 Czekaj na znak Serial(baud); Wczytaj drugą liczbe z terminału i wydaj ją do terminału Operator Czekaj na znak Wczytaj pierwszą liczbe z terminału i wydaj ją do terminału + - Dodaj liczby Odejmij liczby Czekaj na znak * Mnóż liczby Wczytaj i wydaj operanda z terminału / Dziel liczby Wyslji wynik do terminału oraz do wyjścia diod Rys. 11. Procedura kalkulatora czterobitowego 12
Załącznik Schemat ideowy płytki rozszerzeń do systemu Intel Galileo 1: 13
Rozkład złącz i elementów płytki rozszerzeń do systemu Intel Galileo 1: 1 2 3 4 5 6 7 8 9 10 11 12 22 23 24 25 21 20 19 13 14 15 16 17 18 Numer Port 1 SCL (I 2 C) 2 SDA (I 2 C) 3 AREF 4 GND 5 Digital Output 11(PWM) 6 Digital Output 10 (PWM) 7 GND 8 Digital Output 7 9 Digital Output 6 (PWM) 10 Digital Output 5 (PWM) 11 Digital Output 4 12 Digital Output 2 13 PWM GND 14 PWM+15V(Digital Output 3) 15 GND 16 Analog Input 5 17 Analog Input 4 18 Analog Input 3 19 Analog Input 2 20 Analog Input 1 21 Analog Input 0 (Potencjometr) 22 Digital Output 13 (LED1) 23 Digital Output 12 (LED2) 24 Digital Output 9 (LED3/PWM) 25 Digital Output 8 (LED4) 14
Rozkład złącz i elementów płytki rozszerzeń do systemu Intel Galileo 2: Numer Port 1 SCL (I 2 C) 2 SDA (I 2 C) 3 AREF 4 GND 5 Digital Output 11 (PWM / LED 3) 6 Digital Output 10 (PWM / LED 4) 7 GND 8 Digital Output 7 (LED 7) 9 Digital Output 6 (PWM/ LED 8) 10 Digital Output 5 (PWM) 11 Digital Output 4 12 Digital Output 2 13 GND 14 Analog Input 5 15 Analog Input 4 16 Analog Input 3 17 Analog Input 2 18 Analog Input 1 19 Analog Input 0 (Potencjometr) 20 Digital Output 13 (LED1) 21 Digital Output 12 (LED2) 22 Digital Output 9 (LED5/PWM) 23 Digital Output 8 (LED6) 15
Tabela ASCII Zródło: http://www.cdrummond.qc.ca/cegep/informat/professeurs/alain/files/ascii.htm 16