displaying on SSD1306, 128x64 pixels OLED

Dependencies:   microbit

Committer:
bvirk
Date:
Tue Feb 18 15:18:59 2020 +0000
Revision:
4:19da6ea94042
Parent:
3:f36427797fd7
Child:
6:c69f08f464b5
as requestet

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bvirk 3:f36427797fd7 1
bvirk 3:f36427797fd7 2 #include "MicroBit.h"
bvirk 3:f36427797fd7 3 #include "MicroBitI2C.h"
bvirk 3:f36427797fd7 4
bvirk 3:f36427797fd7 5 #include "mathExt.h"
bvirk 3:f36427797fd7 6 #include "OLEDGlobals.h"
bvirk 3:f36427797fd7 7 #include "OLED.h"
bvirk 4:19da6ea94042 8 #include "cppNorm.h"
bvirk 4:19da6ea94042 9
bvirk 4:19da6ea94042 10 /**
bvirk 4:19da6ea94042 11 * Create a representation of a 128x64 pixels, ssd1306 compatble OLED display
bvirk 4:19da6ea94042 12 *
bvirk 4:19da6ea94042 13 **/
bvirk 3:f36427797fd7 14 OLED::OLED() :
bvirk 3:f36427797fd7 15 i2c(I2C_SDA0,I2C_SCL0)
bvirk 3:f36427797fd7 16 ,charX(0)
bvirk 3:f36427797fd7 17 ,charY(0)
bvirk 3:f36427797fd7 18 ,displayWidth(128)
bvirk 3:f36427797fd7 19 ,displayHeight(64 / 8)
bvirk 4:19da6ea94042 20 ,screenSize(0)
bvirk 4:19da6ea94042 21 ,pendingNewline(false)
bvirk 4:19da6ea94042 22 {}
bvirk 3:f36427797fd7 23
bvirk 3:f36427797fd7 24 void OLED::command(uint8_t cmd) {
bvirk 3:f36427797fd7 25 char buf[2];
bvirk 3:f36427797fd7 26 buf[0] = '\0';
bvirk 3:f36427797fd7 27 buf[1] = cmd;
bvirk 3:f36427797fd7 28 i2c.write(chipAdress,buf,2);
bvirk 3:f36427797fd7 29 }
bvirk 4:19da6ea94042 30 void OLED::init() {
bvirk 4:19da6ea94042 31 init(128, 64);
bvirk 4:19da6ea94042 32 }
bvirk 4:19da6ea94042 33
bvirk 3:f36427797fd7 34
bvirk 3:f36427797fd7 35 void OLED::init(uint8_t width, uint8_t height) {
bvirk 3:f36427797fd7 36 command(SSD1306_DISPLAYOFF);
bvirk 3:f36427797fd7 37 command(SSD1306_SETDISPLAYCLOCKDIV);
bvirk 3:f36427797fd7 38 command(0x80); // the suggested ratio 0x80
bvirk 3:f36427797fd7 39 command(SSD1306_SETMULTIPLEX);
bvirk 3:f36427797fd7 40 command(0x3F);
bvirk 3:f36427797fd7 41 command(SSD1306_SETDISPLAYOFFSET);
bvirk 3:f36427797fd7 42 command(0x0); // no offset
bvirk 3:f36427797fd7 43 command(SSD1306_SETSTARTLINE | 0x0); // line #0
bvirk 3:f36427797fd7 44 command(SSD1306_CHARGEPUMP);
bvirk 3:f36427797fd7 45 command(0x14);
bvirk 3:f36427797fd7 46 command(SSD1306_MEMORYMODE);
bvirk 3:f36427797fd7 47 command(0x00); // 0x0 act like ks0108
bvirk 3:f36427797fd7 48 command(SSD1306_SEGREMAP | 0x1);
bvirk 3:f36427797fd7 49 command(SSD1306_COMSCANDEC);
bvirk 3:f36427797fd7 50 command(SSD1306_SETCOMPINS);
bvirk 3:f36427797fd7 51 command(0x12);
bvirk 3:f36427797fd7 52 command(SSD1306_SETCONTRAST);
bvirk 3:f36427797fd7 53 command(0xCF);
bvirk 3:f36427797fd7 54 command(SSD1306_SETPRECHARGE);
bvirk 3:f36427797fd7 55 command(0xF1);
bvirk 3:f36427797fd7 56 command(SSD1306_SETVCOMDETECT);
bvirk 3:f36427797fd7 57 command(0x40);
bvirk 3:f36427797fd7 58 command(SSD1306_DISPLAYALLON_RESUME);
bvirk 3:f36427797fd7 59 command(SSD1306_NORMALDISPLAY);
bvirk 3:f36427797fd7 60 command(SSD1306_DISPLAYON);
bvirk 3:f36427797fd7 61 displayWidth = width;
bvirk 3:f36427797fd7 62 displayHeight = height / 8;
bvirk 3:f36427797fd7 63 screenSize = displayWidth * displayHeight;
bvirk 3:f36427797fd7 64 charX = xOffset;
bvirk 3:f36427797fd7 65 charY = yOffset;
bvirk 3:f36427797fd7 66 loadStarted = false;
bvirk 3:f36427797fd7 67 loadPercent = 0;
bvirk 3:f36427797fd7 68 clear();
bvirk 3:f36427797fd7 69 }
bvirk 3:f36427797fd7 70
bvirk 3:f36427797fd7 71 void OLED::clear() {
bvirk 3:f36427797fd7 72 loadStarted = false;
bvirk 3:f36427797fd7 73 loadPercent = 0;
bvirk 3:f36427797fd7 74 command(SSD1306_SETCOLUMNADRESS);
bvirk 3:f36427797fd7 75 command(0x00);
bvirk 3:f36427797fd7 76 command(displayWidth - 1);
bvirk 3:f36427797fd7 77 command(SSD1306_SETPAGEADRESS);
bvirk 3:f36427797fd7 78 command(0x00);
bvirk 3:f36427797fd7 79 command(displayHeight - 1);
bvirk 3:f36427797fd7 80 char data[17];
bvirk 3:f36427797fd7 81 data[0] = 0x40; // Data Mode;
bvirk 3:f36427797fd7 82 for (int8_t i = 1; i < 17; i++)
bvirk 3:f36427797fd7 83 data[i] = 0x00;
bvirk 3:f36427797fd7 84 // send display buffer in 16 byte chunks;
bvirk 3:f36427797fd7 85 for (int16_t i = 0; i < screenSize; i += 16) {
bvirk 3:f36427797fd7 86 i2c.write(chipAdress, data, 17,false);
bvirk 3:f36427797fd7 87 }
bvirk 3:f36427797fd7 88 charX = xOffset;
bvirk 3:f36427797fd7 89 charY = yOffset;
bvirk 4:19da6ea94042 90 setTextArea(32,true);
bvirk 3:f36427797fd7 91 }
bvirk 3:f36427797fd7 92
bvirk 3:f36427797fd7 93
bvirk 3:f36427797fd7 94 void OLED::drawChar(uint8_t x, uint8_t y, uint8_t chr ) {
bvirk 3:f36427797fd7 95 command(SSD1306_SETCOLUMNADRESS);
bvirk 3:f36427797fd7 96 command(x);
bvirk 3:f36427797fd7 97 command(x + 5);
bvirk 3:f36427797fd7 98 command(SSD1306_SETPAGEADRESS);
bvirk 3:f36427797fd7 99 command(y);
bvirk 3:f36427797fd7 100 command(y + 1);
bvirk 4:19da6ea94042 101 textArea[x/6][y]=chr;
bvirk 3:f36427797fd7 102 char line[2];
bvirk 3:f36427797fd7 103 line[0] = 0x40;
bvirk 3:f36427797fd7 104 for (int8_t i = 0; i < 6; i++) {
bvirk 3:f36427797fd7 105 if (i == 5)
bvirk 3:f36427797fd7 106 line[1] = 0x00;
bvirk 3:f36427797fd7 107 else
bvirk 3:f36427797fd7 108 line[1] = font[chr][i];
bvirk 3:f36427797fd7 109 i2c.write(chipAdress, line, 2, false);
bvirk 3:f36427797fd7 110 }
bvirk 3:f36427797fd7 111 }
bvirk 3:f36427797fd7 112
bvirk 4:19da6ea94042 113
bvirk 4:19da6ea94042 114 void OLED::setTextArea(uint8_t chr, bool setLine8=false) {
bvirk 4:19da6ea94042 115 for (int8_t line = 0; line <= 8; line++)
bvirk 4:19da6ea94042 116 if (line < 8 || setLine8)
bvirk 4:19da6ea94042 117 for (int8_t xPos = 0; xPos < 22; xPos++)
bvirk 4:19da6ea94042 118 textArea[xPos][line]=chr;
bvirk 4:19da6ea94042 119 }
bvirk 4:19da6ea94042 120
bvirk 4:19da6ea94042 121
bvirk 4:19da6ea94042 122 void OLED::scroll() {
bvirk 4:19da6ea94042 123 for (int8_t line = 1; line <= 8; line++)
bvirk 4:19da6ea94042 124 for (int8_t xPos = 0; xPos < 22; xPos++)
bvirk 4:19da6ea94042 125 drawChar(6*xPos,line-1,textArea[xPos][line]);
bvirk 4:19da6ea94042 126 }
bvirk 4:19da6ea94042 127
bvirk 4:19da6ea94042 128 void OLED::newLine() {
bvirk 4:19da6ea94042 129 charY++;
bvirk 4:19da6ea94042 130 charX = xOffset;
bvirk 4:19da6ea94042 131 if (charY == 8) {
bvirk 4:19da6ea94042 132 charY = 7;
bvirk 4:19da6ea94042 133 scroll();
bvirk 4:19da6ea94042 134 }
bvirk 4:19da6ea94042 135 pendingNewline=false;
bvirk 4:19da6ea94042 136 }
bvirk 4:19da6ea94042 137
bvirk 4:19da6ea94042 138 void OLED::write(string str) {
bvirk 4:19da6ea94042 139 if (pendingNewline)
bvirk 4:19da6ea94042 140 newLine();
bvirk 3:f36427797fd7 141 for (uint16_t i = 0; i < str.length(); i++) {
bvirk 3:f36427797fd7 142 if (charX > displayWidth - 6) {
bvirk 4:19da6ea94042 143 charX = xOffset;
bvirk 3:f36427797fd7 144 charY++;
bvirk 3:f36427797fd7 145 }
bvirk 3:f36427797fd7 146 drawChar(charX, charY, (uint8_t)str.charAt(i));
bvirk 3:f36427797fd7 147 charX += 6;
bvirk 3:f36427797fd7 148 }
bvirk 3:f36427797fd7 149 }
bvirk 4:19da6ea94042 150
bvirk 4:19da6ea94042 151 void OLED::crwrite(string str) {
bvirk 4:19da6ea94042 152 charX=xOffset;
bvirk 3:f36427797fd7 153 write(str);
bvirk 4:19da6ea94042 154 }
bvirk 3:f36427797fd7 155
bvirk 4:19da6ea94042 156 void OLED::writeln(string str) {
bvirk 4:19da6ea94042 157 write(str);
bvirk 4:19da6ea94042 158 pendingNewline=true;
bvirk 3:f36427797fd7 159 }
bvirk 3:f36427797fd7 160
bvirk 3:f36427797fd7 161 void OLED::write(float number) {
bvirk 3:f36427797fd7 162 write(ftos(number));
bvirk 3:f36427797fd7 163 }
bvirk 3:f36427797fd7 164
bvirk 4:19da6ea94042 165 void OLED::crwrite(float number) {
bvirk 4:19da6ea94042 166 charX=xOffset;
bvirk 4:19da6ea94042 167 write(ftos(number));
bvirk 4:19da6ea94042 168 }
bvirk 4:19da6ea94042 169
bvirk 3:f36427797fd7 170 void OLED::writeln(float number) {
bvirk 3:f36427797fd7 171 write(number);
bvirk 4:19da6ea94042 172 pendingNewline=true;
bvirk 3:f36427797fd7 173
bvirk 3:f36427797fd7 174 }
bvirk 3:f36427797fd7 175
bvirk 4:19da6ea94042 176 /* dont works
bvirk 4:19da6ea94042 177 void OLED::drawShape(vector<xyPair> & pixels) {
bvirk 4:19da6ea94042 178 uint8_t x1 = displayWidth;
bvirk 4:19da6ea94042 179 uint8_t y1 = displayHeight * 8;
bvirk 4:19da6ea94042 180 uint8_t x2 = 0;
bvirk 4:19da6ea94042 181 uint8_t y2 = 0;
bvirk 4:19da6ea94042 182 for (int8_t i = 0; i < pixels.size(); i++) {
bvirk 4:19da6ea94042 183 if (pixels[i].x < x1)
bvirk 4:19da6ea94042 184 x1 = pixels[i].x;
bvirk 4:19da6ea94042 185 if (pixels[i].x > x2)
bvirk 4:19da6ea94042 186 x2 = pixels[i].x;
bvirk 4:19da6ea94042 187 if (pixels[i].y < y1)
bvirk 4:19da6ea94042 188 y1 = pixels[i].y;
bvirk 4:19da6ea94042 189 if (pixels[i].y > y2)
bvirk 4:19da6ea94042 190 y2 = pixels[i].y;
bvirk 4:19da6ea94042 191 }
bvirk 4:19da6ea94042 192 uint8_t page1 = y1 / 8;
bvirk 4:19da6ea94042 193 uint8_t page2 = y2 / 8;
bvirk 4:19da6ea94042 194 char line[2];
bvirk 4:19da6ea94042 195 line[0] = 0x40;
bvirk 4:19da6ea94042 196 for (uint8_t x = x1; x <= x2; x++) {
bvirk 4:19da6ea94042 197 for (uint8_t page = page1; page <= page2; page++) {
bvirk 4:19da6ea94042 198 line[1] = 0x00;
bvirk 4:19da6ea94042 199 for (uint8_t i = 0; i < pixels.size(); i++)
bvirk 4:19da6ea94042 200 if (pixels[i].x == x)
bvirk 4:19da6ea94042 201 if (pixels[i].y / 8 == page)
bvirk 4:19da6ea94042 202 line[1] |= 1 << (pixels[i].y % 8);
bvirk 4:19da6ea94042 203 if (line[1] != 0x00) {
bvirk 4:19da6ea94042 204 command(SSD1306_SETCOLUMNADRESS);
bvirk 4:19da6ea94042 205 command(x);
bvirk 4:19da6ea94042 206 command(x + 1);
bvirk 4:19da6ea94042 207 command(SSD1306_SETPAGEADRESS);
bvirk 4:19da6ea94042 208 command(page);
bvirk 4:19da6ea94042 209 command(page + 1);
bvirk 4:19da6ea94042 210 //line[1] |= pins.i2cReadBuffer(chipAdress, 2)[1]
bvirk 4:19da6ea94042 211 i2c.write(chipAdress, line, 2, false);
bvirk 4:19da6ea94042 212 }
bvirk 4:19da6ea94042 213 } // for page
bvirk 4:19da6ea94042 214 } // for x
bvirk 4:19da6ea94042 215 }
bvirk 4:19da6ea94042 216
bvirk 4:19da6ea94042 217 void OLED::drawLine(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
bvirk 4:19da6ea94042 218 vector<xyPair> pixels;
bvirk 4:19da6ea94042 219 uint8_t kx, ky, c, i;
bvirk 4:19da6ea94042 220 uint8_t targetX = x1;
bvirk 4:19da6ea94042 221 uint8_t targetY = y1;
bvirk 4:19da6ea94042 222 x1 -= x0; kx = 0;
bvirk 4:19da6ea94042 223 if (x1 > 0)
bvirk 4:19da6ea94042 224 kx = +1;
bvirk 4:19da6ea94042 225 if (x1 < 0) {
bvirk 4:19da6ea94042 226 kx = -1;
bvirk 4:19da6ea94042 227 x1 = -x1;
bvirk 4:19da6ea94042 228 }
bvirk 4:19da6ea94042 229 x1++;
bvirk 4:19da6ea94042 230 y1 -= y0; ky = 0;
bvirk 4:19da6ea94042 231 if (y1 > 0)
bvirk 4:19da6ea94042 232 ky = +1;
bvirk 4:19da6ea94042 233 if (y1 < 0) {
bvirk 4:19da6ea94042 234 ky = -1;
bvirk 4:19da6ea94042 235 y1 = -y1;
bvirk 4:19da6ea94042 236 }
bvirk 4:19da6ea94042 237 y1++;
bvirk 4:19da6ea94042 238 if (x1 >= y1) {
bvirk 4:19da6ea94042 239 c = x1;
bvirk 4:19da6ea94042 240 for (i = 0; i < x1; i++ , x0 += kx) {
bvirk 4:19da6ea94042 241 pixels.push_back(xyPair(x0, y0));
bvirk 4:19da6ea94042 242 c -= y1;
bvirk 4:19da6ea94042 243 if (c <= 0) {
bvirk 4:19da6ea94042 244 if (i != x1 - 1)
bvirk 4:19da6ea94042 245 pixels.push_back(xyPair(x0 + kx, y0));
bvirk 4:19da6ea94042 246 c += x1; y0 += ky;
bvirk 4:19da6ea94042 247 if (i != x1 - 1)
bvirk 4:19da6ea94042 248 pixels.push_back(xyPair(x0, y0));
bvirk 4:19da6ea94042 249 }
bvirk 4:19da6ea94042 250 if (pixels.size() > 20) {
bvirk 4:19da6ea94042 251 drawShape(pixels);
bvirk 4:19da6ea94042 252 pixels.clear();
bvirk 4:19da6ea94042 253 drawLine(x0, y0, targetX, targetY);
bvirk 4:19da6ea94042 254 return;
bvirk 4:19da6ea94042 255 }
bvirk 4:19da6ea94042 256 }
bvirk 4:19da6ea94042 257 } else {
bvirk 4:19da6ea94042 258 c = y1;
bvirk 4:19da6ea94042 259 for (i = 0; i < y1; i++ , y0 += ky) {
bvirk 4:19da6ea94042 260 pixels.push_back(xyPair(x0, y0));
bvirk 4:19da6ea94042 261 c -= x1;
bvirk 4:19da6ea94042 262 if (c <= 0) {
bvirk 4:19da6ea94042 263 if (i != y1 - 1)
bvirk 4:19da6ea94042 264 pixels.push_back(xyPair(x0, y0 + ky));
bvirk 4:19da6ea94042 265 c += y1;
bvirk 4:19da6ea94042 266 x0 += kx;
bvirk 4:19da6ea94042 267 if (i != y1 - 1)
bvirk 4:19da6ea94042 268 pixels.push_back(xyPair(x0, y0));
bvirk 4:19da6ea94042 269 }
bvirk 4:19da6ea94042 270 if (pixels.size() > 20) {
bvirk 4:19da6ea94042 271 drawShape(pixels);
bvirk 4:19da6ea94042 272 pixels.clear();
bvirk 4:19da6ea94042 273 drawLine(x0, y0, targetX, targetY);
bvirk 4:19da6ea94042 274 return;
bvirk 4:19da6ea94042 275 }
bvirk 4:19da6ea94042 276 }
bvirk 4:19da6ea94042 277 }
bvirk 4:19da6ea94042 278 drawShape(pixels);
bvirk 4:19da6ea94042 279 }
bvirk 4:19da6ea94042 280 void OLED::drawRectangle(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
bvirk 4:19da6ea94042 281 drawLine(x0, y0, x1, y0);
bvirk 4:19da6ea94042 282 drawLine(x0, y1, x1, y1);
bvirk 4:19da6ea94042 283 drawLine(x0, y0, x0, y1);
bvirk 4:19da6ea94042 284 drawLine(x1, y0, x1, y1);
bvirk 4:19da6ea94042 285 } */
bvirk 4:19da6ea94042 286
bvirk 3:f36427797fd7 287 void OLED::testOLED(MicroBit & uBit) {
bvirk 3:f36427797fd7 288 writeln("the quick brown fox jumped over the lazy dog?");
bvirk 3:f36427797fd7 289 uBit.sleep(2000);
bvirk 3:f36427797fd7 290 clear();
bvirk 3:f36427797fd7 291 writeln("THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG!");
bvirk 3:f36427797fd7 292 uBit.sleep(2000);
bvirk 3:f36427797fd7 293 clear();
bvirk 3:f36427797fd7 294 write("Your magic number is ");
bvirk 3:f36427797fd7 295 write(23 * 3);
bvirk 3:f36427797fd7 296 writeln("!");
bvirk 3:f36427797fd7 297 writeln(1.4);
bvirk 3:f36427797fd7 298 writeln(12);
bvirk 3:f36427797fd7 299 uBit.sleep(2000);
bvirk 3:f36427797fd7 300 writeln(2.1);
bvirk 3:f36427797fd7 301 uBit.sleep(2000);
bvirk 3:f36427797fd7 302 writeln(3);
bvirk 3:f36427797fd7 303 /*
bvirk 3:f36427797fd7 304 basic.pause(1000)
bvirk 3:f36427797fd7 305 for (let i = 0; i < 100; i++) {
bvirk 3:f36427797fd7 306 oled.drawLoading(i)
bvirk 3:f36427797fd7 307 }
bvirk 3:f36427797fd7 308 basic.pause(1000)
bvirk 3:f36427797fd7 309 oled.clear()
bvirk 3:f36427797fd7 310 oled.drawRectangle(10, 10, 60, 60)
bvirk 3:f36427797fd7 311 oled.drawLine(0, 0, 128, 64)
bvirk 3:f36427797fd7 312 oled.drawLine(0, 64, 128, 0)
bvirk 3:f36427797fd7 313 */
bvirk 3:f36427797fd7 314 }
bvirk 3:f36427797fd7 315