Metadata-Version: 2.4
Name: neng-mag-logger
Version: 0.1.1
Summary: 3-axis magnetometer GUI with real-time plots and SCPI interface for NEnG 3Dmag instruments.
Author-email: Flavio Abreu Araujo <flavio.abreuaraujo@uclouvain.be>
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://gitlab.flavio.be/flavio/mag-logger
Project-URL: Repository, https://gitlab.flavio.be/flavio/mag-logger.git
Project-URL: Changelog, https://gitlab.flavio.be/flavio/mag-logger/-/blob/main/CHANGELOG.md
Project-URL: Bug-Tracker, https://gitlab.flavio.be/flavio/mag-logger/-/issues
Keywords: 3Dmag,magnetometer,SCPI,serial,MLX90393,TLV493D,matplotlib,tkinter,NEnG
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: neng-scpi-tools
Requires-Dist: pyserial>=3.5
Requires-Dist: matplotlib>=3.5
Requires-Dist: numpy>=1.21
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# neng-mag-logger

**Professional real-time magnetometer GUI for NEnG 3Dmag instruments.**

Built with Tkinter and matplotlib. Connects via USB serial or WiFi TCP to a 3Dmag
SCPI server running CircuitPython firmware, providing live magnetic field visualization
and optional CSV data logging.

---

## Features

- **Real-time live chart** — Bx, By, Bz field components (top) and |B| magnitude + temperature (bottom)
- **Live readings panel** — large numeric display of Bx, By, Bz (Gauss), |B|, Temperature (°C)
- **USB and WiFi connection** — Auto/Force USB/WiFi with auto-discovery of WiFi IP via USB
- **Sensor detection** — model, serial, firmware, sensor type (MLX90393/TLV493D/LIS2MDL/MMC5603), I2C address
- **MLX90393 profile switching** — FAST / DEFAULT / HIACC with one click
- **CSV data logging** — configurable output file, sampling rate (50–2000 ms), max buffer points
- **SCPI console** — direct command entry with Up/Down arrow history navigation
- **Dark / Light theme** — full matplotlib chart recolouring on toggle
- **Thread-safe** — all SCPI communication protected by `threading.Lock`

---

## Supported Sensors

| Sensor | Manufacturer | Range | Notes |
| ------ | ------------ | ----- | ----- |
| MLX90393 | Melexis | ±50000 µT | Profiles: FAST / DEFAULT / HIACC |
| TLV493D | Infineon | ±130 mT | Low power |
| LIS2MDL | STMicroelectronics | ±49.152 Gauss | Ultra-low power |
| MMC5603 | MEMSIC | ±30 Gauss | High resolution |
| DUMMY | — | — | Simulation (no hardware) |

---

## Installation

```bash
pip install neng-mag-logger
```

Or from source:

```bash
git clone https://gitlab.flavio.be/flavio/mag-logger.git
cd mag-logger
pip install -e .
```

---

## Usage

```bash
mag-logger              # Launch the GUI
mag-logger --version    # Show version
```

---

## Connection

All NEnG instruments support two transport modes, switchable at runtime in the GUI.

### USB Serial

| Setting | Value |
| ------- | ----- |
| Interface | USB CDC (ACM) — no driver needed on macOS / Linux |
| Baud rate | 115 200 |
| Framing | 8-N-1 |
| Terminator | `\n` (LF); `\r\n` (CRLF) accepted |
| Clients | One at a time |

### WiFi TCP

| Setting | Value |
| ------- | ----- |
| Port | 5025 (standard SCPI-over-TCP) |
| Protocol | Plain-text SCPI, `\n`-terminated |
| Clients | Multiple simultaneous clients supported |
| IP discovery | GUI auto-detects IP via USB (`:WIFI:IP?`) |

> WiFi requires the device to be in `PROD` or `DEV` USB mode (not `DEBUG`) and a WiFi
> network configured on the device.

---

## SCPI Quick Reference

### Measurement

| Command | Description |
| ------- | ----------- |
| `:READ?` | ASCII measurement: `<ts>,<bx>,<by>,<bz>,<temp>` |
| `:READ:BIN?` | Binary measurement (IEEE-488.2 block, 5×float32) |
| `:SENS:TYPE?` | Sensor type (MLX90393 / TLV493D / LIS2MDL / MMC5603 / DUMMY) |
| `:SENS:ADDR?` | Sensor I2C address |
| `:SENS:PROF?` | Active profile (MLX90393 only) |
| `:SENS:PROF FAST\|DEFAULT\|HIACC` | Set profile (MLX90393 only) |

### Connection & System

| Command | Description |
| ------- | ----------- |
| `:WIFI:AVAILABLE?` | `1` if WiFi hardware present, `0` otherwise |
| `:WIFI:CONNECTED?` | `1` if WiFi connected |
| `:WIFI:IP?` | Current WiFi IP address |
| `:WIFI:MAC?` | WiFi MAC address |
| `:WIFI:RSSI?` | Signal strength (dBm) |
| `:WIFI:CHANNEL?` | WiFi channel number |
| `:WIFI:SSID?` | Primary SSID |
| `:WIFI:SSID <name>` | Set primary network SSID |
| `:WIFI:PASSWORD <pass>` | Set primary network password |
| `:WIFI:HOSTNAME?` | Device hostname |
| `:WIFI:HOSTNAME <name>` | Set device hostname |
| `:WIFI:AUTOCONNECT?` | `1` if auto-connect on boot enabled |
| `:WIFI:AUTOCONNECT 1\|0` | Enable / disable auto-connect on boot |
| `:WIFI:STATUS?` | Compact status: `CONNECTED,<ssid>,<ip>,<rssi>` or `DISCONNECTED` |
| `:WIFI:SCAN?` | Scan nearby networks (JSON array: ssid, rssi, channel) |
| `:WIFI:NETWORK:LIST?` | List all configured networks (SSIDs only) |
| `:WIFI:NETWORK:ADD <ssid>,<pass>` | Add / update a fallback network |
| `:WIFI:NETWORK:REMOVE <ssid>` | Remove a fallback network |
| `:WIFI:CONFIG:SAVE` | Persist WiFi config to flash |
| `:WIFI:CONFIG:LOAD` | Reload WiFi config from flash |
| `:WIFI:ENABLE?` | `1` if WiFi radio enabled |
| `:WIFI:ENABLE 1\|0` | Enable / disable WiFi radio |
| `:WIFI:CONNECT` | Manually trigger WiFi connection |
| `:WIFI:DISCONNECT` | Disconnect from WiFi |
| `:SYST:CLIENTS?` | Connected TCP clients: `count,IP:port,status;...` |
| `:SYST:USB:MODE?` | USB mode (`PROD` / `DEV` / `DEBUG`) |
| `:SYST:USB:MODE <mode>` | Set USB mode (requires reboot) |
| `:SYST:VERS?` | Firmware version string |
| `:SYST:ERR?` | Error queue (`0,No error` when empty) |
| `:SYST:LOG? [n]` | Last n log lines (default 10, max 50) |
| `:SYST:RES` | Reboot the MCU |
| `:DIAG:PING?` | Returns `PONG` |
| `*IDN?` | Instrument identification |
| `*RST` | Reset to defaults |
| `*CLS` | Clear status registers |

> **WiFi config persistence:** CIRCUITPY must be unmounted (device in `PROD` mode) for
> `:WIFI:CONFIG:SAVE` to survive reboots. In `DEV`/`DEBUG` mode the filesystem is
> read-only from CircuitPython's side — saves apply only until the next power cycle.

---

## Development

```bash
pip install -e ".[dev]"
./verify-code.sh          # lint + tests
./verify-code.sh --fix    # auto-fix lint issues
```

---

## Release

```bash
./release.sh patch          # bug fix
./release.sh minor          # new feature
./release.sh minor --pypi   # also publish to PyPI
```

Tokens: `~/.config/mag-logger/release.env` (see `release.env.example`)

---

## License

Proprietary — (c) 2024-2026 Prof. Flavio ABREU ARAUJO, UCLouvain. All rights reserved.
