displaying on SSD1306, 128x64 pixels OLED
OLED.cpp
- Committer:
- bvirk
- Date:
- 2020-02-18
- Revision:
- 4:19da6ea94042
- Parent:
- 3:f36427797fd7
- Child:
- 6:c69f08f464b5
File content as of revision 4:19da6ea94042:
#include "MicroBit.h" #include "MicroBitI2C.h" #include "mathExt.h" #include "OLEDGlobals.h" #include "OLED.h" #include "cppNorm.h" /** * Create a representation of a 128x64 pixels, ssd1306 compatble OLED display * **/ 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; // Data Mode; for (int8_t i = 1; i < 17; i++) data[i] = 0x00; // send display buffer in 16 byte chunks; 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::write(string str) { if (pendingNewline) newLine(); for (uint16_t i = 0; i < str.length(); i++) { if (charX > displayWidth - 6) { charX = xOffset; charY++; } drawChar(charX, charY, (uint8_t)str.charAt(i)); charX += 6; } } void OLED::crwrite(string str) { charX=xOffset; write(str); } void OLED::writeln(string str) { write(str); pendingNewline=true; } void OLED::write(float number) { write(ftos(number)); } void OLED::crwrite(float number) { charX=xOffset; write(ftos(number)); } void OLED::writeln(float number) { write(number); pendingNewline=true; } /* dont works void OLED::drawShape(vector<xyPair> & pixels) { uint8_t x1 = displayWidth; uint8_t y1 = displayHeight * 8; uint8_t x2 = 0; uint8_t y2 = 0; for (int8_t i = 0; i < pixels.size(); i++) { if (pixels[i].x < x1) x1 = pixels[i].x; if (pixels[i].x > x2) x2 = pixels[i].x; if (pixels[i].y < y1) y1 = pixels[i].y; if (pixels[i].y > y2) y2 = pixels[i].y; } uint8_t page1 = y1 / 8; uint8_t page2 = y2 / 8; char line[2]; line[0] = 0x40; for (uint8_t x = x1; x <= x2; x++) { for (uint8_t page = page1; page <= page2; page++) { line[1] = 0x00; for (uint8_t i = 0; i < pixels.size(); i++) if (pixels[i].x == x) if (pixels[i].y / 8 == page) line[1] |= 1 << (pixels[i].y % 8); if (line[1] != 0x00) { command(SSD1306_SETCOLUMNADRESS); command(x); command(x + 1); command(SSD1306_SETPAGEADRESS); command(page); command(page + 1); //line[1] |= pins.i2cReadBuffer(chipAdress, 2)[1] i2c.write(chipAdress, line, 2, false); } } // for page } // for x } void OLED::drawLine(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { vector<xyPair> pixels; uint8_t kx, ky, c, i; uint8_t targetX = x1; uint8_t targetY = y1; x1 -= x0; kx = 0; if (x1 > 0) kx = +1; if (x1 < 0) { kx = -1; x1 = -x1; } x1++; y1 -= y0; ky = 0; if (y1 > 0) ky = +1; if (y1 < 0) { ky = -1; y1 = -y1; } y1++; if (x1 >= y1) { c = x1; for (i = 0; i < x1; i++ , x0 += kx) { pixels.push_back(xyPair(x0, y0)); c -= y1; if (c <= 0) { if (i != x1 - 1) pixels.push_back(xyPair(x0 + kx, y0)); c += x1; y0 += ky; if (i != x1 - 1) pixels.push_back(xyPair(x0, y0)); } if (pixels.size() > 20) { drawShape(pixels); pixels.clear(); drawLine(x0, y0, targetX, targetY); return; } } } else { c = y1; for (i = 0; i < y1; i++ , y0 += ky) { pixels.push_back(xyPair(x0, y0)); c -= x1; if (c <= 0) { if (i != y1 - 1) pixels.push_back(xyPair(x0, y0 + ky)); c += y1; x0 += kx; if (i != y1 - 1) pixels.push_back(xyPair(x0, y0)); } if (pixels.size() > 20) { drawShape(pixels); pixels.clear(); drawLine(x0, y0, targetX, targetY); return; } } } drawShape(pixels); } void OLED::drawRectangle(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { drawLine(x0, y0, x1, y0); drawLine(x0, y1, x1, y1); drawLine(x0, y0, x0, y1); drawLine(x1, y0, x1, y1); } */ void OLED::testOLED(MicroBit & uBit) { writeln("the quick brown fox jumped over the lazy dog?"); uBit.sleep(2000); clear(); writeln("THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG!"); uBit.sleep(2000); clear(); write("Your magic number is "); write(23 * 3); writeln("!"); writeln(1.4); writeln(12); uBit.sleep(2000); writeln(2.1); uBit.sleep(2000); writeln(3); /* basic.pause(1000) for (let i = 0; i < 100; i++) { oled.drawLoading(i) } basic.pause(1000) oled.clear() oled.drawRectangle(10, 10, 60, 60) oled.drawLine(0, 0, 128, 64) oled.drawLine(0, 64, 128, 0) */ }