361 lines
14 KiB
Markdown
361 lines
14 KiB
Markdown
# HPCS 6500 USB Protocol Reference
|
||
|
||
Reverse-engineered from USB packet captures of the vendor software.
|
||
|
||
## Device Overview
|
||
|
||
The HPCS 6500 is a spectrophotometer / integrating sphere system for LED and
|
||
light source testing. It includes a built-in programmable AC/DC power supply.
|
||
|
||
**Capabilities:**
|
||
- Spectral power distribution (380-1050 nm, 350 points)
|
||
- Photometric values (lumen, luminous efficacy, CCT, CRI Ra/R1-R15)
|
||
- Chromaticity coordinates (CIE xy, uv, u'v')
|
||
- Radiometric flux (total, UV, blue, yellow, red, far-red, IR)
|
||
- CIE 1931 tristimulus (X, Y, Z), TLCI-2012, SDCM
|
||
- Electrical parameters (voltage, current, power, power factor, frequency)
|
||
- Harmonics analysis (50 harmonics voltage/current %, UThd, AThd, waveforms)
|
||
- Built-in power supply: AC 100-240 V / 50-60 Hz, DC 1-60 V / 0-5 A
|
||
|
||
**Connection:**
|
||
- USB interface via STM32 Virtual COM Port (VID `0483`, PID `5741`)
|
||
- Appears as a serial port (e.g. COM42 on Windows)
|
||
- Baud rate: 115200
|
||
|
||
## Frame Format
|
||
|
||
Every command and response starts with the sync byte `0x8C` followed by a
|
||
command ID byte. The device echoes the command ID in the response. All
|
||
multi-byte numeric values are **little-endian**.
|
||
|
||
```
|
||
TX: 8C <cmd> [payload...]
|
||
RX: 8C <cmd> [data...]
|
||
```
|
||
|
||
Write commands receive a 2-byte ACK (`8C <cmd>`). Read commands return
|
||
variable-length data after the 2-byte header.
|
||
|
||
## Command Table
|
||
|
||
| Cmd | Direction | TX len | RX len | Description |
|
||
|------|-----------|--------|----------------|--------------------------------------|
|
||
| `00` | read | 2 | 16 | Identify device |
|
||
| `01` | write | 6 | 2 | Set integration time (uint32 LE, µs) |
|
||
| `03` | read | 2 | 9 | Poll instrument state |
|
||
| `05` | read | 2 | 7 | Status check |
|
||
| `0E` | write | 3 | 2 | Start (`01`) / Stop (`02`) measuring |
|
||
| `13` | read | 2 | 4 hdr + 3904 | Read measurement block |
|
||
| `25` | write | 2 | 2 | Reset instrument |
|
||
| `26` | read | 2 | 196 | Read instrument ranges |
|
||
| `2A` | read | 2 | 122 | Read device configuration |
|
||
| `72` | write | 3 | 2 | PSU output on (`00`) / off (`01`) |
|
||
| `73` | write | 7 | 2 | Set DC parameter (sub + float32) |
|
||
| `77` | read | 2 | 4 hdr + 1584 | Read electrical / harmonics block |
|
||
| `78` | write | 7 | 2 | Set AC parameter (sub + float32) |
|
||
| `79` | read | 2 | 20 | Read power supply settings |
|
||
| `7A` | write | 3 | 2 | Set output mode (`00`=AC, `01`=DC) |
|
||
| `7B` | read | 2 | 2 | Read test config |
|
||
| `2B` | write | var | 2 | Write test config (see below) |
|
||
|
||
## Measurement Sequences
|
||
|
||
### Single-Shot Measurement
|
||
|
||
The vendor software uses this flow for one-off readings. No explicit start
|
||
command is needed — the stop command (`8C 0E 02`) triggers a single reading.
|
||
|
||
```
|
||
1. TX 8C 00 -> Identify (expect "HPCS6500" in response)
|
||
2. TX 8C 2A -> Read device config
|
||
3. TX 8C 01 <uint32> -> Set integration time (µs), 0 = auto
|
||
4. TX 8C 0E 02 -> Stop / trigger single reading
|
||
5. TX 8C 03 -> Poll state until byte[2] = 0x01 (data ready)
|
||
6. TX 8C 13 -> Read measurement data (3904 bytes)
|
||
7. TX 8C 77 -> Read electrical data (1584 bytes)
|
||
8. TX 8C 25 -> Reset instrument
|
||
```
|
||
|
||
### Continuous Measurement
|
||
|
||
```
|
||
1. TX 8C 00 -> Identify (expect "HPCS6500" in response)
|
||
2. TX 8C 79 -> Read current PSU settings
|
||
3. TX 8C 7A <mode> -> Set output mode (00=AC, 01=DC)
|
||
4. TX 8C 78/73 ... -> Configure voltage/frequency/current as needed
|
||
5. TX 8C 01 <uint32> -> Set integration time (µs), or skip for auto
|
||
6. TX 8C 72 00 -> Turn PSU output ON
|
||
7. TX 8C 0E 01 -> Start continuous measurement
|
||
8. TX 8C 03 -> Poll state until byte[2] = 0x01 (data ready)
|
||
9. TX 8C 13 -> Read measurement data (3904 bytes)
|
||
10. TX 8C 77 -> Read electrical data (1584 bytes)
|
||
(repeat 8-10 for continuous readings, ~550 ms per cycle)
|
||
11. TX 8C 0E 02 -> Stop measurement
|
||
12. TX 8C 72 01 -> Turn PSU output OFF
|
||
13. TX 8C 25 -> Reset instrument
|
||
```
|
||
|
||
## State Polling (`8C 03`)
|
||
|
||
9-byte response: `8C 03 <b2> <b3> <b4> <b5> <b6> <b7> <b8>`
|
||
|
||
| Byte | Meaning |
|
||
|------|------------------------------------------------------|
|
||
| b2 | Data flag: `00` = no new data, `01` = data available |
|
||
| b3 | Mirrors b2 |
|
||
| b4 | Always `00` |
|
||
| b5 | State: `04` = idle, `01` = measuring |
|
||
| b6 | Always `00` |
|
||
| b7 | Always `00` |
|
||
| b8 | Always `01` |
|
||
|
||
## Measurement Block (`8C 13` — 3904 bytes)
|
||
|
||
The response has a 4-byte transport header (`8C 13 0F 40`) followed by a
|
||
3904-byte payload. All floats are IEEE 754 single-precision, little-endian.
|
||
|
||
### Device Header (offset 0-35)
|
||
|
||
| Offset | Size | Type | Field |
|
||
|--------|------|--------|---------------------------|
|
||
| 0 | 10 | ASCII | Device ID (`"HPCS6500"`) |
|
||
| 10 | 26 | — | Internal calibration data |
|
||
|
||
### Photometric (offset 36-75)
|
||
|
||
| Offset | Type | Field | Unit | Example |
|
||
|--------|---------|------------------------|---------|---------|
|
||
| 36 | float32 | Luminous flux | lm | 479.57 |
|
||
| 40 | float32 | Luminous efficacy | lm/W | 57.05 |
|
||
| 44 | float32 | Correlated color temp | K | 5653 |
|
||
| 48 | float32 | Duv | — | 0.00553 |
|
||
| 52 | float32 | CIE x | — | 0.3289 |
|
||
| 56 | float32 | CIE y | — | 0.3489 |
|
||
| 60 | float32 | CIE u | — | 0.2015 |
|
||
| 64 | float32 | CIE v | — | 0.3206 |
|
||
| 68 | float32 | CIE u' | — | 0.2015 |
|
||
| 72 | float32 | CIE v' | — | 0.4809 |
|
||
|
||
### Color Rendering (offset 76-143)
|
||
|
||
| Offset | Type | Field | Example |
|
||
|--------|---------|-------|---------|
|
||
| 76 | float32 | SDCM | 4.71 |
|
||
| 80 | float32 | Ra | 83.0 |
|
||
| 84-140 | float32 | R1-R15 (4 bytes each) | R1=82 .. R15=76 |
|
||
|
||
R*n* is at offset `80 + n × 4` (R1 at 84, R2 at 88, ..., R15 at 140).
|
||
|
||
### Radiometric (offset 144-175)
|
||
|
||
| Offset | Type | Field | Unit | Example |
|
||
|--------|---------|--------------------|------|----------|
|
||
| 144 | float32 | Total radiant flux | mW | 1491.256 |
|
||
| 148 | float32 | UV flux | mW | 0.000 |
|
||
| 152 | float32 | Blue flux | mW | 469.836 |
|
||
| 156 | float32 | Yellow flux | mW | 679.454 |
|
||
| 160 | float32 | Red flux | mW | 330.864 |
|
||
| 164 | float32 | Far-red flux | mW | 11.462 |
|
||
| 168 | float32 | IR flux | mW | 0.000 |
|
||
| 172 | float32 | Total (duplicate) | mW | 1491.256 |
|
||
|
||
### CIE Tristimulus & Sensor (offset 224-255)
|
||
|
||
| Offset | Type | Field | Example |
|
||
|--------|---------|----------------|---------|
|
||
| 224 | float32 | CIE 1931 X | 661.9 |
|
||
| 228 | float32 | CIE 1931 Y | 702.15 |
|
||
| 232 | float32 | CIE 1931 Z | 648.535 |
|
||
| 236 | float32 | TLCI-2012 | 68 |
|
||
| 244 | float32 | Peak Signal | 53088 |
|
||
| 248 | float32 | Dark Signal | 2267 |
|
||
| 252 | float32 | Compensate lvl | 2834 |
|
||
|
||
### Timestamps (offset 272-291)
|
||
|
||
| Offset | Size | Type | Field | Example |
|
||
|--------|------|-------|-----------|----------------|
|
||
| 272 | 11 | ASCII | Test date | `2026-02-04\0` |
|
||
| 283 | 9 | ASCII | Test time | `16:04:17\0` |
|
||
|
||
### Spectral Data (offset 432-1831)
|
||
|
||
| Offset | Type | Field |
|
||
|-----------|---------------|----------------------------------|
|
||
| 430-431 | uint16 | Spectrum header (zero) |
|
||
| 432-1831 | float32 × 350 | Spectral irradiance (µW/cm²/nm) |
|
||
|
||
The 350 floats cover **380 nm to 1050 nm** at ~1.92 nm steps
|
||
((1050-380) / (350-1) = 1.917 nm/step). Values are absolute spectral
|
||
irradiance; the vendor software normalizes by dividing by the peak value.
|
||
|
||
### Unmapped Regions
|
||
|
||
Offsets 176-223, 256-271, and 1832-3903 contain additional data not yet
|
||
fully mapped. They likely hold extended parameters visible in the vendor
|
||
software's advanced views.
|
||
|
||
## Electrical / Harmonics Block (`8C 77` — 1584 bytes)
|
||
|
||
The response has a 4-byte transport header (`8C 77 06 30`) followed by a
|
||
1584-byte payload.
|
||
|
||
### Basic Electrical (always present)
|
||
|
||
| Offset | Type | Field | Example |
|
||
|--------|---------|------------------|---------|
|
||
| 0-7 | — | Reserved (zero) | — |
|
||
| 8 | float32 | Voltage | 230.30 V|
|
||
| 12 | float32 | Current | 0.065 A |
|
||
| 16 | float32 | Active power | 8.406 W |
|
||
| 20 | float32 | Frequency | 50.02 Hz|
|
||
| 24 | float32 | Power factor | 0.558 |
|
||
|
||
### Waveforms (when harmonics enabled, offset 28-543)
|
||
|
||
| Offset | Type | Count | Field |
|
||
|---------|--------------|-------|------------------------|
|
||
| 30-285 | int16 LE | 128 | Voltage waveform |
|
||
| 286-541 | int16 LE | 128 | Current waveform |
|
||
|
||
Each waveform contains 128 signed 16-bit samples representing one complete
|
||
AC cycle.
|
||
|
||
### Voltage Harmonics (when harmonics enabled, offset 544-747)
|
||
|
||
| Offset | Type | Count | Field |
|
||
|---------|--------------|-------|----------------------------|
|
||
| 544-740 | float32 | 50 | H1..H50 voltage (% of H1) |
|
||
| 744 | float32 | 1 | UThd (%) |
|
||
|
||
H1 = 100.0%. H*n* is at offset `544 + (n-1) * 4`.
|
||
|
||
### Current Harmonics (when harmonics enabled, offset 800-1003)
|
||
|
||
| Offset | Type | Count | Field |
|
||
|---------|--------------|-------|----------------------------|
|
||
| 800-996 | float32 | 50 | H1..H50 current (% of H1) |
|
||
| 1000 | float32 | 1 | AThd (%) |
|
||
|
||
H1 = 100.0%. H*n* is at offset `800 + (n-1) * 4`.
|
||
|
||
### Harmonics Detection
|
||
|
||
When harmonics is disabled, offsets 28+ are all zero. To detect whether
|
||
harmonics data is present, check if the float32 at offset 544 equals 100.0
|
||
(H1 voltage fundamental = 100%).
|
||
|
||
## Power Supply Control
|
||
|
||
### Output On/Off (`8C 72`)
|
||
|
||
```
|
||
TX: 8C 72 00 -> Output ON
|
||
TX: 8C 72 01 -> Output OFF
|
||
RX: 8C 72 -> ACK
|
||
```
|
||
|
||
The PSU output must be turned on before taking measurements.
|
||
|
||
### Output Mode (`8C 7A`)
|
||
|
||
```
|
||
TX: 8C 7A 00 -> AC mode
|
||
TX: 8C 7A 01 -> DC mode
|
||
RX: 8C 7A -> ACK
|
||
```
|
||
|
||
### AC Parameters (`8C 78`)
|
||
|
||
```
|
||
TX: 8C 78 00 <float32 LE> -> Set voltage (V), range 100-240
|
||
TX: 8C 78 01 <float32 LE> -> Set frequency (Hz), 50 or 60
|
||
RX: 8C 78 -> ACK
|
||
```
|
||
|
||
### DC Parameters (`8C 73`)
|
||
|
||
```
|
||
TX: 8C 73 00 <float32 LE> -> Set current limit (A), range 0-5
|
||
TX: 8C 73 01 <float32 LE> -> Set voltage (V), range 1-60
|
||
RX: 8C 73 -> ACK
|
||
```
|
||
|
||
### Read Settings (`8C 79`)
|
||
|
||
20-byte response: `8C 79` + 18 bytes payload.
|
||
|
||
| Offset | Type | Field |
|
||
|--------|---------|--------------------|
|
||
| 0 | float32 | AC voltage (V) |
|
||
| 4 | float32 | AC frequency (Hz) |
|
||
| 8 | float32 | DC voltage (V) |
|
||
| 12 | float32 | DC current (A) |
|
||
| 16 | uint8 | Mode (0=AC, 1=DC) |
|
||
| 17 | uint8 | Marker (0xFF) |
|
||
|
||
### Integration Time (`8C 01`)
|
||
|
||
```
|
||
TX: 8C 01 <uint32 LE> -> Integration time in microseconds
|
||
RX: 8C 01 -> ACK
|
||
```
|
||
|
||
Common values: 200000 (200 ms), 500000 (500 ms), 1000000 (1000 ms).
|
||
|
||
## Identify (`8C 00`)
|
||
|
||
16-byte response: `8C 00` + `"HPCS6500\0\0"` + 4 bytes device metadata.
|
||
|
||
## Test Configuration (`8C 2B`)
|
||
|
||
The vendor software sends this before each measurement to configure test
|
||
parameters. It consists of two sub-commands (sub `00` and sub `01`).
|
||
|
||
### Sub 00 — Test Parameters
|
||
|
||
```
|
||
TX: 8C 2B 00 <~58 bytes> -> Write test parameters
|
||
RX: 8C 2B -> ACK
|
||
```
|
||
|
||
Known fields within the sub 00 payload (offsets from start of payload after sub byte):
|
||
|
||
| Offset | Type | Field | Example |
|
||
|--------|---------|---------------------|----------------|
|
||
| 15 | float32 | Frequency? | 50.0 |
|
||
| 35-55 | float32 | Five x 1.0 values | 1.0 each |
|
||
| 55 | float32 | Scale factor? | 0.5 |
|
||
|
||
### Sub 01 — Auto-PSU Flag
|
||
|
||
```
|
||
TX: 8C 2B 01 <~44 bytes> -> Write test config
|
||
RX: 8C 2B -> ACK
|
||
```
|
||
|
||
| Offset | Type | Field |
|
||
|--------|-------|----------------------------------------|
|
||
| 37 | uint8 | Auto-PSU: `01` = on with test, `00` = off |
|
||
|
||
When auto-PSU is enabled (`01`), the device automatically turns the PSU on
|
||
before measuring and off after. When disabled (`00`), the PSU must be
|
||
controlled manually via `8C 72`.
|
||
|
||
### Read Configuration (`8C 7B`)
|
||
|
||
```
|
||
TX: 8C 7B -> Read current test config
|
||
RX: 8C 7B -> ACK (config is returned via subsequent 8C 2B reads?)
|
||
```
|
||
|
||
## Notes
|
||
|
||
- The instrument computes all photometric, colorimetric, and radiometric
|
||
values internally. The host software only reads and displays results.
|
||
- During continuous measurement, the host polls `8C 03` and reads `8C 13`
|
||
+ `8C 77` on each cycle (~550 ms per reading).
|
||
- All float values are IEEE 754 single-precision (4 bytes), little-endian.
|
||
- All integer values are unsigned little-endian unless noted (waveform
|
||
samples are signed int16).
|