Tym razem zajmiemy się kontynuacją tematu programowania platformy Intel Edison z poziomu Arduino IDE. Ta szybka powtórka pozwoli nam od następnego odcinka zajmować się już znacznie ciekawszym tematem, czyli IoT.
Najpierw sprawdźmy jednak, jak szybko, dzięki Arduino można wykorzystać wyświetlacz LCD oraz różne czujniki (m.in. ciśnienia i temperatury).
Bardzo często wykorzystywanym przez hobbystów (i nie tylko) dodatkiem jest wyświetlacz LCD, który pozwala na łatwą komunikację z użytkownikiem budowanego urządzenia. W kursie Arduino Damian opisał, jak wykorzystać najzwyklejszy LCD tekstowy 2x16 znaków.
Przykład z kursu Arduino - wyświetlacz LCD.
Teraz poznamy jak wykorzystać trochę inny LCD. W zestawie znajdziemy wyświetlacz 2x16 znaków z konwerterem I2C. Zastosowanie takiego dodatkowego sterownika pozwala na znaczną oszczędność pinów, ponieważ wyświetlacz możemy podłączyć przy użyciu 2 pinów, zamiast 7!
Gotowe zestawy do kursów Forbota
Komplet elementów Gwarancja pomocy Wysyłka w 24h
Elementy konieczne do wykonania ćwiczeń zebrane zostały w gotowe zestawy, które można nabyć w Botlandzie. W kuferku znajdziecie ponad 180 elementów w tym moduł Intel Edison!
Masz już zestaw? Zarejestruj go wykorzystując dołączony do niego kod. Szczegóły »
Na płytce Arduino znajdziemy linie opisane jako SDA i SCL, to właśnie wyprowadzenia interfejsu I2C. Podłączenie wyświetlacza jest więc bardzo proste:
Podłączenie wyświetlacza tekstowego do płytki Intel Edison.
Natomiast sam sterownik znajdujący się na spodzie wyświetlacza wygląda następująco:
Wyświetlacz tekstowy ze sterownikiem I2C.
Pora na uruchomienie całości. Najpierw tworzymy nowy szkic, następnie wybieramy opcję menu Szkic > Include Library > Manage Libraries. Dla Arduino dostępna jest imponująca liczba gotowych bibliotek. Nas interesuje jedna, konkretna - wyszukujemy LiquidCrystal_I2C i ją instalujemy:
Instalacja biblioteki odpowiedzialnej za obsługę wyświetlacza.
Po kliknięciu na opis biblioteki pojawi się przycisk umożliwiający jej instalację.
Zanim napiszemy własny program, możemy przetestować przykłady dla nowo zainstalowanej biblioteki. W menu Plik > Przykłady pojawiła się nowa opcja (na samym dole): LiquidCrystal_I2C. Jak łatwo się domyślić są tam przykłady do biblioteki wyświetlacza. Wybieramy któryś z nich, na przykład HelloWorld:
Pierwsze, testowe wykorzystanie LCD tekstowego z Edisonem.
Po jego uruchomieniu, na małym ekranie zobaczymy nieśmiertelny komunikat Hello world. Kod programu jest łatwy do prześledzenia, możemy z niego dowiedzieć się jak używać nowej biblioteki.
Stosowanie LCD z dodatkowym konwerterem upraszcza zarówno program,
jak i fizyczne podłączenia układu!
Sygnalizator zamkniętych drzwi
Teraz napiszemy własny program, który wykorzysta czujnik opisywany wcześniej i będzie sprawdzał, czy drzwi są poprawnie zamknięte. Zamiast sterowania buzzerem, jak w wcześniejszym przykładzie, wyświetlimy odpowiednie komunikaty na ekranie.
Jeśli odłączyliśmy czujnik otwarcia drzwi, musimy go ponownie podłączyć. Układ powinien być podłączony zgodnie z poniższym schematem montażowym:
Następnie możemy napisać i uruchomić program:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
constintDOOR_PIN=12;
LiquidCrystal_I2C lcd(0x27,16,2);// set the LCD address to 0x27 for a 16 chars and 2 line display
voidsetup(){
lcd.init();
lcd.backlight();
pinMode(DOOR_PIN,INPUT_PULLUP);
}
voidloop(){
// sprawdz, czy drzwi sa otwarte
if(digitalRead(DOOR_PIN)){
lcd.setCursor(0,0);
lcd.print("Drzwi otwarte ");
}else{
lcd.setCursor(0,0);
lcd.print("Drzwi zamkniete");
}
delay(100);
}
Jak widzimy, jest to połączenie programu napisanego poprzednio oraz przykładów dostarczonych wraz z biblioteką. Osoby chcące lepiej poznać możliwości biblioteki, zachęcamy do analizy jej kodu dostępnego poprzez github-a. Jest to jednak zadanie dla bardziej zaawansowanych czytelników!
Czujnik temperatury i wilgotności HDC1008
Tym razem zajmiemy się cyfrowym czujnikiem HDC1008. Ten jeden, mały układ pozwala na rozbudowę możliwości naszego systemu o pomiar temperatury oraz wilgotności. Czujnik HDC1008 do komunikacji wykorzystuje również interfejs I2C.
Uwaga! W niektórych zestawach poniższy czujnik występuję na innej płytce (koloru czerwonego). Nie jest to jednak istotna różnica - pamiętaj tylko o sprawdzenie poprawności połączeń!
Moduł czujnika HDC1008. Źródło zdjęcia: strona producenta.
Dzięki temu schemat montażowy jest bardzo prosty, układ podłączamy podobnie jak poprzednio:
Podłączenie układu HDC1008 do Intel Edisona.
Również w tym przypadku wykorzystamy gotową bibliotekę do obsługi modułu. Uruchamiamy menedżer bibliotek (menu Szkic > Include Library > Manage Libraries) i instalujemy pakiet hdc1008:
Instalacja biblioteki, do obsługi czujnika HDC1008.
Wraz z biblioteką otrzymaliśmy przykład jej użycia (tym razem tylko jeden). Przykład znajdziemy w menu: Plik > Przykłady > Adafruit HDC1000 library.
Program powinien działać bez problemu, wyniki wysyłane są przez port szeregowy (jak pamiętamy jest on dostępny w menu Narzędzia >Szeregowy monitor). Efekt działania programu:
Odczyt czujnika temperatury i ciśnienia, dzięki Intel Edison.
Jeśli czujnik nie działa...
Wykorzystywany czujnik może "nasłuchiwać" na różnych adresach. Wszystko zależy od firmy, która wyprodukowała dany moduł... Jeśli Twój czujnik nie działa, to spróbuj inne adresy. W tym celu wystarczy w powyższym demie zmienić linijkę:
Arduino
1
if(!hdc.begin()){
Na:
Arduino
1
if(!hdc.begin(0x41)){
W miejscu 0x41, możesz jeszcze wpisywać inne dostępne adresy, czyli 0x40, 0x42 oraz 0x43. Któryś z nich musi zadziałać
Prosta stacja pogodowa
Do interfejsu I2C można jednocześnie podłączyć zarówno wyświetlacz, jak i czujnik HDC1008. Wykorzystamy taką konfigurację do przygotowania prostej stacji pogodowej. Podłączamy układ zgodnie z rysunkiem:
Intel Edison - jednoczesne podłączenie czujnika i wyświetlacza.
Następnie uruchamiamy poniższy program:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <Wire.h>
#include <Adafruit_HDC1000.h>
#include <LiquidCrystal_I2C.h>
Adafruit_HDC1000 hdc=Adafruit_HDC1000();
LiquidCrystal_I2C lcd(0x27,16,2);// set the LCD address to 0x27 for a 16 chars and 2 line display
voidsetup(){
Serial.begin(9600);
lcd.init();
lcd.backlight();
if(!hdc.begin()){
lcd.print("Brak HDC1008");
while(1);
}
}
voidloop(){
lcd.home();
lcd.print("Temp: ");
lcd.print(hdc.readTemperature());
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Hum: ");
lcd.print(hdc.readHumidity());
lcd.print(" ");
delay(500);
}
Jak widzimy, raptem kilka linijek kodu pozwala na uzyskanie całkiem interesującego rezultatu. Wykorzystywanie gotowych bibliotek niewątpliwie bardzo ułatwia programowanie.
Więcej informacji na temat komend sterujących wyświetlaczem (np. lcd.setCursor) znaleźć można w 7 części kursu Arduino.
Klawiatura - wprowadzanie danych
Spróbujemy jeszcze podłączyć do naszego układu klawiaturę numeryczną. Za jej pomocą będziemy mogli w prosty sposób wprowadzać do układu liczby/komendy, które będą mogły zmieniać działanie układu.
Podłączenie klawiatury do modułu Intel Edison.
Schemat podłączenia widoczny jest poniżej, tym razem potrzebujemy już więcej przewodów:
Tak jak w poprzednio zaczniemy od wykorzystania przykładów. Program HelloKeypad będzie dobrym początkiem.
Tym razem musimy jednak dokonać pewnych zmian,
a mianowicie dostosować mapowanie do klawiatury.
Wyprowadzenie z naszej klawiatury wyprowadzone są zgodnie z poniższym schematem. Jak widać odpowiednie poprowadzenie połączeń pozwala sprawdzać stany 12 przycisków za pomocą wyłącznie 7 linii!
Teraz musimy dostosować informacje na temat sposobu podłączenia klawiatury do naszego Edisona (patrz: wcześniejszy schemat montażowy). Chodzi o poniższy fragment:
C
1
2
byterowPins[ROWS]={4,5,6,7};//connect to the row pinouts of the keypad
bytecolPins[COLS]={8,9,10};//connect to the column pinouts of the keypad
Cały kod przykładowego programu ze zmianami wygląda następująco:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* @file HelloKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates the simplest use of the matrix Keypad library.
|| #
*/
#include <Keypad.h>
constbyteROWS=4;//four rows
constbyteCOLS=3;//three columns
charkeys[ROWS][COLS]={
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byterowPins[ROWS]={4,5,6,7};//connect to the row pinouts of the keypad
bytecolPins[COLS]={8,9,10};//connect to the column pinouts of the keypad
charkey=keypad.getKey();// Oczytaj informacje o wciśniętym przycisku
if(key){// Jeśli odczytano jakiś znak, to...
Serial.println(key);// ... wypisz go na ekranie komputera
}
}
Jak widzimy, program wysyła kody naciskanych znaków przez łącze szeregowe:
Efekt działania programu testowego z klawiaturą.
Intel Edison - zamek elektroniczny
Na zakończenie tej części omówimy nieco dłuższy przykład. Załóżmy, że chcemy wykorzystać posiadane umiejętności oraz komponenty do zbudowania elektronicznego zamka do drzwi.
Zamek będzie wyposażony w wyświetlacz oraz klawiaturę. Użytkownik będzie musiał podać tajne hasło - jeśli je poda drzwi zostaną odblokowane.
Oczywiście dodanie drzwi z zamkiem do naszych zestawów części byłoby, delikatnie mówiąc, trudne. Dlatego w tym ćwiczeniu zamknięcie będzie sygnalizowane stanem diody święcącej.
Jeśli uznasz, że chcesz zbudować prawdziwy zamek, to wystarczy dokupić do układu stosowny mechanizm zamka sterowanego elektromagnesem. W razie wątpliwości zachęcam do zadawania pytań w komentarzach
Wiemy już jakie komponenty ma mieć nasz projekt, czas je podłączyć:
Zamek elektroniczny sterowany przez Intel Edisona.
Wszystkie moduły są nam znane, używaliśmy je wcześniej w prostych programach. Teraz spróbujemy połączyć wszystko w całość. Najpierw musimy zdefiniować nasze tajne hasło - na początek zapiszemy je jako stałą w programie. Będziemy również potrzebowali ograniczenia na długość wprowadzanych danych.
Nie chcemy, żeby ktoś bawił się naciskając przyciski, aż do przepełnienia bufora.
Tworzymy więc pierwsze definicje:
C
1
2
constintPASS_MAXLEN=8;// maksymalna dlugosc hasla
constcharPASSWORD[]={"1234#"};// tajne haslo
Jak ustaliliśmy wcześniej, zamiast prawdziwego rygla podłączymy diodę LED. Podobnie jak wcześniej, zdefiniujemy stałą informującą, do którego pinu podłączony jest moduł:
C
1
constintLOCK_PIN=3;
Kody naciskanych przez użytkownika klawiszy będziemy przechowywać w tablicy, którą będziemy traktować jako napis. Zarezerwujemy więc miejsce na znak 0 kończący napisy w języku C.
C
1
charpass[PASS_MAXLEN+1];// wprowadzone haslo
Zaczniemy od napisania procedury pomocniczej, która będzie wypisywała wprowadzane dane na ekran. Oczywiście nie chcemy, żeby hasło było widoczne - więc dla bezpieczeństwa zamiast wprowadzanych znaków będziemy wyświetlać gwiazdki.
C
1
2
3
4
5
6
7
8
staticvoidprint_pass(void)
{
intpass_len=strlen(pass);
lcd.clear();
for(inti=0;i<pass_len;i++)
lcd.print('*');
}
Szczegółowe informacje o pisaniu własnych funkcji/procedur
znaleźć można w: 9 części kursu Arduino.
Przydatna będzie również procedura kasująca wprowadzone przez użytkownika hasło, tak aby mógł podać dane od początku:
C
1
2
3
4
staticvoidclear_pass(void)
{
memset(pass,0,sizeof(pass));// zerowanie hasla
}
Kolejna procedura pomocnicza posłuży nam do symulacji otwarcia drzwi. Będzie wywoływana po poprawnym podaniu hasła:
C
1
2
3
4
5
6
7
8
staticvoidopen_door(void)
{
lcd.clear();
lcd.print("!!! OTWARTE !!!");
digitalWrite(LOCK_PIN,HIGH);
delay(5000);
digitalWrite(LOCK_PIN,LOW);
}
Teraz możemy napisać pętlę główną programu. Interesują nas trzy przypadki:
jeśli użytkownik naciśnie * będziemy kasować dane (aby mógł wprowadzić hasło jeszcze, raz od początku),
jeśli podane hasło jest poprawne, wywołamy funkcję open_door() w celu otwarcia drzwi,
w pozostałych przypadkach, po prostu dodajemy naciśnięty kod do tablicy pass. Jeśli bufor będzie pełny, będziemy odrzucać wprowadzane dane.
Kod, który realizuje powyższe działania, może wyglądać następująco:
}elseif(pass_len<PASS_MAXLEN){// jesli jest miejsce w buforze
pass[pass_len]=key;
if(strcmp(pass,PASSWORD)==0){// poprawne haslo
open_door();
clear_pass();
}
}
Teraz już możemy już złożyć cały kod. Wygląda na długi i skomplikowany, ale wystarczy na spokojnie prześledzić wszystkie procedury, aby zrozumieć działanie układu.
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
constintPASS_MAXLEN=8;// maksymalna dlugosc hasla
constcharPASSWORD[]={"1234#"};// tajne haslo
charpass[PASS_MAXLEN+1];// wprowadzone haslo
constintLOCK_PIN=3;
constbyteROWS=4;//four rows
constbyteCOLS=3;//three columns
charkeys[ROWS][COLS]={
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byterowPins[ROWS]={4,5,6,7};//connect to the row pinouts of the keypad
bytecolPins[COLS]={8,9,10};//connect to the column pinouts of the keypad
}elseif(pass_len<PASS_MAXLEN){// jesli jest miejsce w buforze
pass[pass_len]=key;
if(strcmp(pass,PASSWORD)==0){// poprawne haslo
open_door();
clear_pass();
}
}
print_pass();
}
delay(50);
}
Zadanie 6.1
W momencie otwarcia drzwi można wyłączyć elektromagnes odblokowujący rygiel zamka. Dodaj do układu czujnik otwarcia drzwi oraz zmień odpowiednio program.
Podsumowanie
Nauczyliśmy się już podstaw obsługi dołączonych do zestawu modułów. W kolejnych częściach kursu rozszerzymy nasze umiejętności o pracę przez sieć. Będziemy mogli tworzyć programy, z którymi możliwa będzie komunikacja przez przeglądarkę Internetową. Kolejnym etapem będzie wysyłanie zbieranych informacji do chmury.
Dołącz do 20 tysięcy osób, które otrzymują powiadomienia o nowych artykułach! Zapisz się, a otrzymasz PDF-y ze ściągami (m.in. na temat mocy, tranzystorów, diod i schematów) oraz listę inspirujących DIY na bazie Arduino i Raspberry Pi.
Dołącz do 20 tysięcy osób, które otrzymują powiadomienia o nowych artykułach! Zapisz się, a otrzymasz PDF-y ze ściągami (m.in. na temat mocy, tranzystorów, diod i schematów) oraz listę inspirujących DIY z Arduino i RPi.
Trwa ładowanie komentarzy...