displaying on SSD1306, 128x64 pixels OLED
OLED.cpp
- Committer:
- bvirk
- Date:
- 2020-02-25
- Revision:
- 12:b4d5e007640e
- Parent:
- 11:77aaf68a180b
File content as of revision 12:b4d5e007640e:
#include "MicroBit.h" #include "MicroBitI2C.h" #include "OLED.h" #include "cppNorm.h" OLED::OLED() : i2c(I2C_SDA0,I2C_SCL0) ,charX(0) ,charY(0) ,displayWidth(128) ,displayHeight(64 / 8) ,screenSize(0) ,pendingNewline(false) {} void OLED::command(uint8_t cmd) { char buf[2]; buf[0] = '\0'; buf[1] = cmd; i2c.write(chipAdress,buf,2); } void OLED::init() { init(128, 64); } void OLED::init(uint8_t width, uint8_t height) { command(SSD1306_DISPLAYOFF); command(SSD1306_SETDISPLAYCLOCKDIV); command(0x80); // the suggested ratio 0x80 command(SSD1306_SETMULTIPLEX); command(0x3F); command(SSD1306_SETDISPLAYOFFSET); command(0x0); // no offset command(SSD1306_SETSTARTLINE | 0x0); // line #0 command(SSD1306_CHARGEPUMP); command(0x14); command(SSD1306_MEMORYMODE); command(0x00); // 0x0 act like ks0108 command(SSD1306_SEGREMAP | 0x1); command(SSD1306_COMSCANDEC); command(SSD1306_SETCOMPINS); command(0x12); command(SSD1306_SETCONTRAST); command(0xCF); command(SSD1306_SETPRECHARGE); command(0xF1); command(SSD1306_SETVCOMDETECT); command(0x40); command(SSD1306_DISPLAYALLON_RESUME); command(SSD1306_NORMALDISPLAY); command(SSD1306_DISPLAYON); displayWidth = width; displayHeight = height / 8; screenSize = displayWidth * displayHeight; charX = xOffset; charY = yOffset; loadStarted = false; loadPercent = 0; clear(); } void OLED::clear() { loadStarted = false; loadPercent = 0; command(SSD1306_SETCOLUMNADRESS); command(0x00); command(displayWidth - 1); command(SSD1306_SETPAGEADRESS); command(0x00); command(displayHeight - 1); char data[17]; data[0] = 0x40; for (int8_t i = 1; i < 17; i++) data[i] = 0x00; for (int16_t i = 0; i < screenSize; i += 16) { i2c.write(chipAdress, data, 17,false); } charX = xOffset; charY = yOffset; setTextArea(32,true); } void OLED::drawChar(uint8_t x, uint8_t y, uint8_t chr ) { command(SSD1306_SETCOLUMNADRESS); command(x); command(x + 5); command(SSD1306_SETPAGEADRESS); command(y); command(y + 1); textArea[x/6][y]=chr; char line[2]; line[0] = 0x40; for (int8_t i = 0; i < 6; i++) { if (i == 5) line[1] = 0x00; else line[1] = font[chr][i]; i2c.write(chipAdress, line, 2, false); } } void OLED::setTextArea(uint8_t chr, bool setLine8=false) { for (int8_t line = 0; line <= 8; line++) if (line < 8 || setLine8) for (int8_t xPos = 0; xPos < 22; xPos++) textArea[xPos][line]=chr; } void OLED::scroll() { for (int8_t line = 1; line <= 8; line++) for (int8_t xPos = 0; xPos < 22; xPos++) drawChar(6*xPos,line-1,textArea[xPos][line]); } void OLED::newLine() { charY++; charX = xOffset; if (charY == 8) { charY = 7; scroll(); } pendingNewline=false; } void OLED::puts(string str) { for (uint16_t i = 0; i < str.length(); i++) { if (str.charAt(i) == '\r') charX = xOffset; else if (str.charAt(i) == '\n') { if (pendingNewline) newLine(); pendingNewline=true; } else { if (pendingNewline || charX > displayWidth - 6) newLine(); drawChar(charX, charY, (uint8_t)str.charAt(i)); charX += 6; } } } uint8_t OLED::printf(const char * fmt, ...) { va_list args; va_start(args, fmt); uint8_t len = min(vsnprintf(printf_text, printf_textSize, fmt, args), printf_textSize); va_end(args); printf_text[len] = '\0'; puts(printf_text); return len; }