Manometry – napęd alternatywny

Rozpoczynając przygodę z budową pulpitu, jedyną znaną mi opcją było zastosowanie ustrojów elektromagnetycznych z prędkościomierzy (Polonez/FSO). Możliwość bezpośredniego podłączenia pod piny PWM w PoKeys było idealnym rozwiązaniem. Dość spore, choć solidne udało się całkiem nieźle zabudować na tyłach manometrów i od początku działają bardzo dobrze. Więcej na ten temat można poczytać tutaj. Nie jest to rozwiązanie idealne ale przynajmniej dla mnie jest akceptowalne na tyle, że nie miałem ochoty ich modernizować. Denerwowała mnie oczywiście ich nieliniowość i konieczność kalibracji, do czego przygotowałem sobie stosowne narzędzia ale nie było problemów z płynnym ruchem wskazówek i powrót do zera przy wyłączaniu pulpitu. Przesiadka na Arduino też nie spowodowała większych problemów, tylko sposób kalibracji trochę się zmienił. Teraz musiałem współczynniki wielomianów zaszyć w kodzie Arduino.

Silnik krokowy x27.168

Czas leciał, słyszałem o innych rozwiązaniach wykorzystywanych przez twórców pulpitów ale zawsze zniechęcała mnie perspektywa znacznie większej komplikacji sterowania. Temat jednak powracał od czasu do czasu, a ostatnio wpadłem na materiały pasjonatów lotnictwa i symulatorów lotniczych. Tam zauważyłem dość powszechne stosowanie miniaturowych silników krokowych z serii x25 lub x27. Są to urządzenia od początku zaprojektowane z myślą o wykorzystaniu w deskach rozdzielczych samochodów GM. Są bardzo słabe jak na silniki krokowe ale do obracania lekkimi wskazówkami nadają się idealnie. Dodatkową ich zaletą jest wewnętrzne, mechaniczne ograniczenie co ułatwia powrót do punktu zerowego. Nie jest to łatwe w standardowych silnikach krokowych. W związku z tym nie ma konieczności stosowania dodatkowych czujników wykrywających położenie wskazówki.

Jedną z pierwszych stron, na które trafiłem szukając informacji o tych silniczkach był ten artykuł. Możliwość bezpośredniego podłączenia pod piny Arduino zachęciła mnie do dalszych poszukiwań. Zamówiłem kilka silniczków i jak tylko je dostałem zacząłem eksperymenty. Na chwilę rzeczywiście podpiąłem je do Arduino ale w zasadzie od razu przerzuciłem się na wykorzystanie mostków H – L293D, które miałem w domu. Pierwsze efekty były nad wyraz obiecujące.

Wykorzystałem dostępną bibliotekę SwitecX25 więc obsługa nie nastręczyła wiele problemów. Do obsługi każdego z 3 silników musiałem użyć oddzielnego układu L293D, a każda z kości była podłączona do 4 pinów cyfrowych Arduino. Czyli poza zasilaniem wszystkie manometry zajęły 12 pinów.
Ze względu na to, że silniki krokowe mają liniową charakterystykę to odpadło nieprzyjemne kalibrowanie znane ze wskaźników elektromagnetycznych. Wystarczyło przeskalować zakres danych dostarczanych z symulatora na zakres kroków silników.

motor1.setPosition(map(BrakePress, 0, 1023, 0, 944));
motor2.setPosition(map(PipePress, 0, 1023, 0, 944));
motor3.setPosition(map(TankPress, 0, 1023, 0, 944));

Pierwszą próbę zrobiłem na domyślnej rozdzielczości 8 bitów czyli od 0 do 255, jednak ze względu na to, że silniczki mają 315 stopni z rozdzielczością 3 kroków na stopień, zmotywowało mnie to do skorzystania z dostępnej 10 bitowej rozdzielczości danych otrzymywanych z symulatora. Powyższy przykład przeskalowuje te dane z zakresu 0-1023 na pełny zakres pracy silniczka, czyli 0-944 kroki. Oczywiście jest to zakres większy od skali manometrów, więc korzystając z bardzo użytecznego narzędzia MWD_SerialPort_tester udostępnionego przez @maciek001 określiłem wartości maksymalne i wprowadziłem je zamiast malsymalnych wartości 944.

Apetyt rośnie w miarę jedzenia i po pierwszych zachwytach nad nową możliwością napędzania manometrów zauważyłem pewne niedoskonałości. Pomijając chwilowe problemy z dziwnym zachowaniem wskazówek po restarcie mikrokontrolera, zwłaszcza po załadowaniu nowej wersji kodu, w oczy zaczęły rzucać się się poszczególne kroki podczas wolnego ruchu wskazówek. Wspomniane dziwne zachowania nadal są dla mnie niezbyt jasne, bo wg opisów funkcje:

motor1.zero();
motor2.zero();
motor3.zero();

powinny powodować ustawienie wszystkich wskazówek na pozycję początkową. Niestety po załadowaniu kodu i resecie Arduino każda wskazówka żyła własnym życiem i zatrzymywała się w dość przypadkowej pozycji. Na szczęście gdy już zmusiłem je to przyjęcia położenia zerowego, praca w połączeniu z symulatorem była prawidłowa, a po zamknięciu programu wszystkie wskazówki ładnie wracały na 0.

AX1201728SG – poczwórny sterownik silników krokowych

Chęć poprawienia zachowania silniczków, szczególnie przy wolnej pracy popychała mnie do ciągłego przeglądania projektów symulatorów lotniczych. W końcu trafiłem na ten artykuł, do którego odwoływało się wielu pasjonatów. Guy Carpenter też próbował różnych rozwiązań sterowania silniczkami x25/x27, a jego opis i efekty pokazane na YT zachęciły mnie do zamiany układów L293D na dedykowany sterownik silników krokowych AX1201728SG. Na jego dostawę musiałem dość długo poczekać ale w końcu przesyłka dotarła i mogłem poskładać nowy zestaw. Bardzo pomocny okazał się fakt wykorzystania tej samej biblioteki, którą wykorzystałem przy mostkach H oraz jej modyfikacji SwitecX12 przygotowanej przez Guy’a.
Zmiana w kodzie przy przesiadce z L293D na AX1201728SG nie była zbyt skomplikowana jednak wymagała kilku modyfikacji. Nowy sterownik obsługuje znacznie więcej kroków, więc zamiast 945 mamy teraz 3780. Dodatkowo wszystkie 3 silniki można podpiąć do jednego układu, który może sterować maksymalnie 4 silnikami krokowymi. Sterowanie każdym z nich wymaga podania 2 sygnałów: krok oraz kierunek, więc zamiast 4 przewodów jak poprzednio, wystarczy podłączyć tylko 2. Dzięki temu wszystkie silniki zajęły teraz 7 pinów (po 2 na każdy silnik plus 1 pin Reset) na kontrolerze Arduino.
Ostatecznie po zmianie okablowania, ustaleniu wartości maksymalnych zgodnie ze skalą każdego z manometrów, funkcja ich obsługi wygląda następująco:

void manometry_x25()  {
  motor1.setPosition(map(BrakePress, 0, 1023, 0, 3126));
  motor1.update();
  motor2.setPosition(map(PipePress, 0, 1023, 0, 3126));
  motor2.update();
  motor3.setPosition(map(TankPress, 0, 1023, 0, 3318));
  motor3.update();
}

gdzie wartości 3126 oraz 3318 wynikały z potrzeby ograniczenia zakresu pracy wskazówek do maksimów każdej skali. Pełen zakres ruchu jest oczywiście dostępny dla wartości 3780, którą należy użyć w trakcie dopasowania się do skali manometrów obliczając to przy pełnym zakresie kąta ze wzoru:

<wartość bitowa dla maksimum na skali manometru przy pełnym zakresie> * 3780 / 1023

Oczywiście wcześniej należy użyć stosownej biblioteki i zdefiniować parametry silników i połączeń.

#include <SwitecX12.h>

const int STEPS (315*12);
const int A_STEP = 4;
const int A_DIR = 5;
const int B_STEP = 6;
const int B_DIR = 7;
const int C_STEP = 8;
const int C_DIR = 9;
const int RESET = 10;

SwitecX12 motor1(STEPS, C_STEP, C_DIR);
SwitecX12 motor2(STEPS, B_STEP, B_DIR);
SwitecX12 motor3(STEPS, A_STEP, A_DIR);

Zastosowane przeze mnie podłączenia między pinami silników, a pinami sterownika dla trzech manometrów wyglądają następująco:

  • motor1 (pin1) – OUT1C (pin21)
  • motor1 (pin2) – OUT2C (pin20)
  • motor1 (pin3) – OUT3C (pin18)
  • motor1 (pin4) – OUT4C (pin19)
  • motor2 (pin1) – OUT1B (pin22)
  • motor2 (pin2) – OUT2B (pin23)
  • motor2 (pin3) – OUT3B (pin25)
  • motor2 (pin4) – OUT4B (pin24)
  • motor3 (pin1) – OUT1A (pin7)
  • motor3 (pin2) – OUT2A (pin6)
  • motor3 (pin3) – OUT3A (pin4)
  • motor3 (pin4) – OUT4A (pin5)

Połączenia między pinami sterownika, a pinami Arduino MEGA:

  • A-step [f(scx) A (pin28)] – MEGA (pin4)
  • A-dir [CWCCW A (pin27)] – MEGA (pin5)
  • B-step [f(scx) B (pin3)] – MEGA (pin6)
  • B-dir [CWCCW B (pin2)] – MEGA (pin7)
  • C-step [f(scx) C (pin14)] – MEGA (pin8)
  • C-dir [CWCCW C (pin13)] – MEGA (pin9)
  • Reset [RESET] – MEGA (pin10)
  • VDD [pin1 i 15] – MEGA (+5V)
  • VSS [pin12] – MEGA (GND)

Efekty zastosowania sterownika AX1201728SG wyglądają tak:

Przeprowadziłem różne testy mające na celu minimalizowanie skokowej pracy wskazówek widoczne szczególnie przy powolnych ruchach. Chciałem też zapewnić stabilny powrót wskazań do położenia zerowego i dlatego zrobiłem kilka zmian w samej bibliotece, a konkretnie pliku SwitecX12.cpp. Poniższe wartości dały mi w miarę dobre efekty:

static unsigned short defaultAccelTable[][2] = {
  {  10, 10000},
  {  50,  7000},
  { 150,  3000},
  { 300,  1500},
  { 500,   900}
};

const int resetStepMicrosec = 900;

Jak wspominałem wyżej, użycie funkcji motorX.zero() w setupie nie zawsze powoduje powrót wskazówek do pozycji zerowej, więc przygotowałem dodatkową funkcję zerującą:

void zerowanie_manometrow() {
  motor1.zero();
  motor2.zero();
  motor3.zero();
}

Można ją wywoływać w miarę potrzeby np. jakimś nieużywanym przyciskiem pulpitu, gdy wskazówki zostaną w niezerowym położeniu np. po zawieszeniu się symulatora.

Oczywiście aby manometry działały prawidłowo, niezbędny jest wpis do pliku eu07.ini określający wartość maksymalną i rozdzielczość bitową danej wartości. Jest to parametr uarttune, który w przypadku zastosowania rozdzielczości 10 bitowej wygląda następująco:

uarttune 26 225 71 236 1.6 1023 1.0 1023 1.0 1023 1.0 1023 4000 255 800 255 150 255

Pogrubione wartości odpowiadają testowanym trzem manometrom, od lewej:

  • 1.6 1023 dla zbiornika głównego
  • 1.0 1023 dla przewodu głównego
  • 1.0 1023 dla cylindra hamulcowego

Po powyższych doświadczeniach doszedłem do wniosku, że silniczki x27.168 są bardzo ciekawą alternatywą do napędzania manometrów lokomotywy. Łatwość ich zaimplementowania, niewielkie rozmiary, duży kąt pracy oraz przyzwoite efekty wizualne powodują, że warto się zainteresować taką opcją, szczególnie gdy ktoś jeszcze nie zainwestował w obrotomierze. Wykorzystanie ich w projektach z PoKeys może być trudniejsze, chociaż nie zastanawiałem się nad takim scenariuszem, jednak dla tych, którzy zdecydowali się na Arduino lub inne mikrokontrolery może być to tanie i dobre rozwiązanie. Niestety są też i wady, których nie udało mi się do końca wyeliminować. Gdy wskazania zmieniają się bardzo powoli, np. podczas napełniania zbiornika głównego, daje się zauważyć drobne kroki wskazówki zamiast jej płynnego przesuwu. Może to wina biblioteki, użytych parametrów lub jeszcze czegoś innego o czym nie mam jak na razie pojęcia.

Osobiście nie planuję zamiany działających manometrów i przesiadki na x27 jednak w przypadku awarii któregoś z nich prawdopodobnie będę zmuszony do skorzystania z tej opcji.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.