diff --git a/firmware/test1/heizung-test1/platformio.ini b/firmware/test1/heizung-test1/platformio.ini
index 6c6199b086e1fb6c0551b616eec7053cf572623c..9c6f98e2865ff9d2ddc41e4bc9d8cf4a0a0b0750 100644
--- a/firmware/test1/heizung-test1/platformio.ini
+++ b/firmware/test1/heizung-test1/platformio.ini
@@ -16,3 +16,4 @@ board_build.core = earlephilhower
 lib_deps = 
 	adafruit/Adafruit SSD1306@^2.5.7
 	sparkfun/SparkFun TMP102 Breakout@^1.1.2
+	adafruit/Adafruit MPR121@^1.1.1
diff --git a/firmware/test1/heizung-test1/src/main.cpp b/firmware/test1/heizung-test1/src/main.cpp
index 2147c23361491633e6a83af19d4dff548ff21582..db68267ac4c5429d785d5d5055efb9035cd076c2 100644
--- a/firmware/test1/heizung-test1/src/main.cpp
+++ b/firmware/test1/heizung-test1/src/main.cpp
@@ -3,6 +3,7 @@
 #include <Adafruit_GFX.h>
 #include <Adafruit_SSD1306.h>
 #include <SparkFunTMP102.h>
+#include <Adafruit_MPR121.h>
 
 enum Pinout {
   DRIVE1 = 0,
@@ -45,6 +46,9 @@ bool hasDisplay;
 
 TMP102 sensor0, sensor1;
 
+Adafruit_MPR121 cap0, cap1;
+bool capAvailable[2];
+
 void setup() {
   rp2040.enableDoubleResetBootloader();
 
@@ -96,6 +100,30 @@ void setup() {
     sensor1.setExtendedMode(1);
     sensor1.wakeup();
   }
+
+  capAvailable[0] = cap0.begin(0x5a);
+  capAvailable[1] = cap1.begin(0x5c);
+  for (int i=0;i<2;i++) {
+    if (!capAvailable[i])
+      continue;
+    auto& cap = (i == 0 ? cap0 : cap1);
+
+    // disable it, again
+    cap.writeRegister(MPR121_ECR, 0x0);
+
+    // auto-config code (mostly) copied from Adafruit library
+    cap.writeRegister(MPR121_AUTOCONFIG0, 0x0B);
+
+    // correct values for Vdd = 3.3V
+    cap.writeRegister(MPR121_UPLIMIT, 200);     // ((Vdd - 0.7)/Vdd) * 256
+    cap.writeRegister(MPR121_TARGETLIMIT, 180); // UPLIMIT * 0.9
+    cap.writeRegister(MPR121_LOWLIMIT, 130);    // UPLIMIT * 0.65
+
+    // enable X electrodes and start MPR121
+    // enable virtual proximity electrode, as well
+    cap.writeRegister(MPR121_ECR, 0x8c | 0x30);
+
+  }
 }
 
 void i2c_scan() {
@@ -130,6 +158,14 @@ void i2c_scan() {
   Serial.println();
 }
 
+void displayPrintHexFixed(uint32_t x, int width) {
+  while (width > 1 && (x >> (4*(width-1))) == 0) {
+    display.write('0');
+    width--;
+  }
+  display.print(x, HEX);
+}
+
 void loop() {
   static int led_timer = 0;
   static int led_state = 2;
@@ -178,15 +214,8 @@ void loop() {
     i2c_scan();
   }
 
-  if (rp2040.getCycleCount64() > 2 * 133*1000*1000) {
-    display.fillRect(0, 0, 67, 64, SSD1306_BLACK);
-
-    display.setTextSize(1);
-    display.setTextColor(SSD1306_WHITE);
-    display.setCursor(0, 1);
-    display.print(F("ADDR: "));
-    display.println(digitalRead(BOOT2) ? '_' : 'X');
-
+  bool buttons[4];
+  if (1) {
     // Button Matrix:
     // 1: SDA, IN1
     // 2: SDA, IN3
@@ -196,21 +225,40 @@ void loop() {
     pinMode(I2C_OLED_SDA, OUTPUT);
     pinMode(I2C_OLED_SCL, INPUT_PULLUP);
     delayMicroseconds(1);
-    bool buttons[4];
-    buttons[0] = digitalRead(MATRIX_IN1);
-    buttons[1] = digitalRead(MATRIX_IN3);
+    buttons[0] = !digitalRead(MATRIX_IN1);
+    buttons[1] = !digitalRead(MATRIX_IN3);
     pinMode(I2C_OLED_SDA, INPUT_PULLUP);
     pinMode(I2C_OLED_SCL, OUTPUT);
     delayMicroseconds(1);
-    buttons[2] = digitalRead(MATRIX_IN1);
-    buttons[3] = digitalRead(MATRIX_IN3);
+    buttons[2] = !digitalRead(MATRIX_IN1);
+    buttons[3] = !digitalRead(MATRIX_IN3);
     pinMode(I2C_OLED_SDA, INPUT_PULLUP);
     pinMode(I2C_OLED_SCL, INPUT_PULLUP);
     Wire.begin();
+  }
+
+  static int displayMode = 0;
+  int displayModePrev = displayMode;
+  static bool prevButton4 = 0;
+  if (!prevButton4 && buttons[3]) {
+    displayMode = (displayMode + 1) % 5;
+  }
+  prevButton4 = buttons[3];
+
+  if (rp2040.getCycleCount64() > 2 * 133*1000*1000 && displayMode == 0) {
+    if (displayModePrev != 0)
+      display.drawBitmap(0, 0, logo_data, logo_width, logo_height, SSD1306_WHITE);
+    display.fillRect(0, 0, 67, 64, SSD1306_BLACK);
+
+    display.setTextSize(1);
+    display.setTextColor(SSD1306_WHITE);
+    display.setCursor(0, 1);
+    display.print(F("ADDR: "));
+    display.println(!digitalRead(BOOT2) ? 'X' : '_');
 
     display.print(F("SW:   "));
-    for (auto not_pressed : buttons)
-      display.print(not_pressed ? '_' : 'X');
+    for (auto pressed : buttons)
+      display.print(pressed ? 'X' : '_');
     display.println();
 
     display.print(F("Reed: "));
@@ -227,6 +275,82 @@ void loop() {
     display.print(F("      "));
     display.println(temp1, 2);
 
+    uint16_t touched0 = capAvailable[0] ? cap0.touched() : 0;
+    uint16_t touched1 = capAvailable[1] ? cap1.touched() : 0;
+    display.print(F("T:"));
+    if (capAvailable[0])
+      displayPrintHexFixed(touched0, 4);
+    else
+      display.write("----");
+    if (capAvailable[1])
+      displayPrintHexFixed(touched1, 4);
+    else
+      display.write("----");
+    display.println();
+
+    display.display();
+  } else if (displayMode >= 1 && displayMode <= 3) {
+    int first = (displayMode-1) * 12, last = first + 11;
+    display.fillRect(0, 0, 128, 64, SSD1306_BLACK);
+    display.setTextSize(1);
+    display.setTextColor(SSD1306_WHITE);
+    display.setCursor(0, 1);
+    display.print(F("Touch: "));
+    display.print(first);
+    display.print("..");
+    display.println(last);
+
+    for (int channel=first; channel<=last && channel < 32; channel++) {
+      auto& cap = channel < 16 ? cap0 : cap1;
+      auto b = cap.baselineData(channel % 16);
+      auto v = cap.filteredData(channel % 16);
+      displayPrintHexFixed(b, 4);
+      display.write(',');
+      displayPrintHexFixed(v, 4);
+      if ((channel%2) == 1)
+        display.println();
+      else
+        display.write("  ");
+    }
+    display.display();
+  } else if (displayMode == 4) {
+    display.fillRect(0, 0, 128, 64, SSD1306_BLACK);
+    display.setTextSize(1);
+    display.setTextColor(SSD1306_WHITE);
+    display.setCursor(80, 1);
+    display.println(F("Touch:"));
+
+    static const uint8_t channels[] = {
+      // T1..T8
+      0x09, 0x08, 0x07, 0x0a, 0x05, 0x02, 0x01, 0x00,
+      0x1a, 0x14, 0x11, 0x16, 0x15, 0x13, 0x12,
+      0xff,
+      // R1..R3, north
+      0x04, 0x03, 0x06,
+      0xff,
+      // R1..R3, south
+      0x19, 0x17, 0x18,
+      0xff,
+      // Screw2..4
+      0x0b, 0x1b, 0x10,
+      0xff,
+      // Proximity north and south
+      0x0c, 0x1c,
+      0xff,
+    };
+
+    int y = 6;
+    for (auto channel : channels) {
+      if (channel == 0xff) {
+        display.drawFastHLine(64, y++, 64, SSD1306_WHITE);
+        continue;
+      }
+      auto& cap = channel < 16 ? cap0 : cap1;
+      auto b = cap.baselineData(channel % 16);
+      auto v = cap.filteredData(channel % 16);
+      display.drawFastHLine(0, y++, b/16, SSD1306_WHITE);
+      display.drawFastHLine(0, y++, v/16, SSD1306_WHITE);
+    }
     display.display();
   }