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/

Revision:
2:ef14c6dd6b93
Parent:
1:82ccc138bbe6
Child:
3:e8bbba5c43ba
--- a/hexidraw.cpp	Fri Aug 19 16:28:09 2016 +0000
+++ b/hexidraw.cpp	Fri Aug 19 22:12:11 2016 +0000
@@ -3,6 +3,8 @@
 
 #include "mbed.h"
 
+#include <math.h>
+
 /*
     Command descriptions from:
         https://cdn-shop.adafruit.com/datasheets/SSD1351-Revision+1.3.pdf
@@ -17,25 +19,25 @@
 
 void OLED::begin()
 {
-    
-    #if 0
+
+#if 0
     // set pin directions
     pinMode(_rs, OUTPUT);
-    
+
     if (_sclk) {
         pinMode(_sclk, OUTPUT);
-        
+
         pinMode(_sid, OUTPUT);
     } else {
         // using the hardware SPI
         SPI.begin();
         SPI.setDataMode(SPI_MODE3);
     }
-    
+
     // Toggle RST low to reset; CS low so it'll listen to us
     pinMode(_cs, OUTPUT);
     digitalWrite(_cs, LOW);
-    
+
     if (_rst) {
         pinMode(_rst, OUTPUT);
         digitalWrite(_rst, HIGH);
@@ -52,10 +54,10 @@
 //    _spi.format(8,3);
     _spi.frequency(8000000);
 
-     _dc =0;
+    _dc =0;
     BOOSTEN = 0;
     wait(0.1f);
-    _reset = 0 ; 
+    _reset = 0 ;
     wait(0.1f);
     _reset = 1 ;
     wait(0.1f);
@@ -63,67 +65,67 @@
 
     writeCommand(OLED_CMD_SET_CMD_LOCK);
     writeData(0x12);
-    
+
     writeCommand(OLED_CMD_SET_CMD_LOCK);
     writeData(0xB1);
 
     writeCommand(OLED_CMD_DISPLAYOFF);
-    
-    
+
+
     writeCommand(OLED_CMD_SET_OSC_FREQ_AND_CLOCKDIV);
     writeData(0xF1);
 
     writeCommand(OLED_CMD_SET_MUX_RATIO);
     writeData(0x5F);
-    
+
     writeCommand(OLED_CMD_SET_REMAP);
     writeData(OLED_REMAP_SETTINGS);
-    
+
     writeCommand(OLED_CMD_SET_COLUMN);
     writeData(0x00);
     writeData(0x5F);
-    
+
     writeCommand(OLED_CMD_SET_ROW);
     writeData(0x00);
     writeData(0x5F);
-    
+
     writeCommand(OLED_CMD_STARTLINE);
     writeData(0x80);
-    
+
     writeCommand(OLED_CMD_DISPLAYOFFSET);
     writeData(0x60);
-    
+
     writeCommand(OLED_CMD_PRECHARGE);
     writeData(0x32);
-    
+
     writeCommand(OLED_CMD_VCOMH);
     writeData(0x05);
-    
+
     writeCommand(OLED_CMD_NORMALDISPLAY);
-    
+
     writeCommand(OLED_CMD_CONTRASTABC);
     writeData(0x8A);
     writeData(0x51);
     writeData(0x8A);
-    
+
     writeCommand(OLED_CMD_CONTRASTMASTER);
     writeData(0xCF);
-    
+
     writeCommand(OLED_CMD_SETVSL);
     writeData(0xA0);
     writeData(0xB5);
     writeData(0x55);
-    
+
     writeCommand(OLED_CMD_PRECHARGE2);
     writeData(0x01);
-    
+
     writeCommand(OLED_CMD_DISPLAYON);
 }
 
 void OLED::writeCommand(uint8_t code)
 {
     _dc = 0;
- 
+
     _cs = 0;
     _spi.write(code);
     _cs = 1;
@@ -132,7 +134,7 @@
 void OLED::writeData(uint8_t value)
 {
     _dc = 1;
-    
+
     _cs = 0;
     _spi.write(value);
     _cs = 1;
@@ -148,24 +150,6 @@
     writeCommand(0xAF);
 }
 
-void OLED::pixel(int16_t x, int16_t y, uint16_t color)
-{
-    // Bounds check.
-    if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return;
-    if ((x < 0) || (y < 0)) return;
-
-    cursor(x, y);
-
-    writeCommand(OLED_CMD_WRITERAM);
-    _dc = 1;
-    _cs = 0;
-    
-    writeData(color >> 8);
-    writeData(color);
-    
-    _cs = 1;
-}
-
 void OLED::cursor(int x, int y)   //goTo
 {
     if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return;
@@ -182,7 +166,26 @@
     writeCommand(OLED_CMD_WRITERAM);
 }
 
-void OLED::clear (uint16_t color){
+void OLED::pixel(int16_t x, int16_t y, uint16_t color)
+{
+    // Bounds check.
+    if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return;
+    if ((x < 0) || (y < 0)) return;
+
+    cursor(x, y);
+
+    writeCommand(OLED_CMD_WRITERAM);
+    _dc = 1;
+    _cs = 0;
+
+    writeData(color >> 8);
+    writeData(color);
+
+    _cs = 1;
+}
+
+void OLED::clear (uint16_t color)
+{
     rect(0, 0, OLED_WIDTH, OLED_HEIGHT, color);
 }
 void OLED::rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor)
@@ -200,7 +203,7 @@
     if (x+w > OLED_WIDTH) {
         w = OLED_WIDTH - x - 1;
     }
-    
+
     x+= OLED_COL_OFFSET;
 
     // set location
@@ -214,7 +217,7 @@
     //writeData(y-1);
     // fill!
     writeCommand(OLED_CMD_WRITERAM);
-    
+
     for (uint16_t i=0; i < w*h; i++) {
         //writeData(fillcolor >> 8);
         writeData(fillcolor >> 8);
@@ -222,10 +225,41 @@
     }
 }
 
+void OLED::circle(uint16_t x, uint16_t y, uint16_t radius, uint16_t color, uint16_t width)
+{
+    const float DEG2RAD = 3.14159f/180;
+    for(uint16_t r = 0; r < width; ++r) {
+        for(uint16_t i = 0; i < 360; ++i) {
+            float degInRad = i*DEG2RAD;
+            uint16_t x2 = x + cos(degInRad) * (radius+r);
+            uint16_t y2 = y + sin(degInRad) * (radius+r);
+
+            pixel(x2, y2, color);
+        }
+    }
+}
+
+void OLED::image (uint16_t x, uint16_t y, const uint8_t* image, uint32_t image_data_size)
+{
+//    cursor(x, y);
+
+    writeCommand(OLED_CMD_WRITERAM);
+    _dc = 1;
+    _cs = 0;
+
+    const uint8_t* buffer = image;
+
+    for ( uint32_t i = 0; i < image_data_size; i++) {
+        _spi.write(*buffer);
+        buffer += 1;
+    }
+
+    _cs = 1;
+}
+
 void OLED::dim()
 {
-    for ( int i = 0; i < 16; i++ )
-    {
+    for ( int i = 0; i < 16; i++ ) {
         writeCommand( OLED_CMD_CONTRASTMASTER);
         writeData( 0xC0 | (0xF-i));
         wait( 20 );