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:
@@ -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)
|
||||
Reference in New Issue
Block a user