diff --git a/epicardium/main.c b/epicardium/main.c
index e22d95cbcc258cb963d8d3f476e64e3570365768..49f8649f93768fc164b4f6d63113125ca5c63b08 100644
--- a/epicardium/main.c
+++ b/epicardium/main.c
@@ -30,6 +30,43 @@ TaskHandle_t dispatcher_task_id;
 
 void vBleTask(void *pvParameters);
 
+#define BLEMAXCFGBYTES 100
+int bleShallStart(void)
+{
+	int bleConfigFile = epic_file_open("ble.txt", "r");
+	if (bleConfigFile < 0) {
+		LOG_INFO("startup", "can not open ble.txt -> BLE is not started");
+		epic_file_close(bleConfigFile);
+		return 0;
+	}
+
+	char cfgBuf[BLEMAXCFGBYTES+1];
+	int readNum = epic_file_read(bleConfigFile, cfgBuf, BLEMAXCFGBYTES);
+	LOG_INFO("startup", "readNum %i", readNum);
+	if (readNum < 0) {
+		LOG_INFO("startup", "can not read ble.txt -> BLE is not started");
+		epic_file_close(bleConfigFile);
+		return 0;
+	}
+	cfgBuf[readNum] = '\0';
+
+	LOG_INFO("startup", "faa %s", cfgBuf);
+
+	char bleActiveStr[] = "active=true";
+	cfgBuf[sizeof(bleActiveStr)-1] = '\0';
+	LOG_INFO("startup", "foe %i %s", sizeof(bleActiveStr), cfgBuf);
+
+	if (strcmp(cfgBuf, "active=true") != 0) {
+		LOG_INFO("startup", "ble.txt is not \"active=true\" -> BLE is not started");
+		epic_file_close(bleConfigFile);
+		return 0;
+	}
+
+	LOG_INFO("startup", "ble.txt is \"active=true\" -> BLE is starting");
+	epic_file_close(bleConfigFile);
+	return 1;
+}
+
 int main(void)
 {
 	LOG_INFO("startup", "Epicardium startup ...");
@@ -118,15 +155,17 @@ int main(void)
 	}
 
 	/* BLE */
-	if (xTaskCreate(
-		    vBleTask,
-		    (const char *)"BLE",
-		    configMINIMAL_STACK_SIZE * 10,
-		    NULL,
-		    tskIDLE_PRIORITY + 1,
-		    NULL) != pdPASS) {
-		LOG_CRIT("startup", "Failed to create %s task!", "BLE");
-		abort();
+	if (bleShallStart()) {
+		if (xTaskCreate(
+			    vBleTask,
+			    (const char *)"BLE",
+			    configMINIMAL_STACK_SIZE * 10,
+			    NULL,
+			    tskIDLE_PRIORITY + 1,
+			    NULL) != pdPASS) {
+			LOG_CRIT("startup", "Failed to create %s task!", "BLE");
+			abort();
+		}
 	}
 
 	/* light sensor */
diff --git a/preload/bleoptin.py b/preload/bleoptin.py
new file mode 100644
index 0000000000000000000000000000000000000000..8e992f5156c780f8522e6961f03c0da928e6237f
--- /dev/null
+++ b/preload/bleoptin.py
@@ -0,0 +1,82 @@
+import ujson
+import os
+import display
+import utime
+import buttons
+
+CONFIG_NAME = "ble.txt"
+ACTIVE_STRING = "active=true"
+INACTIVE_STRING = "active=false"
+
+
+def init():
+    if CONFIG_NAME not in os.listdir("."):
+        deactivate()
+
+
+def triangle(disp, x, y, left):
+    yf = 1 if left else -1
+    scale = 6
+    disp.line(x - scale * yf, int(y + scale / 2), x, y)
+    disp.line(x, y, x, y + scale)
+    disp.line(x, y + scale, x - scale * yf, y + int(scale / 2))
+
+
+def activate():
+    with open(CONFIG_NAME, 'w') as f:
+        f.write("active=true")
+    
+
+def deactivate():
+    with open(CONFIG_NAME, 'w') as f:
+        f.write("active=false")
+    
+
+def is_active():
+    with open(CONFIG_NAME, 'r') as f:
+        state = f.readlines()[0]
+        if len(state) < len(ACTIVE_STRING):
+            return False
+        state = state[0:len(ACTIVE_STRING)]
+        print(state)
+        return state == ACTIVE_STRING
+    
+
+def headline():
+    disp.print("BLE", posy=0, fg=[0, 255, 255])
+    if is_active():
+        disp.print("active", posy=20, fg=[0, 255, 255])
+    else:
+        disp.print("inactive", posy=20, fg=[0, 255, 255])
+
+
+def selector():
+    triangle(disp, 10, 46, True)
+    triangle(disp, 150, 66, False)
+    disp.print("activate", posx=15, posy=40, fg=[0, 255, 0])
+    disp.print("deactivate", posx=5, posy=60, fg=[255, 0, 0])
+
+
+disp = display.open()
+print("HALLO")
+button_pressed = False
+init()
+
+while True:
+    disp.clear()
+    headline()
+    v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT)
+    if v == 0:
+        button_pressed = False
+
+    if not button_pressed and v & buttons.BOTTOM_LEFT != 0:
+        button_pressed = True
+        activate()
+    elif not button_pressed and v & buttons.BOTTOM_RIGHT != 0:
+        button_pressed = True
+        deactivate()
+    
+    selector()
+    disp.update()
+    utime.sleep(0.1)
+