1. Colorimeter Specifications
Authors: Richard Hughes <richard@hughsie.com>, <you!>
Note: Richard Hughes has only used USB traces obtained from the windows binary drivers for reverse engineering, and the Argyllcms debug output on Linux. Richard has not studied the Argyllcms source code, or copied code from other projects that reverse engineered the hardware from decompiling the windows driver.
This specification is also completed by other people in the community that are happy to fill in the blanks in the hardware specification and agree not to contribute GcmSensor code to gnome-color-manager if they look at reverse engineered sources. If you're at all unclear why this is required, please ask me on private email.
This is a document detailing certain elements of reverse engineered hardware, and may be incomplete, or just plain wrong. The authors can in no way be held accountable for hardware damage caused by using this specification document.
This document is licensed under the Public Domain. All trademarks and copyrights are property of their respective owners. All rights reserved.
Contents
2. Gretag-Macbeth AG Huey
2.1. Introduction
The Huey is a colorimeter device made my a series of manufacturers, notably X-Rite and now Pantone. The device contains a red, green and blue sensor and allow a computer to read values from the sensor to accurately measure color. It also contains an ambient light sensor.
2.2. Commands
The Huey is actually a very simple device. By sending a variable-width (up to 8 bytes) command to request=0x09, value=0x0200, index=0, and then reading back from interrupt endpoint 0x81 a variable-width (up to 8 bytes) response the device can be instructed to perform a measurement or read back values. The returned response always contains the status value as the first byte, and the command id as the second byte. The data follows after this.
2.2.1. Command 0x00 (GetStatus)
Input: |
none |
Output: |
"Cir001" for all okay, "locked" if the device is locked. |
Notes: |
TODO: find the purpose of a locked device |
2.2.2. Command 0x02 (ReadGreen)
Input: |
none |
Output: |
a 16bit BE value in reply[3,4] |
Notes: |
Read the green sample data -- this doesn't do a sensor read, so we have to do MeasureRGB before this command |
2.2.3. Command 0x03 (ReadBlue)
Input: |
none |
Output: |
a 16bit BE value in reply[3,4] |
Notes: |
Read the blue sample data -- this doesn't do a sensor read, so we have to do MeasureRGB before this command |
2.2.4. Command 0x08 (RegisterRead)
Input: |
8bit byte in request[1] for the eeprom address to read |
Output: |
a 16 bit value in reply[2] |
Notes: |
You can only ask for one value at a time |
2.2.5. Command 0x0e (Unlock)
Input: |
"GrMbked" which can be found in the EEPROM. |
Output: |
Just success or failure |
Notes: |
TODO: We don't know why a device gets locked.TODO: maybe only the first 4 bytes of the unlock string matter.... |
2.2.6. Command 0x13 (MeasureRGB-CRT)
Input: |
Not sure |
Output: |
Not sure |
Notes: |
This samples a color and returns the red component. |
2.2.7. Command 0x16 (MeasureRGB)
Input: |
request[1,2] gain control for red{{{request[3,4] gain control for greenrequest[5,6] gain control for red |
Output: |
a 16 bit value in reply[3] |
Notes: |
This samples a color and returns the red component. This command takes quite some time to execute, longer for black than white. TODO: The gain controls seem to be set to tend to a certain number, which we still don't understand fully. |
2.2.8. Command 0x17 (GetAmbient)
Input: |
The screen type, request[2] set to 0x00 for LCD and 0x02 for CRT |
Output: |
A 16 bit value in reply[5,6] TODO: no idea if this needs to be scaled with a device calibration constant |
Notes: |
This command often needs to be retried, possibly because taking the ambient reading takes so long. TODO: find out why... |
2.2.9. Command 0x18 (SetLeds)
Input: |
request[2] LED mask, where 0x00 is all on and 0x0f is all off |
Output: |
the led mask again in reply[2] |
Notes: |
This seems to be inverted from what you expect. It's a bitfield, and all combinations seem to work. |
2.3. EEPROM Register Map
serial_number |
0x00 (4 bytes) |
matrix1 |
0x04 (36 bytes) |
manufacture_time1 |
0x32 (4 bytes, typically ~2009) |
matrix2 |
0x36 (36 bytes) |
manufacture_time2 |
0x5a (4 bytes, typically ~2009) |
calib_vector |
0x67 (12 bytes) |
unlock |
0x7a (5 bytes) |
calib_value |
0x94 (4 bytes) |
TODO: need some more values as there are holes in the address space, and also need better names about what the constants are and what they do.
2.4. Reading the ambient light value
Send command GetAmbient with the correct display type. Get the reply and read a 16 bit unsigned integer and divide it by a magic constant (TODO: which is...) to get the value in Lux.
2.5. Reading a spot color
Send command MeasureRgb with threshold values of [1, 1, 1] read back the result, and also get the green and blue values from ReadGreen and ReadBlue.
Scale these values with a constant (TODO) and then use these as the next multiplier.
Resend the MeasureRgb command with the new threshold values, and read back the reply, and get the blue and green data. Scale the data with the thresolds we set before. The gain on each channel is probably the number of pulses in a light to frequency converter for a given time value.
Multiply the device RGB result of the second sample with a calibration matrix (TODO: which one?) and multiply by a largeish number (TODO: which has the value...) to get the value in XYZ.
TODO: we probably need to use dark coefficient values, and this is probably in the eeprom somewhere.
2.6. Unanswered questions
- Why are there two calibration matrices available in the device
- How do we convert from the device RGB color to XYZ color accurately
- What is the calibration constant to convert from device ambiance to Lux?
- Why do we have to scale the XYZ resulting value by such a large number
- Where are the ambient light calibration value, and RGB dark values on the sensor, and how do we apply them?
2.7. See also
http://git.gnome.org/browse/gnome-color-manager/tree/libcolor-glib/gcm-sensor-huey.c
http://www.pantone.com/pages/Products/Product.aspx?pid=562&ca=2
3. Gretag-Macbeth AG ColorMunki
3.1. Introduction:
The ColorMunki is a photospectrometer device capable of reading spot colors, ambient light values, calibration strips and also supports internal self calibration. A central dial rotates between different modes to position the sensor in the correct place. It is widely used by artists wanting to match spot colors and by designers wanting to create display and print profiles.
3.2. Commands
3.2.1. Command 0x81 (GetEepromData)
Input: |
8 bytes, request[0] is 32bit LE address, request[4] is 32bit size requested. |
Output: |
none |
Notes: |
We request the EEPROM, rather than trying to read it directly. This command triggers a bulk transfer on the same address of the size of data. |
3.2.2. Command 0x86 (GetFirmwareParameters)
Input: |
none |
Output: |
24 bytes, of:major.minor firmware revision in uint32 reply[0x00] and reply[0x04], tickduration (TODO: what?) in reply[0x8], min_int (TODO: what?) in reply[0x0c]EEPROM blocks in reply[0x10], EEPROM blocksize in reply[0x14] |
Notes: |
Get parameters from the firmware.The EEPROM appears to be in blocks, typically two. |
3.2.3. Command 0x85 (GetVersionString)
Input: |
none |
Output: |
36 byte string of an ASCII version string |
Notes: |
none |
3.2.4. Command 0x87 (RefreshState)
Input: |
none |
Output: |
2 bytes, of:current dial position in reply[0], the button pressed value in reply[1] |
Notes: |
none |
3.2.5. Command 0x83 (GetEvent)
Input: |
none |
Output: |
8 bytes, of:event type in reply[0], uint32 timestamp in reply[4] |
Notes: |
This has to be done in a mainloop event, or in a thread to avoid blocking.The GetEvent call can be done in the reply of the GetEvent loop to ensure button presses and dial rotations continue to be noticed. |
3.3. EEPROM Register Map
serial_number |
0x18 (10 bytes) |
3.4. Reading the ambient light value
No idea.
3.5. Reading a spot color
No idea.