     digitalWrite(pin, LOW);
   }
 }
+
+int countColor(unsigned long millis, int shift) {
+  int t = (millis + shift) % crude_T;
+
+  if (0 <= t && t <= 2*crude_Ts) {
+    return 0;
+  } else if (3*crude_Ts <= t && t <= 5*crude_Ts) {
+    return crude_I;
+  } else if (2*crude_Ts <= t && t <= 3*crude_Ts) {
+    return (int)(crude_I * (t - 2*crude_Ts) / crude_Ts);
+  } else if (5*crude_Ts <= t && t <= 6*crude_Ts) {
+    return (int)(crude_I - crude_I * (t - 5*crude_Ts) / crude_Ts);
+  } else {
+    return 0;
+  }
+}

    String command = Serial.readStringUntil('\n');

    String output = processCommand(command);
    if (output.length() > 1) {
      Serial.println("+" + command);
      if (output != EMPTY_COMMAND_SUCCESS)
        Serial.println(output);

      blink(PIN_STATUS, 1);
    }
  }

  processLightMode();
}

void processLightMode() {
  switch(lightMode) {
    case LightMode::CRUDE:
      processCrudeLightMode();
      break;
  }
}

void processCrudeLightMode() {
  unsigned long m = millis() - lightModeStart;
  int r = countColor(m, 0*crude_Ts);
  int g = countColor(m, 2*crude_Ts);
  int b = countColor(m, 4*crude_Ts);
  setColor(1.5*r, g*0.6, b*0.6); // Some calibrations for LED color brightness
}

String processCommand(String command) {
