diff --git a/SSD1306Ui.cpp b/SSD1306Ui.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bcdb751355cef4eb88932f8f8538bb0695ae5b0f
--- /dev/null
+++ b/SSD1306Ui.cpp
@@ -0,0 +1,249 @@
+#include "SSD1306Ui.h"
+
+
+SSD1306Ui::SSD1306Ui(SSD1306 *display) {
+  this->display = display;
+}
+
+void SSD1306Ui::init() {
+  this->display->init();
+}
+
+void SSD1306Ui::setTargetFPS(byte fps){
+  this->updateInterval = ((float) 1.0 / (float) fps) * 1000;
+  Serial.println(this->updateInterval);
+}
+
+// -/------ Automatic controll ------\-
+
+void SSD1306Ui::enableAutoTransition(){
+  autoTransition = true;
+}
+void SSD1306Ui::disableAutoTransition(){
+  autoTransition = false;
+}
+void SSD1306Ui::setAutoTransitionForwards(){
+  this->frameTransitionDirection = 1;
+}
+void SSD1306Ui::setAutoTransitionBackwards(){
+  this->frameTransitionDirection = 1;
+}
+void SSD1306Ui::setTimePerFrame(int time){
+  this->ticksPerFrame = (int) ( (float) time / (float) updateInterval);
+}
+void SSD1306Ui::setTimePerTransition(int time){
+  this->ticksPerTransition = (int) ( (float) time / (float) updateInterval);
+}
+
+
+// -/------ Customize indicator position and style -------\-
+void SSD1306Ui::setIndicatorPosition(IndicatorPosition pos) {
+  this->indicatorPosition = pos;
+  this->dirty = true;
+}
+void SSD1306Ui::setIndicatorDirection(IndicatorDirection dir) {
+  this->indicatorDirection = dir;
+}
+void SSD1306Ui::setActiveSymbole(const char* symbole) {
+  this->activeSymbole = symbole;
+  this->dirty = true;
+}
+void SSD1306Ui::setInactiveSymbole(const char* symbole) {
+  this->inactiveSymbole = symbole; 
+  this->dirty = true;
+}
+
+
+// -/----- Frame settings -----\-
+void SSD1306Ui::setFrameAnimation(AnimationDirection dir) {  
+  this->frameAnimationDirection = dir;
+}
+void SSD1306Ui::setFrames(bool (*frameFunctions[])(SSD1306 *display, int x, int y), int frameCount) {
+  this->frameCount     = frameCount;
+  this->frameFunctions = frameFunctions;
+}
+
+// -/----- Overlays ------\-
+void SSD1306Ui::setOverlays(bool (*overlayFunctions[])(SSD1306 *display), int overlayCount){
+  this->overlayCount     = overlayCount;
+  this->overlayFunctions = overlayFunctions;
+}
+
+
+// -/----- Manuel control -----\-
+void SSD1306Ui::nextFrame() {
+  this->frameState = IN_TRANSITION;
+  this->ticksSinceLastStateSwitch = 0;
+  this->frameTransitionDirection = 1;
+}
+void SSD1306Ui::previousFrame() {
+  this->frameState = IN_TRANSITION;
+  this->ticksSinceLastStateSwitch = 0;
+  this->frameTransitionDirection = -1;
+}
+
+
+// -/----- State information -----\-
+FrameState SSD1306Ui::getFrameState(){
+  return this->frameState;
+}
+int SSD1306Ui::getCurrentFrame(){
+  return this->currentFrame;
+}
+
+
+int SSD1306Ui::update(){
+  int timeBudget = this->updateInterval - (millis() - this->lastUpdate);
+  if ( timeBudget <= 0) {
+
+    // Implement frame skipping to ensure time budget is keept
+    if (this->autoTransition && this->lastUpdate != 0) this->ticksSinceLastStateSwitch += abs(timeBudget) / this->updateInterval;
+    
+    this->lastUpdate = millis();
+    this->tick();
+  } 
+  return timeBudget;
+}
+
+
+void SSD1306Ui::tick() {
+  this->ticksSinceLastStateSwitch++;
+
+  switch (this->frameState) {
+    case IN_TRANSITION:
+        this->dirty = true;
+        if (this->ticksSinceLastStateSwitch >= this->ticksPerTransition){
+          this->frameState = FIXED;
+          this->currentFrame = getNextFrameNumber();
+          this->ticksSinceLastStateSwitch = 0;
+        }
+      break;
+    case FIXED:
+      if (this->ticksSinceLastStateSwitch >= this->ticksPerFrame){
+          if (this->autoTransition){
+            this->frameState = IN_TRANSITION;
+            this->dirty = true;
+          }
+          this->ticksSinceLastStateSwitch = 0;
+      }
+      break;
+  }
+  
+  if (this->dirty) {
+    this->dirty = false;
+    this->display->clear();
+    this->drawIndicator();  
+    this->drawFrame();
+    this->drawOverlays();
+    this->display->display();
+  }
+}
+
+void SSD1306Ui::drawFrame(){
+  switch (this->frameState){
+     case IN_TRANSITION: {
+       float progress = (float) this->ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
+       int x, y, x1, y1;
+       switch(this->frameAnimationDirection){
+        case SLIDE_LEFT:
+          x = -128 * progress;
+          y = 0;
+          x1 = x + 128;
+          y1 = 0;
+          break;
+        case SLIDE_RIGHT:
+          x = 128 * progress;
+          y = 0;
+          x1 = x - 128;
+          y1 = 0;
+          break;
+        case SLIDE_UP:
+          x = 0;
+          y = -64 * progress;
+          x1 = 0;
+          y1 = y + 64;
+          break;
+        case SLIDE_DOWN:
+          x = 0;
+          y = 64 * progress;
+          x1 = 0;
+          y1 = y - 64;
+          break;
+       }
+
+       // Invert animation if direction is reversed.
+       int dir = frameTransitionDirection >= 0 ? 1 : -1;
+       x *= dir; y *= dir; x1 *= dir; y1 *= dir;
+
+       this->dirty |= (*this->frameFunctions[this->currentFrame])(this->display, x, y);
+       this->dirty |= (*this->frameFunctions[this->getNextFrameNumber()])(this->display, x1, y1);
+       break;
+     }
+     case FIXED:
+      this->dirty |= (*this->frameFunctions[this->currentFrame])(this->display, 0, 0);
+      break;
+  }
+}
+
+void SSD1306Ui::drawIndicator() {
+    byte posOfCurrentFrame; 
+    
+    switch (this->indicatorDirection){
+      case LEFT_RIGHT:
+        posOfCurrentFrame = this->currentFrame;
+        break;
+      case RIGHT_LEFT:
+        posOfCurrentFrame = (this->frameCount - 1) - this->currentFrame;
+        break;
+    }
+    
+    for (byte i = 0; i < this->frameCount; i++) {
+      
+      const char *xbm;
+      
+      if (posOfCurrentFrame == i) {
+         xbm = this->activeSymbole;
+      } else {
+         xbm = this->inactiveSymbole;  
+      }
+
+      int x,y;
+      switch (this->indicatorPosition){
+        case TOP:
+          y = 0;
+          x = 64 - (12 * frameCount / 2) + 12 * i;
+          break;
+        case BOTTOM:
+          y = 56;
+          x = 64 - (12 * frameCount / 2) + 12 * i;
+          break;
+        case RIGHT:
+          x = 120;
+          y = 32 - (12 * frameCount / 2) + 12 * i;
+          break;
+        case LEFT:
+          x = 0;
+          y = 32 - (12 * frameCount / 2) + 12 * i;
+          break;
+      }
+      
+      this->display->drawXbm(x, y, 8, 8, xbm);
+    }  
+}
+
+void SSD1306Ui::drawOverlays() {
+ for (int i=0;i<this->overlayCount;i++){
+    this->dirty |= (*this->overlayFunctions[i])(this->display);
+ }
+}
+
+int SSD1306Ui::getNextFrameNumber(){
+  int nextFrame = (this->currentFrame + this->frameTransitionDirection) % this->frameCount;
+  if (nextFrame < 0){
+    nextFrame = this->frameCount + nextFrame;
+  }
+  return nextFrame;  
+}
+
+
+
diff --git a/SSD1306Ui.h b/SSD1306Ui.h
new file mode 100644
index 0000000000000000000000000000000000000000..d5d7257002dc9363d4fecf9a4f7c522936ef93f4
--- /dev/null
+++ b/SSD1306Ui.h
@@ -0,0 +1,202 @@
+/**The MIT License (MIT)
+
+Copyright (c) 2015 by Fabrice Weinberg
+
+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.
+
+Credits for parts of this code go to Daniel Eichhorn
+*/
+
+#pragma once
+
+#include <Arduino.h>
+#include "ssd1306_i2c.h"
+
+enum AnimationDirection {
+  SLIDE_UP,
+  SLIDE_DOWN,
+  SLIDE_LEFT,
+  SLIDE_RIGHT
+};
+
+enum IndicatorPosition {
+  TOP,
+  RIGHT,
+  BOTTOM,
+  LEFT
+};
+
+enum IndicatorDirection {
+  LEFT_RIGHT,
+  RIGHT_LEFT
+};
+
+enum FrameState {
+  IN_TRANSITION,
+  FIXED
+};
+
+const char ANIMATION_activeSymbole[] PROGMEM = {
+  0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00
+};
+
+const char ANIMATION_inactiveSymbole[] PROGMEM = {
+  0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00
+};
+
+class SSD1306Ui {
+  private:
+    SSD1306             *display;
+
+    // Global dirty flag to indicate that the display needs to be redraw.
+    bool                dirty                     = true;
+
+    // Symboles for the Indicator
+    IndicatorPosition   indicatorPosition         = BOTTOM;
+    IndicatorDirection  indicatorDirection        = LEFT_RIGHT;
+
+    const char*         activeSymbole             = ANIMATION_activeSymbole;
+    const char*         inactiveSymbole           = ANIMATION_inactiveSymbole;
+
+    // Values for the Frames
+    AnimationDirection  frameAnimationDirection   = SLIDE_RIGHT;
+    FrameState          frameState                = FIXED;
+
+    int                 frameTransitionDirection  = 1;
+
+    int                 ticksPerFrame             = 313; // ~ 5000ms at 60 FPS
+    int                 ticksPerTransition        = 32;  // ~  500ms at 60 FPS
+    int                 ticksSinceLastStateSwitch = 0;
+    int                 currentFrame              = 0;
+
+    bool                autoTransition            = true;
+
+    bool                (**frameFunctions)(SSD1306 *display, int x, int y);
+    int                 frameCount                = 0;
+
+    // Values for Overlays
+    bool                (**overlayFunctions)(SSD1306 *display);
+    int                 overlayCount              = 0;
+
+
+    // Bookeeping for update
+    int                 updateInterval            = 16;
+    unsigned long       lastUpdate                = 0;
+
+
+    int                 getNextFrameNumber();
+    void                drawIndicator();
+    void                drawFrame();
+    void                drawOverlays();
+    void                tick();
+
+  public:
+
+    SSD1306Ui(SSD1306 *display);
+
+    /**
+     * Initialise the display
+     */
+    void init();
+
+    /**
+     * Configure the internal used target FPS
+     */
+    void setTargetFPS(byte fps);
+
+    // Automatic Controll
+    /**
+     * Enable automatic transition to next frame after the some time can be configured with `setTimePerFrame` and `setTimePerTransition`.
+     */
+    void enableAutoTransition();
+
+    /**
+     * Disable automatic transition to next frame.
+     */
+    void disableAutoTransition();
+
+    /**
+     * Set the direction if the automatic transitioning
+     */
+    void setAutoTransitionForwards();
+    void setAutoTransitionBackwards();
+
+    /**
+     *  Set the approx. time a frame is displayed
+     */
+    void setTimePerFrame(int time);
+
+    /**
+     * Set the approx. time a transition will take
+     */
+    void setTimePerTransition(int time);
+
+    // Customize Indicator Position and style
+    /**
+     * Set the position of the indicator bar.
+     */
+    void setIndicatorPosition(IndicatorPosition pos);
+
+    /**
+     * Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING
+     */
+    void setIndicatorDirection(IndicatorDirection dir);
+
+    /**
+     * Set the symbole to indicate an active frame in the indicator bar.
+     */
+    void setActiveSymbole(const char* symbole);
+
+    /**
+     * Set the symbole to indicate an inactive frame in the indicator bar.
+     */
+    void setInactiveSymbole(const char* symbole);
+
+    // Frame settings
+
+    /**
+     * Configure what animation is used to transition from one frame to another
+     */
+    void setFrameAnimation(AnimationDirection dir);
+
+    /**
+     * Add frame drawing functions
+     */
+    void setFrames(bool (*frameFunctions[])(SSD1306 *display, int x, int y), int frameCount);
+
+    // Overlay
+
+    /**
+     * Add overlays drawing functions that are draw independent of the Frames
+     */
+    void setOverlays(bool (*overlayFunctions[])(SSD1306 *display), int overlayCount);
+
+    // Manuell Controll
+    void  nextFrame();
+    void  previousFrame();
+
+    // State Info
+    FrameState getFrameState();
+    int        getCurrentFrame();
+
+
+    int update();
+};
+
+
diff --git a/examples/SSD1306Demo/SSD1306Demo.ino b/examples/SSD1306Demo/SSD1306Demo.ino
index df7eb61a125bd839a3360d3b39031c0452943c09..721e02a96a72ea3a1bb2541cbfc2d67cfd95a916 100644
--- a/examples/SSD1306Demo/SSD1306Demo.ino
+++ b/examples/SSD1306Demo/SSD1306Demo.ino
@@ -1,5 +1,3 @@
-#include <ArduinoJson.h>
-
 /**The MIT License (MIT)
 
 Copyright (c) 2015 by Daniel Eichhorn
@@ -26,6 +24,7 @@ See more at http://blog.squix.ch
 */
 #include <Wire.h>
 #include "ssd1306_i2c.h"
+#include "SSD1306Ui.h"
 #include "images.h"
 
 // if you are using a ESP8266 module with NodeMCU
@@ -48,105 +47,125 @@ See more at http://blog.squix.ch
 
 // Initialize the oled display for address 0x3c
 // sda-pin=14 and sdc-pin=12
-SSD1306 display(0x3c, NODEMCU_D6, NODEMCU_D5);
+SSD1306   display(0x3c, NODEMCU_D6, NODEMCU_D5);
+SSD1306Ui ui     ( &display );
 
 // this array keeps function pointers to all frames
 // frames are the single views that slide from right to left
-void (*frameCallbacks[])(int x, int y) = {drawFrame1, drawFrame2, drawFrame3, drawFrame4};
+bool (*frames[])(SSD1306 *display, int x, int y) = { drawFrame1, drawFrame2, drawFrame3, drawFrame4 };
 
 // how many frames are there?
 int frameCount = 4;
 
+bool (*overlays[])(SSD1306 *display)             = { msOverlay };
+int overlaysCount = 1;
+
 void setup() {
   Serial.begin(115200);
   Serial.println();
   Serial.println();
-  
-  // initialize dispaly
-  display.init();
+
+
+  ui.setTargetFPS(30);
+
+  ui.setActiveSymbole(activeSymbole);
+  ui.setInactiveSymbole(inactiveSymbole);
+
+  // You can change this to
+  // TOP, LEFT, BOTTOM, RIGHT
+  ui.setIndicatorPosition(BOTTOM);
+
+  // Defines where the first frame is located in the bar.
+  ui.setIndicatorDirection(LEFT_RIGHT);
+
+  // You can change the transition that is used
+  // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
+  ui.setFrameAnimation(SLIDE_LEFT);
+
+  // Add frames
+  ui.setFrames(frames, frameCount);
+
+  // Add overlays
+  ui.setOverlays(overlays, overlaysCount);
+
+  // Inital UI takes care of initalising the display too.
+  ui.init();
+
   display.flipScreenVertically();
-  // set the drawing functions
-  display.setFrameCallbacks(frameCount, frameCallbacks);
-  // how many ticks does a slide of a frame take?
-  display.setFrameTransitionTicks(10);
-  // defines how many ticks the driver waits between frame transitions
-  display.setFrameWaitTicks(150);
-
-  display.clear();
-  display.display();
-  
+
 }
 
 void loop() {
-  if (display.getFrameState() == display.FRAME_STATE_FIX) {
-    // do something which consumes a lot of time in a moment
-    // when there is no transition between frames going on.
-    // This will keep transitions smooth;
-  }
-
-  // clear the frame
-  display.clear();
-
-  // Tell the driver to render the next frame.
-  // This enables the frame mode including the transition
-  // and the drawing of the frame indicators
-  display.nextFrameTick();
+  int remainingTimeBudget = ui.update();
 
-  // Even in frame mode you can draw static elements.
-  // But they won't be transitioned
-  display.setFont(ArialMT_Plain_10);
-  display.setTextAlignment(TEXT_ALIGN_LEFT);
-  display.drawString(0, 54, "20:54");
+  if (remainingTimeBudget > 0) {
+    // You can do some work here
+    // Don't do stuff if you are below your
+    // time budget.
+    delay(remainingTimeBudget);
+  }
+}
 
-  // copy the buffer to the display
-  display.display();
+bool msOverlay(SSD1306 *display) {
+  display->setTextAlignment(TEXT_ALIGN_RIGHT);
+  display->setFont(ArialMT_Plain_10);
+  display->drawString(128, 0, String(millis()));
+  return true;
 }
 
-void drawFrame1(int x, int y) {
+bool drawFrame1(SSD1306 *display, int x, int 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(int x, int y) {
+  // if this frame need to be refreshed at the targetFPS you need to
+  // return true
+  display->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
+  return false;
+}
+
+bool drawFrame2(SSD1306 *display, int x, int 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, 0 + y, "Arial 10");
+  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_16);
-  display.drawString(0 + x, 10 + y, "Arial 16");
+  display->setFont(ArialMT_Plain_24);
+  display->drawString(0 + x, 34 + y, "Arial 24");
 
-  display.setFont(ArialMT_Plain_24);
-  display.drawString(0 + x, 24 + y, "Arial 24");
+  return false;
 }
 
-void drawFrame3(int x, int y) {
+bool drawFrame3(SSD1306 *display, int x, int y) {
   // Text alignment demo
-  display.setFont(ArialMT_Plain_10);
+  display->setFont(ArialMT_Plain_10);
 
   // The coordinates define the left starting point of the text
-  display.setTextAlignment(TEXT_ALIGN_LEFT);
-  display.drawString(0 + x, 0 + y, "Left aligned (0,0)");
+  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, 20, "Center aligned (64,20)");
+  display->setTextAlignment(TEXT_ALIGN_CENTER);
+  display->drawString(64 + x, 22, "Center aligned (64,22)");
 
   // The coordinates define the right end of the text
-  display.setTextAlignment(TEXT_ALIGN_RIGHT);
-  display.drawString(128 + x, 40, "Right aligned (128,40)");
+  display->setTextAlignment(TEXT_ALIGN_RIGHT);
+  display->drawString(128 + x, 33, "Right aligned (128,33)");
+  return false;
 }
 
-void drawFrame4(int x, int y) {
-  // Demo for drawStringMaxWidth: 
+bool drawFrame4(SSD1306 *display, int x, int 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, 0 + y, 128, "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore."); 
+  display->setTextAlignment(TEXT_ALIGN_LEFT);
+  display->setFont(ArialMT_Plain_10);
+  display->drawStringMaxWidth(0 + x, 10 + y, 128, "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore.");
+  return false;
 }
 
 
diff --git a/examples/SSD1306Demo/images.h b/examples/SSD1306Demo/images.h
index 8f5de149d1733553de8cbd7d3dbef167b9551aec..c280b555ce6010e5879f757fb4abff7bd090f466 100644
--- a/examples/SSD1306Demo/images.h
+++ b/examples/SSD1306Demo/images.h
@@ -1,28 +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, 
-  };   
+  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 activeSymbole[] PROGMEM = {
+    B00000000,
+    B00000000,
+    B00011000,
+    B00100100,
+    B01000010,
+    B01000010,
+    B00100100,
+    B00011000
+};
+
+const char inactiveSymbole[] PROGMEM = {
+    B00000000,
+    B00000000,
+    B00000000,
+    B00000000,
+    B00011000,
+    B00011000,
+    B00000000,
+    B00000000
+};
\ No newline at end of file
diff --git a/ssd1306_i2c.cpp b/ssd1306_i2c.cpp
index 37c628cb33d9d85f2107c42b1e0d31225f48227f..2bd40d445c661bff2ca0685d2956c84983449272 100644
--- a/ssd1306_i2c.cpp
+++ b/ssd1306_i2c.cpp
@@ -29,23 +29,20 @@ Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
 #include <Wire.h>
 
 
-SSD1306::SSD1306(int i2cAddress, int sda, int sdc)
-{
+SSD1306::SSD1306(int i2cAddress, int sda, int sdc) {
   myI2cAddress = i2cAddress;
   mySda = sda;
   mySdc = sdc;
- 
 }
 
 void SSD1306::init() {
   Wire.begin(mySda, mySdc);
-  Wire.setClock(400000); 
+  Wire.setClock(400000);
   sendInitCommands();
   resetDisplay();
 }
 
-void SSD1306::resetDisplay(void)
-{
+void SSD1306::resetDisplay(void) {
   displayOff();
   clear();
   display();
@@ -53,30 +50,29 @@ void SSD1306::resetDisplay(void)
 }
 
 void SSD1306::reconnect() {
-  Wire.begin(mySda, mySdc);  
+  Wire.begin(mySda, mySdc);
 }
 
-void SSD1306::displayOn(void)
-{
+void SSD1306::displayOn(void) {
     sendCommand(0xaf);        //display on
 }
 
-void SSD1306::displayOff(void)
-{
-  sendCommand(0xae);		//display off
+void SSD1306::displayOff(void) {
+  sendCommand(0xae);          //display off
 }
 
 void SSD1306::setContrast(char contrast) {
   sendCommand(0x81);
-  sendCommand(contrast);  
+  sendCommand(contrast);
 }
+
 void SSD1306::flipScreenVertically() {
   sendCommand(0xA0 | 0x1);      //SEGREMAP   //Rotate screen 180 deg
-  
   sendCommand(0xC8);            //COMSCANDEC  Rotate screen 180 Deg
 }
+
 void SSD1306::clear(void) {
-    memset(buffer, 0, (128*64 / 8));
+    memset(buffer, 0, (128 * 64 / 8));
 }
 
 void SSD1306::display(void) {
@@ -88,10 +84,8 @@ void SSD1306::display(void) {
     sendCommand(0x0);
     sendCommand(0x7);
 
-    
     for (uint16_t i=0; i<(128*64/8); i++) {
       // send a bunch of data in one xmission
-      //Wire.begin(mySda, mySdc);
       Wire.beginTransmission(myI2cAddress);
       Wire.write(0x40);
       for (uint8_t x=0; x<16; x++) {
@@ -102,18 +96,17 @@ void SSD1306::display(void) {
       yield();
       Wire.endTransmission();
     }
-    
 
 
 }
 
 void SSD1306::setPixel(int x, int y) {
   if (x >= 0 && x < 128 && y >= 0 && y < 64) {
-     
+
      switch (myColor) {
-      case WHITE:   buffer[x+ (y/8)*128] |=  (1 << (y&7)); break;
-      case BLACK:   buffer[x+ (y/8)*128] &= ~(1 << (y&7)); break; 
-      case INVERSE: buffer[x+ (y/8)*128] ^=  (1 << (y&7)); break; 
+      case WHITE:   buffer[x + (y/8)*128] |=  (1 << (y&7)); break;
+      case BLACK:   buffer[x + (y/8)*128] &= ~(1 << (y&7)); break;
+      case INVERSE: buffer[x + (y/8)*128] ^=  (1 << (y&7)); break;
     }
   }
 }
@@ -122,15 +115,15 @@ void SSD1306::setChar(int x, int y, unsigned char data) {
   for (int i = 0; i < 8; i++) {
     if (bitRead(data, i)) {
      setPixel(x,y + i);
-    }   
-  }   
+    }
+  }
 }
 
 // Code form http://playground.arduino.cc/Main/Utf8ascii
 byte SSD1306::utf8ascii(byte ascii) {
-    if ( ascii<128 )   // Standard ASCII-set 0..0x7F handling  
-    {   lastChar=0; 
-        return( ascii ); 
+    if ( ascii<128 ) {   // Standard ASCII-set 0..0x7F handling
+       lastChar=0;
+       return( ascii );
     }
 
     // get previous input
@@ -147,7 +140,7 @@ byte SSD1306::utf8ascii(byte ascii) {
 }
 
 // Code form http://playground.arduino.cc/Main/Utf8ascii
-String SSD1306::utf8ascii(String s) {       
+String SSD1306::utf8ascii(String s) {
         String r= "";
         char c;
         for (int i=0; i<s.length(); i++)
@@ -192,7 +185,7 @@ void SSD1306::drawString(int x, int y, String text) {
     currentCharWidth = pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + charCode);
     // Jump to font data beginning
     currentCharStartPos = CHAR_WIDTH_START_POS + numberOfChars;
-    
+
     for (int m = 0; m < charCode; m++) {
 
       currentCharStartPos += pgm_read_byte(myFontData + CHAR_WIDTH_START_POS + m)  * charHeight / 8 + 1;
@@ -201,26 +194,24 @@ void SSD1306::drawString(int x, int y, String text) {
     currentCharByteNum = ((charHeight * currentCharWidth) / 8) + 1;
     // iterate over all bytes of character
     for (int i = 0; i < currentCharByteNum; i++) {
-      
+
       currentByte = pgm_read_byte(myFontData + currentCharStartPos + i);
       //Serial.println(String(charCode) + ", " + String(currentCharWidth) + ", " + String(currentByte));
       // iterate over all bytes of character
       for(int bit = 0; bit < 8; bit++) {
          //int currentBit = bitRead(currentByte, bit);
-         
+
          currentBitCount = i * 8 + bit;
 
          charX = currentBitCount % currentCharWidth;
          charY = currentBitCount / currentCharWidth;
 
          if (bitRead(currentByte, bit)) {
-          //Serial.println(String(charX) + ", " + String(charY));
-          setPixel(startX + cursorX + charX, startY + charY); 
-          //setPixel(charX, charY);
+          setPixel(startX + cursorX + charX, startY + charY);
          }
 
-      } 
-      yield();     
+      }
+      yield();
     }
     cursorX += currentCharWidth;
 
@@ -248,7 +239,7 @@ void SSD1306::drawStringMaxWidth(int x, int y, int maxLineWidth, String text) {
         startsAt = endsAt + 1;
       }
     }
-    
+
   }
   drawString(x, y + lineNumber * lineHeight, text.substring(startsAt));
 }
@@ -275,28 +266,28 @@ void SSD1306::setFont(const char *fontData) {
 void SSD1306::drawBitmap(int x, int y, int width, int height, const char *bitmap) {
   for (int i = 0; i < width * height / 8; i++ ){
     unsigned char charColumn = 255 - pgm_read_byte(bitmap + i);
-    for (int j = 0; j < 8; j++) { 
+    for (int j = 0; j < 8; j++) {
       int targetX = i % width + x;
       int targetY = (i / (width)) * 8 + j + y;
       if (bitRead(charColumn, j)) {
-        setPixel(targetX, targetY);  
+        setPixel(targetX, targetY);
       }
     }
-  }  
+  }
 }
 
 void SSD1306::setColor(int color) {
-  myColor = color;  
+  myColor = color;
 }
 
 void SSD1306::drawRect(int x, int y, int width, int height) {
   for (int i = x; i < x + width; i++) {
     setPixel(i, y);
-    setPixel(i, y + height);    
+    setPixel(i, y + height);
   }
   for (int i = y; i < y + height; i++) {
     setPixel(x, i);
-    setPixel(x + width, i);  
+    setPixel(x + width, i);
   }
 }
 
@@ -314,28 +305,24 @@ void SSD1306::drawXbm(int x, int y, int width, int height, const char *xbm) {
   }
   for (int i = 0; i < width * height / 8; i++ ){
     unsigned char charColumn = pgm_read_byte(xbm + i);
-    for (int j = 0; j < 8; j++) { 
+    for (int j = 0; j < 8; j++) {
       int targetX = (i * 8 + j) % width + x;
       int targetY = (8 * i / (width)) + y;
       if (bitRead(charColumn, j)) {
-        setPixel(targetX, targetY);  
+        setPixel(targetX, targetY);
       }
     }
-  }    
+  }
 }
 
-void SSD1306::sendCommand(unsigned char com)
-{
-  //Wire.begin(mySda, mySdc);
+void SSD1306::sendCommand(unsigned char com) {
   Wire.beginTransmission(myI2cAddress);     //begin transmitting
   Wire.write(0x80);                          //command mode
   Wire.write(com);
   Wire.endTransmission();                    // stop transmitting
 }
 
-void SSD1306::sendInitCommands(void)
-{
-
+void SSD1306::sendInitCommands(void) {
   sendCommand(DISPLAYOFF);
   sendCommand(NORMALDISPLAY);
   sendCommand(SETDISPLAYCLOCKDIV);
@@ -363,53 +350,4 @@ void SSD1306::sendInitCommands(void)
   sendCommand(NORMALDISPLAY);
   sendCommand(0x2e);            // stop scroll
   sendCommand(DISPLAYON);
-  
-}
-
-void SSD1306::nextFrameTick() {
-    myFrameTick++;
-    if (myFrameTick==myFrameWaitTicks && myFrameState == 0 || myFrameTick==myFrameTransitionTicks && myFrameState == 1) {
-      myFrameState = (myFrameState + 1) %  2;
-      if (myFrameState==FRAME_STATE_FIX) {
-        myCurrentFrame = (myCurrentFrame + 1) % myFrameCount; 
-      } 
-      myFrameTick = 0; 
-    }
-    drawIndicators(myFrameCount, myCurrentFrame);
-    
-    switch(myFrameState) {
-    case 0:
-      (*myFrameCallbacks[myCurrentFrame])(0, 0);
-      break;
-    case 1:
-      (*myFrameCallbacks[myCurrentFrame])(-128 * myFrameTick / myFrameTransitionTicks, 0);
-      (*myFrameCallbacks[(myCurrentFrame + 1) % myFrameCount])(-128 * myFrameTick / myFrameTransitionTicks + 128, 0);
-      break;
-    }
-    
-}
-void SSD1306::drawIndicators(int frameCount, int activeFrame) {
-  for (int i = 0; i < frameCount; i++) {
-    const char *xbm;
-    if (activeFrame == i) {
-       xbm = active_bits;
-    } else {
-       xbm = inactive_bits;  
-    }
-    drawXbm(64 - (12 * frameCount / 2) + 12 * i,56, 8, 8, xbm);
-  }  
-}
-void SSD1306::setFrameCallbacks(int frameCount, void (*frameCallbacks[])(int x, int y)) {
-  myFrameCount = frameCount;
-  myFrameCallbacks = frameCallbacks;
-}
-
-void SSD1306::setFrameWaitTicks(int frameWaitTicks) {
-  myFrameWaitTicks = frameWaitTicks; 
-}
-void SSD1306::setFrameTransitionTicks(int frameTransitionTicks) {
-  myFrameTransitionTicks = frameTransitionTicks; 
-}
-int SSD1306::getFrameState() {
-  return myFrameState; 
-}
+}
\ No newline at end of file
diff --git a/ssd1306_i2c.h b/ssd1306_i2c.h
index 078868cbd3ea2c68b5e4a04dde042e8c7e965de2..a3cb628d797cf7779dd23d7285a430315d6edfb9 100644
--- a/ssd1306_i2c.h
+++ b/ssd1306_i2c.h
@@ -29,21 +29,10 @@ Credits for parts of this code go to Mike Rankin. Thank you so much for sharing!
 #include <Arduino.h>
 #include "SSD1306Fonts.h"
 
-#define active_width 8
-#define active_height 8
-const char active_bits[] PROGMEM = {
-   0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00 };
-
-#define inactive_width 8
-#define inactive_height 8
-const char inactive_bits[] PROGMEM = {
-   0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00 };
-
 #define BLACK 0
 #define WHITE 1
 #define INVERSE 2
 
-
 #define WIDTH_POS 0
 #define HEIGHT_POS 1
 #define FIRST_CHAR_POS 2
@@ -88,19 +77,10 @@ private:
    int mySda;
    int mySdc;
    uint8_t buffer[128 * 64 / 8];
-   int myFrameState = 0;
-   int myFrameTick = 0;
-   int myCurrentFrame = 0;
-   int myFrameCount = 0;
-   int myFrameWaitTicks = 100;
-   int myFrameTransitionTicks = 25;
    int myTextAlignment = TEXT_ALIGN_LEFT;
    int myColor = WHITE;
    byte lastChar;
    const char *myFontData = ArialMT_Plain_10;
-   void (**myFrameCallbacks)(int x, int y);
-
-
 
 public:
    // Create the display object connected to pin sda and sdc
@@ -190,32 +170,4 @@ public:
    // ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
    void setFont(const char *fontData);
 
-   // Sets the callback methods of the format void method(x,y)
-   void setFrameCallbacks(int frameCount, void (*frameCallbacks[])(int x, int y));
-
-   // Tells the framework to move to the next tick. The
-   // current visible frame callback will be called once
-   // per tick
-   void nextFrameTick(void);
-
-   // Draws the frame indicators. In a normal setup
-   // the framework does this for you
-   void drawIndicators(int frameCount, int activeFrame);
-
-   // defines how many ticks a frame should remain visible
-   // This does not include the transition
-   void setFrameWaitTicks(int frameWaitTicks);
-
-   // Defines how many ticks should be used for a transition
-   void setFrameTransitionTicks(int frameTransitionTicks);
-
-   // Returns the current state of the internal state machine
-   // Possible values: FRAME_STATE_FIX, FRAME_STATE_TRANSITION
-   // You can use this to detect when there is no transition
-   // on the way to execute operations that would
-   int getFrameState();
-
-   const int FRAME_STATE_FIX = 0;
-   const int FRAME_STATE_TRANSITION = 1;
-
-};
+};
\ No newline at end of file