Arduino Nano, Nokia 5110 LCD i NTC 103 Termistor
Kod Arduina je najlepše to što možeš da se igraš komponentama do
besvesti, da kombinuješ sve i svašta. Rad sa ekranima je svakako
najzanimljiviji a na pomen Nokie 5110 bi svakom ko je iole malo stariji
trebalo da pođu žmarci. E baš ekran Nokie 5110 je na redu da se malo
igramo. Pride je tu i termistor da malo začini celu priču.
Arduino Nano je već koliko toliko poznat pa ćemo ga ovaj put zaobići.
Nokia
5110. Heh, moj prvi mobilni telefon tamo negde 2000-te. Za tadašnje
pojmove već pomalo u kategoriji cigli sa spoljašnjom antenom koja je
hvatala signal bez problema u vremenu kada predajnih antena nije bilo
toliko. Baterija je držala po nedelju dana i to nakon par godina
korišćenja. Ove karakteristike su danas misaona imenica. Elem, ekran
koji se ugrađivao u te Nokie se može kupiti preko interneta i upotrebiti
za prikaz teksta u Arduino svetu. Ekran koristi PCD8544 kontroler koje
je zadužen za grafički prikaz na ekranu rezolucije 48x84. Kontroler
sadrži sve neophodne funkcije za LCD, kao i naponski kontroler što na
kraju znači da nije neophodno dodavati nikakve druge komponente. Za
povezivanje sa Arduinom se koristi 8 pinova zalemljenih na PCB ploči. U
zavisnosti od modela, postoje ekrani sa dva reda pinova gde isti mogu
doći zalemljeni i oni gde je potrebno da radi lemilica. Takođe,
pozadinsko osvetljenje može biti zeleno kao na originalnoj Nokiji ili
plavo kao u mom slučaju.
Pinovi su redom:
- RST - RESET
- CE - Chip Enable
- DC - Data/Command
- DIN - Data In
- CLK - Clock
- VCC - Power Input
- BL - Backlight
- GND - Ground
Za korišćenje ekrana sa Arduinom je potrebna biblioteka, a može se i bez nje. Na youtube postoji rešenje koje je postavio Julian Ilett u tri videa gde se za povezivanje ekrana sa Arduinom ne koristi nikakva biblioteka. Video klipove možete pogledati ovde. Upotrebom određenih funkcija, čovek je postigao skoro sve što bi se postiglo i korišćenjem biblioteke. Ovom prilikom neću dublje ulaziti u skeč i objašnjavati ga, sve to ima na youtube, uz malu napomenu da se skeč sa youtube pukim kopiranjem ne može koristiti zbog "hidden" karaktera. Ovaj ovde bi trebalo da možete . Da biste podrobnije razumeli način korišćenja skeča i Džulijanova objašnjenja, potrebno je ispratiti i datasheet a posebno set instrukcija na strani 14. I kako je on rekao ovu tehničku dokumentaciju je potrebno pročitati više puta. U skeču koji je napisao koristi se heksadecimalni sistem brojeva a šema se nalazi na pomenutoj strani tehničke dokumentacije. U mom slučaju za ekran koji sam koristio sam morao malo da korigujem vrednosti ali suština je ista. Nisam hteo ništa previše da eksperimentišem i uradio sam (skoro) sve po njegovom primeru.
Pinove sam povezao na sledeći način:
- RST - pin 3 gde se u setup funkciji prvo zadaje digitalWrite() LOW pa HIGH
- CE - pin 4 gde se pinu ispisuje prvo LOW a zatim dodeljuje izlaz
- DC - pin 5 gde se ispisuje LOW za komande a nakon funkcije shiftOut() HIGH i dodeljuje izlaz
- DIN - pin 6 koji se određuje za prenos podataka
- CLK - pin 7 isto za prenos podataka
- VCC - u slučaju mog ekrana ide na 5V, jer je u pitanju model koji može da radi na 5V i 3V i na ovo je potrebno obratiti pažnju
- BL - za pozadinsko osvetljenje ide na 5V, gde treba obratiti pažnju jer neki modeli idu na GND
- GND - ide na GND
Za ispisivanje teksta Džulijan je sastavio svojevrsnu biblioteku sa heksadecimalnim brojevima koja dozvoljava ispisivanje najosnovnijih brojeva, slova i znakova. Za korišćenje karaktera van onih iz biblioteke potrebno je istu dopuniti. Biblioteku je potrebno snimiti pod nazivom font.h i smestiti je u isti folder gde i skeč. Ukoliko je snimamo preko notepada ili sličnog editora vrlo je bitno da se snimi u ASCI enkoderu.
Do sada je bilo reči o DHT11 i DHT22, komponentama za merenje spoljašnje temperature. Ovi senzori mere u nekom realnom dnevnom opegu ali šta uzeti da bi se izmerila neka ekstremno visoka ili ekstremno niska temperatura? Odgovor je termistor. U pitanju su otpornici kojima otpornost varira u odnosu na spoljnu temperaturu i mogu da mere od -55°C do 200°. Za 5-6 dinara (da dobro ste pročitali) se preko Aliexpresa može nabaviti termistor sa oznakom 103. U pitanju je NTC termistor a treba znati da postoji i PTC gde je razlika da li će se vrednosti u odnosu na spoljnu temperaturu smanjivati ili povećavati. U Arduino svetu se najčešće koriste NTC termistori.
Da bi se dobila ispravna očitavanja potrebno je malo poznavanje matematike. Treba da znamo kako Arduino konvertuje analogni signal u digitalni. Na ovaj način saznajemo da je maksimalna očitana konvertovana vrednost sa analognog pina 1023. Ovde ide napomena da Arduino ne može izmeriti otpornost već samo napon. Preko jednačine naponskog razdelnika dobijamo ispravna očitavanja koja su dobijena od termistora. Preko Štajnhart-Hartove jednačine dobijamo vrednost u Kelvinima a koju konverzijom pretvaramo u Celzijuse.
Termistor povezujemo prema šemi gde GND ide na jedan kraj otpornika od 10oma a 5V na jedan termistora. Zajednički krajevi otpornika i termistora idu na analogni pin Arduina A0.
Na redu je skeč:
----------------------------------
#define RST 3
#define CE 4
#define DC 5
#define DIN 6
#define CLK 7
#include "font.h";
int tempPin = 0;
int Vout, charTc ;
float R1 = 10000;
float R2, Tk, Tc;
float Ac = 1.009249522e-03, Bc = 2.378405444e-04, Cc = 2.019202697e-07;
char charBuffer[10];
void LcdWriteString(char *characters) {
while(*characters) LcdWriteCharacter(*characters++);
}
void LcdWriteCharacter(char character) {
for(int i=0; i<5; i++) LcdWriteData(ASCII[character - 0x20][i]);
LcdWriteData(0x00);
}
void LcdWriteData(byte dat) {
digitalWrite(DC, HIGH); //DC pin is low for commands
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, dat); //transmit serial data
digitalWrite(CE, HIGH);
}
void LcdXY(int x, int y) {
LcdWriteCmd(0x80 | x); // Column.
LcdWriteCmd(0x40 | y); // Row.
}
void LcdWriteCmd(byte cmd) {
digitalWrite(DC, LOW); //DC pin is low for commands
digitalWrite(CE, LOW);
shiftOut(DIN, CLK, MSBFIRST, cmd); //transmit serial data
digitalWrite(CE, HIGH);
}
void setup() {
Serial.begin(9600);
pinMode(RST, OUTPUT);
pinMode(CE, OUTPUT);
pinMode(DC, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(CLK, OUTPUT);
digitalWrite(RST, LOW);
digitalWrite(RST, HIGH);
LcdWriteCmd(0x21); // LCD extended commands
LcdWriteCmd(0xB0); // set LCD Vop (contrast)
LcdWriteCmd(0x04); // set temp coefficent
LcdWriteCmd(0x14); // LCD bias mode 1:40
LcdWriteCmd(0x20); // LCD basic commands
LcdWriteCmd(0x0C); // LCD normal video
for(int i=0; i<504; i++) LcdWriteData(0x00); // clear LCD
}
void loop() {
Vout = analogRead(tempPin);
R2 = R1 * (1023.0 / (float)Vout - 1.0);
Tk = (1.0 / (Ac + Bc*log(R2) + Cc*log(R2)*log(R2)*log(R2)));
Tc = Tk - 273.15;
charTc=dtostrf(Tc, 3, 2, charBuffer);
Serial.print("Temperatura: ");
Serial.print(Tc);
Serial.println(" °C u sobi!");
LcdXY(8,0);
LcdWriteString("Nije realno");
LcdXY(25,1);
LcdWriteString("ovih");
LcdXY(24,2);
LcdWriteString(charTc);
LcdXY(15,3);
LcdWriteString("stepeni C");
LcdXY(24,4);
LcdWriteString("u sobi");
LcdXY(0,5);
LcdWriteString("Sta vi mislite");
delay(2000);
}
----------------------------------
Malo da pojasnim skeč, a za podrobnije objašnjenje u vezi dela za Nokijin ekran imate link iznad ka youtube. Prvo definišemo pinove koji će biti zaduženi za prenos određenih podataka ka ekranu, određujemo promenjljive i postavljamo konstante. Zatim pravimo par funkcija koje će koristiti namensku biblioteku koju je Džulijan napravio a koju snimamo u isti folder gde i skeč. Dakle jedno pored drugog.
--------------------------------
#include <Arduino.h>
static const byte ASCII[][5] =
{
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f →
};
--------------------------------------------
Nakon toga zadajemo početne vrednosti pinovima određenim za ekran funkcijom LcdWriteCmd(), i određujemo koordinate ekrana funkcijom LcdXY(). Setup funkcija pokreće ekran sa osnovnim postavkama, kao i Serial Monitor. U Loop funkciji kreće magija. Čitamo vrednosti termistora na analognom pinu. U sledećem redu konvertujemo analognu vrednost u digitalnu uz pomoć naponskog razdelnika. Dalje putem Štajnhart-Hartove jednačine dobijamo temperaturu u Kelvinima koju konvertujemo u Celzijuse. Uz pomoć dtostrf() funkcije konvertujemo float u char i dobijamo nešto što se može prikazati na ekranu gde dobijene vrednosti formatiramo po želji i prikazujemo na Serial Monitoru i ekranu Nokie 5110.
Džulijanova uputstva na youtube (link iznad) omogućavaju još mnogo toga, i bilo bi dobro baciti oko. Eventualno proširivanje koda pozdravljam, uz molbu da isti postavite ovde. U pitanju je slobodan softver, ali slobodan je da bi se delio. Delite, molim vas.