first commit

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 13:57:58 +07:00
commit 0f09c70215
7 changed files with 1595 additions and 0 deletions

299
PROTOCOL.md Normal file
View File

@@ -0,0 +1,299 @@
# 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 output mode |
## Measurement Sequence
```
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 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.
## 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).