Metadata-Version: 2.4
Name: pololu
Version: 0.1.8
Summary: Sterowanie silnikiem krokowym bipolarnym przez Pololu Tic T249 z obsługą wyłączników krańcowych i procedury homing
Project-URL: Homepage, https://github.com/maskservice/rpi-motor-tic249
Project-URL: Repository, https://github.com/maskservice/rpi-motor-tic249
Project-URL: Issues, https://github.com/maskservice/rpi-motor-tic249/issues
Author: MaskService
Author-email: Tom Sapletta <tom@sapletta.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: controller,motor,pololu,raspberry-pi,stepper,t249,tic
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: POSIX :: Linux
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: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Hardware
Requires-Python: >=3.9
Requires-Dist: flask>=2.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: pyusb>=1.2.0
Requires-Dist: ticlib>=0.3.0
Provides-Extra: gpio
Requires-Dist: gpiozero>=2.0; extra == 'gpio'
Requires-Dist: rpi-gpio>=0.7.0; extra == 'gpio'
Description-Content-Type: text/markdown

# Pololu Tic T249 - Stepper Motor Controller

Kompletne rozwiązanie do sterowania silnikiem krokowym bipolarnym przez **Pololu Tic T249** (TB67S249FTG) z pełną obsługą **wyłączników krańcowych** (limit switches), procedurą **homing**, oraz nowoczesnym **panelem web**.

## Funkcje

- **Panel Web** - Intuicyjny interfejs w przeglądarce (Flask)
- **Wybór urządzenia USB** - Auto-detekcja i ręczny wybór portu USB
- **Konfiguracja .env** - Łatwa konfiguracja przez zmienne środowiskowe
- **Docker** - Pełne wsparcie dla Docker i docker-compose
- **Testy E2E** - Automatyczne testy Playwright
- **CLI** - Pełna obsługa z linii komend
- **Homing** - Automatyczne zerowanie pozycji
- **Krańcówki** - Obsługa sprzętowa (Tic) i programowa (GPIO)

## Szybki start

### Instalacja (automatyczna)

```bash
# Klonowanie repo
git clone https://github.com/maskservice/rpi-motor-tic249.git
cd rpi-motor-tic249

# Instalacja (z sudo dla udev rules)
sudo make install

# Lub bez sudo (tylko zależności Python)
make install
```

### Uruchomienie panelu web

```bash
# Lokalnie
make web

# W Dockerze
docker-compose up -d
```

Panel dostępny pod adresem: **http://localhost:5000**

## Tryby obsługi krańcówek

### 1. Tryb `tic` — sprzętowy (zalecany)

Wyłączniki podłączone bezpośrednio do pinów Tic T249 (SCL, SDA, TX, RX lub RC). Konfiguracja pinów w **Tic Control Center** → Advanced → Pin configuration. Wymaga firmware ≥1.06.

Tic automatycznie blokuje ruch w kierunku aktywnego wyłącznika i obsługuje sprzętową procedurę homing (go_home → jedzie do krańcówki → cofa → pozycja = 0).

```
Tic T249 Pin TX ─── Limit Switch Forward ─── GND
Tic T249 Pin RX ─── Limit Switch Reverse ─── GND
```

### 2. Tryb `gpio` — programowy (Raspberry Pi)

Wyłączniki podłączone do dowolnych pinów GPIO, monitorowane z przerwaniami. Natychmiastowe zatrzymanie silnika (emergency stop) przy aktywacji krańcówki w kierunku ruchu.

```
RPi GPIO 17 ─── Limit Switch Forward ─── GND  (pull-up wewnętrzny)
RPi GPIO 27 ─── Limit Switch Reverse ─── GND  (pull-up wewnętrzny)
```

Wymaga `gpiozero` lub `RPi.GPIO`:
```bash
pip install gpiozero
```

## Instalacja

```bash
sudo apt-get install libusb-1.0-0-dev
pip install -r requirements.txt

# Reguła udev
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1ffb", MODE="0666"' | \
    sudo tee /etc/udev/rules.d/99-pololu-tic.rules
sudo udevadm control --reload-rules
```

## Użycie — Web Panel

### Panel web - funkcje

- **Wybór urządzenia USB** - Lista wykrytych urządzeń Pololu z możliwością wyboru
- **Status w czasie rzeczywistym** - Pozycja, prędkość, stan krańcówek (odświeżanie 2x/s)
- **Sterowanie** - Homing, jog, ruch do pozycji, zasilanie silnika
- **Skróty klawiszowe** - ← → (jog), Spacja (stop), H (homing)

### Konfiguracja przez .env

```bash
# Kopiowanie przykładowej konfiguracji
cp .env.example .env

# Edycja ustawień
nano .env
```

Przykładowa konfiguracja `.env`:

```ini
# Flask
FLASK_HOST=0.0.0.0
FLASK_PORT=5000

# USB - auto-detect gdy puste, lub konkretne wartości
USB_VENDOR_ID=0x1ffb
USB_PRODUCT_ID=0x00c9

# Motor
DEFAULT_MAX_SPEED=2000000
DEFAULT_CURRENT_LIMIT_MA=1000
```

## Docker

### Uruchomienie z docker-compose

```bash
# Produkcja
docker-compose up -d

# Ze skonfigurowanym urządzeniem
USB_PRODUCT_ID=0x00c9 docker-compose up -d

# Tryb developerski (hot reload)
docker-compose --profile dev up -d

# Zatrzymanie
docker-compose down
```

### Build obrazu

```bash
docker build -t pololu-tic .
docker run -d --privileged -p 5000:5000 pololu-tic
```

## Makefile - komendy

```bash
make help           # Lista komend
make install        # Pełna instalacja
make web            # Uruchom panel web
make web-stop       # Zatrzymaj panel
make detect-usb     # Wykryj urządzenia USB
make cli            # CLI kontroler
make home           # Homing
make status         # Status silnika
make test           # Testy jednostkowe
make clean          # Wyczyść build
```

## CLI Shell (interaktywny)

Interaktywny shell do sterowania silnikiem przez API web panelu:

```bash
# Uruchomienie shella (wymaga uruchomionego web panelu)
make shell

# Lub bezpośrednio
bash cli_shell.sh

# Z innym adresem API
API_BASE=http://192.168.1.100:5000 bash cli_shell.sh
```

### Komendy w shellu

```
tic> status              # Status silnika
tic> devices             # Lista urządzeń USB
tic> connect 0           # Połącz z urządzeniem #0
tic> home                # Homing reverse
tic> home forward        # Homing forward
tic> move 1000           # Idź do pozycji 1000
tic> move-rel 500        # Przesuń o +500 kroków
tic> jog forward 100     # Jog forward 100 kroków
tic> jog reverse 200     # Jog reverse 200 kroków
tic> stop                # Emergency stop
tic> energize on         # Włącz zasilanie silnika
tic> energize off        # Wyłącz zasilanie silnika
tic> reciprocate 500 100000 5 0.5  # Ruch P-Z: kroki, prędkość, cykle, pauza
tic> settings            # Pokaż ustawienia
tic> logs                # Pokaż logi
tic> help                # Pomoc
tic> quit                # Wyjście
```

## Testy E2E

### Uruchomienie testów

```bash
# Lokalnie (wymaga playwright)
pip install pytest-playwright
pytest tests/e2e/ -v

# W Dockerze
docker-compose --profile test up
```

### Struktura testów

```
tests/e2e/
├── test_web_panel.py    # Testy UI (Playwright)
└── conftest.py          # Konfiguracja pytest
```

## Użycie — CLI

### Homing (zerowanie na krańcówce)

```bash
# Homing sprzętowy Tic — jedź reverse aż limit switch, cofnij, pozycja=0
python tic_t249_controller.py home-reverse --limit-mode tic

# Homing forward
python tic_t249_controller.py home-forward --limit-mode tic

# Homing GPIO — piny BCM 17 (forward) i 27 (reverse)
python tic_t249_controller.py home-reverse --limit-mode gpio --gpio-fwd 17 --gpio-rev 27

# Z pliku konfiguracji
python tic_t249_controller.py home-reverse --config config.json
python tic_t249_controller.py home-reverse --config config-gpio.json
```

### Wyznaczanie zakresu ruchu

```bash
# Jedź do reverse limit (pozycja=0), potem do forward limit → odczytaj zakres
python tic_t249_controller.py demo-range --limit-mode tic
```

### Ruch z ochroną krańcówek

```bash
# Ruch do pozycji (Tic blokuje sprzętowo przy limit switch)
python tic_t249_controller.py move -p 5000 --limit-mode tic

# Ruch z soft limitami (przycina do zakresu - margin)
python tic_t249_controller.py move-safe -p 3000

# GPIO — emergency stop jeśli krańcówka aktywna w kierunku ruchu
python tic_t249_controller.py move -p 5000 --limit-mode gpio --gpio-fwd 17 --gpio-rev 27
```

### Status krańcówek

```bash
python tic_t249_controller.py limit-status --limit-mode tic
python tic_t249_controller.py status --limit-mode tic
```

### Pozostałe komendy

```bash
python tic_t249_controller.py demo-positions
python tic_t249_controller.py demo-velocity
python tic_t249_controller.py demo-homing --limit-mode tic
python tic_t249_controller.py velocity --speed 1000000 --duration 5
python tic_t249_controller.py home  # ręczne zerowanie, bez krańcówek
```

## Użycie — Python API

```python
from tic_t249_controller import (
    TicT249Controller, MotorConfig, LimitSwitchConfig,
    StepMode, HomingDirection,
)

# --- Tryb Tic (sprzętowy) ---
config = MotorConfig(
    current_limit_ma=1200,
    step_mode=StepMode.SIXTEENTH,
    limit_switches=LimitSwitchConfig(mode="tic"),
)

with TicT249Controller(config) as ctrl:
    # Homing na reverse limit switch → pozycja = 0
    ctrl.go_home(HomingDirection.REVERSE)

    # Ruch — Tic automatycznie blokuje przy limit switch
    ctrl.move_to(5000)
    ctrl.wait_for_position()

    # Status krańcówek
    status = ctrl.get_limit_switch_status()
    print(f"Forward: {status['forward_active']}")
    print(f"Reverse: {status['reverse_active']}")

    # Wyznacz zakres ruchu
    travel = ctrl.find_travel_range()
    print(f"Zakres: {travel} kroków")

    # Ruch bezpieczny (z soft limitami)
    ctrl.move_to_safe(travel // 2)
    ctrl.wait_for_position()


# --- Tryb GPIO (Raspberry Pi) ---
config_gpio = MotorConfig(
    limit_switches=LimitSwitchConfig(
        mode="gpio",
        gpio_forward_pin=17,
        gpio_reverse_pin=27,
        gpio_active_low=True,  # NO switch z pull-up
        homing_speed_towards=300_000,
        homing_speed_away=100_000,
    ),
)

with TicT249Controller(config_gpio) as ctrl:
    ctrl.go_home(HomingDirection.REVERSE)
    ctrl.move_to(3000)
    ctrl.wait_for_position()  # przerywa jeśli krańcówka aktywna
```

## Konfiguracja JSON

### `config.json` (tryb Tic)

```json
{
  "limit_switches": {
    "mode": "tic",
    "homing_speed_towards": 500000,
    "homing_speed_away": 200000,
    "soft_limit_margin": 50
  }
}
```

### `config-gpio.json` (tryb GPIO)

```json
{
  "limit_switches": {
    "mode": "gpio",
    "gpio_forward_pin": 17,
    "gpio_reverse_pin": 27,
    "gpio_active_low": true,
    "gpio_bounce_time_ms": 5,
    "homing_speed_towards": 500000,
    "homing_speed_away": 200000,
    "soft_limit_margin": 50
  }
}
```

## Procedura homing — jak działa

### Tryb Tic (sprzętowy)

1. Komenda `go_home(direction)` → Tic jedzie w zadanym kierunku
2. Tic napotyka limit switch → natychmiastowe zatrzymanie (sprzętowe)
3. Tic czeka 20 ms
4. Tic cofa wolno aż limit switch się dezaktywuje
5. Pozycja = 0, flaga "position uncertain" skasowana

### Tryb GPIO (programowy)

1. Jeśli już na krańcówce → najpierw odjazd
2. Ruch wolny w kierunku krańcówki (`homing_speed_towards`)
3. GPIO przerwanie → `halt_and_hold()` (natychmiastowy stop)
4. Cofanie wolne (`homing_speed_away`) aż GPIO zwolni
5. `halt_and_set_position(0)`

## Bezpieczeństwo

- **Ctrl+C** → bezpieczne deenergize (cewki wyłączone)
- **GPIO emergency stop** → natychmiastowe `halt_and_hold()` przy krańcówce
- **Soft limity** → `move_to_safe()` przycina pozycję do zakresu ± margines
- **Nigdy nie odłączaj silnika przy zasilonym sterowniku**
- Bez radiatora max ~1800 mA na cewkę

## Licencja

Program: **MIT** (Softreck, softreck.dev)
Zależność ticlib: **BSD-2-Clause** (Julien Phalip) — dozwolona komercyjnie

## License

Apache License 2.0 - see [LICENSE](LICENSE) for details.

## Author

Created by **Tom Sapletta** - [tom@sapletta.com](mailto:tom@sapletta.com)
