diff --git a/SSD1306Ui.cpp b/SSD1306Ui.cpp
index bcdb751355cef4eb88932f8f8538bb0695ae5b0f..198e3d2e11744ba22b7014d657516e1a92c4cf8f 100644
--- a/SSD1306Ui.cpp
+++ b/SSD1306Ui.cpp
@@ -10,17 +10,22 @@ void SSD1306Ui::init() {
 }
 
 void SSD1306Ui::setTargetFPS(byte fps){
+  int oldInterval = this->updateInterval;
   this->updateInterval = ((float) 1.0 / (float) fps) * 1000;
-  Serial.println(this->updateInterval);
+
+  // Calculate new ticksPerFrame
+  float changeRatio = oldInterval / this->updateInterval;
+  this->ticksPerFrame *= changeRatio;
+  this->ticksPerTransition *= changeRatio;
 }
 
 // -/------ Automatic controll ------\-
 
 void SSD1306Ui::enableAutoTransition(){
-  autoTransition = true;
+  this->autoTransition = true;
 }
 void SSD1306Ui::disableAutoTransition(){
-  autoTransition = false;
+  this->autoTransition = false;
 }
 void SSD1306Ui::setAutoTransitionForwards(){
   this->frameTransitionDirection = 1;
@@ -49,22 +54,22 @@ void SSD1306Ui::setActiveSymbole(const char* symbole) {
   this->dirty = true;
 }
 void SSD1306Ui::setInactiveSymbole(const char* symbole) {
-  this->inactiveSymbole = symbole; 
+  this->inactiveSymbole = symbole;
   this->dirty = true;
 }
 
 
 // -/----- Frame settings -----\-
-void SSD1306Ui::setFrameAnimation(AnimationDirection dir) {  
+void SSD1306Ui::setFrameAnimation(AnimationDirection dir) {
   this->frameAnimationDirection = dir;
 }
-void SSD1306Ui::setFrames(bool (*frameFunctions[])(SSD1306 *display, int x, int y), int frameCount) {
+void SSD1306Ui::setFrames(FrameCallback* frameFunctions, int frameCount) {
   this->frameCount     = frameCount;
   this->frameFunctions = frameFunctions;
 }
 
 // -/----- Overlays ------\-
-void SSD1306Ui::setOverlays(bool (*overlayFunctions[])(SSD1306 *display), int overlayCount){
+void SSD1306Ui::setOverlays(OverlayCallback* overlayFunctions, int overlayCount){
   this->overlayCount     = overlayCount;
   this->overlayFunctions = overlayFunctions;
 }
@@ -72,67 +77,63 @@ void SSD1306Ui::setOverlays(bool (*overlayFunctions[])(SSD1306 *display), int ov
 
 // -/----- Manuel control -----\-
 void SSD1306Ui::nextFrame() {
-  this->frameState = IN_TRANSITION;
-  this->ticksSinceLastStateSwitch = 0;
+  this->state.frameState = IN_TRANSITION;
+  this->state.ticksSinceLastStateSwitch = 0;
   this->frameTransitionDirection = 1;
 }
 void SSD1306Ui::previousFrame() {
-  this->frameState = IN_TRANSITION;
-  this->ticksSinceLastStateSwitch = 0;
+  this->state.frameState = IN_TRANSITION;
+  this->state.ticksSinceLastStateSwitch = 0;
   this->frameTransitionDirection = -1;
 }
 
 
 // -/----- State information -----\-
-FrameState SSD1306Ui::getFrameState(){
-  return this->frameState;
-}
-int SSD1306Ui::getCurrentFrame(){
-  return this->currentFrame;
+SSD1306UiState SSD1306Ui::getUiState(){
+  return this->state;
 }
 
 
 int SSD1306Ui::update(){
-  int timeBudget = this->updateInterval - (millis() - this->lastUpdate);
+  int timeBudget = this->updateInterval - (millis() - this->state.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();
+    if (this->autoTransition && this->state.lastUpdate != 0) this->state.ticksSinceLastStateSwitch += ceil(-timeBudget / this->updateInterval);
+
+    this->state.lastUpdate = millis();
     this->tick();
-  } 
+  }
   return timeBudget;
 }
 
 
 void SSD1306Ui::tick() {
-  this->ticksSinceLastStateSwitch++;
+  this->state.ticksSinceLastStateSwitch++;
 
-  switch (this->frameState) {
+  switch (this->state.frameState) {
     case IN_TRANSITION:
         this->dirty = true;
-        if (this->ticksSinceLastStateSwitch >= this->ticksPerTransition){
-          this->frameState = FIXED;
-          this->currentFrame = getNextFrameNumber();
-          this->ticksSinceLastStateSwitch = 0;
+        if (this->state.ticksSinceLastStateSwitch >= this->ticksPerTransition){
+          this->state.frameState = FIXED;
+          this->state.currentFrame = getNextFrameNumber();
+          this->state.ticksSinceLastStateSwitch = 0;
         }
       break;
     case FIXED:
-      if (this->ticksSinceLastStateSwitch >= this->ticksPerFrame){
+      if (this->state.ticksSinceLastStateSwitch >= this->ticksPerFrame){
           if (this->autoTransition){
-            this->frameState = IN_TRANSITION;
+            this->state.frameState = IN_TRANSITION;
             this->dirty = true;
           }
-          this->ticksSinceLastStateSwitch = 0;
+          this->state.ticksSinceLastStateSwitch = 0;
       }
       break;
   }
-  
+
   if (this->dirty) {
     this->dirty = false;
     this->display->clear();
-    this->drawIndicator();  
+    this->drawIndicator();
     this->drawFrame();
     this->drawOverlays();
     this->display->display();
@@ -140,9 +141,9 @@ void SSD1306Ui::tick() {
 }
 
 void SSD1306Ui::drawFrame(){
-  switch (this->frameState){
+  switch (this->state.frameState){
      case IN_TRANSITION: {
-       float progress = (float) this->ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
+       float progress = (float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
        int x, y, x1, y1;
        switch(this->frameAnimationDirection){
         case SLIDE_LEFT:
@@ -175,36 +176,36 @@ void SSD1306Ui::drawFrame(){
        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);
+       this->dirty |= (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, x, y);
+       this->dirty |= (this->frameFunctions[this->getNextFrameNumber()])(this->display, &this->state, x1, y1);
        break;
      }
      case FIXED:
-      this->dirty |= (*this->frameFunctions[this->currentFrame])(this->display, 0, 0);
+      this->dirty |= (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, 0, 0);
       break;
   }
 }
 
 void SSD1306Ui::drawIndicator() {
-    byte posOfCurrentFrame; 
-    
+    byte posOfCurrentFrame;
+
     switch (this->indicatorDirection){
       case LEFT_RIGHT:
-        posOfCurrentFrame = this->currentFrame;
+        posOfCurrentFrame = this->state.currentFrame;
         break;
       case RIGHT_LEFT:
-        posOfCurrentFrame = (this->frameCount - 1) - this->currentFrame;
+        posOfCurrentFrame = (this->frameCount - 1) - this->state.currentFrame;
         break;
     }
-    
+
     for (byte i = 0; i < this->frameCount; i++) {
-      
-      const char *xbm;
-      
+
+      const char *image;
+
       if (posOfCurrentFrame == i) {
-         xbm = this->activeSymbole;
+         image = this->activeSymbole;
       } else {
-         xbm = this->inactiveSymbole;  
+         image = this->inactiveSymbole;
       }
 
       int x,y;
@@ -226,24 +227,23 @@ void SSD1306Ui::drawIndicator() {
           y = 32 - (12 * frameCount / 2) + 12 * i;
           break;
       }
-      
-      this->display->drawXbm(x, y, 8, 8, xbm);
-    }  
+
+      this->display->drawFastImage(x, y, 8, 8, image);
+    }
 }
 
 void SSD1306Ui::drawOverlays() {
  for (int i=0;i<this->overlayCount;i++){
-    this->dirty |= (*this->overlayFunctions[i])(this->display);
+    this->dirty |= (this->overlayFunctions[i])(this->display, &this->state);
  }
 }
 
 int SSD1306Ui::getNextFrameNumber(){
-  int nextFrame = (this->currentFrame + this->frameTransitionDirection) % this->frameCount;
+  int nextFrame = (this->state.currentFrame + this->frameTransitionDirection) % this->frameCount;
   if (nextFrame < 0){
     nextFrame = this->frameCount + nextFrame;
   }
-  return nextFrame;  
+  return nextFrame;
 }
 
 
-
diff --git a/SSD1306Ui.h b/SSD1306Ui.h
index e43f8980c37b5d76b67f1777d77129204a216253..703d47b6bd20551ddd8415abe711b4c63f35a32a 100644
--- a/SSD1306Ui.h
+++ b/SSD1306Ui.h
@@ -60,6 +60,19 @@ const char ANIMATION_inactiveSymbole[] PROGMEM = {
   0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00
 };
 
+
+// Structure of the UiState
+struct SSD1306UiState {
+  int           lastUpdate                = 0;
+  int           ticksSinceLastStateSwitch = 0;
+
+  FrameState    frameState                = FIXED;
+  int           currentFrame              = 0;
+};
+
+typedef bool (*FrameCallback)(SSD1306 *display,  SSD1306UiState* state, int x, int y);
+typedef bool (*OverlayCallback)(SSD1306 *display,  SSD1306UiState* state);
+
 class SSD1306Ui {
   private:
     SSD1306             *display;
@@ -76,29 +89,26 @@ class SSD1306Ui {
 
     // 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;
+    int                 ticksPerFrame             = 151; // ~ 5000ms at 30 FPS
+    int                 ticksPerTransition        = 15;  // ~  500ms at 30 FPS
 
     bool                autoTransition            = true;
 
-    bool                (**frameFunctions)(SSD1306 *display, int x, int y);
+    FrameCallback*      frameFunctions;
     int                 frameCount                = 0;
 
     // Values for Overlays
-    bool                (**overlayFunctions)(SSD1306 *display);
+    OverlayCallback*    overlayFunctions;
     int                 overlayCount              = 0;
 
+    // UI State
+    SSD1306UiState      state;
 
     // Bookeeping for update
-    int                 updateInterval            = 16;
-    unsigned long       lastUpdate                = 0;
-
+    int                 updateInterval            = 33;
 
     int                 getNextFrameNumber();
     void                drawIndicator();
@@ -147,7 +157,7 @@ class SSD1306Ui {
      */
     void setTimePerTransition(int time);
 
-    // Customize Indicator Position and style
+    // Customize indicator position and style
     /**
      * Set the position of the indicator bar.
      */
@@ -178,25 +188,22 @@ class SSD1306Ui {
     /**
      * Add frame drawing functions
      */
-    void setFrames(bool (*frameFunctions[])(SSD1306 *display, int x, int y), int frameCount);
+    void setFrames(FrameCallback* frameFunctions, int frameCount);
 
     // Overlay
 
     /**
      * Add overlays drawing functions that are draw independent of the Frames
      */
-    void setOverlays(bool (*overlayFunctions[])(SSD1306 *display), int overlayCount);
+    void setOverlays(OverlayCallback* overlayFunctions, int overlayCount);
 
     // Manuell Controll
     void  nextFrame();
     void  previousFrame();
 
     // State Info
-    FrameState getFrameState();
-    int        getCurrentFrame();
-
+    SSD1306UiState getUiState();
 
     int update();
 };
 
-