NOWAE

Our ideas, your fun!

OLED: una libreria per iniziare a disegnare!



Ogni volta che si progetta una nuova scheda elettronica, l'interfaccia uomo-macchina, dove necessaria, è di fondamentale importanza. In una dei miei primi progetti (più di venti anni fa ormai...) utilizzai il classico display LCD alfanumerico 16x2: è stata la mia prima volta con un display! L'elettronica in questi anni si è evoluta molto, ed anche i display. Negli ultimi dieci anni hanno preso piede i display OLED ed ovviamente non ho resistito a disegnare su questi splendidi display grafici.

In questo articolo vi voglio presentare due librerie per gestire i display OLED che ho iniziato a scrivere due anni fa e che ho ultimato solo ora:

  • GDL: Graphic Design Library
  • SSD1306: OLED Driver Library
La GDL è una libreria pensata per contenere le primitive di disegno. Le primitive sono per ora quattro: linea, rettangolo, carattere e immagine. Queste quattro primitive si appoggiano su una funzione specifica del driver del display che si occupa di disegnare il singolo pixel. Queste primitive devono essere chiamate dalla specifica libreria del driver che in questo caso fa solamente da interfaccia.
La SSD1306 è invece la libreria che si occupa di gestire un display OLED che monta il driver omonimo SSD1306 della Solomon Systech. La libreria, come detto qualche riga fa, si occupa di gestire completamente il driver, ma allo stesso tempo utilizza le funzione della GDL per disegnare!
Un errore da non fare è quello di pensare di poter usare la libreria as-is con qualsiasi display che monta il driver SSD1306Z. Purtroppo ogni costruttore collega il driver al display in maniera diversa e quindi all'interno delle varie funzioni i comandi che devono essere mandati al driver potrebbero essere diversi. Pertanto, prima di utilizzare la libreria con un modello non catalogato nella lista SSD1306_Type_Product, è bene studiare il nuovo dispositivo ed aggiungere il codice necessario, se necessario!
Una cosa importante da considerare è che le periferiche del microcontrollore che comunicano con il driver del display, sia che sia SPI, I2C o semplici GPIO, vengono gestiti mediante la libohiboard, di cui abbiamo parlato già in precedenti articoli.

Esempio

Per mostrarvi le funzionalità delle due librerie, ho deciso di usare la scheda di sviluppo NUCLEO-L073RZ della ST Microelectronics, e il display Grove OLED 0.96 inch di Seeed Studio. Come ambiente di sviluppo ho scelto il nuovissimo STM32CubeIDE, versione 1.0.2 (in realtà mi sono accorto che due giorni fa è stata rilasciata la versione 1.1.0).
Prepariamo il nostro progetto.
Prima di tutto inseriamo la libohiboard seguendo le indicazioni riportate in questo articolo. Nonostante le istruzioni riportate nel tutorial siano state scritte per l'ambiente di sviluppo di NXP, anche l’IDE di STM è basato su Eclipse ed a meno di qualche icona tutta la procedura rimane identica. Aggiunta la libohiboard è necessario inserire nelle cartelle del progetto i sorgenti scaricabili da GitHub della GDL e della SSD1306. Completata questa operazione possiamo scrivere il nostro semplicissimo main().


#define APPLICATION_DISPLAY_TYPE   SSD1306_PRODUCT_SEEEDSTUDIO_OLED_1_1

static SSD1306_Device_t mDisplay = {0};
static SSD1306_DeviceHandle_t mDisplayHandle = {0};

void main (void)
{
    // MCU CLOCK INITIALIZATION

    mDisplayHandle = &mDisplay;

    // Display initialization
    Iic_Config displayCommConfig =
    {
        .sclPin       = DISPLAY_COMM_PIN_SCL,
        .sdaPin       = DISPLAY_COMM_PIN_SDA,
    
        .baudrate     = 100000,
        .devType      = IIC_MASTER_MODE,
        .addressMode  = IIC_SEVEN_BIT,
    
        .pullupEnable = FALSE,
    
        .clockSource  = IIC_CLOCKSOURCE_SYSCLK,
    };
    
    SSD1306_Config_t displayConfig =
    {
        .product = APPLICATION_DISPLAY_TYPE,
    
        .rstPin  = DISPLAY_COMM_PIN_RESET,
    
        .iicConfig = displayCommConfig,
        .iicDev    = DISPALY_COMM_PORT,
    };
    
    SSD1306_init(mDisplayHandle, &displayConfig);
    SSD1306_clear(mDisplayHandle);
    SSD1306_drawString(mDisplayHandle, 0, 0,  
                       "SSD1306 Library", 
                       SSD1306_COLOR_COLOR, 1);
    SSD1306_drawString(mDisplayHandle, 0, 15, 
                       "by warcomeb", 
                       SSD1306_COLOR_COLOR, 1);
    SSD1306_drawString(mDisplayHandle, 0, 30, 
                       "follow us NOWAE.IT", 
                       SSD1306_COLOR_COLOR, 1);
    SSD1306_flush(mDisplayHandle);

    while(1) 
    {
        // APPLICATION LOOP
    }
}
                            
Il codice riportato è molto semplice. Dopo la creazioni delle due variabili necessarie a configurare la periferica I2C ed il display, la prima funzione da invocare è SSD1306_init(), la quale inizializza la periferica I2C, effettua un reset del display e successivamente lo configura. Dopo l'inizializzazione è bene pulire il display, riportando con la funzione SSD1306_clear() tutti i pixel allo stato di riposo. Successivamente è possibili iniziare a scrivere, come è stato fatto nell'esempio, o a disegnare. Una cosa importantissima da tenere bene a mente è che ogni operazione di disegno non ha alcun effetto sul display fino a quando non viene chiamata la funzione SSD1306_flush() che realmente invia lo stato di ogni pixel al driver e quindi al display.

La documentazione completa di queste due librerie è in formato doxigen e può essere generata direttamente dall'utilizzatore, oppure, per i più pigri come me, è possibile trovarla nel mio sito web ai seguiti indirizzi: GDL e SSD1306.

Nella libreria SSD1306 ad oggi sono presenti solo due display: il Grove OLED 0.96 inch di Seeed Studio e il Monochrome 128x32 I2C OLED graphic display di Adafruit. Vi invito a fare un fork del repository ed aggiungere altri display: ogni pull-request è la benvenuta!!

Articoli correlati