diff --git a/ampel-firmware/co2_sensor.cpp b/ampel-firmware/co2_sensor.cpp
index 5dff6765fb7c4a6b19d9dc631af15c3474d9840b..50930c6c93912b14c8043a72d69b524089b7ee4b 100644
--- a/ampel-firmware/co2_sensor.cpp
+++ b/ampel-firmware/co2_sensor.cpp
@@ -25,6 +25,29 @@ namespace sensor {
   char timestamp[23];
   int16_t stable_measurements = 0;
   uint32_t waiting_color = color::blue;
+
+  /**
+   * Define sensor states
+   * INITIAL -> initial state
+   * BOOTUP -> state after initializing the sensor, i.e. after scd.begin()
+   * READY -> sensor does output valid information (> 0 ppm) and no other condition takes place
+   * (NOTE: This state is currently unused)
+   * NEEDSCALIBRATION -> sensor measurements are too low (< 250 ppm)
+   * PREPARECALIBRATION -> forced calibration was initiated, waiting for stable measurements
+   * CALIBRATION -> the sensor does calibrate itself
+   */
+  enum state {INITIAL, BOOTUP, READY, NEEDSCALIBRATION, PREPARECALIBRATION, CALIBRATION};
+  const char *state_names[] = {
+    "INITIAL",
+    "BOOTUP",
+    "READY",
+    "NEEDSCALIBRATION",
+    "PREPARECALIBRATION",
+    "CALIBRATION"
+  };
+  state current_state = INITIAL;
+  void switchState(state);
+
   bool should_calibrate = false;
 
   void initialize() {
@@ -49,6 +72,8 @@ namespace sensor {
       ESP.restart();
     }
 
+    switchState(BOOTUP);
+
     // SCD30 has its own timer.
     //NOTE: The timer seems to be inaccurate, though, possibly depending on voltage. Should it be offset?
     Serial.println();
@@ -116,9 +141,11 @@ namespace sensor {
     Serial.println(F("Waiting until the measurements are stable for at least 2 minutes."));
     Serial.println(F("It could take a very long time."));
     should_calibrate = true;
+    switchState(PREPARECALIBRATION);
   }
 
   void calibrateAndRestart() {
+    switchState(CALIBRATION);
     Serial.print(F("Calibrating SCD30 now..."));
     scd30.setAltitudeCompensation(config::altitude_above_sea_level);
     scd30.setForcedRecalibrationFactor(config::co2_calibration_level);
@@ -137,10 +164,20 @@ namespace sensor {
     Serial.println(humidity, 1);
   }
 
+  void switchState(state new_state) {
+    if (new_state == current_state) return;
+    Serial.print(F("Changing sensor state: "));
+    Serial.print(state_names[current_state]);
+    Serial.print(" -> ");
+    Serial.println(state_names[new_state]);
+    current_state = new_state;
+  }
+
   void displayCO2OnLedRing() {
     if (co2 < 250) {
       // Sensor should be calibrated.
       led_effects::showWaitingLED(color::magenta);
+      switchState(NEEDSCALIBRATION);
       return;
     }
     /**
@@ -174,8 +211,11 @@ namespace sensor {
     //NOTE: Data is available, but it's sometimes erroneous: the sensor outputs zero ppm but non-zero temperature and non-zero humidity.
     if (co2 <= 0) {
       // No measurement yet. Waiting.
+      switchState(BOOTUP);
       led_effects::showWaitingLED(color::blue);
       return false;
+    } else if (current_state != PREPARECALIBRATION) {
+      switchState(READY);
     }
 
     /**