Initial commit: merge nuescan, pymso, pybbd202, and pypewpewhops into scanengine-3

- Merged four separate hardware control projects into unified platform
- Created unified requirements.txt with all dependencies
- Added comprehensive .gitignore
- Added project overview README

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Thomas Ales [M S E]
2026-01-16 20:11:31 -06:00
commit fc43fbe4b0
65 changed files with 19127 additions and 0 deletions
+283
View File
@@ -0,0 +1,283 @@
# PyPewPewHOPS - Coherent HOPS Laser Control Library
Python library for controlling Coherent HOPS laser systems via I2C protocol through an FTDI FT2232C USB interface.
## Features
- Complete implementation of all documented I2C commands
- Support for system information queries
- Temperature monitoring and control for all sensors
- Power and current control
- Digital I/O operations
- Configuration register access
- Context manager support for safe resource handling
- Dummy laser simulator for development without hardware
- Comprehensive error handling
## Installation
### Requirements
- Python 3.7+
- FTDI FT2232C USB device
- libftdi library (for Linux)
### Install Dependencies
```bash
pip install -r requirements.txt
```
### Linux Setup
On Linux, you may need to install libftdi:
```bash
# Debian/Ubuntu
sudo apt install libftdi-dev
# Fedora
sudo dnf install libftdi-devel
```
You may also need to add your user to the appropriate group:
```bash
sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER
```
Then log out and log back in for the changes to take effect.
## Quick Start
### Using the Simulator (No Hardware)
```python
from coherent_hops_laser import DummyLaser
with DummyLaser() as laser:
# Query system information
info = laser.get_system_info()
print(f"Model: {info.laser_model}")
print(f"Wavelength: {info.wavelength}")
# Monitor temperatures
temps = laser.get_all_temperatures()
print(f"Main temperature: {temps.main}°C")
# Control power
laser.set_power_command(100.0)
power = laser.get_power_command()
print(f"Power set to: {power} mW")
```
### Using Real Hardware
```python
from coherent_hops_laser import CoherentHOPSLaser, I2CMode
# Initialize laser controller
laser = CoherentHOPSLaser(
slave_address=0x50, # I2C slave address
i2c_mode=I2CMode.STANDARD # 100 kHz
)
# Connect to FTDI device
laser.connect('ftdi://ftdi:2232/1')
try:
# Query laser model
model = laser.get_laser_model()
print(f"Laser Model: {model}")
# Get all temperatures
temps = laser.get_all_temperatures()
print(f"Temperatures: {temps}")
# Set power
laser.set_power_command(50.0)
# Check control mode
mode = laser.get_control_mode()
print(f"Control Mode: {mode}")
finally:
laser.disconnect()
```
### Using Context Manager
```python
from coherent_hops_laser import CoherentHOPSLaser
with CoherentHOPSLaser() as laser:
laser.connect()
# Your laser control code here
info = laser.get_system_info()
print(info)
# Automatically disconnects
```
## Available Commands
### System Information
- `get_hardware_id()` - Hardware ID
- `get_head_type()` - Head type
- `get_head_board_revision()` - PCB revision
- `get_laser_model()` - Laser model (G532, Tina, Mini00, MiniX)
- `get_power_units()` - Power units (mW, W)
- `get_wavelength()` - Wavelength (e.g., 532nm)
- `get_system_info()` - All system info at once
### Temperature Monitoring
- `get_temperature_main()` - Main heatsink temperature
- `get_temperature_brf()` - BRF temperature
- `get_temperature_shg()` - SHG temperature
- `get_temperature_thg()` - THG temperature
- `get_temperature_eta()` - ETA temperature
- `get_all_temperatures()` - All temperatures at once
### Temperature Control
- `get_temperature_setpoint_main()` / `set_temperature_setpoint_main(temp)`
- `get_temperature_setpoint_brf()` / `set_temperature_setpoint_brf(temp)`
- `get_temperature_setpoint_shg()` / `set_temperature_setpoint_shg(temp)`
- `get_temperature_setpoint_thg()` / `set_temperature_setpoint_thg(temp)`
- `get_temperature_setpoint_eta()` / `set_temperature_setpoint_eta(temp)`
### Power Control
- `get_power_command()` / `set_power_command(power)` - Get/set power
- `get_power_memory()` - Stored power settings
- `get_power_limits()` - Power limits
### Current Control
- `get_current_command()` / `set_current_command(current)` - Get/set current
- `get_current_limits()` - Current limits
- `get_control_mode()` / `set_control_mode(mode)` - Control mode (POWER/CURRENT)
### Status Monitoring
- `get_key_switch_status()` - Key switch status
- `get_fan_status()` / `set_fan_control(value)` - Fan control
- `get_interlock_status()` - Interlock status
- `get_remote_control_status()` - Remote control status
- `get_analog_values()` - Analog sensor values
### Configuration
- `get_config_register_0()` / `set_config_register_0(value)`
- `get_config_register_1()` / `set_config_register_1(value)`
- `get_config_register_2()` / `set_config_register_2(value)`
- `get_config_register_3()` / `set_config_register_3(value)`
See the [API documentation](LASER_I2C_PROTOCOL.md) for complete command reference.
## Examples
Run the example script:
```bash
# Simulation mode (no hardware)
python3 example_usage.py 1
# Real hardware mode
python3 example_usage.py 2
# Continuous monitoring
python3 example_usage.py 3
```
Or run the built-in test:
```bash
python3 coherent_hops_laser.py
```
## Continuous Monitoring Example
```python
from coherent_hops_laser import CoherentHOPSLaser
import time
with CoherentHOPSLaser() as laser:
laser.connect()
while True:
temps = laser.get_all_temperatures()
power = laser.get_power_command()
print(f"Main: {temps.main:.1f}°C Power: {power:.1f}mW")
time.sleep(1)
```
## Troubleshooting
### Cannot find FTDI device
```bash
# Check if device is connected
lsusb | grep FTDI
# Should show something like:
# Bus 001 Device 005: ID 0403:6010 Future Technology Devices International, Ltd FT2232C
```
### Permission denied
Add your user to the dialout/plugdev group:
```bash
sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER
```
Then log out and back in.
### I2C communication errors
- Verify correct slave address (default: 0x50)
- Check I2C speed (try I2CMode.STANDARD instead of FAST)
- Verify physical connections
- Check for other devices on the bus
### Import errors
```bash
# Install pyftdi
pip install pyftdi
# If that fails, try:
pip install --user pyftdi
```
## Architecture
- **CoherentHOPSLaser**: Main class for real hardware control
- **DummyLaser**: Simulator for development without hardware
- **I2CController**: Low-level FTDI I2C communication (from pyftdi)
- **LaserInfo / TemperatureStatus**: Data classes for structured responses
## Safety Notes
- Always verify power levels before enabling laser output
- Monitor temperatures during operation
- Check interlock status before operation
- Use appropriate laser safety equipment
- Follow all manufacturer safety guidelines
## License
This implementation is based on the Coherent HOPS Demo v2.0.7 protocol documentation.
## References
- FTDI MPSSE Documentation: https://ftdichip.com/software-examples/mpsse-projects/
- PyFTDI: https://github.com/eblot/pyftdi
- Original Protocol Documentation: [LASER_I2C_PROTOCOL.md](LASER_I2C_PROTOCOL.md)