diff --git a/docs/badge/usage.rst b/docs/badge/usage.rst
index 2be0c91bce6822736b0f64c7a7aabd7433edb4ec..e1c1076d852c041954cdb18e0e77eeee5eeba423 100644
--- a/docs/badge/usage.rst
+++ b/docs/badge/usage.rst
@@ -159,8 +159,7 @@ headphone output.
 Captouch Demo
 ^^^^^^^^^^^^^
 
-Visualizes the positional data from the captouch pads. Unfortunately petal 5 is not
-fully functional with the current driver.
+Visualizes the positional data from the captouch pads. Unfortunately petal 5 is not fully functional with the current driver so it performs slightly worse than all the others. Press shoulder button in any direction to enter captouch calibration mode. *Note: calibration happens during every boot, the data is not permanently stored at this point in time. If you experience a captouch malfunction during runtime and do not wish to lose your runtime data this is useful. In the future we will probably move to calibrating more explicitely and storing the data.*
 
 Files
 ^^^^^
diff --git a/python_payload/apps/demo_cap_touch/__init__.py b/python_payload/apps/demo_cap_touch/__init__.py
index 27e712415b092c31e48d0302fd63e361514f643f..314bd02cf8b2a882098a27bbea7c8150e3447970 100644
--- a/python_payload/apps/demo_cap_touch/__init__.py
+++ b/python_payload/apps/demo_cap_touch/__init__.py
@@ -1,3 +1,124 @@
-from .main import CapTouchDemo
+from st3m import logging
+from st3m.application import Application, ApplicationContext
+from st3m.goose import List
+from st3m.input import InputState
+from ctx import Context
 
-App = CapTouchDemo
+log = logging.Log(__name__, level=logging.INFO)
+log.info("import")
+
+import cmath
+import math
+import time
+import captouch
+
+
+class Dot:
+    def __init__(self, size: float, imag: float, real: float) -> None:
+        self.size = size
+        self.imag = imag
+        self.real = real
+
+    def draw(self, i: int, ctx: Context) -> None:
+        imag = self.imag
+        real = self.real
+        size = self.size
+
+        col = (1.0, 0.0, 1.0)
+        if i % 2:
+            col = (0.0, 0.8, 0.8)
+        ctx.rgb(*col).rectangle(
+            -int(imag - (size / 2)), -int(real - (size / 2)), size, size
+        ).fill()
+
+
+class CapTouchDemo(Application):
+    def __init__(self, app_ctx: ApplicationContext) -> None:
+        super().__init__(app_ctx)
+        self.dots: List[Dot] = []
+        self.last_calib = None
+        self.state = 0
+        self.timer = 0
+        self.button = 0
+
+    def think(self, ins: InputState, delta_ms: int) -> None:
+        super().think(ins, delta_ms)
+        press_event = (self.button != ins.buttons.app) and ins.buttons.app
+        self.button = int(ins.buttons.app)
+        if press_event:
+            print(self.button)
+        if self.state == 0:
+            if press_event and self.button == ins.buttons.PRESSED_DOWN:
+                self.state = 1
+            self.dots = []
+            for i in range(10):
+                petal = ins.captouch.petals[i]
+                (rad, phi) = petal.position
+                size = 4
+                if petal.pressed:
+                    size += 4
+                x = 70 + (rad / 1000) + 0j
+                x += ((-phi) / 600) * 1j
+                rot = cmath.exp(-2j * math.pi * i / 10)
+                x = x * rot
+                self.dots.append(Dot(size, x.imag, x.real))
+        elif self.state == 1:
+            if press_event:
+                if self.button == ins.buttons.PRESSED_DOWN:
+                    self.state = 2
+                    self.timer = 2999
+                else:
+                    self.state = 0
+        elif self.state == 2:
+            self.timer -= delta_ms
+            if self.timer < 0:
+                self.state = 3
+                captouch.calibration_request()
+        elif self.state == 3:
+            if not captouch.calibration_active():
+                self.state = 0
+
+    def draw(self, ctx: Context) -> None:
+        ctx.rgb(0, 0, 0).rectangle(-120, -120, 240, 240).fill()
+        if self.state == 0:
+            for i, dot in enumerate(self.dots):
+                dot.draw(i, ctx)
+        else:
+            ctx.rgb(0, 0.8, 0.8)
+            ctx.text_align = ctx.CENTER
+            ctx.move_to(0, 0)
+            ctx.font = ctx.get_font_name(0)
+            ctx.font_size = 20
+            pos = -55
+            ctx.move_to(0, pos)
+            ctx.text("calibration mode")
+            pos += 30
+            ctx.move_to(0, pos)
+            ctx.text("do not touch the petals")
+            pos += 20
+            ctx.move_to(0, pos)
+            ctx.text("from the front during")
+            pos += 20
+            ctx.move_to(0, pos)
+            ctx.text("calibration")
+            pos += 40
+            ctx.move_to(0, pos)
+            if self.state == 1:
+                pos -= 10
+                ctx.move_to(0, pos)
+                ctx.text("down: start 3s countdown")
+                pos += 20
+                ctx.move_to(0, pos)
+                ctx.text("left/right: canel")
+            elif self.state == 2:
+                ctx.text("calibrating in " + str(1 + int(self.timer / 1000)))
+            elif self.state == 3:
+                ctx.rgb(1.0, 0.5, 0.2)
+                ctx.text("calibrating...")
+
+
+# For running with `mpremote run`:
+if __name__ == "__main__":
+    import st3m.run
+
+    st3m.run.run_app(CapTouchDemo)
diff --git a/python_payload/apps/demo_cap_touch/flow3r.toml b/python_payload/apps/demo_cap_touch/flow3r.toml
index cc859bb6ca0335054f9710076d3b0d4c7d60feee..ed6f8f183837cb97804f934420abd0f378135187 100644
--- a/python_payload/apps/demo_cap_touch/flow3r.toml
+++ b/python_payload/apps/demo_cap_touch/flow3r.toml
@@ -1,5 +1,5 @@
 [app]
-name = "Captouch Demo"
+name = "captouch demo"
 category = "Apps"
 
 [entry]
diff --git a/python_payload/apps/demo_cap_touch/main.py b/python_payload/apps/demo_cap_touch/main.py
deleted file mode 100644
index d39fb9ed33935ae3a0aee0d2f9800adb0853a6d3..0000000000000000000000000000000000000000
--- a/python_payload/apps/demo_cap_touch/main.py
+++ /dev/null
@@ -1,89 +0,0 @@
-from st3m import logging
-from st3m.application import Application, ApplicationContext
-from st3m.goose import List
-from st3m.input import InputState
-from ctx import Context
-
-log = logging.Log(__name__, level=logging.INFO)
-log.info("import")
-
-import cmath
-import math
-import time
-
-
-class Dot:
-    def __init__(self, size: float, imag: float, real: float) -> None:
-        self.size = size
-        self.imag = imag
-        self.real = real
-
-    def draw(self, i: int, ctx: Context) -> None:
-        imag = self.imag
-        real = self.real
-        size = self.size
-
-        col = (1.0, 0.0, 1.0)
-        if i % 2:
-            col = (0.0, 1.0, 1.0)
-        ctx.rgb(*col).rectangle(
-            -int(imag - (size / 2)), -int(real - (size / 2)), size, size
-        ).fill()
-
-
-class CapTouchDemo(Application):
-    def __init__(self, app_ctx: ApplicationContext) -> None:
-        super().__init__(app_ctx)
-        self.dots: List[Dot] = []
-        self.last_calib = None
-        # self.ui_autocalib = ui.IconLabel("Autocalib done", size=30)
-
-        # self.add_event(
-        #    event.Event(
-        #        name="captouch_autocalib",
-        #        action=self.do_autocalib,
-        #        condition=lambda data: data["type"] == "button"
-        #        and data["index"] == 0
-        #        and data["change"]
-        #        and data["from"] == 2,
-        #        enabled=True,
-        #    )
-        # )
-
-    def think(self, ins: InputState, delta_ms: int) -> None:
-        super().think(ins, delta_ms)
-        self.dots = []
-        for i in range(10):
-            petal = ins.captouch.petals[i]
-            (rad, phi) = petal.position
-            size = 4
-            if petal.pressed:
-                size += 4
-            x = 70 + (rad / 1000) + 0j
-            x += ((-phi) / 600) * 1j
-            rot = cmath.exp(-2j * math.pi * i / 10)
-            x = x * rot
-
-            self.dots.append(Dot(size, x.imag, x.real))
-
-    def draw(self, ctx: Context) -> None:
-        # print(self.last_calib)
-
-        ctx.rgb(0, 0, 0).rectangle(-120, -120, 240, 240).fill()
-        for i, dot in enumerate(self.dots):
-            dot.draw(i, ctx)
-        # if not self.last_calib is None and self.last_calib > 0:
-        #    self.last_calib -= 1
-        #    self.ui_autocalib.draw(ctx)
-
-    # def do_autocalib(self, data) -> None:
-    #    log.info("Performing captouch autocalibration")
-    #    captouch.calibration_request()
-    #    self.last_calib = 50
-
-
-# For running with `mpremote run`:
-if __name__ == "__main__":
-    import st3m.run
-
-    st3m.run.run_app(CapTouchDemo)