# MPPT Testbench

Unified tool for testing and tuning MPPT (Maximum Power Point Tracking) converters. Combines three bench instruments with direct STM32 firmware access for closed-loop parameter optimization.

| Instrument | Role | Interface |
|---|---|---|
| **ITECH IT6537D** | DC power supply (solar panel simulator, 80V/120A/6kW) | USB-TMC / SCPI via PyVISA |
| **Prodigit 3366G** | DC electronic load (600V/420A/6kW) | RS-232 (115200 8N1 RTS/CTS) |
| **HIOKI 3193-10** | Power analyzer (efficiency measurement) | GPIB via UsbGpib / PyVISA |
| **STM32G474** | Converter firmware (LVSolarBuck64) | Serial 460800 baud (debug protocol) |

## Wiring

```
                        +------------------+
  IT6500D  --(+/-)-->   |   MPPT Tracker   |  --(+/-)-->  Prodigit 3366G
                        |      (DUT)       |
  HIOKI Ch5 --(sense)-- |  Input    Output | --(sense)--  HIOKI Ch6
                        +------------------+
                              |
                          STM32 debug
                          serial (COM28)

  HIOKI EFF1 = P6 / P5 x 100%  (output power / input power)
```

## Installation

Requires Python 3.12+, NI-VISA runtime, and [uv](https://docs.astral.sh/uv/).

```bash
git clone --recurse-submodules https://git.b4l.co.th/B4L/mppt-testbench.git
cd mppt-testbench
uv sync
```

The debug console (inside `code64/`) has its own environment:

```bash
cd code64
uv sync
```

## Step-by-Step Guide

### 1. Connect and verify instruments

```bash
# Check all bench instruments respond
uv run bench identify

# Check STM32 responds (reads params + telemetry)
uv run bench stm32-read --stm32-port COM28
```

### 2. Configure instruments for MPPT testing

```bash
uv run bench setup
```

This sets wiring mode (1P2W), DC coupling, auto-ranging, efficiency formula (EFF1 = P6/P5), and display layout on the HIOKI.

### 3. Basic measurements

```bash
# Single reading from all instruments
uv run bench measure

# Continuous text monitoring with CSV export
uv run bench monitor --interval 1.0 --output data.csv
```

### 4. Launch the GUI

```bash
uv run bench-gui
```

The GUI provides:
- Real-time readouts from all three instruments
- Supply voltage/current control with ON/OFF indicators
- Load mode (CC/CR/CV/CP) and setpoint control
- HIOKI channel range selectors + degauss buttons
- Meter format selector (scientific/normal)
- 2D sweep panel with time estimate
- Live-updating power, efficiency, voltage, and current plots
- Console log panel

### 5. Run efficiency sweeps

#### Voltage sweep (1D)

```bash
uv run bench sweep \
  --v-start 30 --v-stop 100 --v-step 5 \
  --current-limit 20 \
  --load-mode CP --load-value 200 \
  --settle 2.0 -o voltage_sweep.csv
```

#### Load sweep at fixed voltage (1D)

```bash
uv run bench sweep-load \
  --voltage 60 --current-limit 20 \
  --i-start 0.5 --i-stop 15 --i-step 0.5 \
  --settle 2.0 -o load_sweep.csv
```

#### 2D voltage x load sweep (efficiency map)

```bash
# Constant Power mode
uv run bench sweep-vi \
  --v-start 60 --v-stop 100 --v-step 5 \
  --l-start 50 --l-stop 500 --l-step 50 \
  --load-mode CP --current-limit 20 \
  --settle 2.0 -o map_cp.csv

# Constant Current mode
uv run bench sweep-vi \
  --v-start 35 --v-stop 100 --v-step 5 \
  --l-start 0.5 --l-stop 15 --l-step 0.5 \
  --load-mode CC --current-limit 20 \
  --settle 2.0 -o map_cc.csv
```

### 6. Analyze sweep results

```bash
# Generate efficiency overlay, heatmap, and power loss plots (no instruments needed)
uv run bench plot-sweep map_cp.csv

# Save plots without displaying
uv run bench plot-sweep map_cp.csv --no-show -o plots/
```

Produces three PNG files:
- `*_efficiency.png` -- efficiency vs load, one line per voltage, best point marked
- `*_heatmap.png` -- 2D efficiency surface (voltage x load)
- `*_loss.png` -- power loss vs load, all voltages overlaid

### 7. Tune converter parameters

The tuning commands combine the testbench instruments (ground truth efficiency from HIOKI) with direct STM32 parameter writes to find optimal settings.

#### Read current STM32 state

```bash
uv run bench stm32-read
```

#### Write a single parameter

```bash
uv run bench stm32-write --param dt_10_20A --value 20
```

#### Sweep a parameter to find the optimum

Sweeps a parameter from start to stop, measuring HIOKI efficiency + STM32 telemetry at each step. Plots the result.

```bash
# Optimize deadtime for the 10-20A bracket at 300W
uv run bench tune-param \
  --param dt_10_20A --start 14 --stop 40 --step 1 \
  --voltage 60 --current-limit 20 \
  --load-mode CP --load-value 300 \
  --settle 3.0 -o dt_tune.csv

# Tune Vfly proportional gain
uv run bench tune-param \
  --param vfly_kp --start -2 --stop 2 --step 0.1 \
  --voltage 60 --current-limit 20 \
  --load-mode CP --load-value 200 \
  --settle 3.0
```

#### Auto-optimize all deadtime brackets

Automatically sweeps deadtime for each of the 6 current brackets (0-3A, 3-5A, 5-10A, 10-20A, 20-30A, 30-45A), setting an appropriate load for each bracket.

```bash
# Sweep and report best values
uv run bench tune-deadtime \
  --voltage 60 --current-limit 20 --load-mode CP \
  --dt-start 14 --dt-stop 50 --dt-step 1 \
  -o deadtime_results.csv

# Sweep, report, and apply best values to STM32
uv run bench tune-deadtime \
  --voltage 60 --current-limit 20 --load-mode CP \
  --load-values 20,50,100,250,400,600 \
  --apply
```

### 8. Shade / irradiance profile simulation

Simulate cloud passing or partial shading with a CSV-driven sequence:

```bash
uv run bench shade-profile \
  --profile samples/cloud_pass.csv \
  --settle 2.0 -o shade_results.csv
```

Profile CSV format: `time,voltage,current_limit,load_mode,load_value`

### 9. Real-time debug console (TUI)

For live monitoring and parameter tuning via the Textual terminal UI:

```bash
cd code64
uv run debug-console COM28
```

Keybindings: `p` ping, `r` read params, `f` toggle EMA filter, `l` show log path, `q` quit.

### 10. Direct instrument control

```bash
# Supply
uv run bench supply set --voltage 48 --current 10
uv run bench supply on
uv run bench supply off

# Load
uv run bench load set --mode CP --value 200
uv run bench load on
uv run bench load off

# Emergency shutdown (load first, then supply)
uv run bench safe-off
```

## CLI Reference

```
uv run bench [-h] [--supply-address ADDR] [--load-port PORT] [--load-baud BAUD]
            [--meter-address ADDR] [--timeout MS]
            [--stm32-port PORT] [--stm32-baud BAUD]
            {command}
```

| Command | Description |
|---|---|
| `identify` | Show identity and status of all instruments |
| `setup` | Configure all instruments for MPPT testing |
| `measure` | Single measurement from all three instruments |
| `monitor` | Continuous text monitoring with optional CSV |
| `live` | Real-time 4-panel matplotlib graph |
| `sweep` | Voltage sweep with efficiency recording |
| `sweep-load` | Load current sweep at fixed voltage |
| `sweep-vi` | 2D voltage x load sweep (efficiency map) |
| `efficiency` | Averaged efficiency at a fixed operating point |
| `shade-profile` | Run shade/irradiance profile from CSV |
| `plot-sweep` | Generate analysis plots from sweep CSV (offline) |
| `stm32-read` | Read all STM32 parameters and telemetry |
| `stm32-write` | Write a parameter to the STM32 |
| `tune-param` | Sweep an STM32 parameter while measuring efficiency |
| `tune-deadtime` | Auto-optimize deadtime for each current bracket |
| `supply` | Direct IT6500D control (on/off/set) |
| `load` | Direct Prodigit 3366G control (on/off/set) |
| `safe-off` | Emergency shutdown (load first, then supply) |

### Global Options

| Option | Default | Description |
|---|---|---|
| `--supply-address` | auto-detect | IT6500D VISA address |
| `--load-port` | `COM1` | Prodigit 3366G serial port |
| `--load-baud` | `115200` | Prodigit 3366G baud rate |
| `--meter-address` | auto-detect | HIOKI 3193-10 VISA address |
| `--timeout` | `5000` | VISA timeout in milliseconds |
| `--stm32-port` | `COM28` | STM32 debug serial port |
| `--stm32-baud` | `460800` | STM32 debug baud rate |

## Tunable STM32 Parameters

| Parameter | Type | Range | Description |
|---|---|---|---|
| `VREF` | uint16 | 3100-3700 | ADC reference voltage |
| `vfly_kp` | float | -10 to 10 | Vfly proportional gain |
| `vfly_ki` | float | -10 to 10 | Vfly integral gain |
| `vfly_clamp` | uint16 | 0-10000 | Vfly integrator clamp |
| `vfly_active` | uint8 | 0-1 | Vfly loop enable |
| `cc_target` | float | 0-60000 | CC target (mA) |
| `cc_gain` | float | -1 to 1 | CC proportional gain |
| `cc_active` | int32 | 0-1 | CC loop enable |
| `mppt_step` | float | 0-10000 | MPPT P&O step size (mA) |
| `mppt_deadband` | float | 0-1 | MPPT deadband |
| `mppt_active` | int32 | 0-1 | MPPT loop enable |
| `dt_0_3A` | uint8 | 14-200 | Deadtime 0-3A (HRTIM ticks) |
| `dt_3_5A` | uint8 | 14-200 | Deadtime 3-5A |
| `dt_5_10A` | uint8 | 14-200 | Deadtime 5-10A |
| `dt_10_20A` | uint8 | 14-200 | Deadtime 10-20A |
| `dt_20_30A` | uint8 | 14-200 | Deadtime 20-30A |
| `dt_30_45A` | uint8 | 14-200 | Deadtime 30-45A |

## CSV Output Format

Sweep CSV files contain:

| Column | Description |
|---|---|
| `voltage_set` | Supply voltage setpoint (V) |
| `current_limit` | Supply current limit (A) |
| `load_setpoint` | Load setpoint value (A for CC, W for CP) |
| `supply_V/I/P` | Supply measured voltage, current, power |
| `load_V/I/P` | Load measured voltage, current, power |
| `input_power` | HIOKI P5 -- power into MPPT tracker (W) |
| `output_power` | HIOKI P6 -- power out of MPPT tracker (W) |
| `efficiency` | HIOKI EFF1 -- P6/P5 x 100 (%) |

Tuning CSV files additionally contain `param_name`, `param_value`, and STM32 telemetry columns (`stm_vin`, `stm_vout`, `stm_iin`, `stm_iout`, `stm_eff`, `stm_vfly`, `stm_etemp`).

## Project Structure

```
mppt-testbench/
+-- IT6500D/              git submodule -- DC power supply driver
+-- PRODIGIT-3366G/       git submodule -- electronic load driver
+-- HIOKI-3193-10/        git submodule -- power analyzer driver
+-- testbench/
|   +-- __init__.py       exports MPPTTestbench
|   +-- bench.py          orchestrator (sweeps, measurement, auto-range wait)
|   +-- cli.py            unified CLI entry point
|   +-- gui.py            tkinter GUI with live plots
|   +-- gui_workers.py    background instrument I/O thread
|   +-- stm32_link.py     synchronous STM32 debug protocol interface
|   +-- tuner.py          automated tuning routines (param sweep, deadtime opt)
+-- code64/
|   +-- Core/             STM32G474 firmware (C)
|   +-- Drivers/          HAL drivers
|   +-- debug_console/    Textual TUI for live debugging
|   +-- pyproject.toml    uv-compatible package config
+-- samples/              shade profile CSV examples
+-- pyproject.toml        package config, entry points: bench, bench-gui
```

## Dependencies

- Python >= 3.12
- [PyVISA](https://pyvisa.readthedocs.io/) + [pyvisa-py](https://pyvisa.readthedocs.io/projects/pyvisa-py/)
- [pyserial](https://pyserial.readthedocs.io/)
- [matplotlib](https://matplotlib.org/)
- [numpy](https://numpy.org/)
- NI-VISA runtime (for GPIB/USB-TMC communication)
- [Textual](https://textual.textualize.io/) (debug console only, in code64/)
