STM32F767とOLED、OLED096UNO-Aで12345678を表示(16x24)(Mbed-OS5)(SSD1306)



x SSD1308_128x64_I2Cのライブラリディレクトリを作ってライブラリを入れてください。
x 長いです。

目的
OLEDのテスト

![o_con602.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f92c67ce-8106-2b1c-0e67-8789eac23ac2.jpeg)



改造元


https://os.mbed.com/users/wim/code/SSD1308_128x64_I2C/


oled_test_os5_16x24_767_1

main.cpp


```c++



//oled_test2_16x24_767_1

#include "mbed.h"
#include "SSD1308.h"

//i2c initialization
I2C i2c(I2C_SDA, I2C_SCL); //767

// Instantiate OLED
SSD1308 oled = SSD1308(&i2c, SSD1308_SA0);

// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx

//メイン関数
int main()
{

    int ii; //ループカウンター
    int nn; //文字カウンター

    //charge pump  add=>ca45040
    i2c.write(SSD1308_SA0, "\200\215\200\024", 4); //0x80,0x8d,0x80,0x14
    //set access
    oled.setDisplayFlip(false, false);

    //シリアルの初期化
    pc.baud(9600);

    char n1_8[] = "12345678";
    //char n1_8[] = "87654321";

    ii=0;
    for(nn=0; nn<8; nn++) {
        //                y   x
        oled.writeBigChar(0, ii*16,n1_8[nn]);
        ii = ii + 1;
    } //for
    pc.printf("Printed something\r\n");
    //printf("Printed something\r\n");
    
    //oled.writeString(0, 0, "Hello World !");  
    
    while(1) {}

}//main




```


SSD1308.cpp



```c++



#include "mbed.h"
#include "SSD1308.h"

#include "font_8x8.h"
#include "font_16x24.h"

#if defined(TARGET_LPC1768)
#define I2C_OPTIMIZE   1
#else
#define I2C_OPTIMIZE   0
#endif

/*
void fff(char *str1)
{
    printf(str1);//debug
}
*/


/**
 *@brief Constructor
 *@param I2C *i2c reference to i2c
 *@param uint8_t deviceAddress slaveaddress
 */
SSD1308::SSD1308(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c) {
  
  _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write
  _readOpcode  = deviceAddress | 0x01; // low order bit = 1 for read  
  
  initialize(); 
}//SSD1308

//イニシャライズ
void SSD1308::initialize()
{

//    fff("initialize\r\n");//debug

    setHorizontalAddressingMode(); //メモリーアクセスモード

    clearDisplay();

    setInverted(false); //反転

    setDisplayOn();
}//initialize

//クリアディスプレー
void SSD1308::clearDisplay()
{

//    fff("clearDisplay\r\n");//debug

    //setDisplayOff();
    setPageAddress(0, MAX_PAGE);  // all pages
    setColumnAddress(0, MAX_COL); // all columns

/*
    for (uint8_t page = 0; page < PAGES; page++) {
        for (uint8_t col = 0; col < COLUMNS; col++) {
            _sendData(0x00);
        }
    }
*/

    //128*64/8=1024
    for (int icount = 0; icount < 1024; icount++) {
        _sendData(0x00);
    }

    //setDisplayOn();
}//clearDisplay

//
void SSD1308::fillDisplay(uint8_t pattern,
                          uint8_t start_page, uint8_t end_page,
                          uint8_t start_col, uint8_t end_col)
{

    int count = (end_page - start_page + 1) * (end_col - start_col + 1);

    //setDisplayOff();
    setPageAddress(start_page, end_page);  // set page window
    setColumnAddress(start_col, end_col);  // set column window

    for (int i=0; i<count; i++) {
        _sendData(pattern); // Write Data
    }

    //setDisplayOn();
}//

//ライトビットマップ
void SSD1308::writeBitmap(uint8_t* data,
                          uint8_t start_page, uint8_t end_page,
                          uint8_t start_col, uint8_t end_col)
{

//    fff("  writeBitmap\r\n");//debug

    int count = (end_page - start_page + 1) * (end_col - start_col + 1);

    //setDisplayOff();
    setPageAddress(start_page, end_page);  // set page window
    setColumnAddress(start_col, end_col);  // set column window

    for (int i=0; i<count; i++) {
        _sendData(data[i]); // Write Data
    }

    //setDisplayOn();
}//writeBitmap


#define PRG_MAX_SCALE     50
#define PRG_LEFT_EDGE   0xFF
#define PRG_RIGHT_EDGE  0xFF
#define PRG_ACTIVE      0xFF
//#define PRG_ACTIVE      0xBD
#define PRG_NOT_ACTIVE  0x81

//
void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage)
{
    uint8_t scale_value;

    if (percentage <= 0) {
        scale_value = 0;
    } else if (percentage >= 100) {
        scale_value = PRG_MAX_SCALE - 1;
    } else {
        scale_value = (percentage * PRG_MAX_SCALE) / 100;
    }

    //setDisplayOff();
    setPageAddress(page, page);
    setColumnAddress(col, MAX_COL);

    _sendData(PRG_LEFT_EDGE);

    for (uint8_t col = 0; col < scale_value; col++) {
        _sendData(PRG_ACTIVE);
    }

    _sendData(PRG_ACTIVE);

    for (uint8_t col = (scale_value+1); col < PRG_MAX_SCALE; col++) {
        _sendData(PRG_NOT_ACTIVE);
    }

    _sendData(PRG_RIGHT_EDGE);

    //setDisplayOn();
}//writeProgressBar

//ライトレベルバー
void SSD1308::writeLevelBar(uint8_t page, uint8_t col, int percentage)
{
    uint8_t scale_value;

    if (percentage <= 0) {
        scale_value = 0;
    } else if (percentage >= 100) {
        scale_value = PRG_MAX_SCALE - 1;
    } else {
        scale_value = (percentage * PRG_MAX_SCALE) / 100;
    }

    //setDisplayOff();
    setPageAddress(page, page);
    setColumnAddress(col, MAX_COL);

    _sendData(PRG_LEFT_EDGE);

    for (uint8_t col = 0; col < scale_value; col++) {
        _sendData(PRG_NOT_ACTIVE);  // Write Data
    }

    _sendData(PRG_ACTIVE);  // Write Data at active meterlevel

    for (uint8_t col = scale_value+1; col < PRG_MAX_SCALE; col++) {
        _sendData(PRG_NOT_ACTIVE);
    }

    _sendData(PRG_RIGHT_EDGE);

    //setDisplayOn();
}//writeLevelBar

//ライトキャラ
void SSD1308::writeChar(char chr)
{

    const uint8_t char_index = chr - 0x20;

    /*
    for (uint8_t i = 0; i < 8; i++) {
        if (_inverted) {
            _sendData( ~font_8x8[char_index][i] );
        } else {
            _sendData( font_8x8[char_index][i] );
        }
    }
    */

    if (_inverted) {
        for (int i = 0; i < 8; i++) {
            _sendData( ~font_8x8[char_index][i] );
        }
    } else { 
        for (int i = 0; i < 8; i++) {
            _sendData( font_8x8[char_index][i] );
        }
    }


}//writeChar

//ライトストリング
void SSD1308::writeString(uint8_t row, uint8_t col, const char * text)
{
    uint16_t index = 0;
    uint16_t len = strlen(text);

    setPageAddress(row, MAX_PAGE);
    const uint8_t col_addr = FONT8x8_WIDTH*col;
    setColumnAddress(col_addr, MAX_COL);

    while ((col+index) < CHARS && (index < len)) {
        // write first line, starting at given position
        writeChar(text[index++]);
    }

    // write remaining lines
    // write until the end of memory
    // then wrap around again from the top.
    if (index + 1 < len) {
        setPageAddress(row + 1, MAX_PAGE);
        setColumnAddress(0, MAX_COL);
        bool wrapEntireScreen = false;
        while (index + 1 < len) {
            writeChar(text[index++]);
            // if we've written the last character space on the screen,
            // reset the page and column address so that it wraps around from the top again
            if (!wrapEntireScreen && (row*CHARS + col + index) > 127) {
                setPageAddress(0, MAX_PAGE);
                setColumnAddress(0, MAX_COL);
                wrapEntireScreen = true;
            }
        }
    }
}//

//ライトビッグキャラ
void SSD1308::writeBigChar(uint8_t row, uint8_t col, char chr)
{

//    fff("writeBigChar\r\n");//debug

    writeBitmap((uint8_t*) font_16x24[int(chr) - FONT16x24_START],
                row, (row + FONT16x24_BYTES - 1),
                col, (col + FONT16x24_WIDTH - 1));
}//writeBigChar

//センドコマンド コマンドx1
void SSD1308::_sendCommand(uint8_t command)
{
    char databytes[2] = {    COMMAND_MODE,    command             };
    _i2c->write(_writeOpcode,databytes, 2); 
    //_i2c.write(_writeOpcode, databytes, 2);    // Write command
}//

//センドコマンド コマンドx1 パラメーターx1
void SSD1308::_sendCommand(uint8_t command, uint8_t param1)
{
    char databytes[4] = {    COMMAND_MODE,    command,    COMMAND_MODE,    param1              };
    _i2c->write(_writeOpcode, databytes, 4);
    //_i2c.write(_writeOpcode, databytes, 4);    // Write command

}//

//センドコマンド コマンドx1 パラメーターx2
void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2)
{
    char databytes[6] = {    COMMAND_MODE,    command,    COMMAND_MODE,    param1,    COMMAND_MODE,    param2              };
    _i2c->write(_writeOpcode, databytes, 6);
    //_i2c.write(_writeOpcode, databytes, 6);    // Write command

}//

//センドコマンド コマンドx1 パラメーターx5
void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
                           uint8_t param3, uint8_t param4,
                           uint8_t param5)
{
    char databytes[12] = {    COMMAND_MODE,    command,    COMMAND_MODE,    param1,    COMMAND_MODE,    param2,
    COMMAND_MODE,    param3,    COMMAND_MODE,    param4,    COMMAND_MODE,    param5               };
    _i2c->write(_writeOpcode, databytes, 12);
    //_i2c.write(_writeOpcode, databytes, 12);    // Write command
}//

//センドコマンド コマンドx1 パラメーターx6
void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
                           uint8_t param3, uint8_t param4,
                           uint8_t param5, uint8_t param6)
{
    char databytes[14] = {    COMMAND_MODE,    command,    COMMAND_MODE,    param1,    COMMAND_MODE,    param2,
    COMMAND_MODE,    param3,    COMMAND_MODE,    param4,    COMMAND_MODE,    param5,    COMMAND_MODE,    param6              };
    _i2c->write(_writeOpcode, databytes, 14);
    //_i2c.write(_writeOpcode, databytes, 14);    // Write command

}//

//センドデータ コマンドx1
void SSD1308::_sendData(uint8_t data)
{
    char databytes[2] = {    DATA_MODE,    data };
    _i2c->write(_writeOpcode, databytes, 2);
    //_i2c.write(_writeOpcode, databytes, 2);    // Write Data
}//

//センドデータ コマンドx1 データ
void SSD1308::_sendData(uint8_t len, uint8_t* data)
{
    for (int i=0; i<len ; i++) {
        _sendData(data[i]);  // Write Data
    }
}//_sendData

//セット
void SSD1308::setHorizontalAddressingMode()
{

//    fff("setHorizontalAddressingMode\r\n");//debug

    setMemoryAddressingMode(HORIZONTAL_ADDRESSING_MODE);
}//setHorizontalAddressingMode

//
void SSD1308::setVerticalAddressingMode()
{
    setMemoryAddressingMode(VERTICAL_ADDRESSING_MODE);
}//setVerticalAddressingMode

//セットページ
void SSD1308::setPageAddressingMode()
{
    setMemoryAddressingMode(PAGE_ADDRESSING_MODE);
}//setPageAddressingMode

//セットメモリーアドレシングモード
void SSD1308::setMemoryAddressingMode(uint8_t mode)
{
    _sendCommand(SET_MEMORY_ADDRESSING_MODE, mode);
}//setMemoryAddressingMode

//セットページアドレス
void SSD1308::setPageAddress(uint8_t start, uint8_t end)
{
    _sendCommand(SET_PAGE_ADDRESS, start, end);
}//setPageAddress

//セット
void SSD1308::setColumnAddress(uint8_t start, uint8_t end)
{
    _sendCommand(SET_COLUMN_ADDRESS, start, end);
}//setColumnAddress

//セットディスプレースタートライン
void SSD1308::setDisplayStartLine(uint8_t line)
{
    line = line & MAX_ROW;

    _sendCommand(SET_DISPLAY_START_LINE | line);
}//setDisplayStartLine

//セットカラムスタート for ページアクセシングモード
void SSD1308::setColumnStartForPageAddressingMode(uint8_t column)
{
    column = column & MAX_COL;

    _sendCommand(SET_LOWER_COLUMN  | ( column     & 0x0F));  // lower nibble
    _sendCommand(SET_HIGHER_COLUMN | ((column>>4) & 0x0F));  // higher nibble
}//setColumnStartForPageAddressingMode

//セットカラムページ for ページアクセシングモード
void SSD1308::setPageStartForPageAddressingMode(uint8_t page)
{
    page = page & MAX_PAGE;

    _sendCommand(SET_PAGE_START_ADDRESS | page);
}//setPageStartForPageAddressingMode

//セットコントラストコントロール
void SSD1308::setContrastControl(uint8_t contrast)
{
    _sendCommand(SET_CONTRAST, contrast);
}//setContrastControl

//セットディスプレーオン
void SSD1308::setDisplayOn()
{

//    fff("setDisplayOn\r\n");//debug

    _sendCommand(SET_DISPLAY_POWER_ON);
}//setDisplayOn

//セットディスプレーオフ
void SSD1308::setDisplayOff()
{
    _sendCommand(SET_DISPLAY_POWER_OFF);
}//setDisplayOff

//セットディスプレーパワー
void SSD1308::setDisplayPower(bool on)
{
    if (on) {
        setDisplayOn();
    } else {
        setDisplayOff();
    }
}//setDisplayPower

//セットディスプレーノーマル
void SSD1308::setDisplayNormal()
{
    _sendCommand(SET_NORMAL_DISPLAY);
}//setDisplayNormal

//セットディスプレーインバース
void SSD1308::setDisplayInverse()
{
    _sendCommand(SET_INVERSE_DISPLAY);
}//setDisplayInverse

//セットディスプレーブリンク
void SSD1308::setDisplayBlink(bool on)
{
    if (on) {
        _sendCommand(SET_FADE_BLINK, (BLINK_ENABLE | FADE_INTERVAL_128_FRAMES));
    } else {
        _sendCommand(SET_FADE_BLINK, FADE_BLINK_DISABLE);
    }
}//setDisplayBlink

//セットディスプレー fade
void SSD1308::setDisplayFade(bool on)
{
    if (on) {
        _sendCommand(SET_FADE_BLINK, (FADE_OUT_ENABLE | FADE_INTERVAL_128_FRAMES));
    } else {
        _sendCommand(SET_FADE_BLINK, FADE_BLINK_DISABLE);
    }
}//setDisplayFade

//セットディスプレー Flip
void SSD1308::setDisplayFlip(bool left, bool down)
{
    if (left) {
        // column address   0 is mapped to SEG0 (Reset)
        _sendCommand(SET_SEGMENT_REMAP_0);
    } else {
        // column address 127 is mapped to SEG0
        _sendCommand(SET_SEGMENT_REMAP_127);
    }

    if (down) {
        // Reset mode
        _sendCommand(SET_COMMON_REMAP_0);
    } else {
        // Flip Up/Down (Need to rewrite display before H effect shows)
        _sendCommand(SET_COMMON_REMAP_63);
    }

}//setDisplayFlip

//セットインターナル
void SSD1308::setInternalIref()
{
    _sendCommand(SET_IREF_SELECTION, INTERNAL_IREF);
}//setInternalIref

//セット
void SSD1308::setExternalIref()
{
    _sendCommand(SET_IREF_SELECTION, EXTERNAL_IREF);
}//setExternalIref

//セットエンタイアーディスプレーオン
void SSD1308::setEntireDisplayOn()
{
    _sendCommand(SET_ENTIRE_DISPLAY_ON);
}//setEntireDisplayOn

//セットエンタイアーディスプレーRAM
void SSD1308::setEntireDisplayRAM()
{
    _sendCommand(SET_DISPLAY_GDDRAM);
}//setEntireDisplayRAM

//セットエンタイアーディスプレー
void SSD1308::setEntireDisplay(bool on)
{
    if (on) {
        setEntireDisplayOn();  // All Pixels on
    } else {
        setEntireDisplayRAM(); // Pixels are RAM content
    }
}//setEntireDisplay

//セット
void SSD1308::setContinuousHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, uint8_t interval)
{
    if (left) {
        _sendCommand(SET_LEFT_HOR_SCROLL, 0x00, start_page, interval, end_page, 0x00, 0xFF);  // Scroll Left
    } else {
        _sendCommand(SET_RIGHT_HOR_SCROLL, 0x00, start_page, interval, end_page, 0x00, 0xFF); // Scroll Right
    }

}//setContinuousHorizontalScroll

//セット
void SSD1308::setContinuousVerticalAndHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page,
        uint8_t offset, uint8_t interval)
{
    if (left) {
        _sendCommand(SET_VERT_LEFT_HOR_SCROLL, 0x00, start_page, interval, end_page, offset);  // Scroll Left
    } else {
        _sendCommand(SET_VERT_RIGHT_HOR_SCROLL, 0x00, start_page, interval, end_page, offset); // Scroll Right
    }

}//setContinuousVerticalAndHorizontalScroll

//セット
void SSD1308::setVerticalScrollArea(uint8_t topRowsFixed, uint8_t scrollRows)
{
    if ((topRowsFixed + scrollRows) > ROWS) {
        scrollRows = ROWS - topRowsFixed;
    }

    _sendCommand(SET_VERTICAL_SCROLL_AREA, topRowsFixed, scrollRows);
}//setVerticalScrollArea

//セットディスプレースクロール
void SSD1308::setDisplayScroll(bool on)
{
    if (on) {
        _sendCommand(SET_ACTIVATE_SCROLL);   // Scroll on
    } else {
        _sendCommand(SET_DEACTIVATE_SCROLL); // Scroll off
    }
}//setDisplayScroll

//
void SSD1308::_init()
{
    _sendCommand(SET_DISPLAY_POWER_OFF);      // 0xAE

    // column address   0 is mapped to SEG0 (Reset)
    // row address   0 is mapped to COM0 (Reset)
    _sendCommand(SET_SEGMENT_REMAP_0);        // 0xA0 (Reset)
    _sendCommand(SET_COMMON_REMAP_0);         // 0xC0 (Reset)

    setDisplayStartLine(0);                   // 0x40 (Reset)

    _sendCommand(SET_COMMON_CONF, COMMON_BASE | COMMON_ALTERNATIVE | COMMON_LEFTRIGHT_NORMAL); // 0xDA, 0x12 (Reset)

    // Pagemode or Horizontal mode
//  setPageAddressingMode();                  // 0x20, 0x02 (Reset)
//  setColumnStartForPageAddressingMode(0);   // 0x00, 0x10 (Reset = Column 0)
//  setPageStartForPageAddressingMode(PAGE_0);// 0xBO       (Reset = Page 0)
    setHorizontalAddressingMode();            // 0x20, 0x00 (Non-Reset)
    setColumnAddress(0, MAX_COL);             // 0x21, 0x00, 0x37 (Reset)
    setPageAddress(0, MAX_PAGE);              // 0x22, 0x00, 0x07 (Reset)

    setExternalIref();                        // 0xAD, 0x10 (Reset)

    _sendCommand(SET_DISPLAY_CLOCK, 0x70);    // 0xD5, 0x70 (Reset = 0x80)
    _sendCommand(SET_PRECHARGE_TIME, 0x21);   // 0xD9, 0x21 (Reset = 0x22)
    _sendCommand(SET_VCOMH_DESELECT_LEVEL, 0x30); // 0xDB, 0x30 (Reset = 0x20)
    _sendCommand(SET_MULTIPLEX_RATIO, 0x3F);  // 0xA8, 0x3F (Reset)
    _sendCommand(SET_DISPLAY_OFFSET, 0x00);   // 0xD3, 0x00 (Reset)

    _sendCommand(SET_CONTRAST, 0x7F);         // 0x81, 0x7F (Reset)

    _sendCommand(SET_NORMAL_DISPLAY);         // 0xA6 (Reset)

    setEntireDisplayRAM();                    // 0xA4 (Reset)
    setDisplayScroll(false);

    clearDisplay();

    _sendCommand(SET_DISPLAY_POWER_ON);       // 0xAF
}//_init




```


SSD1308.h


```c++


/** @file SSD1308 I2C device class header file
 *   Based on Solomon Systech SSD1308 datasheet, rev. 1, 10/2008
 *   The SSD1308 is used for example in the Seeed 128x64 OLED Display
 *   http://www.seeedstudio.com/depot/grove-oled-display-12864-p-781.html?cPath=163_167
 */
// The original code by Andrew Schamp is using (and has been submitted as a part of) Jeff Rowberg's I2Cdevlib library,
// which should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
// Some parts also mashed up from Graphic Library for driving monochrome displays based on the PCD8544,
// Copyright (c) 2011, Wim De Roeve, who in turn did partial port of code found on
// http://serdisplib.sourceforge.net/ser/pcd8544.html#links and by Petras Saduikis <petras@petras.co.uk>
//
// Changelog:
//   2011-08-25 - Initial release by Andrew Schamp <schamp@gmail.com>
//   2012-06-19 - Ported to mbed and optimised (WH)
//   2013-07-12 - Minor comment fix and placeholder for SSD1306 (WH)
//   2015-01-01 - Switch for optimised I2C calls to test on F401 (WH)
//   2017-12-18 - Fixed non-copyable issue (Thx kenjiArai)
//             
/* 
================================================================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Andrew Schamp
Copyright (c) 2012,2013,2017 WH (mbed port)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================================================
*/

#ifndef SSD1308_H
#define SSD1308_H

// This is the I2C address (8 bit)
//  There are two possible addresses: with D/C# (pin 13) grounded, the address is 0x78,
//  with D/C# tied high it is 0x7A. Assume grounded by default.
#define SSD1308_SA0                0x78
#define SSD1308_SA1                0x7A
#define SSD1308_DEF_SA             SSD1308_SA0

// Display dimensions
#define ROWS                       64
#define COLUMNS                    128
#define PAGES                      (ROWS / 8)
#define MAX_PAGE                   (PAGES - 1)
#define MAX_ROW                    (ROWS - 1)
#define MAX_COL                    (COLUMNS - 1)

// Character dimensions 8x8 font
#define CHARS                      (COLUMNS / FONT8x8_WIDTH)

// Command and Datamode 
#define COMMAND_MODE               0x80 // continuation bit is set!
#define DATA_MODE                  0x40

// Commands and Parameter defines
#define SET_LOWER_COLUMN           0x00 // | with lower nibble  (Page mode only)
#define SET_HIGHER_COLUMN          0x10 // | with higher nibble (Page mode only)

#define HORIZONTAL_ADDRESSING_MODE 0x00
#define VERTICAL_ADDRESSING_MODE   0x01
#define PAGE_ADDRESSING_MODE       0x02
#define SET_MEMORY_ADDRESSING_MODE 0x20 // takes one byte as given above

#define SET_COLUMN_ADDRESS         0x21 // takes two bytes, start address and end address of display data RAM
#define SET_PAGE_ADDRESS           0x22 // takes two bytes, start address and end address of display data RAM

// Command maybe unsupported by SSD1308
#define FADE_INTERVAL_8_FRAMES     0x00
#define FADE_INTERVAL_16_FRAMES    0x01
#define FADE_INTERVAL_24_FRAMES    0x02
#define FADE_INTERVAL_32_FRAMES    0x03
#define FADE_INTERVAL_64_FRAMES    0x07
#define FADE_INTERVAL_128_FRAMES   0x0F
#define FADE_BLINK_DISABLE         0x00
#define FADE_OUT_ENABLE            0x20
#define BLINK_ENABLE               0x30
#define SET_FADE_BLINK             0x23 // takes one byte
                                        //  bit5-4 = 0, fade/blink mode
                                        //  bit3-0 = Time interval in frames 

#define SET_DISPLAY_START_LINE     0x40 // | with a row number 0-63 to set start row. (Reset = 0)

#define SET_CONTRAST               0x81 // takes one byte, 0x00 - 0xFF

#define SET_SEGMENT_REMAP_0        0xA0 // column address 0 is mapped to SEG0 (Reset)
#define SET_SEGMENT_REMAP_127      0xA1 // column address 127 is mapped to SEG0

#define SET_DISPLAY_GDDRAM         0xA4 // restores display to contents of RAM
#define SET_ENTIRE_DISPLAY_ON      0xA5 // turns all pixels on, does not affect RAM

#define SET_NORMAL_DISPLAY         0xA6 // a databit of 1 indicates pixel 'ON'
#define SET_INVERSE_DISPLAY        0xA7 // a databit of 1 indicates pixel 'OFF'

#define SET_MULTIPLEX_RATIO        0xA8 // takes one byte, from 16xMUX to 64xMUX (MUX Ratio = byte+1; Default 64)

#define EXTERNAL_IREF              0x10
#define INTERNAL_IREF              0x00
#define SET_IREF_SELECTION         0xAD // sets internal or external Iref

#define SET_DISPLAY_POWER_OFF      0xAE
#define SET_DISPLAY_POWER_ON       0xAF

#define PAGE0                      0x00
#define PAGE1                      0x01
#define PAGE2                      0x02
#define PAGE3                      0x03
#define PAGE4                      0x04
#define PAGE5                      0x05
#define PAGE6                      0x06
#define PAGE7                      0x07
#define SET_PAGE_START_ADDRESS     0xB0 // | with a page number to get start address (Page mode only)

#define SET_COMMON_REMAP_0         0xC0 // row address  0 is mapped to COM0 (Reset)
#define SET_COMMON_REMAP_63        0xC8 // row address 63 is mapped to COM0

#define SET_DISPLAY_OFFSET         0xD3 // takes one byte from 0-63 for vertical shift, Reset = 0

#define SET_DISPLAY_CLOCK          0xD5 // takes one byte
                                        //  bit7-4 = Osc Freq DCLK (Reset = 1000b) 
                                        //  bit3-0 = Divide ration (Reset = oooob, Ratio = 1)   

#define SET_PRECHARGE_TIME         0xD9 // takes one byte
                                        //  bit7-4 = Phase2, upto 15 DCLKs (Reset = 0010b) 
                                        //  bit3-0 = Phase1, upto 15 DCLKs (Reset = 0010b)   

                                       
#define COMMON_BASE                0x02 // 
#define COMMON_SEQUENTIAL          0x00 // Sequential common pins config
#define COMMON_ALTERNATIVE         0x10 // Odd/Even common pins config (Reset)
#define COMMON_LEFTRIGHT_NORMAL    0x00 // LeftRight Normal (Reset)
#define COMMON_LEFTRIGHT_FLIP      0x20 // LeftRight Flip 
#define SET_COMMON_CONF            0xDA // takes one byte as given above


#define VCOMH_DESELECT_0_65_CODE   0x00
#define VCOMH_DESELECT_0_77_CODE   0x20
#define VCOMH_DESELECT_0_83_CODE   0x30
#define SET_VCOMH_DESELECT_LEVEL   0xDB // takes one byte as given above

#define NOP                        0xE3

#define SCROLL_INTERVAL_5_FRAMES   0x00
#define SCROLL_INTERVAL_64_FRAMES  0x01
#define SCROLL_INTERVAL_128_FRAMES 0x02
#define SCROLL_INTERVAL_256_FRAMES 0x03
#define SCROLL_INTERVAL_3_FRAMES   0x04
#define SCROLL_INTERVAL_4_FRAMES   0x05
#define SCROLL_INTERVAL_25_FRAMES  0x06
#define SCROLL_INTERVAL_2_FRAMES   0x07

#define SET_RIGHT_HOR_SCROLL       0x26 // takes 6 bytes: 0x00, PageStart, Scroll_Interval, PageEnd, 0x00, 0xFF
#define SET_LEFT_HOR_SCROLL        0x27 // takes 6 bytes: 0x00, PageStart, Scroll_Interval, PageEnd, 0x00, 0xFF

#define SET_VERT_RIGHT_HOR_SCROLL  0x29 // takes 5 bytes: 0x00, PageStart, Scroll_Interval, PageEnd, VertOffset
#define SET_VERT_LEFT_HOR_SCROLL   0x2A // takes 5 bytes: 0x00, PageStart, Scroll_Interval, PageEnd, VertOffset

#define SET_DEACTIVATE_SCROLL      0x2E
#define SET_ACTIVATE_SCROLL        0x2F

#define SET_VERTICAL_SCROLL_AREA   0xA3 // takes 2 bytes: Rows in Top Area (Reset=0), Rows in Scroll Area (Reset=64)



/** Class to control an SSD1308 based oled Display
 *
 * Example:
 * @code
 * #include "mbed.h"
 * #include "mbed_logo.h"
 * #include "SSD1308.h"
 
 * //Pin Defines for I2C Bus
 * #define D_SDA                  p28
 * #define D_SCL                  p27
 * I2C i2c(D_SDA, D_SCL);
 *
 * // Host PC Communication channels
 * Serial pc(USBTX, USBRX); // tx, rx
 *
 * // Instantiate OLED
 * SSD1308 oled = SSD1308(&i2c, SSD1308_SA0);
 * 
 * int main() {
 *   pc.printf("OLED test start\r");  
 *   oled.writeString(0, 0, "Hello World !");
 *   //  oled.printf("Hello World !");
 * 
 *   oled.fillDisplay(0xAA);
 *   oled.setDisplayOff();
 *   wait(1);   
 *   oled.setDisplayOn();
 * 
 *   oled.clearDisplay();
 *   oled.setDisplayInverse();
 *   wait(0.5);
 *   oled.setDisplayNormal();                                         
 *
 *   oled.writeBitmap((uint8_t*) mbed_logo);
 *
 *   pc.printf("OLED test done\r\n");  
 * }
 *
 * @endcode
 */
class SSD1308 : public Stream {
  public:
    
/**
  *@brief Constructor
  *@param I2C &i2c reference to i2c,
  *@param uint8_t deviceAddress slaveaddress (8bit to use for the controller (0x78 by default, assumes D/C# (pin 13) grounded)
 */    
    SSD1308(I2C *i2c, uint8_t address = SSD1308_DEF_SA);

// High Level methods

/** @brief High level Init, most settings remain at Power-On reset value
 */
    void initialize();

/** @brief clear the display
*/
    void clearDisplay();


/** @brief fill the display
 *  @param uint8_t pattern fillpattern vertical patch or 8 bits 
 *  @param uint8_t start_page begin page   (0..MAX_PAGE)
 *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
 *  @param uint8_t start_col  begin column (0..MAX_COL)
 *  @param uint8_t end_col    end column   (start_col..MAX_COL)
*/ 
    void fillDisplay(uint8_t pattern = 0x00,
                     uint8_t start_page=0, uint8_t end_page=MAX_PAGE,
                     uint8_t start_col=0, uint8_t end_col=MAX_COL);


/** @brief write a bitmap to the display
 *  @param uint8_t* data pointer to bitmap
 *  @param uint8_t start_page begin page   (0..MAX_PAGE)
 *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
 *  @param uint8_t start_col  begin column (0..MAX_COL)
 *  @param uint8_t end_col    end column   (start_col..MAX_COL)
*/  
    void writeBitmap(uint8_t* data,
                     uint8_t start_page=0, uint8_t end_page=MAX_PAGE,
                     uint8_t start_col=0, uint8_t end_col=MAX_COL);
    
/** @brief write a level meter to the display, Width is (PRG_MAX_SCALE + 2) pixels
 *  @param uint8_t page begin page   (0..MAX_PAGE)
 *  @param uint8_t col  begin column (0..MAX_COL)
 *  @param int percentage value      (0..100)
*/
    void writeProgressBar(uint8_t page, uint8_t col, int percentage);


/** @brief write a level meter to the display, Width is (PRG_MAX_SCALE + 2) pixels
 *  @param uint8_t page begin page   (0..MAX_PAGE)
 *  @param uint8_t col  begin column (0..MAX_COL)
 *  @param int percentage value      (0..100)
*/
    void writeLevelBar(uint8_t page, uint8_t col, int percentage);

    //void setXY(uint8_t, uint8_t y);
    
    // Select inverted or normal text    
    void setInverted(bool inverted) { _inverted = inverted; };    
        
/** @brief Write single character to the display using the 8x8 fontable
 *  @brief Start at current cursor location
 *  @param char chr character to write
*/ 
    void writeChar(char chr);  
    
/** @brief Write large character (16x24 font)
 *  @param uint8_t row  row number    (0...MAX_ROW)
 *  @param uint8_t col  column number (0...MAX_COL)
 *  @param char chr     Used for displaying numbers 0 - 9 and '+', '-', '.'
 */   
    void writeBigChar(uint8_t row, uint8_t col, char chr);      
    
/** @brief Write a string to the display using the 8x8 font
 *  @brief Start at selected cursor location, text will wrap around until it is done
 *  @param uint8_t row  row number    (0...ROWS/FONT_HEIGHT)
 *  @param uint8_t col  column number (0...COLUMNS/FONT_WIDTH)
 *  @param const char * text pointer to text
 */   
    void writeString(uint8_t row, uint8_t col, const char* txt);
    
    // Stream implementation - provides printf() interface
    // You would otherwise be forced to use writeChar() or writeString()
    virtual int _putc(int value) { writeChar(value); return 1; };
    virtual int _getc() { return -1; };
   
// Future extension with graphics features
    // this must be defined by the subclass
//    virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
    
// Medium Level methods

/** @brief Set Horizontal Addressing Mode (cursor incr left-to-right, top-to-bottom)
 * 
 */
    void setHorizontalAddressingMode();
    
/** @brief Set Vertical Addressing Mode  (cursor incr top-to-bottom, left-to-right)
 * 
 */
    void setVerticalAddressingMode();
    
/** @brief Set Page Addressing Mode  (cursor incr left-to-right)
 * 
 */
    void setPageAddressingMode();
        
/** @brief Set Addressing Mode
 *  @param uint8_t mode 
 */
    void setMemoryAddressingMode(uint8_t mode);


/** 
 *  @brief Set Column Start (for Page Addressing Mode only)
 *  @param uint8_t column column start (valid range 0..MAX_COLS)
 */    
    void setColumnStartForPageAddressingMode(uint8_t column);
    
/** 
 *  @brief Set Page Start (for Page Addressing Mode only)
 *  @param uint8_t page page start (valid range PAGE0 - PAGE7)
 */    
    void setPageStartForPageAddressingMode(uint8_t page);
   


/** @param uint8_t start startcolumn (valid range 0..MAX_COL)
 *  @param uint8_t end   endcolumn   (valid range start..MAX_COL)
 */   
    void setColumnAddress(uint8_t start, uint8_t end);
    
/** @param uint8_t start startpage (valid range 0..MAX_PAGE)
 *  @param uint8_t end   endpage   (valid range start..MAX_PAGE)
 */  
    void setPageAddress(uint8_t start, uint8_t end);
    

/** 
 *  @brief Set Display StartLine, takes one byte, 0x00-0x3F
 *  @param uint8_t line startline (valid range 0..MAX_ROWS)
 */  
    void setDisplayStartLine(uint8_t line);
    
/** @brief Set Contrast
 *  @param uint8_t contrast (valid range 0x00 (lowest) - 0xFF (highest))
*/    
    void setContrastControl(uint8_t contrast);


/** @brief Shows All Pixels On
 */
    void setEntireDisplayOn();
    
/** @brief Shows Pixels as RAM content
 */
    void setEntireDisplayRAM();
    
/** @brief Shows Pixels On or as RAM content
 *  @param bool on (true is All on, false is RAM content)
 */
    void setEntireDisplay(bool on);
    
 
    // @brief Set Display line MPX Ratio, takes one byte, 0x00-0x3F
    // @param uint8_t lines (valid range 0..MAX_ROWS)
    void setMultiplexRatio(uint8_t lines);


/** @brief Sets Internal Iref
 */
    void setInternalIref();

/** @brief Sets External Iref (default)
 */   
    void setExternalIref();


/** @brief Enable Display
*/    
    void setDisplayOn();

/** @brief Disable Display
*/     
    void setDisplayOff();

/** @brief Enable or Disable Display
 *  @param bool on
 */    
    void setDisplayPower(bool on);

/** @brief Show White pixels on Black background
 */ 
    void setDisplayNormal();

/** @brief Show Black pixels on White background
 */   
    void setDisplayInverse();

/** @brief Blink display by fading in and out over a set number of frames
 *  @param bool on
 */
    void setDisplayBlink(bool on);  
    
/** @brief Fade out display in set number of frames
 *  @param bool on
 */        
    void setDisplayFade(bool on);    
    
/** @brief Display Flip (Left/Right, Up/Down)
 *  @param bool left flip Left/Right
 *  @param bool down flip Up/Down
 */  
    void setDisplayFlip(bool left, bool down);

    // Set vertical shift by COM from 0 - 63 (0x00 - 0x3F) (Reset = 0x00)
    void setDisplayOffset(uint8_t offset);
    
    // Oscillator freq 0x00-0x0F (reset 0x08)
    // Divide ratio 0x00-0x0F, value +1 (reset 0x00)
    void setDisplayClock(uint8_t divideRatio, uint8_t oscFreq);
    
    // Phase1 0x01-0x0F period of up to 15 DCLK clocks (reset 0x02, 0 is invalid)
    // Phase2 0x01-0x0F period of up to 15 DCLK clocks (reset 0x02, 0 is invalid)
    void setPrechargePeriod(uint8_t phase1, uint8_t phase2);
    
    // See defines above for levels
    void setVcomhDeselectLevel(uint8_t level);


    // Command for no-operation
    void nop();
    

/** @brief Horizontal scroll by one column per interval
 *  @param bool left select Left/Right scroll
 *  @param uint8_t start_page begin page   (0..MAX_PAGE)
 *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
 *  @param uint8_t interval   scroll interval in frames (see codes above)                      
 */  
    void setContinuousHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, uint8_t interval);


/** @brief Horizontal and Vertical scroll by one column per interval
 *  @param bool left select Left/Right scroll
 *  @param uint8_t start_page begin page   (0..MAX_PAGE)
 *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
 *  @param uint8_t offset     vert offset  (0x01..0x63)                       
 *  @param uint8_t interval   scroll interval in frames (see codes above)                       
 */  
    void setContinuousVerticalAndHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, 
                                                  uint8_t offset, uint8_t interval);
    
/** @brief Activate or Deactivate Horizontal and Vertical scroll
 *  @brief Note: after deactivating scrolling, the RAM data needs to be rewritten
 *  @param bool on activate scroll 
 */  
    void setDisplayScroll(bool on);
    

/** @brief Set Vertical scroll area
 *  @param uint8_t topRowsFixed      fixed rows   (0..MAX_ROW)                     
 *  @param uint8_t scrollRowsoffset  scroll rows  (topRowsFixed..MAX_ROW)                       
 */  
    void setVerticalScrollArea(uint8_t topRowsFixed, uint8_t scrollRows); 
  
  private:

// Low Level methods

/** @brief Write command that has no parameters
*/    
    void _sendCommand(uint8_t command); 

/** @brief Write command that has one parameter
*/    
    void _sendCommand(uint8_t command, uint8_t param1);

/** @brief Write command that has two parameters
*/ 
    void _sendCommand(uint8_t command, uint8_t param1, uint8_t param2);              
//    void sendCommands(uint8_t len, uint8_t* buf);

/** @brief Write command that has five parameters
*/ 
    void _sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
                                       uint8_t param3, uint8_t param4,
                                       uint8_t param5);

/** @brief Write command that has six parameters
*/ 
    void _sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
                                       uint8_t param3, uint8_t param4,
                                       uint8_t param5, uint8_t param6);
    
/** @brief Write databyte to display
 *  @brief Start at current cursor location
 *  @param uint8_t data databyte to write
*/  
    void _sendData(uint8_t data);

/** @brief Write len bytes from buffer data to display, 
 *  @brief Start at current cursor location
 *  @param uint8_t len number of bytes to write 
 *  @param uint8_t* data pointer to data
*/   
    void _sendData(uint8_t len, uint8_t* data);

/** @brief Low level Init
 *  @brief Init the configuration registers in accordance with the datasheet
 */   
    void _init();

    I2C *_i2c;             // I2C bus reference
    uint8_t _readOpcode;   // contains the I2C address of the device
    uint8_t _writeOpcode;  // contains the I2C address of the device
    
    bool _inverted;        // inverted or normal text   
};

#endif




```


font_8x8.h


```c++


#ifndef _FONT_8x8_H_
#define _FONT_8x8_H_


//----- DEFINES -----
#define FONT8x8_START                   0x20
//#define FONT8x8_END                     0x44
#define FONT8x8_WIDTH                   8
#define FONT8x8_HEIGHT                  8
#define FONT8x8_BYTES                   1

//========================
const uint8_t font_8x8[][8] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
{0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
{0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
{0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
{0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
{0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
{0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
{0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
{0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
{0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
{0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
{0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
{0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
{0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
{0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
{0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
{0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
{0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
{0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
{0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
{0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
{0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
{0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
{0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
{0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
{0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
{0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
{0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
{0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
{0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
{0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
{0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
{0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
{0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
{0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
{0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
{0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
{0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
{0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
{0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
{0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
{0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
{0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
{0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
{0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
{0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
{0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
{0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
{0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
{0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
{0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
{0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
{0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
{0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
{0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
{0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
{0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
{0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
{0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
{0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
{0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
{0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
{0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
{0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
{0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
{0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
{0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
{0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
{0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
{0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
{0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
{0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
{0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
{0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
{0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
{0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
{0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00} 
};

#endif // include


```


font_16x24.h



```c++



#ifndef _FONT_16x24_H_
#define _FONT_16x24_H_

//----- DEFINES -----
#define FONT16x24_START                   0x20
#define FONT16x24_END                     0x44
#define FONT16x24_WIDTH                   11
#define FONT16x24_HEIGHT                  24
#define FONT16x24_BYTES                   3

//Used for displaying numbers 0 - 9 and '+', '-', '.'

const uint8_t font_16x24[36][3][11]  = 
{

  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x20
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x21
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x22
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x23
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x24
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x25
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x26
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x27
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x28
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x29
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x2A

  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,64,64,64,254,254,64,64 , 0,0,0,0,0,0,0,15,15,0,0  ,// '+'// 0x2B
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0          , 0,0,0,0,0,0,0,0,0,0,0    ,//    // 0x2C
 
  0,0,0,0,0,0,0,0,0,0,0  ,  0,64,64,64,64,64,64,0,0,0,0    , 0,0,0,0,0,0,0,0,0,0,0    ,// '-'// 0x2D
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,         0,0,0,60,60,60,0,0,0,0,0 ,// '.'// 0x2E
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,         0,0,0,0,0,0,0,0,0,0,0    ,//       0x2F
  
  0,128,192,224,224,96,224,224,192,128,0     ,  112,255,255,1,0,0,0,0,255,255,254  ,  0,15,31,60,56,48,56,56,31,15,3           , //'0' 0x30
  0,0,0,0,128,224,224,0,0,0,0                ,  0,0,3,3,3,255,255,0,0,0,0          ,  0,0,56,56,56,63,63,56,56,56,0            , //'1' 0x31
  0,192,192,224,96,96,224,224,192,128,0      ,  0,1,0,0,128,192,224,249,63,31,0    ,  0,60,62,63,63,59,57,56,56,56,56          , //'2' 0x32
  0,192,224,224,96,96,224,224,192,192,0      ,  0,1,0,0,48,48,56,125,239,207,0     ,  0,28,56,56,48,48,56,60,31,15,1           , //'3' 0x33
  0,0,0,0,0,128,192,224,224,0,0              ,  224,240,248,222,207,199,193,255,255,192,192 ,  0,0,0,0,0,0,0,63,63,0,0         , //'4' 0x34
  0,224,224,224,224,224,224,224,224,224,224  ,  0,63,63,63,56,56,48,112,240,224,0           ,  0,28,56,56,48,48,56,60,31,15,1  , //'5' 0x35
  0,0,128,192,192,224,96,96,224,224,0        ,  224,254,255,55,57,24,24,56,240,240,192      ,  0,15,31,28,56,48,48,56,31,15,7  , //'6' 0x36
  0,224,224,224,224,224,224,224,224,224,224  ,  0,0,0,0,128,224,248,126,31,7,1              ,  0,0,56,62,31,7,1,0,0,0,0        , //'7' 0x37
  0,128,192,224,224,96,96,224,192,192,0      ,  0,207,255,127,56,48,112,112,255,239,199     ,  3,15,31,60,56,48,48,56,31,31,15 , //'8' 0x38
  0,128,192,224,224,96,224,224,192,128,0     ,  12,63,127,241,224,192,192,225,255,255,254   ,  0,0,56,48,48,56,56,30,15,7,0    , //'9' 0x39
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x3A
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x3B
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x3C
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x3D
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x3E
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x3F
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x40
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x41
  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,  0,0,0,0,0,0,0,0,0,0,0  ,// 0x42
  0,128,192,224,224,96,224,224,192,128,0    ,  112,112,112,1,0,0,0,0,112,112,112            ,  0,0,0,0,0,0,0,0,0,0,0    //'C' 0x43
};

#endif




```