Pololu Tic T249 - Stepper Motor Controller
AI Cost Tracking
- 🤖 LLM usage: $3.4965 (22 commits)
- 👤 Human dev: ~$1805 (18.0h @ $100/h, 30min dedup)
Generated on 2026-05-13 using openrouter/qwen/qwen3-coder-next
https://www.waveshare.com/wiki/Infrared_Reflective_Sensor
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)
Aktualne poprawki (2026-05-05)
Najważniejsze poprawki po diagnostyce na realnym sterowniku Tic T249:
- Usunięto fałszywy stan "obie krańcówki aktywne" wynikający z konfiguracji pinów limit switch bez pull-up.
- Potwierdzono poprawną konfigurację dla wejść limit switch:
SCL: reverse limit + pull-upSDA: forward limit + pull-up
- Po naprawie wejść limit switch błąd ruchu zmienia się na rzeczywisty stan zasilania, jeśli występuje:
low_vin/ "Motor supply voltage is too low".
To rozróżnienie jest kluczowe: wcześniej ruch był blokowany logicznie przez błędny stan wejść, teraz blokada (jeśli występuje) wynika z fizycznego braku zasilania silnika.
Szybka weryfikacja po uruchomieniu
make limits
Oczekiwany wynik w stanie spoczynku:
Forward limit: inactiveReverse limit: inactive
Następnie sprawdź napięcie zasilania silnika (VIN) przez status web/CLI. Jeśli pojawia się low_vin, problem dotyczy zasilacza (VIN/GND), a nie logiki krańcówek.
Szybki start
Instalacja (automatyczna)
Wspierane systemy: Debian/Ubuntu/Raspberry Pi OS, Fedora, RHEL/CentOS
# 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
Instalacja na Fedorze/RHEL
Na systemach Fedora lub RHEL/CentOS używane są pakiety dnf/yum zamiast apt-get:
# Instalacja zależności systemowych na Fedora
sudo dnf install -y libusbx-devel python3-pip python3-virtualenv git
# Na RHEL 8+ / CentOS Stream
sudo dnf install -y libusbx-devel python3-pip python3-virtualenv git
# Na RHEL 7 / CentOS 7
sudo yum install -y libusbx-devel python3-pip python3-virtualenv git
# Następnie standardowa instalacja
make install
Uruchomienie panelu web
# 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 krańcowe podłączone do pinów Tic T249 SCL i SDA — po jednym wejściu na kierunek:
Limit switch forward→SCLLimit switch reverse→SDA
Krańcówka jest aktywna, gdy na wejście podawana jest masa (GND) — tryb active LOW.
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).
Podłączenie:
Tic T249 Pin SCL ───[NC Switch forward]─── GND
Tic T249 Pin SDA ───[NC Switch reverse]─── GND
- NC (Normally Closed) = domyślnie zamknięty, otwiera się gdy wciśnięty
- Aktywny stan: masa/GND na wejściu (active LOW)
- Pull-up włączony: pin ma stan wysoki (5V) gdy switch otwarty
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:
pip install gpiozero
Instalacja
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
# Kopiowanie przykładowej konfiguracji
cp .env.example .env
# Edycja ustawień
nano .env
Przykładowa konfiguracja .env:
# 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 (zalecane na Fedora i innych systemach)
Docker działa niezależnie od dystrybucji Linux i jest najprostszą metodą uruchomienia projektu na Fedorze, RHEL i innych systemach bez potrzeby instalowania zależności systemowych.
Wymagania
# Fedora - instalacja Docker
sudo dnf install -y docker docker-compose
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
# Wyloguj się i zaloguj ponownie, aby grupa docker zadziałała
Szybki start z Docker
# Uruchomienie pełnego stacku w Docker (alias: make web-docker)
make docker-up
# Lub bezpośrednio
make web-docker
Serwisy dostępne pod:
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- MQTT: localhost:1883
Zarządzanie Docker
# Zatrzymanie stacku
make docker-down
# Podgląd logów
make docker-logs
# Rebuild obrazów
make docker-build
Makefile - komendy
Wspierane systemy: Debian/Ubuntu, Raspberry Pi OS, Fedora, RHEL/CentOS
make help # Lista komend
make install # Pełna instalacja (autodetekcja systemu)
make web # Uruchom panel web (natywnie)
make web-docker # Uruchom w Docker (zalecane na Fedora)
make web-stop # Zatrzymaj panel
make detect-usb # Wykryj urządzenia USB
make cli # CLI kontroler
make cli-shell # Interaktywny shell Python
make shell # Legacy bash shell przez API web panelu
make home # Homing
make status # Status silnika
make standby # Stan spoczynku (de-energize, no heat)
make limits # Stan krańcówek
make test-limit # Test krańcówki z auto-reverse (MAX speed)
# ticcmd fallback (gdy Python niedostępny)
make tic-list # Lista urządzeń via ticcmd
make tic-status # Status via ticcmd
make tic-home-reverse # Homing reverse via ticcmd
make tic-deenergize # Wyłączenie silnika via ticcmd
make docker-up # Uruchom w Docker
docker-down # Zatrzymaj Docker
make test # Testy jednostkowe
make clean # Wyczyść build
CLI Shell
1. Python CLI shell — bezpośrednio do Tic T249
To jest interaktywny shell do bezpośredniego sterowania sterownikiem i odczytu statusu krańcówek:
make cli-shell
# albo bezpośrednio
.venv/bin/python -m firmware.cli_shell
2. Legacy bash shell — przez API web panelu
Ten wariant steruje przez API panelu webowego i wymaga uruchomionego backendu:
make shell
# albo 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> limits # Stan krańcówek (FWD/REV)
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
# 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)
# 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
# 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
# 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
python tic_t249_controller.py limit-status --limit-mode tic
python tic_t249_controller.py status --limit-mode tic
Pozostałe komendy
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
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
Examples
Multiple format examples with auto-diagnostics - no manual setup required.
Quick Start with Examples
cd /home/tom/github/maskservice/rpi-motor-tic249
# Bash scripts with auto-diagnostics
bash examples/bash/basic_test.sh
bash examples/bash/simple/basic_test_simple.sh
# DSL scripts via runner
bin/pololu-dsl examples/dsl/basic_test.dsl
# Via CLI shell
tic> EXEC examples/bash/basic_test.sh
tic> EXEC examples/dsl/basic_test.dsl
Available Formats
- Bash Scripts - Auto-diagnostics, standalone & library versions
- DSL Scripts - Domain-specific language with validation
- JSON Format - Command lists and sequences
- YAML Format - Clean syntax configuration
- All Formats Overview - Complete examples guide
Auto-Diagnostics Features
Examples automatically:
- Detect Python environment (
.venv,venv, system) - Create virtual environment if missing
- Install
ticlibdependency - Configure USB permissions (if needed)
See Examples Troubleshooting for USB permissions and common issues.
Konfiguracja JSON
config.json (tryb Tic)
{
"limit_switches": {
"mode": "tic",
"homing_speed_towards": 500000,
"homing_speed_away": 200000,
"soft_limit_margin": 50
}
}
config-gpio.json (tryb GPIO)
{
"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)
- Komenda
go_home(direction)→ Tic jedzie w zadanym kierunku - Tic napotyka limit switch → natychmiastowe zatrzymanie (sprzętowe)
- Tic czeka 20 ms
- Tic cofa wolno aż limit switch się dezaktywuje
- Pozycja = 0, flaga "position uncertain" skasowana
Tryb GPIO (programowy)
- Jeśli już na krańcówce → najpierw odjazd
- Ruch wolny w kierunku krańcówki (
homing_speed_towards) - GPIO przerwanie →
halt_and_hold()(natychmiastowy stop) - Cofanie wolne (
homing_speed_away) aż GPIO zwolni halt_and_set_position(0)
Tryb Standby (oszczędzanie energii)
Gdy silnik nie jest używany, można przejść w tryb standby żeby obniżyć temperaturę sterownika i wydłużyć żywotność silnika:
make standby # De-energize silnika + release USB
Co robi standby:
- Wyłącza zasilanie cewek (motor de-energized)
- Zwalnia uchwyt USB (inny proces może przejąć kontrolę)
- Czyści błędy drivera
Aby wznowić pracę:
make cli-shell # Przejmij kontrolę, silnik się energizuje
Krańcówki i Ruch z Limitami
Konfiguracja sprzętowa (Tic Control Center)
Piny Tic T249 skonfigurowane jako active LOW (aktywne na masę GND):
| Pin Tic | Funkcja | Konfiguracja |
|---|---|---|
| SCL | Limit switch FORWARD | Uncheck "Active high", check "Pull-up" |
| SDA | Limit switch REVERSE | Uncheck "Active high", check "Pull-up" |
Ciągły ruch posuwisto-zwrotny z krańcówkami — make run-limit
Główny tryb pracy produkcyjnej.
make run-limit # Start — silnik energizuje się i jedzie w pętli
# Ctrl+C — silnik de-energizuje się (no heat)
Parametry w .env:
LIMIT_RECIPROCATE_STEPS=2000 # kroków w jedną stronę
LIMIT_RECIPROCATE_SPEED_PULSES_PER_SEC=5000 # prędkość
LIMIT_RECIPROCATE_ACCEL_PULSES_PER_SEC2=15000
Działanie:
- ⚡ Energizuje silnik (tylko podczas działania skryptu)
- Jedzie 2000 kroków naprzód, 2000 kroków wstecz — w pętli
- Jeśli SCL (forward) lub SDA (reverse) aktywna mid-cycle → natychmiastowy reverse
- Ctrl+C → de-energizuje silnik + zwalnia USB (brak ciepła w spoczynku)
Test jednorazowy krańcówki — make test-limit
make test-limit # Forward → limit → reverse → standby (jednorazowy)
Scenariusz:
- Rusza do przodu, czeka na SCL (forward limit)
- Gdy limit wykryty → odwraca kierunek
- Jedzie wstecz, czeka na SDA (reverse limit)
- Przechodzi w standby (de-energize)
Sprawdzenie stanu krańcówek
make limits # Szybki odczyt FWD/REV limit switches
Wynik:
🔍 Checking limit switches...
Forward limit: inactive
Reverse limit: ACTIVE
⚠️ Limit triggered - motor blocked in that direction
Test z ticcmd (fallback bez Pythona)
Jeśli Python ma problemy, użyj natywnego ticcmd:
make tic-list # Lista urządzeń
make tic-status # Pełny status
make tic-home-reverse # Homing via ticcmd
make tic-deenergize # Wyłączenie silnika
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
Licensed under Apache-2.0.
Author
Tom Sapletta
Metadata
Release files for pololu 0.1.17
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pololu-0.1.17.tar.gz | 11.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pololu-0.1.17-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.3 MB
Release files / pololu-0.1.17.tar.gz
| Download URL | pololu-0.1.17.tar.gz |
|---|---|
| Size | 11.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9717106687ca2045b655e43f9ea3a335ec4863816565197672eaa029c46a0a54
|
|
BLAKE2b-256 checksum How to use checksums |
e861adcffb8e1222958a3b4cd6802f910768441a021021ef11d889f879b4197a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / pololu-0.1.17-py3-none-any.whl
| Download URL | pololu-0.1.17-py3-none-any.whl |
|---|---|
| Size | 11.7 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2be9775e0c2e179a934747e27279075a45c720fe602d1623dc6f1429c56c93eb
|
|
BLAKE2b-256 checksum How to use checksums |
4e3a156b060ae8201d021014641c3d3c420fb429caf1a68fe01ef75953256500
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|