   float B;
 };
 
+struct Calibration {
+  // Luminous fluxes
+  float redLum;
+  float greenLum;
+  float blueLum;
+  float maxLum;
+  
+  // LED u', v' coordinates
+  Luv redUv;
+  Luv greenUv;
+  Luv blueUv;
+  
+  // Mixing fit coefficients
+  float redToGreenFit[3];
+  float greenToBlueFit[3];
+  float blueToRedFit[3];
+
+  // Checksum
+  uint32_t crc32;
+};
+
 // Is the light on?
-bool onOff_ = false;
+bool onOff_;
 
 // Raw PWM values
 RGB raw_;

// Correlated color temperature (in Kelvins)
int T_;


// Calibration coefficients with default values

// Luminous fluxes
float redLum_ = 0.5;
float greenLum_ = 1.0;
float blueLum_ = 0.75;
float maxLum_ = redLum_ + greenLum_ + blueLum_;

// LED u', v' coordinates
Luv redUv_ = {100, 0.5535, 0.5170};
Luv greenUv_ = {100, 0.0373, 0.5856};
Luv blueUv_ = {100, 0.1679, 0.1153};

// Mixing fit coefficients
float redToGreenFit_[] = {2.9658, 0.0, 1.9658};
float greenToBlueFit_[] = {1.3587, 0.0, 0.3587};
float blueToRedFit_[] = {-0.2121, 0.2121, 0.2121};



/**
 * Utility functions

  return level;
}

/**
 * CCIT CRC-32 (Autodin II) Polynomial
 */
uint32_t CRC32 (uint32_t crc, uint8_t *buf, uint16_t len) {
  while (len--) {
    crc = crc ^ *buf++;
    for (uint8_t i = 0; i < 8; ++i) {
      if (crc & 1) {
        crc = (crc >>1) ^ 0xEDB88320;
      } else {
        crc = crc >> 1;
      }
    }
  }
}

/**
 * Calculate CRC32 for calibration data
 */
uint32_t calibrationCRC32 (Calibration *cal) {
  // Non crc32 parts of calibration structure are 22 floats = 88 bytes
  const uint8_t len = 88;
  // Initial value for CRC
  uint32_t crc32 = 0xFFFFFFFF;
  // temporary data buffer
  uint8_t buf[len]; 
  
  // Copy calibration data to byte array
  memcpy(buf, cal, len);
  
  // Calculate CRC
  crc32 = CRC32(crc32, buf, len);

  return crc32;
}

/**
 * Internal getters and setters
