2 rzeczy, które wcześniej pominąłem.
Pierwsza, to fakt, że regulator w przypadku, gdy prędkość aktualna przekroczy zadaną, wypracuje wyjście ujemne, a to niestety nie spowoduje wyhamowania napędu w tak zorganizowanym sterowniku, a nawet może spowodować jego rozpędzenie do maksymalnej wartości. Generalnie w taki sposób zorganizowany regulator nie jest idealnym podejściem, ale jest na to rozwiązanie. Po przekroczeniu wartości zadanej, trzeba zadać PWM równe zero, tak aby wrzeciono własną bezwładnością zwolniło do oczekiwanej. Komponent PID ma możliwość ograniczania maksymalnej wartości wyjścia, ale nie ma możliwości ograniczania minimalnej wartości. Dlatego Do tego celu użyję komponentu limit1, który ograniczy tą wartość z góry i z dołu według ustawionego progu.
Druga sprawa to taka, że przyjąłem nieprawidłowe założenie. Uznałem, że skoro z g-kodu zadajemy zawsze wartość dodatniej prędkości, to taka też będzie wchodzić na sterowanie w sygnale spindle.0.speed-out.
Otóż nie. Jeśli włączymy obroty CW, np. M03 S1000 to wartość sygnału spindle.0.speed-out wyniesie 1000, natomiast jeśli włączymy obroty CCW M04 S1000 to wartość sygnału spindle.0.speed-out wyniesie -1000.
Dlatego sygnał spindle.0.speed-out nie powinien być podawany na wejście regulatora przez komponent abs, ale trzeba zadbać o poprawne ustawienie kierunku enkodera (sygnały A i B).
Jeśli natomiast enkoder nie ma podłączonych obydwu sygnałów A i B albo czasami tylko sam Z, nie będzie odczytu kierunku prędkości, wtedy należy zarówno sygnał prędkości enkodera (encoder.0.velocity-rpm) jak i sygnał wartości zadanej prędkości (spindle.0.speed-out) podłączyć poprzez moduł abs do regulatora PID.
I takie rozwiązanie przedstawię.
A więc aktualizacja pierwszego postu:
.
.
.
Do sterowania prędkością wrzeciona potrzebny będzie regulator.
HAL udostępnia różnego rodzaju komponenty, między innymi regulator PID.
Aby użyć regulator, trzeba dodać i skonfigurować komponent PID, w tym celu należy dodać kod do pliku .hal
Kod: Zaznacz cały
# Initialize the PID
loadrt pid num_chan=1
addf pid.0.do-pid-calcs servo-thread
setp pid.0.Pgain 1
setp pid.0.Igain 0
setp pid.0.Dgain 0
setp pid.0.maxoutput 100
setp pid.0.maxerrorI 0
Pgain, Igain i Dgain to nastawy regulatora. Na początek zerujemy nastawy poza nastawą proporcjonalną.
maxoutput to maksymalna wartość wyjścia regulatora. Ustawiamy ją np. na 100, będzie to odpowiadać 100% wypełnienia PWM.
MaxerrorI to maksymalna wartość nacałkowania błędu – parametr istotny, aby nie powodować długotrwałemu całkowaniu błędu, w przypadku gdy napęd nie może osiągnąć prędkości zadanej.
MaxerrorI powinien być regulowany równocześnie z nastawą Igain i powinien wynosić nie więcej niż maxoutput/ Igain
Następnie trzeba ustawić, aby komponent PID włączał się wraz z łączeniem wrzeciona.
A więc do linii, która załącza pwmgen wraz z uruchomieniem wrzeciona:
Kod: Zaznacz cały
#net spindle-on <= spindle.0.on => pwmgen.0.enable
Kod: Zaznacz cały
net spindle-on <= spindle.0.on => pwmgen.0.enable => pid.0.enable
-Prędkość zadaną
-prędkość aktualną
-wyjście regulatora
W celu odnalezienia prędkości zadanej, sprawdziłem w pliku i zweryfikowałem w pomiarze HAL który sygnał temu odpowiada – jest to sygnał spindle.0.speed-out

W moim pliku hal, sygnał spindle.0.speed-out jest już połączony ze zmienną spindle-cmd-rpm
Kod: Zaznacz cały
net spindle-cmd-rpm <= spindle.0.speed-out
Kod: Zaznacz cały
net spindle-cmd-rpm => pwmgen.0.value
Pwmgen to komponent służący do generowania sygnałów pwm i jest on już ustawiony w mojej konfiguracji przez stepconf wizard.
Ponieważ chcemy, aby to regulator PID sterował wartością PWM, trzeba odłączyć sygnał spindle.0.speed-out od sygnału pwmgen.0.value w tym celu trzeba usunąć następujące linie (lub zakomentować)
Kod: Zaznacz cały
net spindle-cmd-rpm <= spindle.0.speed-out
net spindle-cmd-rpm => pwmgen.0.value
Do tego celu trzeba utworzyć 2 komponenty abs.
W mojej konfiguracji jest już ładowanie jednej „instancji” modułu abs
Kod: Zaznacz cały
loadrt abs count=1
Kod: Zaznacz cały
loadrt abs count=3
addf abs.1 servo-thread
addf abs.2 servo-thread
Kod: Zaznacz cały
loadrt limit1 count=1
addf limit1.0 servo-thread
setp limit1.0.min 0
setp limit1.0.max 100
Sygnał zadanej prędkości (spindle.0.speed-out) przez komponent abs na wejście command regulatora
Kod: Zaznacz cały
net spindle-cmd-abs spindle.0.speed-out => abs.2.in
net pid-0-command abs.2.out => pid.0.command
Kod: Zaznacz cały
net pid_feedback_rpm_ABS encoder.0.velocity-rpm => abs.1.in
net pid_feedback pid.0.feedback <= abs.1.out
Kod: Zaznacz cały
net pid-output-value pid.0.output => limit1.0.in
net pwmgen_value pwmgen.0.value <= limit1.0.out
Pwmgen ma kilka ustawień istotnych:
Kod: Zaznacz cały
setp pwmgen.0.pwm-freq 1000.0
setp pwmgen.0.scale 100.0
setp pwmgen.0.offset 0.0
Dalsza część bez zmian.
Tutaj film z testów na moim mini modelu tokarki CNC oraz Linumeric-LPT V3
Niestety wydaje nieprzyjemny dźwięk taki PWM 1 kHz.
Idelanie byłoby wyjść z częstotliwości akustycznych, ale na stepgen się nie da.