Files
HPCS6500-py/PROTOCOL.md

361 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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).