Library for drawing on the Hexiwear's OLED - more features being actively worked on

Dependents:   Hexidraw_Demo Hexiwear-FinalProject_v2

Discussion: https://developer.mbed.org/forum/team-4615-Hexiwear-community/topic/26595/

Hexidraw is a library for drawing on the Hexiwear's OLED. Be aware that it is not very optimized, so drawing may be slow, especially when drawing on large areas of the screen.

Please see the wiki for API documentation.

Features:

  • Screen fill with a color
  • Drawing filled rectangles
  • Drawing circles with a set radius and line width
  • Setting individual pixels
  • Turning on and off the OLED's sleep mode
  • Drawing images

Example project: https://developer.mbed.org/users/keithm01/code/Hexidraw_Demo/

Committer:
keithm01
Date:
Fri Aug 19 22:12:11 2016 +0000
Revision:
2:ef14c6dd6b93
Parent:
1:82ccc138bbe6
Child:
3:e8bbba5c43ba
Added image drawing function

Who changed what in which revision?

UserRevisionLine numberNew contents of line
keithm01 0:2d3fcb6dabd4 1 #include "oled_info.h"
keithm01 0:2d3fcb6dabd4 2 #include "hexidraw.h"
keithm01 0:2d3fcb6dabd4 3
keithm01 0:2d3fcb6dabd4 4 #include "mbed.h"
keithm01 0:2d3fcb6dabd4 5
keithm01 2:ef14c6dd6b93 6 #include <math.h>
keithm01 2:ef14c6dd6b93 7
keithm01 0:2d3fcb6dabd4 8 /*
keithm01 0:2d3fcb6dabd4 9 Command descriptions from:
keithm01 0:2d3fcb6dabd4 10 https://cdn-shop.adafruit.com/datasheets/SSD1351-Revision+1.3.pdf
keithm01 0:2d3fcb6dabd4 11 */
keithm01 0:2d3fcb6dabd4 12
keithm01 0:2d3fcb6dabd4 13 OLED::OLED () :
keithm01 0:2d3fcb6dabd4 14 _spi(oled_sdi_pin, NC, oled_sck_pin),
keithm01 0:2d3fcb6dabd4 15 _cs(oled_cs_pin),
keithm01 0:2d3fcb6dabd4 16 _reset(oled_rst_pin),
keithm01 0:2d3fcb6dabd4 17 _dc(oled_dc_pin)
keithm01 0:2d3fcb6dabd4 18 {}
keithm01 0:2d3fcb6dabd4 19
keithm01 0:2d3fcb6dabd4 20 void OLED::begin()
keithm01 0:2d3fcb6dabd4 21 {
keithm01 2:ef14c6dd6b93 22
keithm01 2:ef14c6dd6b93 23 #if 0
keithm01 0:2d3fcb6dabd4 24 // set pin directions
keithm01 0:2d3fcb6dabd4 25 pinMode(_rs, OUTPUT);
keithm01 2:ef14c6dd6b93 26
keithm01 0:2d3fcb6dabd4 27 if (_sclk) {
keithm01 0:2d3fcb6dabd4 28 pinMode(_sclk, OUTPUT);
keithm01 2:ef14c6dd6b93 29
keithm01 0:2d3fcb6dabd4 30 pinMode(_sid, OUTPUT);
keithm01 0:2d3fcb6dabd4 31 } else {
keithm01 0:2d3fcb6dabd4 32 // using the hardware SPI
keithm01 0:2d3fcb6dabd4 33 SPI.begin();
keithm01 0:2d3fcb6dabd4 34 SPI.setDataMode(SPI_MODE3);
keithm01 0:2d3fcb6dabd4 35 }
keithm01 2:ef14c6dd6b93 36
keithm01 0:2d3fcb6dabd4 37 // Toggle RST low to reset; CS low so it'll listen to us
keithm01 0:2d3fcb6dabd4 38 pinMode(_cs, OUTPUT);
keithm01 0:2d3fcb6dabd4 39 digitalWrite(_cs, LOW);
keithm01 2:ef14c6dd6b93 40
keithm01 0:2d3fcb6dabd4 41 if (_rst) {
keithm01 0:2d3fcb6dabd4 42 pinMode(_rst, OUTPUT);
keithm01 0:2d3fcb6dabd4 43 digitalWrite(_rst, HIGH);
keithm01 0:2d3fcb6dabd4 44 delay(500);
keithm01 0:2d3fcb6dabd4 45 digitalWrite(_rst, LOW);
keithm01 0:2d3fcb6dabd4 46 delay(500);
keithm01 0:2d3fcb6dabd4 47 digitalWrite(_rst, HIGH);
keithm01 0:2d3fcb6dabd4 48 delay(500);
keithm01 0:2d3fcb6dabd4 49 }
keithm01 0:2d3fcb6dabd4 50 #endif
keithm01 0:2d3fcb6dabd4 51 DigitalOut BOOSTEN(oled_power_enable); //Enable OLED
keithm01 0:2d3fcb6dabd4 52
keithm01 0:2d3fcb6dabd4 53 //Set SPI modes
keithm01 0:2d3fcb6dabd4 54 // _spi.format(8,3);
keithm01 0:2d3fcb6dabd4 55 _spi.frequency(8000000);
keithm01 0:2d3fcb6dabd4 56
keithm01 2:ef14c6dd6b93 57 _dc =0;
keithm01 0:2d3fcb6dabd4 58 BOOSTEN = 0;
keithm01 0:2d3fcb6dabd4 59 wait(0.1f);
keithm01 2:ef14c6dd6b93 60 _reset = 0 ;
keithm01 0:2d3fcb6dabd4 61 wait(0.1f);
keithm01 0:2d3fcb6dabd4 62 _reset = 1 ;
keithm01 0:2d3fcb6dabd4 63 wait(0.1f);
keithm01 0:2d3fcb6dabd4 64 BOOSTEN = 1;
keithm01 0:2d3fcb6dabd4 65
keithm01 0:2d3fcb6dabd4 66 writeCommand(OLED_CMD_SET_CMD_LOCK);
keithm01 0:2d3fcb6dabd4 67 writeData(0x12);
keithm01 2:ef14c6dd6b93 68
keithm01 0:2d3fcb6dabd4 69 writeCommand(OLED_CMD_SET_CMD_LOCK);
keithm01 0:2d3fcb6dabd4 70 writeData(0xB1);
keithm01 0:2d3fcb6dabd4 71
keithm01 0:2d3fcb6dabd4 72 writeCommand(OLED_CMD_DISPLAYOFF);
keithm01 2:ef14c6dd6b93 73
keithm01 2:ef14c6dd6b93 74
keithm01 0:2d3fcb6dabd4 75 writeCommand(OLED_CMD_SET_OSC_FREQ_AND_CLOCKDIV);
keithm01 0:2d3fcb6dabd4 76 writeData(0xF1);
keithm01 0:2d3fcb6dabd4 77
keithm01 0:2d3fcb6dabd4 78 writeCommand(OLED_CMD_SET_MUX_RATIO);
keithm01 0:2d3fcb6dabd4 79 writeData(0x5F);
keithm01 2:ef14c6dd6b93 80
keithm01 0:2d3fcb6dabd4 81 writeCommand(OLED_CMD_SET_REMAP);
keithm01 0:2d3fcb6dabd4 82 writeData(OLED_REMAP_SETTINGS);
keithm01 2:ef14c6dd6b93 83
keithm01 0:2d3fcb6dabd4 84 writeCommand(OLED_CMD_SET_COLUMN);
keithm01 0:2d3fcb6dabd4 85 writeData(0x00);
keithm01 0:2d3fcb6dabd4 86 writeData(0x5F);
keithm01 2:ef14c6dd6b93 87
keithm01 0:2d3fcb6dabd4 88 writeCommand(OLED_CMD_SET_ROW);
keithm01 0:2d3fcb6dabd4 89 writeData(0x00);
keithm01 0:2d3fcb6dabd4 90 writeData(0x5F);
keithm01 2:ef14c6dd6b93 91
keithm01 0:2d3fcb6dabd4 92 writeCommand(OLED_CMD_STARTLINE);
keithm01 0:2d3fcb6dabd4 93 writeData(0x80);
keithm01 2:ef14c6dd6b93 94
keithm01 0:2d3fcb6dabd4 95 writeCommand(OLED_CMD_DISPLAYOFFSET);
keithm01 0:2d3fcb6dabd4 96 writeData(0x60);
keithm01 2:ef14c6dd6b93 97
keithm01 0:2d3fcb6dabd4 98 writeCommand(OLED_CMD_PRECHARGE);
keithm01 0:2d3fcb6dabd4 99 writeData(0x32);
keithm01 2:ef14c6dd6b93 100
keithm01 0:2d3fcb6dabd4 101 writeCommand(OLED_CMD_VCOMH);
keithm01 0:2d3fcb6dabd4 102 writeData(0x05);
keithm01 2:ef14c6dd6b93 103
keithm01 0:2d3fcb6dabd4 104 writeCommand(OLED_CMD_NORMALDISPLAY);
keithm01 2:ef14c6dd6b93 105
keithm01 0:2d3fcb6dabd4 106 writeCommand(OLED_CMD_CONTRASTABC);
keithm01 0:2d3fcb6dabd4 107 writeData(0x8A);
keithm01 0:2d3fcb6dabd4 108 writeData(0x51);
keithm01 0:2d3fcb6dabd4 109 writeData(0x8A);
keithm01 2:ef14c6dd6b93 110
keithm01 0:2d3fcb6dabd4 111 writeCommand(OLED_CMD_CONTRASTMASTER);
keithm01 0:2d3fcb6dabd4 112 writeData(0xCF);
keithm01 2:ef14c6dd6b93 113
keithm01 0:2d3fcb6dabd4 114 writeCommand(OLED_CMD_SETVSL);
keithm01 0:2d3fcb6dabd4 115 writeData(0xA0);
keithm01 0:2d3fcb6dabd4 116 writeData(0xB5);
keithm01 0:2d3fcb6dabd4 117 writeData(0x55);
keithm01 2:ef14c6dd6b93 118
keithm01 0:2d3fcb6dabd4 119 writeCommand(OLED_CMD_PRECHARGE2);
keithm01 0:2d3fcb6dabd4 120 writeData(0x01);
keithm01 2:ef14c6dd6b93 121
keithm01 0:2d3fcb6dabd4 122 writeCommand(OLED_CMD_DISPLAYON);
keithm01 0:2d3fcb6dabd4 123 }
keithm01 0:2d3fcb6dabd4 124
keithm01 0:2d3fcb6dabd4 125 void OLED::writeCommand(uint8_t code)
keithm01 0:2d3fcb6dabd4 126 {
keithm01 0:2d3fcb6dabd4 127 _dc = 0;
keithm01 2:ef14c6dd6b93 128
keithm01 0:2d3fcb6dabd4 129 _cs = 0;
keithm01 0:2d3fcb6dabd4 130 _spi.write(code);
keithm01 0:2d3fcb6dabd4 131 _cs = 1;
keithm01 0:2d3fcb6dabd4 132 }
keithm01 0:2d3fcb6dabd4 133
keithm01 0:2d3fcb6dabd4 134 void OLED::writeData(uint8_t value)
keithm01 0:2d3fcb6dabd4 135 {
keithm01 0:2d3fcb6dabd4 136 _dc = 1;
keithm01 2:ef14c6dd6b93 137
keithm01 0:2d3fcb6dabd4 138 _cs = 0;
keithm01 0:2d3fcb6dabd4 139 _spi.write(value);
keithm01 0:2d3fcb6dabd4 140 _cs = 1;
keithm01 0:2d3fcb6dabd4 141 }
keithm01 0:2d3fcb6dabd4 142 //Turns on OLED sleep mode
keithm01 0:2d3fcb6dabd4 143 void OLED::sleep()
keithm01 0:2d3fcb6dabd4 144 {
keithm01 0:2d3fcb6dabd4 145 writeCommand(0xAE);
keithm01 0:2d3fcb6dabd4 146 }
keithm01 0:2d3fcb6dabd4 147 //Turns off OLED sleep mode
keithm01 0:2d3fcb6dabd4 148 void OLED::wake()
keithm01 0:2d3fcb6dabd4 149 {
keithm01 0:2d3fcb6dabd4 150 writeCommand(0xAF);
keithm01 0:2d3fcb6dabd4 151 }
keithm01 0:2d3fcb6dabd4 152
keithm01 0:2d3fcb6dabd4 153 void OLED::cursor(int x, int y) //goTo
keithm01 0:2d3fcb6dabd4 154 {
keithm01 0:2d3fcb6dabd4 155 if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return;
keithm01 1:82ccc138bbe6 156 x+=OLED_COL_OFFSET;
keithm01 0:2d3fcb6dabd4 157 // set x and y coordinate
keithm01 0:2d3fcb6dabd4 158 writeCommand(OLED_CMD_SET_COLUMN);
keithm01 0:2d3fcb6dabd4 159 writeData(x);
keithm01 0:2d3fcb6dabd4 160 writeData(OLED_WIDTH-1);
keithm01 0:2d3fcb6dabd4 161
keithm01 0:2d3fcb6dabd4 162 writeCommand(OLED_CMD_SET_ROW);
keithm01 0:2d3fcb6dabd4 163 writeData(y);
keithm01 0:2d3fcb6dabd4 164 writeData(OLED_HEIGHT-1);
keithm01 0:2d3fcb6dabd4 165
keithm01 0:2d3fcb6dabd4 166 writeCommand(OLED_CMD_WRITERAM);
keithm01 0:2d3fcb6dabd4 167 }
keithm01 0:2d3fcb6dabd4 168
keithm01 2:ef14c6dd6b93 169 void OLED::pixel(int16_t x, int16_t y, uint16_t color)
keithm01 2:ef14c6dd6b93 170 {
keithm01 2:ef14c6dd6b93 171 // Bounds check.
keithm01 2:ef14c6dd6b93 172 if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return;
keithm01 2:ef14c6dd6b93 173 if ((x < 0) || (y < 0)) return;
keithm01 2:ef14c6dd6b93 174
keithm01 2:ef14c6dd6b93 175 cursor(x, y);
keithm01 2:ef14c6dd6b93 176
keithm01 2:ef14c6dd6b93 177 writeCommand(OLED_CMD_WRITERAM);
keithm01 2:ef14c6dd6b93 178 _dc = 1;
keithm01 2:ef14c6dd6b93 179 _cs = 0;
keithm01 2:ef14c6dd6b93 180
keithm01 2:ef14c6dd6b93 181 writeData(color >> 8);
keithm01 2:ef14c6dd6b93 182 writeData(color);
keithm01 2:ef14c6dd6b93 183
keithm01 2:ef14c6dd6b93 184 _cs = 1;
keithm01 2:ef14c6dd6b93 185 }
keithm01 2:ef14c6dd6b93 186
keithm01 2:ef14c6dd6b93 187 void OLED::clear (uint16_t color)
keithm01 2:ef14c6dd6b93 188 {
keithm01 1:82ccc138bbe6 189 rect(0, 0, OLED_WIDTH, OLED_HEIGHT, color);
keithm01 1:82ccc138bbe6 190 }
keithm01 0:2d3fcb6dabd4 191 void OLED::rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor)
keithm01 0:2d3fcb6dabd4 192 {
keithm01 0:2d3fcb6dabd4 193 // Bounds check
keithm01 0:2d3fcb6dabd4 194 if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT))
keithm01 0:2d3fcb6dabd4 195 return;
keithm01 0:2d3fcb6dabd4 196
keithm01 0:2d3fcb6dabd4 197 // Y bounds check
keithm01 0:2d3fcb6dabd4 198 if (y+h > OLED_HEIGHT) {
keithm01 0:2d3fcb6dabd4 199 h = OLED_HEIGHT - y - 1;
keithm01 0:2d3fcb6dabd4 200 }
keithm01 0:2d3fcb6dabd4 201
keithm01 0:2d3fcb6dabd4 202 // X bounds check
keithm01 0:2d3fcb6dabd4 203 if (x+w > OLED_WIDTH) {
keithm01 0:2d3fcb6dabd4 204 w = OLED_WIDTH - x - 1;
keithm01 0:2d3fcb6dabd4 205 }
keithm01 2:ef14c6dd6b93 206
keithm01 1:82ccc138bbe6 207 x+= OLED_COL_OFFSET;
keithm01 0:2d3fcb6dabd4 208
keithm01 0:2d3fcb6dabd4 209 // set location
keithm01 0:2d3fcb6dabd4 210 writeCommand(OLED_CMD_SET_COLUMN);
keithm01 0:2d3fcb6dabd4 211 writeData(x);
keithm01 0:2d3fcb6dabd4 212 writeData(x+(w-1));
keithm01 0:2d3fcb6dabd4 213 //writeData(x-1);
keithm01 0:2d3fcb6dabd4 214 writeCommand(OLED_CMD_SET_ROW);
keithm01 0:2d3fcb6dabd4 215 writeData(y);
keithm01 0:2d3fcb6dabd4 216 writeData(y+(h-1));
keithm01 0:2d3fcb6dabd4 217 //writeData(y-1);
keithm01 0:2d3fcb6dabd4 218 // fill!
keithm01 0:2d3fcb6dabd4 219 writeCommand(OLED_CMD_WRITERAM);
keithm01 2:ef14c6dd6b93 220
keithm01 0:2d3fcb6dabd4 221 for (uint16_t i=0; i < w*h; i++) {
keithm01 0:2d3fcb6dabd4 222 //writeData(fillcolor >> 8);
keithm01 0:2d3fcb6dabd4 223 writeData(fillcolor >> 8);
keithm01 0:2d3fcb6dabd4 224 writeData(fillcolor);
keithm01 0:2d3fcb6dabd4 225 }
keithm01 0:2d3fcb6dabd4 226 }
keithm01 0:2d3fcb6dabd4 227
keithm01 2:ef14c6dd6b93 228 void OLED::circle(uint16_t x, uint16_t y, uint16_t radius, uint16_t color, uint16_t width)
keithm01 2:ef14c6dd6b93 229 {
keithm01 2:ef14c6dd6b93 230 const float DEG2RAD = 3.14159f/180;
keithm01 2:ef14c6dd6b93 231 for(uint16_t r = 0; r < width; ++r) {
keithm01 2:ef14c6dd6b93 232 for(uint16_t i = 0; i < 360; ++i) {
keithm01 2:ef14c6dd6b93 233 float degInRad = i*DEG2RAD;
keithm01 2:ef14c6dd6b93 234 uint16_t x2 = x + cos(degInRad) * (radius+r);
keithm01 2:ef14c6dd6b93 235 uint16_t y2 = y + sin(degInRad) * (radius+r);
keithm01 2:ef14c6dd6b93 236
keithm01 2:ef14c6dd6b93 237 pixel(x2, y2, color);
keithm01 2:ef14c6dd6b93 238 }
keithm01 2:ef14c6dd6b93 239 }
keithm01 2:ef14c6dd6b93 240 }
keithm01 2:ef14c6dd6b93 241
keithm01 2:ef14c6dd6b93 242 void OLED::image (uint16_t x, uint16_t y, const uint8_t* image, uint32_t image_data_size)
keithm01 2:ef14c6dd6b93 243 {
keithm01 2:ef14c6dd6b93 244 // cursor(x, y);
keithm01 2:ef14c6dd6b93 245
keithm01 2:ef14c6dd6b93 246 writeCommand(OLED_CMD_WRITERAM);
keithm01 2:ef14c6dd6b93 247 _dc = 1;
keithm01 2:ef14c6dd6b93 248 _cs = 0;
keithm01 2:ef14c6dd6b93 249
keithm01 2:ef14c6dd6b93 250 const uint8_t* buffer = image;
keithm01 2:ef14c6dd6b93 251
keithm01 2:ef14c6dd6b93 252 for ( uint32_t i = 0; i < image_data_size; i++) {
keithm01 2:ef14c6dd6b93 253 _spi.write(*buffer);
keithm01 2:ef14c6dd6b93 254 buffer += 1;
keithm01 2:ef14c6dd6b93 255 }
keithm01 2:ef14c6dd6b93 256
keithm01 2:ef14c6dd6b93 257 _cs = 1;
keithm01 2:ef14c6dd6b93 258 }
keithm01 2:ef14c6dd6b93 259
keithm01 1:82ccc138bbe6 260 void OLED::dim()
keithm01 1:82ccc138bbe6 261 {
keithm01 2:ef14c6dd6b93 262 for ( int i = 0; i < 16; i++ ) {
keithm01 1:82ccc138bbe6 263 writeCommand( OLED_CMD_CONTRASTMASTER);
keithm01 1:82ccc138bbe6 264 writeData( 0xC0 | (0xF-i));
keithm01 1:82ccc138bbe6 265 wait( 20 );
keithm01 1:82ccc138bbe6 266 }
keithm01 1:82ccc138bbe6 267 }
keithm01 1:82ccc138bbe6 268
keithm01 0:2d3fcb6dabd4 269 uint16_t Color565(uint8_t r, uint8_t g, uint8_t b)
keithm01 0:2d3fcb6dabd4 270 {
keithm01 0:2d3fcb6dabd4 271 uint16_t c;
keithm01 0:2d3fcb6dabd4 272 c = r >> 3;
keithm01 0:2d3fcb6dabd4 273 c <<= 6;
keithm01 0:2d3fcb6dabd4 274 c |= g >> 2;
keithm01 0:2d3fcb6dabd4 275 c <<= 5;
keithm01 0:2d3fcb6dabd4 276 c |= b >> 3;
keithm01 0:2d3fcb6dabd4 277
keithm01 0:2d3fcb6dabd4 278 return c;
keithm01 0:2d3fcb6dabd4 279 }