Oled i PIR modul
Za Arduino se mogu mogu naći razni ekrani a OLED su iako među
najmanjima, možda i najzanimljiviji. OLED ekrani su monohromatski ekrani
i mogu se naći u rezolucijama 128x64 i 128x32 piksela. Ekrani dolaze u
raznim dijagonalama ekrana ali samo u jednoj od ove dve rezolucije.
Najčešći su oni sa dijagonalama 0,96" za 128x64px i 0,91" za 128x32px.
Takođe razlikuju se i u boji gde tekst ispisuju u beloj, plavoj a ima ih
i višebojnih. Sa Arduinom se u zavisnosti od modela povezuju na tri
načina: SPI, I2C i 8-bitni paralelni. OLED ekrani nemaju pozadinsko
osvetljenje zato sam ekran ima svoje osvetljenje tako da su izuzetno
mali potrošači. Zbog male potrošnje ekran ima veliki kontrast i iz tog
razloga je prikaz na njemu velike oštrine. Kontroler zadužen za
upravljanje ovim ekranima je SSD1306 a odgovarajuće biblioteke se lako
mogu naći. Ja sam nekako najviše orijentisan Adafruit bibliotekama a
možete je preuzeti ovde.
Moj
primerak je rezolucije 128x64 piksela sa dijagonalom 0,96" i belim
tekstom. Ekran se povezuje putem I2C interfejsa preko četiri pina: GND,
VCC, SCL i SDA. Povezivanje ide klasično s tim što se mora voditi računa
jer stariji tipovi ovih ekrana nisu 5V tolerantni i mora se koristiti
neki logic level shifter. Moj primerak jeste i povezujem ga sa MEGA na
sledeći način:
GND -> GND
VCC -> 5V
SCL -> 20(SCL)
SDA -> 21(SDA)
Položaj I2C pinova zavisi od ploče do ploče i treba ispratiti pinout šemu.
PIR senzor je ostao povezan na način iz prethodnog članka a povezivanje prema fritzing šemi.
----
/*-----------------------------------
* Skeč za potrebe članka na www.itstreet.org
* Author: Petrović Dejan
* Date: 11/24/2017
* Arduino MEGA, OLED display 128x64, PIR AM 312
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display (OLED_RESET);
int ledPin = 13;
int pirPin = 2;
int pirState = LOW;
int pirRead = 0;
static const unsigned char PROGMEM boomBmp[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x60, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x04,
0x01, 0xC0, 0x00, 0x08, 0x30, 0x00, 0x00, 0x1C, 0x01, 0xE0, 0x00, 0x18, 0x10, 0x00, 0x00, 0x7C,
0x00, 0xF8, 0x00, 0x10, 0x10, 0x00, 0x00, 0xD8, 0x00, 0xCE, 0x00, 0x10, 0x10, 0x00, 0x03, 0x98,
0x00, 0x43, 0x00, 0x10, 0x18, 0x00, 0x0E, 0x10, 0x00, 0x41, 0xC0, 0x30, 0x08, 0x00, 0x18, 0x30,
0x00, 0x60, 0x60, 0x20, 0x08, 0x00, 0x70, 0x20, 0x00, 0x20, 0x38, 0x20, 0x0C, 0x01, 0xC0, 0x60,
0x00, 0x30, 0x0C, 0x20, 0x04, 0x07, 0x00, 0x40, 0x00, 0x10, 0x07, 0x60, 0x04, 0x0C, 0x00, 0xC0,
0x00, 0x10, 0x01, 0xE0, 0x06, 0x38, 0x00, 0x80, 0x00, 0x18, 0x00, 0xC0, 0x06, 0xE0, 0x01, 0x80,
0x00, 0x08, 0x00, 0x01, 0x83, 0x80, 0x01, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x83, 0x00, 0x03, 0x00,
0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x01, 0x80, 0x00, 0x06, 0x00,
0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x01, 0xC0, 0x00, 0x0C, 0x00,
0x00, 0x02, 0x03, 0x01, 0xC0, 0x08, 0x08, 0x00, 0x00, 0x03, 0x03, 0x81, 0x40, 0x38, 0x18, 0x00,
0x00, 0x01, 0x01, 0xC1, 0xC0, 0x70, 0x10, 0x00, 0x00, 0x01, 0x81, 0xE3, 0xC0, 0xF0, 0x30, 0x00,
0x00, 0x00, 0x80, 0xF3, 0x43, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x80, 0xFE, 0x66, 0x40, 0x60, 0x00,
0x00, 0x01, 0xC0, 0x4E, 0x7C, 0x40, 0x38, 0x00, 0x00, 0x1F, 0x00, 0x66, 0x38, 0x80, 0x0E, 0x00,
0x00, 0xF8, 0x00, 0x20, 0x21, 0x80, 0x03, 0x80, 0x07, 0xC0, 0x00, 0x30, 0x01, 0x00, 0x00, 0xF0,
0x3C, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x1C, 0x68, 0x00, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x0B,
0x3C, 0x00, 0x1F, 0xE0, 0x07, 0xFF, 0x00, 0x0E, 0x07, 0x00, 0x0D, 0x00, 0x00, 0x3B, 0x00, 0x38,
0x01, 0xE0, 0x07, 0x00, 0x00, 0x3C, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xE0, 0x00, 0x70, 0x07, 0x80,
0x00, 0x0E, 0x00, 0x60, 0x03, 0xC0, 0x1C, 0x00, 0x00, 0x03, 0xC0, 0x60, 0x03, 0x00, 0x70, 0x00,
0x00, 0x00, 0x60, 0xC0, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
pinMode(ledPin, OUTPUT);
pinMode(pirPin, INPUT);
}
void loop() {
pirRead = digitalRead(pirPin);
if (pirRead == HIGH) {
digitalWrite(ledPin, HIGH);
if (pirState == LOW) {
Serial.println("Detektovan pokret!");
display.clearDisplay();
display.drawBitmap(32, 0, boomBmp, 64, 64, 1);
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW);
if (pirState == HIGH){
Serial.println("Pokret je prestao!");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(5,5);
display.print("It's a");
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(20,24);
display.print("FAKE!");
pirState = LOW;
}
}
delay(2000);
display.display();
}
----
Prvo
što treba uraditi je pokrenuti neki I2C skener da bi se našla adresa
ekrana. Njačešće je 0x3C kao i u mom slučaju ali nije uvek. I2C skener
imate ovde. Takođe, pre svih testova treba u okviru drajvera (Adafruit_SSD1306.h) izabrati rezoluciju ekrana, a ostale isključiti (//).
Nakon toga ide skeč. U suštini je blago prepravljeni skeč koji sam koristio u prethodnom članku. S tim da su dodate Wire, Adafruit_GFX
i Adafruit_SSD1306 biblioteke. Određujemo reset funkciju display(),
dodeljujemo funkcije neophodnim pinovima kao i par promenljivih. U setup
funkciji pokrećemo ekran koristeći I2C adresu i postavljamo mod
pinovima. U loop funkciji čekamo PIR modul i ako postoji detekcija,
provalnik će aktivirati "bombu" na OLED ekranu a kad opasnost prođe
ispisaćemo da je u pitanju "lažnjak".
Prilikom
česte promene teksta na ekranu potrebno je brisati ekran da ne bi došlo
do pisanja preko teksta funkcijom clearDisplay(). Tekst se može
formatirati po želji: veličina fonta, pozicija, boja... Osim teksta OLED
ekran je u stanju da iscrta i Bitmap, a u ovom slučaju je u pitanju
bomba. U tu svrhu se koristi odgovarajuća veličina BMP slike koju je
potrebno konvertovati u bitmap niz (bitmap array - hex vrednosti).
Najzgodniji za to je LCD Asistent.
Na File->Load image uvozimo sliku. Horizontalna orijentacija je vrlo
bitna a ostalo ostaje kako jeste. Sliku izvozimo na File->Save
Output i snimamo pod explosion.cpp. Ovaj fajl se može otvoriti preko IDE
ili Notepad++ gde je potrebno editovati liniju:
const unsigned char explosion [] = {
u:
const unsigned char PROGMEM explosion [] = {
Ovim govorimo kompajleru da se explosion učita u programsku memoriju a ne u memoriju koja se koristi za globalne promenljive.
OLED
ekrani su generalno laki za upotrebu, mali potrošači i izuzetno oštrog
prikaza. I2C varijante su sporije u odnosu na SPI varijante i razlika je
primetna prilikom iscrtavanja BMP. To ipak ne smeta za ugradnju u
gotove projekte. Sa oštrinom i kontrastom koji poseduje, može se očitati
i sa malo veće daljine.