0.96 ιντσών OLED Display SPI με Arduino nano

Η χρήση οθόνης σε ένα project με arduino είναι σχεδόν υποχρεωτική όταν θέλετε να έχετε επικοινωνία με τον χρήστη.

Υπάρχουν πολλών ειδών οθόνες, με τις δύο επικρατέστερες κατηγορίες να είναι αυτές των LCD και των OLED. Για τις οθόνες LCD σας έχουμε παρουσιάσει στο παρελθόν ένα project αν θέλετε να το ρίξετε μία ματιά αργότερα, είναι εδώ.

Στις οθόνες OLED, έχετε τη δυνατότητα να εμφανίσετε γραφικά με περισσότερη λεπτομέρεια καθώς οι οθόνες αυτές, αποτελούνται από pixels και η ανάλυσή τους διαφέρει. Όταν λέμε ανάλυση εννοούμε τον συνολικό αριθμό pixel που μπορούν να απεικονιστούν.

Μία οθόνη όπως αυτή που θα χρησιμοποιήσουμε, έχει 64x128 pixel άρα μπορεί να απεικονίσει σε αυτή την αναλογία έως 8192 pixel το μέγιστο.

Οθόνες OLED

Η οθόνη OLED που θα χρησιμοποιήσουμε στο project μας, είναι μία μονόχρωμη οθόνη 64x128 pixel η οποία χρησιμοποιεί το πρωτόκολλο SPI. Υπάρχει και η ίδια η οποία χρησιμοποιεί το πρωτόκολλο I2C με λιγότερα PIN.

Η οθόνη είναι ένα παραλληλόγραμμο το οποίο λειτουργεί με συντεταγμένες X, Y. Παρακάτω φαίνεται το σύστημα συντεταγμένων όπου μπορείτε να διακρίνετε που βρίσκεται το ελάχιστο και μέγιστο σημείο της οθόνης για τον σχεδιασμό των γραφικών.

OLED SPI 0.96 ιντσες Arduino συντεταγμένες για σχεδιασμό

PINS

PINS OLED 0.96 SSD1306 INCH SPI
PIN Περιγραφή
VCC 3.3V/5V Τάση εισόδου
GND Γείωση / Αρνητικό
NC NC
DIN SPI Data Input
CLK SPI Clock input
CS Chip select, low active
D/C Command signal, low level for command, high level for data
RES Reset signal, low active

Χαρακτηριστικά οθόνης 

  • Operating Voltage: 3.3V/5V
  • Communication Interface: 3-wire SPI, 4-wire SPI, I2C
  • Screen Type: OLED
  • Driver Chip: SSD1306
  • Resolution: 128*64 (Pixel)
  • Display Size: 0.96inch
  • Display Color: 1/4 yellow section, 3/4 blue section
  • Operating Temp. (℃): -20°C ~ 70°C
  • Storage Temp. (℃): -30°C ~ 80°C
  • Visible Angle: >160°

Εντολές σχεδίασης

Drawing pixels (points)

Εντολή για σχεδιασμό ενός απλού pixel στην οθόνη σε θέση x και y με συγκεκριμένο χρώμα

void drawPixel(uint16_t x, uint16_t y, uint16_t color);

Drawing lines

Εντολή για σχεδιασμό γραμμής η οποία έχει συντεταγμένες x, y έναρξης και x, y λήξης με συγκεκριμένο χρώμα

void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);

Για οριζόντιες η κατακόρυφες γραμμές υπάρχουν και οι βελτιστοποιημένες εκδόσεις των εντολών που μπορείτε να χρησιμοποιείτε. Το length είναι το μήκος της γραμμής

void drawFastVLine(uint16_t x0, uint16_t y0, uint16_t length, uint16_t color);
void drawFastHLine(uint8_t x0, uint8_t y0, uint8_t length, uint16_t color);

Rectangles

Εντολή για σχεδιασμό παραλληλόγραμμου με σημείο έναρξης x, y και σημείο λήξης x, y και με συγκεκριμένο χρώμα. Η εντολή βγαίνει με δύο παραλλαγές. Η drawRect η οποία σχεδιάζει ένα περίγραμμα του παραλληλογράμμου και η fillRect η οποία γεμίζει με χρώμα το παραλληλόγραμμο.

void drawRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color);
void fillRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color);

Circles

Εντολή για σχεδιασμό κύκλων με κέντρο κύκλου τις συντεταγμένες x, y, ακτίνα r και συγκεκριμένου χρώματος. Υπάρχουν δύο παραλλαγές σχεδιασμού. η drawCircle η οποία σχεδιάζει μόνο το περίγραμμα του κύκλου και η fillCircle που σχεδιάζει έναν γεμάτο με χρώμα κύκλο.

void drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color);
void fillCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color);

Rounded rectangles

Εντολή για σχεδιασμό παραλληλόγραμμου με στρογγυλεμένες γωνίες με σημείο έναρξης x, y και σημείο λήξης x, y και με συγκεκριμένο χρώμα. Η εντολή βγαίνει με δύο παραλλαγές. Η drawRoundRect η οποία σχεδιάζει ένα περίγραμμα του παραλληλογράμμου και η fillRoundRect η οποία γεμίζει με χρώμα το παραλληλόγραμμο.

void drawRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color);
void fillRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color);

Triangles

Εντολή για σχεδιασμό τριγώνων. Για να σχηματιστεί το τρίγωνο χρειαζόμαστε 3 σημεία x,y με συγκεκριμένο χρώμα τα οποία είναι οι πλευρές κάθε τρίγωνο. Στη συνέχεια η εντολή ενώνει αυτά τα σημεία. Υπάρχουν δύο παραλλαγές της εντολής, η drawTriangle η οποία σχηματίζει το περίγραμμα του τριγώνου και η fillTriangle η οποία γεμίζει με το επιλεγμένο χρώμα το τρίγωνο.

void drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void fillTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);

Χαρακτήρες και ρυθμίσεις κειμένου

Για το κείμενο, υπάρχουν δύο βασικοί τρόποι εισαγωγής. Ο πρώτος είναι για την περίπτωση που θέλουμε να εισάγουμε έναν μόνο χαρακτήρα. Μπορείτε να τοποθετήσετε τον χαρακτήρα σε όποιο σημείο της οθόνης επιθυμείτε με ένα επιλεγμένο χρώμα. Προαιρετικά μπορείτε να δηλώσετε και το μέγεθος γραματοσειράς (1=μικρή γραμματοσειρά, 2=μεγάλη 10x16pixel ανά χαρακτήρα, 3=μεγαλύτερη...). Μοιάζει λίγο σαν να συναρμολογούμε ένα puzzle με αυτό το τρόπο αλλά είναι αποδοτικός όσον αφορά το μέγεθος του προγράμματος

Για την εκτύπωση ενός χαρακτήρα, χρειαζόμαστε το σημείο έναρξης x, y και το μέγεθος γραμματοσειράς

void drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, uint8_t size);

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

setCursor: Επιλέγουμε την θέση στην οποία θέλουμε να εμφανιστεί το κείμενο

setTextColor: επιλέγουμε το χρώμα για το κείμενο, η συγκεκριμένο συνάρτηση μπορεί να χρησιμοποιηθεί και με δύο ορίσματα για να δηλώσουμε και το χρώμα του φόντου background color

setTextSize: Επιλέγουμε το μέγεθος της γραμματοσειράς 1 μικρά γράμματα και όσο ανεβαίνει τα γράμματα μεγαλώνουν.

setTextWrap: Επιλέγουμε με true ή false αν θέλουμε το κείμενο να κάνει αναδίπλωση όταν δεν φτάνει να εμφανιστεί σε μία σειρά.

void setCursor(int16_t x0, int16_t y0);
void setTextColor(uint16_t color);
void setTextColor(uint16_t color, uint16_t backgroundcolor);
void setTextSize(uint8_t size);
void setTextWrap(boolean w);

Tο project

Θα χρησιμοποιήσουμε ένα RTC module για να μετράμε τον χρόνο και να εμφανίζουμε την ώρα και ημερομηνία στην οθόνη μας.

Για να το πετύχουμε αυτό θα χρειαστούμε τα παρακάτω υλικά

  1. Arduino Nano
  2. Breadboard + καλώδια
  3. Real Time Clock module. Για το RTC module θα χρειαστείτε και μία μπαταρία CR2032
  4. OLED 0.96 SPI Display Module Arduino

Το σχέδιο

Παρακάτω η εικόνα που αποτυπώνει το σχέδιο. 

Σχέδιο για οθόνη SPI OLED 0.96" με module RTC

Ο κώδικας

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI 11
#define OLED_CLK 13
#define OLED_DC 9
#define OLED_CS 10
#define OLED_RESET 8
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
                         OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void setup() {
  Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  if (!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }
  display.clearDisplay();
}

void loop() {
  DateTime now = rtc.now();
  testfillrect();
  prepText(5,5,1);
  display.print("Date");
  prepText(5,35,1);
  display.print("Time");
  prepText(4,15,2);

  if (now.day()<10) {
    display.print((String)"0"+now.day()+(String)"/");    
  }
  else {
    display.print(now.day()+ (String)"/");
  }
  if (now.month()<10) {
    display.print((String)"0"+now.month()+(String)"/");    
  }
  else {
    display.print(now.month()+ (String)"/");
  }  
  display.print(now.year());
  prepText(4,45,2);  
  if (now.hour()<10) {
    display.print((String)"0"+ now.hour()+ (String)":");
  }
  else {
    display.print(now.hour()+ (String)":");
  }
  if (now.minute()<10) {
    display.print((String)"0" + now.minute() + (String)":");
  } 
  else {
    display.print(now.minute() + (String)":");    
  }
  if (now.second()<10) { 
    display.print((String)"0"+ now.second());
  }
  else {
    display.print(now.second());
  }
  display.display();
  display.clearDisplay();
}

void testfillrect(void) {
    display.fillRect(0, 0, display.width(), display.height(), SSD1306_INVERSE);
    display.fillRect(1, 1, display.width()-2, display.height()-2, SSD1306_INVERSE);
}

void prepText(int x, int y, int s) {
  display.setTextSize(s);               // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);  // Draw white text
  display.setCursor(x, y);              // Start at top-left corner
  display.cp437(true);                  // Use full 256 char 'Code Page 437' font
}

Ο κώδικας χρησιμοποιεί αρκετές βιβλιοθήκες για την οθόνη καθώς και για το RTC. Όλες οι βιβλιοθήκες είναι από την Adafruit, δοκιμασμένες και σταθερές.

Στο βίντεο, εξηγούμε ποιες βιβλιοθήκες χρησιμοποιούμε τις οποίες μάλιστα, κατεβάζουμε μέσα από το Arduino IDE

Σχετικά άρθρα

Συγχώνευση αλληλογραφίας

Μαθήματα Wordpress

Excel Συναρτήσεις DAX CALCULATE και ALLEXCEPT

Πληροφορίες

Χατζηγεωργίου Γεώργιος

info[@]getcert.gr

6945531647