Διασύνδεση του I2C LCD με το Arduino

Στις ηλεκτρονικές κατασκευές που κάνουμε με το Arduino, συχνά δημιουργείται η ανάγκη της απεικόνισης δεδομένων. Ένας τρόπος που μπορούμε να το κάνουμε είναι με τη χρήση μιας μονάδας LCD χαρακτήρων.

Στη διασύνδεση της μονάδας LCD με το Arduino χρησιμοποιούνται 6 ψηφιακά Ι/Ο pins στην κατάσταση λειτουργίας 4-bit mode και μας μένουν διαθέσιμα 14 – 6 = 8 ψηφιακά pins εισόδου -εξόδου. Υπάρχουν περιπτώσεις που αυτός ο διαθέσιμος αριθμός ψηφιακών pins δεν μας φτάνει.

Μπορούμε να ξεπεράσουμε αυτό το πρόβλημα με τη χρήση μιας μονάδας I2C LCD. Αυτό περιλαμβάνει 2 pins (εκτός τους 2 ακροδέκτες τροφοδοσίας) που συνδέονται στο δίαυλο I2C του Arduino, ελευθερώνοντας όλα τα ψηφιακά pins I/O.

Επισκόπηση του I2C LCD

Μια τυπική I2C LCD μονάδα αποτελείται από δυο μέρη. Τη LCD μονάδα χαρακτήρων που βασίζεται στο τσιπ HD44780 και ένα pcb προσαρμογέα που είναι κολλημένο πίσω από τη μονάδα LCD.

Η μονάδα LCD χρησιμοποιείται για την απεικόνιση αλφαριθμητικών χαρακτήρων όπως γράμματα, αριθμούς και χαρακτήρες. Κατασκευάζεται σε διάφορα μεγέθη, για παράδειγμα μια 16Χ2 μονάδα LCD μπορεί να απεικονίσει 32 ASCII χαρακτήρες σε δυο γραμμές των 16 χαρακτήρων η κάθε μια.

Εάν παρατηρήσεις από κοντά τη μονάδα LCD, θα δεις τον κάθε χαρακτήρα μέσα σε ένα παραλληλόγραμμο  με τα pixel να τον σχηματίζουν. Κάθε παραλληλόγραμμο αποτελείται από ένα πλέγμα 5Χ8 pixels

To pcb του προσαρμογέα βασίζεται στον 8-bit  I/O Expander chip – PCF8574. Αυτό το ολοκληρωμένο κύκλωμα μετατρέπει τα σειριακά δεδομένα του πρωτοκόλλου I2C σε παράλληλα δεδομένα για επικοινωνία με το LCD module.

Πάνω στο pcb του προσαρμογέα υπάρχει ένα τρίμερ για τη ρύθμιση της αντίθεσης του ντισπλέι. Επιπρόσθετα υπάρχει και ένας βραχυκυκλωτήρας πάνω στο pcb για την επιλογή του πίσω φωτισμού.

I2C διευθύνσεις του LCD

Υπάρχει η περίπτωση να χρησιμοποιείς πολλαπλές συσκευές πάνω στον ίδιο δίαυλο I2C. Σε αυτή την περίπτωση θα πρέπει να επιλέξεις μια διαφορετική διεύθυνση για τη I2C LCD μονάδα για να μην έχουμε σύγκρουση δεδομένων με άλλες I2C συσκευές.

Πάνω στο pcb του προσαρμογέα υπάρχουν επαφές (βλέπε εικόνα) που μπορείς να τις βραχυκυκλώσεις κατάλληλα με κόλληση για να ορίσεις την I2C διεύθυνση του I2C LCD module.

Ευτυχώς ή δυστυχώς υπάρχουν αρκετές εταιρίες που κατασκευάζουν το ίδιο PCF8574 τσιπ όπως η Texas Instruments, η NXP Semiconductors και άλλες. Η I2C διεύθυνση του LCD module ορίζεται διαφορετικά από εταιρεία – σε εταιρία.

Αν το LCD έχει ένα PCF8574 από την Texas Instruments

Σύμφωνα με το εγχειρίδιο της Texas Instruments, τα 3 λιγότερα σημαντικά bit (Α0, Α1, Α2) του 7-bit του καταχωρητή διεύθυνσης είναι bits επιλογής που ορίζουν και από μια διαφορετική διεύθυνση:

Αφού υπάρχουν 3-bit με τα οποία μπορούμε να ορίσουμε και από μια διαφορετική διεύθυνση και κάθε bit έχει δυο δυνατές τιμές 0 και 1, τότε μπορούμε να θέσουμε μια από οχτώ διαφορετικές διευθύνσεις.

Προκαθορισμένα και τα τρία bit επιλογής της διεύθυνσης έχουν τιμή το λογικό 1 με τράβηγμα pull up, ορίζοντας το PCF8574 με την προκαθορισμένη διεύθυνση 0100111 στο δυαδικό ή 0x27 στο δεκαεξαδικό.

Βραχυκυκλώνοντας με κόλληση τις επαφές που ορίζουν την διεύθυνση τότε τα αντίστοιχα bit τίθενται σε LOW.

Αν το LCD  έχει ένα PCF8574 τσιπ από την NXP Semiconductor

Σύμφωνα με το εγχειρίδιο της NXP Semiconductor υπάρχουν τρία bit επιλογής (Α0, Α1, Α2) πάνω στο 7-bit I2C καταχωρητή διεύθυνσης που στο κάθε ένα μπορούμε να δώσουμε τιμή 0 ή 1 και έτσι ορίζονται οκτώ διαφορετικές διευθύνσεις.

Προκαθορισμένα και τα τρια bit επιλογής της διεύθυνσης έχουν τιμή το λογικό 1 με τράβηγμα pull up, ορίζοντας το PCF8574 στην προκαθορισμένη διεύθυνση 0111111 στο δυαδικό ή 0x3F στο δεκαεξαδικό.

Βραχυκυκλώνοντας με κόλληση τις επαφές που ορίζουν την διεύθυνση τότε τα αντίστοιχα pins τίθενται σε LOW.

Διάταξη ακροδεκτών του I2C LCD

To I2C LCD module επικοινωνεί με τον έξω κόσμο χρησιμοποιώντας 4 ακροδέκτες:

GND: είναι ο ακροδέκτης της γείωσης και συνδέεται με τον ακροδέκτη 0V του Arduino.
Vcc: είναι η τάση τροφοδοσίας του LCD. Συνδέεται στην έξοδο 5V του Arduino ή σε εξωτερικό τροφοδοτικό 5V
SDA: είναι ο ακροδέκτης σειριακών δεδομένων που χρησιμοποιείται για αποστολή ή λήψη δεδομένων. Συνδέεται στο pin SDA του Arduino.
SCL: είναι ο ακροδέκτης ρολογιού για συγχρονισμό μετάδοσης δεδομένων. Οι παλμοί ρολογιού παράγονται από την Master συσκευή. Συνδέεται στο pin SCL του Arduino

Διασύνδεση του Arduino Uno σε ένα I2C LCD module

Επειδή το I2C LCD χρησιμοποιεί 4 pins για την διασύνδεση του, είναι πιο εύκολο να το χρησιμοποιήσουμε αυτό αντί του κλασικού LCD που χρησιμοποιεί 12 pins.

Για να χρησιμοποιήσεις τη I2C LCD μονάδα σύνδεσε το VIN pin με το pin 5V του Arduino και το GND με το 0V του Arduino.

Τώρα μένει να συνδέσουμε τα pins που ορίζουν την I2C επικοινωνία. Ας σημειώσουμε εδώ ότι κάθε Arduino Board έχει διαφορετικά pins για I2C επικοινωνία τα οποία θα πρέπει να συνδεθούν κατάλληλα. Για το Arduino Uno R3, ο ακροδέκτης SDA (data line) του I2C LCD συνδέεται με το pin A4(SDA) του Arduino Uno και ο ακροδέκτης SCL (clock line) του I2C LCD συνδέεται με το pin Α5(SCL) του Arduino Uno.

Εάν χρησιμοποιείς διαφορετικό Arduino Board βασίσου στον πίνακα που ακολουθεί:

Μετά που διασυνδέσεις το I2C LCD module θα πρέπει να ρυθμίσεις την αντίθεση της οθόνης για να έχεις το βέλτιστο αποτέλεσμα. Στο I2C LCD θα βρεις ένα μικρό ποτενσιόμετρο που μπορείς να το ρυθμίσεις με ένα μικρό κατσαβίδι για να ορίσεις την επιθυμητή αντίθεση.

Εγκατάσταση βιβλιοθήκης

Για να μπορέσει το Arduino Board να επικοινωνήσει με τη μονάδα I2C LCD και να απεικονίσει δεδομένα είναι αναγκαίο να εγκαταστήσουμε την κατάλληλη βιβλιοθήκη. Γι’ αυτό το σκοπό θα πρέπει να χρησιμοποιήσουμε την βιβλιοθήκη LiquidCrystal_I2C Library.

Υπάρχουν αρκετές εκδόσεις αυτής της βιβλιοθήκης διαθέσιμες, αλλά μία από τις πιο αξιόπιστες είναι η έκδοση που δημιούργησε ο Frank de Brabander. Για να εγκαταστήσεις τη βιβλιοθήκη:

  1. Άνοιξε πρώτα το πρόγραμμα Arduino IDE. Έπειτα κάνε κλικ στο εικονίδιο Library Manager στην αριστερή πλαϊνή μπάρα.
  2. Πληκτρολόγησε “liquidcrystal” στο πεδίο αναζήτησης για να φιλτράρεις τα αποτελέσματα.
  3. Αναζήτησε τη βιβλιοθήκη “LiquidCrystal I2C library” που δημιουργήθηκε από τον Frank de Brabander.
  4. Πάτησε το κουμπί Install για να την προσθέσεις στο Arduino IDE.

Ανιχνεύοντας την I2C διεύθυνση

Η διεύθυνση της μονάδας I2C LCD εξαρτάται από τον κατασκευαστή του PCF8574 και την βραχυκύκλωση των επαφών όπως εξηγήσαμε νωρίτερα. Η προκαθορισμένη διεύθυνση (χωρίς τη βραχυκύκλωση των επαφών) για το τσιπ που είναι κατασκευασμένο από την Texas Instruments είναι 0x27 ενώ η προκαθορισμένη διεύθυνση του τσιπ κατασκευασμένο από την NXP Semiconductors είναι 0x3F.

Παρατηρούμε ότι υπάρχει σύγχυση για τον προσδιορισμό της διεύθυνσης του PCF8574 τσιπ. Ένας τρόπος για να το λύσουμε αυτό είναι να χρησιμοποιήσουμε ένα sketch που αφού συνδέσουμε τη μονάδα στο Arduino και το τρέξουμε δίνει στο Serial Monitor την επιθυμητή I2C διεύθυνση.

Μπορείς να βρείς αυτό το sketch στη διαδρομή File > Examples > Wire > i2c_scanner στο μενού του Arduino IDE.

Φόρτωσε το i2c_scanner sketch στο Arduino IDE:

#include <Wire.h>

void setup() {
  Wire.begin();

  Serial.begin(9600);
  while (!Serial); // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop() {
  int nDevices = 0;

  Serial.println("Scanning...");

  for (byte address = 1; address < 127; ++address) {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.print(address, HEX);
      Serial.println("  !");

      ++nDevices;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0) {
    Serial.println("No I2C devices found\n");
  } else {
    Serial.println("done\n");
  }
  delay(5000); // Wait 5 seconds for next scan
}

Αφού ανεβάσεις το sketch στο Arduino σου, άνοιξε το Serial Monitor και ρύθμισέ το στα 9600 baud. Σε λίγα δευτερόλεπτα, θα πρέπει να εμφανιστεί στην οθόνη η διεύθυνση I2C της LCD οθόνης σου.

Φρόντισε να σημειώσεις αυτή τη διεύθυνση κάπου με ασφάλεια. Θα τη χρειαστείς όταν δουλέψουμε με την LCD σε επόμενα παραδείγματα.

Κώδικας επίδειξης για το Arduino – Hello World

Παρακάτω δίνεται δοκιμαστικός κώδικας για το Arduino που απεικονίζει το μήνυμα «Hello World» στην πρώτη γραμμή και «LCD tutorial» στην δεύτερη γραμμή σε μια μονάδα I2C LCD.

Στον κώδικα που ακολουθεί θα πρέπει να κάνεις αλλαγές που εξαρτώνται από την διεύθυνση του I2C και τις διαστάσεις σε στήλες και γραμμές του LCD. Εάν χρησιμοποιείς 16Χ2 χαρακτήρων LCD πέρασε τις παραμέτρους 16, 2 και εάν χρησιμοποιείς 20Χ4 LCD πέρασε τις παραμέτρους 20, 4 στην συνάρτηση δημιουργίας του αντικειμένου lcd.

Όταν γίνει κατανοητό προχώρησε και φόρτωσε τον ακόλουθο κώδικα:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);  // Ορισμός της διεύθυνσης για ένα 16 Χ 2                                      
                       //χαρακτήρων I2C LCD και δήλωση του μεγέθους του LCD.

void setup() {
  lcd.init();
  lcd.clear();         
  lcd.backlight();      // Άναψε τον πίσω φωτισμό
  
  // Εμφάνισε ένα μήνυμα και στις δυο γραμμές του LCD.
  lcd.setCursor(2,0);   //Μετακίνησε τον κέρσορα στον χαρακτήρα 2 στη γραμμή 0
  lcd.print("Hello world!");
  
  lcd.setCursor(2,1);   //Μετακίνησε τον κέρσορα στον χαρακτήρα 2 στη γραμμή 1
  lcd.print("LCD Tutorial");
}

void loop() {
}

Όταν όλα πάνε καλά θα έχεις το αποτέλεσμα όπως στην ακόλουθη εικόνα:

Επεξήγηση του κώδικα

Ο κώδικας ξεκινά με την συμπερίληψη της βιβλιοθήκης LiquidCrystal_I2C, που περιέχει όλο τον κώδικα για τον έλεγχο της μονάδας I2C LCD.

# include <LiquidCrystal_I2C.h>

Στη συνέχεια δημιουργείται ένα αντικείμενο της κλάσης LiquidCrystal_I2C. Η συνάρτηση δημιουργίας του αντικειμένου παίρνει τρείς παραμέτρους: την διεύθυνση, τον αριθμό των στηλών και γραμμών. Εδώ μπορείς να δηλώσεις την διεύθυνση, την προκαθορισμένη ή την διεύθυνση που βρήκες νωρίτερα και τις διαστάσεις της οθόνης του I2C LCD.

LiquidCrystal_I2C lcd(0x3F, 16, 2);

Μόλις το αντικείμενο της κλάσης δημιουργηθεί τότε αυτό μπορεί να δράσει σε μεθόδους (συναρτήσεις) που έχουν οριστεί για το I2C.

Στη συνάρτηση ‘setup’ χρησιμοποιείται η συνάρτηση init() για να αρχικοποιήσει το lcd αντικείμενο. Στη συνέχεια καλείται η συνάρτηση clear() η οποία καθαρίζει την οθόνη του LCD και μετακινεί τον κέρσορα στην πάνω αριστερή γωνία. Η συνάρτηση backlight() χρησιμοποιείται για να ανάψει τον πίσω φωτισμό:

lcd.init();
lcd.clear();
lcd.backlight();

Στη συνέχεια με την συνάρτηση lcd.setCursor(2, 0); ο κέρσορας τοποθετείται στη τρίτη στήλη και στη πρώτη γραμμή, που ορίζει τη θέση που θα εισαχθεί νέο κείμενο στο LCD. Σημείωση: η πάνω αριστερή θέση έχει συντεταγμένες στήλη = 0 και γραμμή = 0.

lcd.setCursor(2, 0);

Στη συνέχεια, καλώντας την παρακάτω συνάρτηση print εμφανίζεται στο I2C LCD το μήνυμα «Hello World»

lcd.print(“Hello World”);

Στη συνέχεια ο κέρσορας τοποθετείται στη τρίτη στήλη και στη δεύτερη γραμμή και με την εντολή print εμφανίζεται το μήνυμα «LCD Tutorial» στην οθόνη του LCD:

lcd.setCursor(2, 1);
lcd.print(“LCD Tutorial”);

Εάν έχεις ένα μήνυμα με μέγεθος μεγαλύτερο από 16 χαρακτήρες, ή θέλεις να κάνεις το εφέ της κύλισης, τότε μπορείς να χρησιμοποιήσεις τις συναρτήσεις scrollDisplayLeft() ή scrollDisplay() σε βρόγχο για να κυλίσεις το κείμενο κατά μήκος της οθόνης.

Το ακόλουθο sketch δείχνει πως να κυλίσεις το μήνυμα συνεχόμενα προς τα αριστερά:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x3F for a 16 chars and 2 line display

void setup() {
  lcd.init();
  lcd.clear();         
  lcd.backlight();      // Make sure backlight is on
  
  // Print a message
  lcd.print("Scrolling Text Demo");
  delay(1000);  // pause to read the message initially
}

void loop() {
  lcd.scrollDisplayLeft();   // scroll everything to the left by one position
  delay(300);                // small delay for visible scrolling speed
}

Σε αυτό το παράδειγμα, προβάλουμε ένα μήνυμα το οποίο έχει μέγεθος 19 χαρακτήρες (“Scrolling Text Demo”) στη μονάδα LCD. Επειδή η οθόνη μπορεί να εμφανίσει μόνο 16 χαρακτήρες τη φορά, αρχικά θα είναι ορατοί μόνο οι πρώτοι 16 χαρακτήρες.

// Εκτύπωσε ένα μήνυμα στην LCD
lcd.print("Scrolling Text Demo");

Στη συνάρτηση loop(), καλούμε την lcd.scrollDisplayLeft(), η οποία μετακινεί όλο το περιεχόμενο της οθόνης μια θέση προς τα αριστερά. Επαναλαμβάνοντας αυτό με μια μικρή παύση μεταξύ των μετακινήσεων, εμφανίζεται το μήνυμα να κυλίεται συνεχόμενα και ομαλά κατά μήκος της οθόνης.

void loop(){
   lcd.scrollDisplayLeft(); // κύλιση προς τα αριστερά κατά μια θέση
   delay(300); // μικρή παύση για ορατή ομαλή κίνηση
}

Καθώς το κείμενο κυλάει, οι χαρακτήρες που βγαίνουν από το αριστερό άκρο εξαφανίζονται και κενά διαστήματα εμφανίζονται στη δεξιά πλευρά της οθόνης. Αν θέλεις το μήνυμα να επαναλαμβάνεται συνεχώς σε βρόχο, θα χρειαστεί να προσθέσεις κώδικα που να το επανεμφανίζει περιοδικά.

Άλλες χρήσιμες συναρτήσεις της βιβλιοθήκης:

— lcd.home()  μετακινεί τον κέρσορα στην πάνω αριστερή γωνία χωρίς να καθαρίσει την οθόνη.
— lcd.clear() καθαρίζει τα περιεχόμενα της οθόνης
— lcd.cursor() εμφανίζει τον κέρσορα σαν μια γραμμή υπογράμμισης στη θέση που ο επόμενος χαρακτήρας θα εμφανιστεί.
— lcd.noCursor()  κρύβει τον κέρσορα.
— lcd.blink() αναβοσβήνει ένα παραλληλόγραμμο από 5Χ8 pixels στη θέση που ο επόμενος χαρακτήρας θα εμφανιστεί.
— lcd.noBlink() απενεργοποιεί την λειτουργία blink του 5Χ8 pixel κέρσορα.
— lcd.display() εμφανίζει τα περιεχόμενα της οθόνης LCD που προηγουμένως υπήρχαν στην LCD.
— lcd.noDisplay() θέτει σε κατάσταση off την οθόνη χωρίς να την καθαρίζει έτσι ώστε οι χαρακτήρες / κείμενο μπορούν να ξαναεμφανιστούν καλώντας την συνάρτηση display()
— lcd.scrollDisplayLeft()  κυλίει τα περιεχόμενα της οθόνης ένα διάστημα αριστερά. Εάν θέλεις να κυλίεις το κείμενο συνεχόμενα, τότε θα πρέπει να χρησιμοποιήσεις αυτή τη συνάρτηση μέσα σε επαναληπτικό βρόγχο.
— lcd.scrollDisplayRight() μετακινεί τα περιεχόμενα της οθόνης ένα διάστημα δεξιά.
— lcd.autoscroll() ενεργοποιεί την αυτόματη κύλιση του περιεχομένου της οθόνης του I2C LCD. Εάν η τρέχουσα κατεύθυνση του κειμένου είναι αριστερά προς δεξιά (προεπιλεγμένη) τα περιεχόμενα κυλίωνται προς τα αριστερά και εάν η τρέχουσα κατεύθυνση είναι από δεξιά προς αριστερά τα περιεχόμενα κυλίονται προς δεξιά.
— lcd.noAutoscroll() απενεργοποιεί την αυτόματη κύλιση.

Μερικές φορές μπορεί να θέλετε να εμφανίσετε ειδικούς χαρακτήρες που δεν ανήκουν στο τυπικό αλφάβητο ή στους αριθμούς — για παράδειγμα, σύμβολα όπως ένα χαμογελαστό πρόσωπο, το σύμβολο βαθμού (∘) για ενδείξεις θερμοκρασίας ή διασκεδαστικά εικονίδια όπως καρδιές, μουσικές νότες ή βέλη.

Τα καλά νέα είναι ότι οι LCD HD44780 σας επιτρέπουν να δημιουργήσετε έως και 8 προσαρμοσμένους χαρακτήρες δικού σας σχεδιασμού! Όπως μάθαμε νωρίτερα σε αυτό το εκπαιδευτικό υλικό, κάθε χαρακτήρας στην LCD εμφανίζεται χρησιμοποιώντας ένα μικρό πλέγμα από pixels διατεταγμένα σε μοτίβο 5×8 (5 pixels σε πλάτος και 8 pixels σε ύψος). Για να δημιουργήσετε τον δικό σας χαρακτήρα, θα πρέπει να αποφασίσετε ποια από αυτά τα μικροσκοπικά σημεία θα είναι ενεργοποιημένα και ποια θα είναι απενεργοποιημένα.

Για να δημιουργήσετε τον προσαρμοσμένο χαρακτήρα σας, πρέπει πρώτα να φτιάξετε στον κώδικά σας έναν πίνακα 8 bytes. Κάθε byte σε αυτόν τον πίνακα αντιπροσωπεύει μία οριζόντια γραμμή του χαρακτήρα σας, ξεκινώντας από την επάνω γραμμή και προχωρώντας προς την κάτω. Για κάθε byte, θα χρησιμοποιήσετε τα bits (τα 1 και 0 στο δυαδικό σύστημα) για να δηλώσετε ποια pixels θα είναι ΕΝΕΡΓΑ (1) και ποια θα είναι ΑΝΕΝΕΡΓΑ (0). Χρησιμοποιούνται μόνο τα πρώτα 5 bits από κάθε byte, αφού ο χαρακτήρας έχει πλάτος 5 pixels.

Αφού σχεδιάσετε τον χαρακτήρα σας ρυθμίζοντας αυτόν τον πίνακα, μπορείτε να χρησιμοποιήσετε τη συνάρτηση createChar() για να αποθηκεύσετε τον προσαρμοσμένο χαρακτήρα σας στη CGRAM (Character Generator RAM) της LCD, η οποία είναι μια ειδική περιοχή μνήμης σχεδιασμένη αποκλειστικά για την αποθήκευση προσαρμοσμένων χαρακτήρων.

Η δημιουργία προσαρμοσμένων χαρακτήρων στην μονάδα I2C LCD είναι σχεδόν η ίδια με εκείνης της απλής μονάδας LCD που αναπτύσουμε σε άλλο άρθρο.

Το sketch που ακολουθεί δείχνει το τρόπο που δημιουργούνται οι προσαρμοσμένοι χαρακτήρε στο I2C LCD. Σε αυτό το παράδειγμα δημιουργούμε το σύμβολο της καρδιάς και δείχνουμε πως το εμφανίζουμε στην οθόνη:

include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);  // θέτει την διεύθυνση του LCD σε 0x3F 
                                      //για ένα 16x2 LCD

// πίνακας για τον προσαρμοσμένο χαρακτήρα καρδιάς:
byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
void setup() 
{
  lcd.init();
  // Άναψε τον οπίσθιο φωτισμό       
  lcd.backlight();

  // Δημιούργησε τον νέο χαρακτήρα
  lcd.createChar(0, Heart);
 // Καθάρισε την LCD οθόνη
  lcd.clear();

  // Εμφάνισε ένα μήνυμα στην οθόνη.
  lcd.print("Custom Character");
}
// Εμφάνισε τον προσαρμοσμένο χαρακτήρα
void loop() 
{ 
  lcd.setCursor(0, 1);
  lcd.write(0);
  while(1);
}

Όταν πάνε όλα καλά θα έχουμε το ακόλουθο αποτέλεσμα στην οθόνη:

Μετά που συμπεριλάβουμε τη βιβλιοθήκη LiquidCrystal_I2C και δημιουργήσουμε ένα αντικείμενο LCD, στον κώδικα ορίζουμε ένα πίνακα που παριστάνει το σύμβολο της καρδιάς. Ο πίνακας αποτελείται από 8 bytes και κάθε byte ελέγχει την αντίστοιχη γραμμή των pixel στο 5×8 πλέγμα χαρακτήρα.

byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

Κάθε γραμμή αντιπροσωπεύει μία σειρά από pixels, ξεκινώντας από την κορυφή του χαρακτήρα. Το “0b” στην αρχή απλώς λέει στο Arduino ότι αυτός είναι ένας δυαδικός αριθμός (αποτελούμενος από 0 και 1). Κάθε 0 σημαίνει «pixel σβηστό» και κάθε 1 σημαίνει «pixel αναμμένο». Αν παρατηρήσετε προσεκτικά το μοτίβο, μπορείτε να δείτε πώς τα 1 σχηματίζουν το σχήμα μιας καρδιάς!

Στο τμήμα setup του κώδικα, χρησιμοποιούμε τη συνάρτηση createChar() για να αποθηκεύσουμε τον προσαρμοσμένο χαρακτήρα μας στη μνήμη της LCD. Αυτή η συνάρτηση χρειάζεται δύο πληροφορίες: έναν αριθμό από 0 έως 7 (ο οποίος λέει στην LCD ποια από τις οκτώ διαθέσιμες θέσεις μνήμης θα χρησιμοποιήσει) και το όνομα του πίνακα που περιέχει το σχέδιο του χαρακτήρα μας.

Στη μονάδα LCD μπορούμε να δημιουργήσουμε μέχρι και οκτώ προσαρμοσμένους χαρακτήρες. Κάθενας από αυτούς τους χαρακτήρες ορίζεται και από ένα πίνακα 8 bytes. Στη συνέχεια αποθηκεύουμε τους χαρακτήρες με την εντολή lcd.createChar() σε θέσεις της μνήμης CGRAM. Για να εμφανίσουμε τον προσαρμοσμένο χαρακτήρα χρησιμοποιούμε τη συνάρτηση lcd.write() όπου μέσα στις παρενθέσεις καταχωρούμε την θέση μνήμης που βρίσκεται ο χαρακτήρας.

Ο παρακάτω κώδικας αποθηκεύει το σχέδιο της καρδιάς στη θέση 0 της μνήμης CGRAM της LCD.

// Δημιουργία νέου χαρακτήρα
lcd.createChar(0, Heart);

Προβάλουμε τον χαρακτήρα της καρδιάς στη μονάδα LCD, με την ακόλουθη εντολή:

// Προβάλει τον χαρακτήρα της καρδιάς
lcd.write(0)