Izrada HMI ja Human Machine Interface
Sučelje čovjek-stroj (engl. Human-Machine Interface, HMI) je rješenje koje povezuje sklopovlje i programsku podršku radi međusobne komunikacije. Nextion zaslon je HMI koji omogućuje povezivanje s mikroupravljačem ili nekim drugim elektroničkim sklopom koji za komunikaciju koristi UART (engl. Universal asynchronous receiver-transmitter) sučelje.
Na laboratorijskim vježbama koristi se osnovni (engl. Basic) model NX3224T024_011 Nextion zaslona (Slike 2 i 3) čije su glavne značajke vidljive u tablici niže. Osim Basic modela postoje još Intelligent i Enhanced modeli koji dolaze s dodatnim sklopovskim i programskim mogućnostima.
Potrošnja u normalnom načinu rada | 90mA@5V, jačina svjetline ekrana 100% |
Potrošnja u štednom načinu rada | 15mA |
Veličina dijagonale zaslona | 2.4“ |
Rezolucija | 240x320 piksela |
Vrsta dodirnog zaslona | Rezistivni |
Brzina prijenosa podataka | 2400 – 115200 bps |
Za izradu korisničkog sučelja koristi se program Nextion Editor. Projekti izrađeni u njemu poprimaju ".HMI" ekstenziju i njih je moguće naknadno uređivati. Generirana datoteka koju je potrebno prebaciti u memoriju Nextion zaslona ima ekstenziju ".tft" i nju nije moguće naknadno uređivati. Ona se na Nextion zaslon prenosi pomoću prilagodnog RS232 međusklopa ili microSD memorijske kartice. RS232 prilagodni međusklop olakšava prijenos ".tft" datoteke na Nextion zaslon ali ujedno i pruža mogućnost otklanjanja pogrešaka (engl. debugging). Primjer takvog RS232 prilagodnog međusklopa prikazan je na slici 4.
Preuzmite i instalirajte Nextion Editor s ove poveznice. U nastavku je prikazan postupak izrade novog projekta i generiranja fontova. Budući da ćete u ovoj vježbi koristiti gotov predložak, kojeg ćete preuzeti sa stranice kolegija na LMS-u, ne trebate kreirati novi projekt niti fontove, ali pročitajte upute kako bi se upoznali sa korisničkim sučeljem aplikacije.
Nextion Editor - izrada novog projekta¶
Pokretanjem Nextion Editor-a na osobnom računalu pojavljuje se glavni prozor njegovog korisničkog sučelja (Slika 5). Za kreiranje novog projekta potrebno je u padajućem izborniku File kliknuti na New.
Nakon potvrde unosa imena projekta pojavljuje se prozor (slika 6) u kojem je potrebno odabrati točnu verziju korištenog Nextion zaslona (Basic - NX3224T024_011). Također je potrebno i odabrati željenu orijentaciju zaslona u podizborniku Display (Slika 7).
Potvrdom prethodnih odabira ponovno se pojavljuje glavni prozor novostvorenog projekta (Slika 8). Moguće je uočiti sljedeća polja korisničkog sučelja:
- Toolbox – dostupni grafički elementi za uređivanje korisničkog sučelja
- Picture/Fonts – slike i fontovi koje je korisnik dodao u projekt
- Display – izgled trenutno odabrane stranice (engl. Page)
- Output – konzola koja služi za prikaz statusa memorije i informacija o greškama nastalih prilikom prevođenja programskog koda
- Event – prostor za pisanje programskog koda i definiranje radnji ovisno o događajima
- Page – popis svih stranica od kojih se sastoji Nextion korisničko sučelje
- Attribute – svojstva odabranog elementa korisničkog sučelja
Nextion Editor - generiranje fontova¶
Za prikaz bilo kakvog oblika teksta na zaslonu potrebno je odabrati font. Stoga je nakon otvaranja novog projekta potrebno dodati barem jedan font. To je moguće napraviti klikom na padajući izbornik Tools i otvaranjem aplikacije Font Generator. Time se otvara novi prozor (Slika 9) gdje je potrebno odabrati željeni font i njegovu veličinu. Također je moguće i podebljati font (engl. Bold) i zagladiti mu rubove (engl. Anti-aliasing). Upisivanjem imena fonta (engl. Font Name) koje će biti prikazano u Nextion Editor-u i klikom na generiranje fonta (engl. Generate Font) pojavljuje se prozor u kojem je potrebno upisati ime i navesti lokaciju spremanja datoteke na disk.
Nakon spremanja pojavljuje se prozor gdje je potrebno potvrditi dodavanje kreiranog fonta u Nextion Editor. Font tada poprima ID odnosno redni broj i postaje vidljiv u polju Fonts (Slika 10).
1. zadatak¶
Omogućiti paljenje i gašenje crvene i zelene svjetleće diode s mbed platformom LPC1768. Crvenom svjetlećom diodom je potrebno upravljati pomoću tipkala dok je zelenom potrebno upravljati pomoću tipke koja zadržava stanje. Na tipkalo postaviti tekst „CRVENA“ a na tipku koja zadržava stanje tekst „ZELENA“, kako bi korisniku bilo jasnije čemu služe ta dva grafička elementa. Podesiti njihove dimenzije na 240x60 piksela.
Rješenje:
Preuzeti predložak Nextion HMI projekta sa stranice kolegija na LMS-u te ga pokrenuti na računalu. Iz dostupnih elemenata grafičkog sučelja (polje Toolbox – Slika 8) potrebno je odabrati Button i Dual-state button. Nakon što se tipkalo pojavilo na početnoj stranici, potrebno je promijeniti njegove dimenzije, umetnuti proizvoljni tekst te njegov font (ID 1). Navedeni parametri se nalaze u polju Attribute (Slika 11). U predlošku Nextion HMI projekta sa stranice kolegija su već uključena 3 fonta veličina 16, 32 i 64 piksela.
Analogno tome potrebno je promijeniti parametre tipke koja zadržava stanje (engl. Dual-state button). Na slici 12 je prikazan izgled traženog korisničkog sučelja za ovaj zadatak.
U polju Event (Slika 8, polje 5) potrebno je definirati radnje koje se izvršavaju djelovanjem na grafičke elemente. Za Touch Press Event odnosno pritisak tipkala je stoga potrebno upisati sljedeće:
print "C" // pošalji znak C printh FF FF FF //pošalji tri hex vrijednost FF FF FF kojima se označava kraj poruke
Radnje koje je potrebno izvršiti pritiskom tipke koja zadržava stanje:
if(bt0.val==0)// ako je vrijednost objekta bt0 jednak nuli { print "Z0" // pošalji string "Z0" }else if(bt0.val==1)// ako je vrijednost objekta bt0 jednak jedinici { print "Z1" // pošalji string "Z1" } printh FF FF FF //pošalji tri hex vrijednost FF FF FF kojima se označava kraj poruke
Pritiskom na tipku Debug u alatnoj traci vrši se prevođenje programskog koda te pokretanje simulatora u slučaju da postoje greške prilikom prevođenja. U konzoli je moguće vidjeti rezultat prevođenja (Slika 13).
U polju Simulator Return (Slika 14) Debug prozora moguće je u različitim formatima (HEX i string) vidjeti podatke koje šalje Nextion zaslon.
Pritiskom na tipkalo pojavljuju se HEX vrijednosti 43 i triput FF. Vrijednost 43 prema ASCII tablici odgovara znaku "C".
Potrebno je spojiti shemu prema slici 15 (gore). Zatvaranjem simulatora i pritiskom na tipku Upload u alatnoj traci otvara se prozor za flash-anje Nextion zaslona. Pritiskom na tipku Go započinje flash-anje što je vidljivo na računalu i na samom Nextion zaslonu (Slike 16 i 17).
U nastavku je prikazan programski kod za 1. zadatak:
Import program
00001 #include "mbed.h" 00002 00003 Serial nextion(p28, p27); 00004 DigitalOut myled1(LED2); 00005 DigitalOut myled2(LED4); 00006 00007 char buffer[20]; 00008 int znak = 0; 00009 00010 void Rx_interrupt(void){ 00011 char c; 00012 if(nextion.readable()) { 00013 c = nextion.getc(); 00014 buffer[znak] = c; 00015 znak++; 00016 if ((znak >= 3) && (buffer[znak-1] == 0xff) && (buffer[znak-2] == 0xff) && (buffer[znak-3] == 0xff)) { 00017 if (buffer[0] == 0x43){ 00018 myled1 = !myled1; 00019 }else if (buffer[0] == 0x5A){ 00020 myled2 = buffer[1] - 48; 00021 } 00022 memset(buffer,0,strlen(buffer)); 00023 znak = 0; 00024 } 00025 } 00026 } 00027 00028 int main(){ 00029 nextion.attach(&Rx_interrupt, Serial::RxIrq); 00030 while (1) { 00031 } 00032 }
U gore prikazanom programskom kodu najprije je deklariran objekt klase Serial
, kojim se ostvaruje komunikacija između mikroupravljača i Nextion-a. Nadalje je u programu napisana prekidna funkcija Rx_interrupt()
unutar koje se naprije ispituje dobiva li mikroupravljač podatke od Nextion-a. Ako prima isti se zapisuju u varijablu tipa char
tj. u polje buffer
tipa char
. Istovremeno s punjenjm polja buffer
povečava se i vrijednost cijelobrojne varijale znak
. Ako su poslana tri ili više znaka te ako je na tri zadnja mjesta u polju upisana vrijednost FF, provjerit će se podaci zapisani u polje buffer
. Ako je na nultom mjestu zapisan podatak 0x43, znamo da je pritisnuto tipkalo te će onda digitalni izlaz, na koji je spojena LED2, promjeniti stanje. U suprotnom ako je pritisnuta tipka koja zadržava stanje provjerava se podatak zapisan na nultom mjestu polja te se digitalni izlaz, na koji je spojena LED4, postavlja u visoko ili nisko stanje. U tom slučaju unutar polja na prvom mjestu je zapisana heksadecimalna vrijednost 0x30 ili 0x31, ovisno o stanju tipke. Navedene vrijednosti kada se prebace u dekadski zapis poprimaju vrijednosti 48 ili 49 te se stoga od nje oduzima vrijednost 48 kako bi na digitalni izlaz slali vrijednosti 0 ili 1.
Na kraju prekidne funkcije koriste se funkcije strlen()
, koja vraća broj znakova zapisan u nekoj string
varijabli, u ovom slučaju to je polje znakova buffer
. Druga funkcija je memset()
, kojom se određeni broj znakova u nekoj varijabli postavlja na željene znakove definirane drugim argumentom kojeg funkcija prima. U ovom slučaju cijelo polje zankova buffer
, čiji smo ukupni broj znakova dobili koristeći funkciju strlen()
, postavljamo u nulu, drugim riječima izbirsali smo sve podatke zapisane u navedenom polju.
Unutar glavne funkcije main()
svaki put kada se primi podatak pozvati će se prekidna funkcija Rx_interrupt()
.
Spojite mbed platformu s Nextion zaslonom prema shemi na slici 18.
2. zadatak¶
Prikazati brzinu vrtnje ventilatora na Nextion zaslonu pomoću tekstualnog indikatora i grafa. Očitane vrijednosti je potrebno s mikroupravljača slati svaku sekundu.
Rješenje:
U vježbi se koristi maketa (Slika 19) sastavljena od ventilatora i transmisivnog optičkog senzora TCST1103 koji služi za mjerenje brzine vrtnje ventilatora.
TCST1103 optički element se sastoji od infracrvene svjetleće diode i fototranzistora te je spojen prema shemi na slici 20. Ako infracrvena svjetleća dioda nesmetano osvjetljava fototranzistor, naponski potencijal u točki p18 (Slika 20) iznosi 0V. Ako se blokira svjetlosna zraka, fototranzistor prestaje voditi i naponski potencijal u točki p18 iznosi 5V.
Spojiti pinove makete s mbed platformom (raspored ponova na maketi je slijeva nadesno) prema tablici 2.
Maketa | mbed platforma LPC1768 |
Pin broj 1 | 39. pin (5.0 V USB Out - VU) |
Pin broj 2 | 18. pin |
Pin broj 3 | 1. pin (0 V - GND) |
U prozoru Page (Slika 8, polje 6) Nextion Editor-a kliknuti mišem na stranicu page1 kako bi ona postala aktivna. Iz dostupnih elemenata grafičkog sučelja (polje Toolbox) odabrati tekstualni indikator (Text) i graf (Waveform). Za prikaz teksta na tekstualnom indikatoru odabrati font veličine 32 piksela (ID 1). Skaliranje vrijednosti prikazanih na grafu je potrebno postaviti na 60 (Slika 21).
Na slici 22 je prikazan izgled traženog korisničkog sučelja za ovaj zadatak.
Spojiti shemu prema slici 15 te flash-ati Nextion zaslon s novim korisničkim sučeljem.
U nastavku je prikazan programski kod za 2. zadatak:
Import program
00001 #include "mbed.h" 00002 00003 InterruptIn optic(p18); 00004 Serial nextion(p28, p27); 00005 Ticker sendData; 00006 00007 Timer t; 00008 float T = 0; 00009 uint16_t rpm = 0; 00010 bool flag = false; 00011 00012 void prolaz(){ 00013 T = t.read(); 00014 t.reset(); 00015 flag = true; 00016 } 00017 00018 void data(){ 00019 if (t.read() < 1.0 && flag) 00020 rpm = 30.0/T; // rpm = 60 * f = 60 * 1/T * 1/2 = 30/T 00021 else rpm = 0; 00022 nextion.printf("t1.txt=\"%d rpm\"%c%c%c", rpm, 255, 255, 255); //t1.txt="tekst" 0xFF 0xFF 0xFF 00023 nextion.printf("add 5,0,%d%c%c%c", rpm/100, 255, 255, 255); //add <waveform>,<channel>,<value> 0xFF 0xFF 0xFF 00024 } 00025 00026 int main(){ 00027 t.start(); 00028 optic.rise(&prolaz); 00029 sendData.attach(&data, 1.0); 00030 while(1) { 00031 wait(1.0); 00032 } 00033 }
U gore prikazanom programskom kodu je, kao i u prethodnom, deklariran objekt klase Serial
kojim se ostvaruje komunikacija između mikroupravljača i Nextion-a. Svakim prolazom elise ispred senzora se blokira zraka svjetlosti što rezultira generiranjem prekida na ulaznom pinu mikroupravljača. Na prekid je potrebno reagirati programski zbog čega je i kreiran objekt klase InterruptIn
. Slanje podataka s mikroupravljača na Nextion se vrši svaku sekundu, što je izvedeno pomoću ticker-a sendData
te je stoga kreiran objekt klase Ticker
. Za izračun brzine vrtnje motora potrebno je mjeriti vrijeme između dva prekida. Iz tog razloga je kreiran objekt klase Timer
.
Brzina vrtnje motora može se izračunati prema izrazu:
n=60*f [rpm]
Pri čemu je f frekvencija odnosno broj generiranih prekida (prolaska elisa). Vrijeme između dva generirana prekida je recipročna vrijednost frekvencije, odnosno:
T= 1/f [s]
Ako se uzme u obzir da se prilikom jednog punog okreta osovine motora generira dva prekida, brzina vrtnje motora se može izračunati kao:
n=60* 1/T* 1/2= 30/T [rpm]
U prekidnoj rutini (funkcija prolaz()
) se očitava vrijeme koje je timer izmjerio nakon čega se timer resetira. Istovremeno se bool
varijabla flag
postavlja u true. Ona služi za pravilan proračun brzine vrtnje motora. Pomoću ticker-a se u prekidnoj funkciji data()
svaku sekundu provjerava stanje bool varijable. U slučaju da se u prethodnoj sekundi generirao barem jedan prekid, vrši se proračun brzine vrtnje motora prema zadnjem izrazu. U protivnom brzina vrtnje iznosi 0.
Slanje vrijednosti brzine vrtnje motora se također izvršava pomoću ticker-a. Prema kreiranom korisničkom sučelju, da bi se upisala neka vrijednost u elementu korisničkog sučelja t1, potrebno je poslati podatak formata t1.txt="brzina"FF FF FF. Za dodavanje točke na graf potrebno je poslati podatak formata add <waveform>,<channel>,<value>FF FF FF. Argument waveform predstavlja ID oznaku grafičkog elementa na korisničkom sučelju. Potrebno je uzeti u obzir da Y os predstavlja memorijsku lokaciju od jednog bajta (engl. byte). Stoga Y vrijednost mora biti u rasponu od 0 do 255. U protivnom dolazi do preljeva i neželjenog prikaza na grafu.
Detalje vezane za navedene naredbe moguće je vidjeti na službenoj internet stranici Nextion zaslona.
Spojite ventilator na laboratorijski izvor konstante struje te pažljivo povećavajte strujni limit kako bi se ventilator krenuo vrtjeti. Pritom pripazite da napon napajanje ne prelazi 1 V.
3. zadatak¶
Omogućiti upravljanje SG90 servo motora pomoću kliznog upravljača (engl. Slider) i prikaz kuta pomoću tekstualnog indikatora (engl. Text).
Rješenje:
Preuzeti predložak Nextion HMI projekta sa stranice kolegija na LMS-u te ga pokrenuti na računalu. U prozoru Page (Slika 8, polje 6) Nextion Editor-a kliknuti mišem na stranicu page2 kako bi ona postala aktivna. Iz dostupnih elemenata grafičkog sučelja (polje Toolbox – Slika 8) potrebno je odabrati Text i Slider. Podesiti minimalnu vrijednost kliznog upravljača na 0, maksimalnu na 180 te zadanu vrijednost na 90 (Slika 23).
U parametrima tekstualnog indikatora odabrati font visine 32 piksela (ID 1). U polju Event (Slika 8, polje 5) potrebno je definirati radnju koje se izvršava djelovanjem na klizni upravljač.
Za Touch Release Event je stoga potrebno upisati sljedeće:
covx h0.val,t1.txt,0,0 // pretvaranje cjelobrojne vrijednosti slidera h0 u string i zapis u tekstualni indikator t1 print t1.txt // printanje vrijednosti tekstualnog indikatora printh 0D // CR, krajnji znak t1.txt=t1.txt+"°" // dodavanje znaka '°' na kraj stringa t1
Na slici 24 je prikazan izgled traženog korisničkog sučelja za ovaj zadatak.
Spojiti shemu prema slici 15 te flash-ati Nextion zaslon s novim sučeljem.
Import program
00001 #include "mbed.h" 00002 00003 Serial nextion(p28, p27); 00004 PwmOut servo(p21); 00005 00006 char buffer[20]; 00007 int znak = 0; 00008 00009 uint8_t pozicija = 0; 00010 00011 void Rx_interrupt(void){ 00012 char c; 00013 00014 if(nextion.readable()) { 00015 c = nextion.getc(); 00016 buffer[znak] = c; 00017 znak++; 00018 if ((znak >= 2) && (buffer[znak-1] == 0x0d)) { 00019 pozicija = 0; 00020 for(int i = 0; i < 3; i++) { 00021 if(buffer[i] == 0x0d) break; 00022 pozicija = pozicija * 10 + (buffer[i] - 48); 00023 } 00024 servo.pulsewidth_us(5.56*pozicija+1000); 00025 memset(buffer,0,strlen(buffer)); 00026 znak = 0; 00027 } 00028 } 00029 } 00030 00031 int main(){ 00032 nextion .attach(&Rx_interrupt, Serial::RxIrq); 00033 servo.period(0.02); 00034 while (1) { 00035 wait(1.0); 00036 } 00037 }
Kao i u prijašnjim zadacima, u gore prikazanom programskom kodu najprije je deklariran objekt klase Serial
kako bi se ostvarila komunikacija između mikroupravljača i Nextion-a. Također, isto kao i u prvom zadatku deklarirano je polje znakova buffer
i cjelobrojna pomoćna varijabla znak
. Dodana je i nova pomoćna varijabla koja će služiti za spremanje podatka o poziciji zadanoj putem Nextion-a. U glavnoj funkciji main()
osim poziva prekidne funkcije Rx_interrupt()
postavljen je i period tj. frekvencija pwm izlaza na koji je spojen servo motor te ona iznosi 50 Hz. U prekidnoj funkciji Rx_interrupt
ponavlja se sličan postupak provjere primljenog podatka iz 1. zadatka. Unutar for
petlje prolazimo kroz polje znakova buffer
sve dok ne naiđemo na znak "0x0d". Podaci poslani s Nextion-a prebaciju se iz heksadecimalnog zapisa u dekadski te se zapisuju u varijablu pozicija
sljedećim postupkom:
1. npr. poslan je podatak 130° - u heksadecimalnom zapisu taj podatak glasi: 31 33 30 OD, kada ga prebacimo u dekadski zapis to je 49 51 48
2. pri prvom prolazu kroz for
petlju u varijablu pozicija
, u koju je prije for
zapisana vrijednost nula, zapisuje se vrijednost 1 sljedećom jednadžbom: 0 * 10 + 49 - 48
3. pri drugom i trećem prolazu kroz for
petlju prema istoj jednadžbi u varijablu pozicija zapisuju se vrijednosti 3 i 0, s time da se varijabla u svakoj iteraciji množi s 10 pa je konačna vrijednost spremljena u nju jednaka 130.
Navedena vrijednost se zatim šalje na pwm izlaz mikroupravljača koristeći funkciju pulsewidth_us()
. Budući da se servo motor SG90 aktivira samo s radnim ciklusom (engl. duty cycle) u rasponu od 1 do 2 ms, potrebno je skalirati signal koji dobivamo na pwm izlazu mikroupravljača. Budući da funkcija pulsewidth_ms
prima samo cjelobrojne vrijednosti, koristi se funkcija pulsewidth_us
. Skaliranje je izvedeno tako da se vrijednost dobivena s Nextion-a (u rasponu od 0° do 180°) pomnoži s vrijednošću 5.56 što bi u slučaju za 180° rezultiralo vrijednošću 1000 us zbroji s vriejdnošću od 1000 us te smo time dobili signal radnog ciklusa u rasponu od 1000 do 2000 us tj. od 1 do 2 ms.
Na kraju prekidne funkcije ponovno imamo, kao i prvom zadatku brisanje podataka koji su zapisani u polje znakova buffer
te postavljanje pomoćne variajble znak
na nulu.
Servo motor spojite tako da crvenu žicu motora spojite na +5 V laboratorijskog izvora napajanja, narančastu 21. pin mbed platforme a smeđu spojite na GND laboratorijskog izvora napajanja i mbed platforme.
Čestitke!
Završili ste sve vježbe iz teme Koristenje ARM Keil razvojnog okruzenja.
Povratak na naslovnu stranicu TVZ Mechatronics Team-a.