diff --git a/SSD1306.cpp b/SSD1306.cpp
index b103f7612e426b554a4e193faf25abc7b546e829..0b4189075a71843f09596f282c197456d83a45bd 100644
--- a/SSD1306.cpp
+++ b/SSD1306.cpp
@@ -109,6 +109,44 @@ void SSD1306::fillRect(int16_t xMove, int16_t yMove, int16_t width, int16_t heig
   }
 }
 
+void SSD1306::drawCircle(int16_t x0, int16_t y0, int16_t radius) {
+  int16_t x = 0, y = radius;
+	int16_t dp = 1 - radius;
+	do {
+		if (dp < 0)
+			dp = dp + 2 * (++x) + 3;
+		else
+			dp = dp + 2 * (++x) - 2 * (--y) + 5;
+
+		setPixel(x0 + x, y0 + y);     //For the 8 octants
+		setPixel(x0 - x, y0 + y);
+		setPixel(x0 + x, y0 - y);
+		setPixel(x0 - x, y0 - y);
+		setPixel(x0 + y, y0 + x);
+		setPixel(x0 - y, y0 + x);
+		setPixel(x0 + y, y0 - x);
+		setPixel(x0 - y, y0 - x);
+
+	} while (x < y);
+
+  setPixel(x0 + radius, y0);
+  setPixel(x0, y0 + radius);
+  setPixel(x0 - radius, y0);
+  setPixel(x0, y0 - radius);
+}
+
+void SSD1306::fillCircle(int16_t x, int16_t y, int16_t radius) {
+  int sqrRadius = radius * radius;
+  for (int xv = -radius; xv < radius; xv++) {
+    for (int yv = -radius; yv < radius; yv++) {
+      int currentSqrRadius = xv * xv + yv * yv;
+      if (currentSqrRadius <= sqrRadius) {
+        setPixel(x + xv, y + yv);
+      }
+    }
+  }
+}
+
 void SSD1306::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
   if (y < 0 || y >= DISPLAY_HEIGHT) { return; }
 
@@ -211,6 +249,23 @@ void SSD1306::drawVerticalLine(int16_t x, int16_t y, int16_t length) {
   }
 }
 
+void SSD1306::drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress) {
+  uint16_t radius = height / 2;
+  uint16_t innerRadius = radius - 3;
+  setColor(WHITE);
+  drawCircle(x + radius, y + radius, radius);
+  drawRect(x+radius, y, width - 2*radius, height);
+  drawCircle(x + width - radius, y + radius, radius);
+  setColor(BLACK);
+  fillRect(x+radius, y+1, width - 2*radius + 1, height - 1);
+  setColor(WHITE);
+  uint16_t maxProgressWidth = (width - 2 * radius) * progress / 100;
+  for (uint16_t i = 0; i < maxProgressWidth; i++) {
+    fillCircle(x + radius + i, y + radius, innerRadius);
+  }
+
+}
+
 void SSD1306::drawFastImage(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *image) {
   drawInternal(xMove, yMove, width, height, image, 0, 0);
 }
diff --git a/SSD1306.h b/SSD1306.h
index 76a5b31f0b748d30e4c239373b4684b7b545fdd6..84cb5a9918654fda16e88045b207a085235da734 100644
--- a/SSD1306.h
+++ b/SSD1306.h
@@ -166,12 +166,23 @@ class SSD1306 {
     // Fill the rectangle
     void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);
 
+    // Draw the border of a circle
+    void drawCircle(int16_t x, int16_t y, int16_t radius);
+
+    // Fill circle
+    void fillCircle(int16_t x, int16_t y, int16_t radius);
+
     // Draw a line horizontally
     void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
 
     // Draw a lin vertically
     void drawVerticalLine(int16_t x, int16_t y, int16_t length);
 
+    /**
+     * Draws a rounded progress bar with the outer dimensions given by width and height.
+     */
+    void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);
+
     // Draw a bitmap in the internal image format
     void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const char *image);
 
diff --git a/SSD1306Ui.cpp b/SSD1306Ui.cpp
index 44cc87f8792f6bc9287ed3b552490bb7ec65d839..36b46aa129e836f96bedec98e2956bff829bcb5b 100644
--- a/SSD1306Ui.cpp
+++ b/SSD1306Ui.cpp
@@ -89,7 +89,6 @@ void SSD1306Ui::setInactiveSymbol(const char* symbol) {
   this->inactiveSymbol = symbol;
 }
 
-
 // -/----- Frame settings -----\-
 void SSD1306Ui::setFrameAnimation(AnimationDirection dir) {
   this->frameAnimationDirection = dir;
diff --git a/SSD1306Ui.h b/SSD1306Ui.h
index bdf218fd4e9c2e79dfcc68b9431d85c03ec6547c..690e37e860e37e37dad644cb10d8e2db91ba9161 100644
--- a/SSD1306Ui.h
+++ b/SSD1306Ui.h
@@ -231,7 +231,6 @@ class SSD1306Ui {
      */
     void setInactiveSymbol(const char* symbol);
 
-
     // Frame settings
 
     /**
diff --git a/examples/SSD1306Demo/SSD1306Demo.ino b/examples/SSD1306Demo/SSD1306Demo.ino
index 68dcc667dcb4b1b5bf398a18f5527740ee34f046..604dab144699ffe921d0c8f3c55ad8c17a5fa299 100644
--- a/examples/SSD1306Demo/SSD1306Demo.ino
+++ b/examples/SSD1306Demo/SSD1306Demo.ino
@@ -33,12 +33,71 @@
 SSD1306   display(0x3c, D3, D4);
 SSD1306Ui ui     ( &display );
 
+
+void msOverlay(SSD1306 *display, SSD1306UiState* state) {
+  display->setTextAlignment(TEXT_ALIGN_RIGHT);
+  display->setFont(ArialMT_Plain_10);
+  display->drawString(128, 0, String(millis()));
+}
+
+void drawFrame1(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
+  // draw an xbm image.
+  // Please note that everything that should be transitioned
+  // needs to be drawn relative to x and y
+
+  display->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
+}
+
+void drawFrame2(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
+  // Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file
+  // Besides the default fonts there will be a program to convert TrueType fonts into this format
+  display->setTextAlignment(TEXT_ALIGN_LEFT);
+  display->setFont(ArialMT_Plain_10);
+  display->drawString(0 + x, 10 + y, "Arial 10");
+
+  display->setFont(ArialMT_Plain_16);
+  display->drawString(0 + x, 20 + y, "Arial 16");
+
+  display->setFont(ArialMT_Plain_24);
+  display->drawString(0 + x, 34 + y, "Arial 24");
+}
+
+void drawFrame3(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
+  // Text alignment demo
+  display->setFont(ArialMT_Plain_10);
+
+  // The coordinates define the left starting point of the text
+  display->setTextAlignment(TEXT_ALIGN_LEFT);
+  display->drawString(0 + x, 11 + y, "Left aligned (0,10)");
+
+  // The coordinates define the center of the text
+  display->setTextAlignment(TEXT_ALIGN_CENTER);
+  display->drawString(64 + x, 22 + y, "Center aligned (64,22)");
+
+  // The coordinates define the right end of the text
+  display->setTextAlignment(TEXT_ALIGN_RIGHT);
+  display->drawString(128 + x, 33 + y, "Right aligned (128,33)");
+}
+
+void drawFrame4(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
+  // Demo for drawStringMaxWidth:
+  // with the third parameter you can define the width after which words will be wrapped.
+  // Currently only spaces and "-" are allowed for wrapping
+  display->setTextAlignment(TEXT_ALIGN_LEFT);
+  display->setFont(ArialMT_Plain_10);
+  display->drawStringMaxWidth(0 + x, 10 + y, 128, "Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore.");
+}
+
+void drawFrame5(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
+  
+}
+
 // This array keeps function pointers to all frames
 // frames are the single views that slide in
-FrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3, drawFrame4 };
+FrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5 };
 
 // how many frames are there?
-int frameCount = 4;
+int frameCount = 5;
 
 // Overlays are statically drawn on top of a frame eg. a clock
 OverlayCallback overlays[] = { msOverlay };
@@ -80,8 +139,12 @@ void setup() {
 
   display.flipScreenVertically();
 
+
+
+
 }
 
+
 void loop() {
   int remainingTimeBudget = ui.update();
 
@@ -90,59 +153,9 @@ void loop() {
     // Don't do stuff if you are below your
     // time budget.
     delay(remainingTimeBudget);
-  }
-}
-
-void msOverlay(SSD1306 *display, SSD1306UiState* state) {
-  display->setTextAlignment(TEXT_ALIGN_RIGHT);
-  display->setFont(ArialMT_Plain_10);
-  display->drawString(128, 0, String(millis()));
-}
-
-void drawFrame1(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
-  // draw an xbm image.
-  // Please note that everything that should be transitioned
-  // needs to be drawn relative to x and y
-
-  display->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
-}
-
-void drawFrame2(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
-  // Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file
-  // Besides the default fonts there will be a program to convert TrueType fonts into this format
-  display->setTextAlignment(TEXT_ALIGN_LEFT);
-  display->setFont(ArialMT_Plain_10);
-  display->drawString(0 + x, 10 + y, "Arial 10");
-
-  display->setFont(ArialMT_Plain_16);
-  display->drawString(0 + x, 20 + y, "Arial 16");
-
-  display->setFont(ArialMT_Plain_24);
-  display->drawString(0 + x, 34 + y, "Arial 24");
-}
-
-void drawFrame3(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
-  // Text alignment demo
-  display->setFont(ArialMT_Plain_10);
 
-  // The coordinates define the left starting point of the text
-  display->setTextAlignment(TEXT_ALIGN_LEFT);
-  display->drawString(0 + x, 11 + y, "Left aligned (0,10)");
+  }
 
-  // The coordinates define the center of the text
-  display->setTextAlignment(TEXT_ALIGN_CENTER);
-  display->drawString(64 + x, 22 + y, "Center aligned (64,22)");
 
-  // The coordinates define the right end of the text
-  display->setTextAlignment(TEXT_ALIGN_RIGHT);
-  display->drawString(128 + x, 33 + y, "Right aligned (128,33)");
 }
 
-void drawFrame4(SSD1306 *display, SSD1306UiState* state, int16_t x, int16_t y) {
-  // Demo for drawStringMaxWidth:
-  // with the third parameter you can define the width after which words will be wrapped.
-  // Currently only spaces and "-" are allowed for wrapping
-  display->setTextAlignment(TEXT_ALIGN_LEFT);
-  display->setFont(ArialMT_Plain_10);
-  display->drawStringMaxWidth(0 + x, 10 + y, 128, "Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore.");
-}
diff --git a/examples/SimpleSSD1306Demo/SimpleSSD1306Demo.ino b/examples/SimpleSSD1306Demo/SimpleSSD1306Demo.ino
new file mode 100644
index 0000000000000000000000000000000000000000..6549183844badef7c386678bf6eabf7c4f0e212b
--- /dev/null
+++ b/examples/SimpleSSD1306Demo/SimpleSSD1306Demo.ino
@@ -0,0 +1,146 @@
+/**
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 by Daniel Eichhorn
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <Wire.h>
+#include "SSD1306.h"
+#include "images.h"
+
+#define DEMO_SPEED 500
+#define NUMBER_OF_DEMOS 5
+typedef void (*Demo)(void);
+
+// Initialize the OLED display on address 0x3c
+// D3 and D4 are the pin names on the NodeMCU. Change to int values
+// if get compilation errors
+SSD1306   display(0x3c, D3, D4);
+
+
+int demoMode = 0;
+int counter = 1;
+
+void setup() {
+  Serial.begin(115200);
+  Serial.println();
+  Serial.println();
+
+
+  // Initialising the UI will init the display too.
+  display.init();
+
+  display.flipScreenVertically();
+  display.setFont(ArialMT_Plain_10);
+
+}
+
+void fontFaceDemo() {
+    // Font Demo1
+    // create more fonts at http://oleddisplay.squix.ch/
+    display.setTextAlignment(TEXT_ALIGN_LEFT);
+    display.setFont(ArialMT_Plain_10);
+    display.drawString(0, 0, "Hello world");
+    display.setFont(ArialMT_Plain_16);
+    display.drawString(0, 10, "Hello world");
+    display.setFont(ArialMT_Plain_24);
+    display.drawString(0, 26, "Hello world");
+}
+
+void textFlowDemo() {
+    display.setFont(ArialMT_Plain_10);
+    display.drawStringMaxWidth(0, 0, 128, 
+      "Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore." );
+}
+
+void textAlignmentDemo() {
+    // Text alignment demo
+  display.setFont(ArialMT_Plain_10);
+
+  // The coordinates define the left starting point of the text
+  display.setTextAlignment(TEXT_ALIGN_LEFT);
+  display.drawString(0, 10, "Left aligned (0,10)");
+
+  // The coordinates define the center of the text
+  display.setTextAlignment(TEXT_ALIGN_CENTER);
+  display.drawString(64, 22, "Center aligned (64,22)");
+
+  // The coordinates define the right end of the text
+  display.setTextAlignment(TEXT_ALIGN_RIGHT);
+  display.drawString(128, 33, "Right aligned (128,33)");
+}
+
+void drawRectDemo() {
+      // Draw a pixel at given position
+    for (int i = 0; i < 10; i++) {
+      display.setPixel(i, i);
+      display.setPixel(10 - i, i);
+    }
+    display.drawRect(12, 12, 20, 20);
+
+    // Fill the rectangle
+    display.fillRect(14, 14, 17, 17);
+
+    // Draw a line horizontally
+    display.drawHorizontalLine(0, 40, 20);
+
+    // Draw a line horizontally
+    display.drawVerticalLine(40, 0, 20);
+
+    // this demo is too fast otherwise
+    delay(10);
+} 
+
+void circleDemo() {
+  for (int i=1; i < 8; i++) {
+    display.setColor(WHITE);
+    display.drawCircle(32, 32, i*3);
+    if (i % 2 == 0) {
+      display.setColor(BLACK);
+    }
+    display.fillCircle(96, 32, 32 - i* 3);
+  }
+  delay(25);
+}
+
+void progressBarDemo() {
+  display.drawProgressBar(0, 32, 120, 16, (counter / 5) % 100);
+}
+
+Demo demos[] = {progressBarDemo, /*fontFaceDemo, textFlowDemo, textAlignmentDemo, drawRectDemo, circleDemo*/};
+int demoLength = (sizeof(demos) / sizeof(Demo));
+
+void loop() {
+  // clear the display
+  display.clear();
+  // draw the current demo method
+  demos[demoMode]();
+  // write the buffer to the display
+  display.display();
+
+  if (counter % DEMO_SPEED == 0) {
+    demoMode = (demoMode + 1)  % demoLength;
+    Serial.println(String(counter) + ": " + String(demoMode));
+  }
+  counter++;
+}
+
diff --git a/examples/SimpleSSD1306Demo/images.h b/examples/SimpleSSD1306Demo/images.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b876a369e6f2609700798da9da47431e5e0db21
--- /dev/null
+++ b/examples/SimpleSSD1306Demo/images.h
@@ -0,0 +1,50 @@
+#define WiFi_Logo_width 60
+#define WiFi_Logo_height 36
+const char WiFi_Logo_bits[] PROGMEM = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
+  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+  0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,
+  0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,
+  0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,
+  0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,
+  0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,
+  0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,
+  0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,
+  0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,
+  0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,
+  0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,
+  0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,
+  0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,
+  0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
+  0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
+  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+
+const char activeSymbol[] PROGMEM = {
+    B00000000,
+    B00000000,
+    B00011000,
+    B00100100,
+    B01000010,
+    B01000010,
+    B00100100,
+    B00011000
+};
+
+const char inactiveSymbol[] PROGMEM = {
+    B00000000,
+    B00000000,
+    B00000000,
+    B00000000,
+    B00011000,
+    B00011000,
+    B00000000,
+    B00000000
+};