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