W porze letniej, jak to zwykle bywa, słońce lubi dać się we znaki. Najlepiej wówczas wypoczywać nad wodą, jednak nie wszyscy lubią się bezsensownie smażyć lub dryfować jak korek.
Opisany poniżej projekcik może przysporzyć świetnej zabawy podczas wypoczynku na plaży lub basenie (oraz zająć czas przed wyprawą nad wodę :) ) Jest to zdalnie sterowany ślizgacz napędzany niewielką „turbiną wiatrową”.
W założeniu projektowym chciałem ograniczyć rozmiary ślizgacza, tak aby nadawał się do transportu w plecaku lub większej torbie, chciałem również wykonać projekt jak najniższym kosztem, używając części z odzysku lub najtańszych na rynku oraz wykorzystać jak najprostsze i najłatwiejsze w obsłudze komponenty. Założyłem sobie również cel, aby ślizgacz był w stanie udźwignąć masę własną około 500g.
Do wykonania projektu użyłem:
- materiałów na ślizgacz:
- gąbki izolującej do rur miedzianych około 160-200cm, 15/9mm
- kawałka butelki z płaskim brzegiem
- drewnianej listewki 15x15mm
- kawałka miedzianego drutu 0.8mm
- 3 opakowań kleju szybkoschnącego (cyjanowego) i/lub opcjonalnie kleju na gorąco
- mostka H, modułu L298N Dual H Bridge
- przełącznika MTS-2
- Arduino Nano v3
- modułu nrf2401l
- koszyczka do baterii AAx8
- 8 baterii AA 1.5V
- około 380g filamentu PLA
- 19 przewodów z zarobionymi końcówkami nsr-01 (do goldpinów)
- silnika DC 12v
- serwo MG90S
- śrubek M3 i M4 (4 x 16mm M3 + nakrętka i podkładka, 2 x 15mm M4 + nakrętka i podkładka)
- szpil M3 (2 x 65mm, 2 x 115mm + 8x nakrętka i podkładka)
- spinacza biurowego
- materiałów na kontroler:
- Arduino Nano v3
- modułu nrf2401l
- joysticka
- przełącznika
- klipsa do baterii 9V
- baterii 9V
- około 70g filamentu PLA
- 12 przewodów z zarobionymi końcówkami nrs-01
- dwóch kolorów lakieru (opcjonalnie)
- narzędzi:
- komputera :)
- drukarki 3D i osprzętu niezbędnego do drukowania
- lutownicy i osprzętu niezbędnego do lutowania
- piłki do drewna
- nożyka (tapeciaka, ale każdy ostry się nada)
- śrubokrętu krzyżakowego
- kombinerek/szczypczyków, dwie sztuki
- kawałka papieru ściernego lub pilniczka (około 200p)
- środków ochrony:
- rękawiczek gumowych, (w skrajnych przypadkach niepewności własnych rąk polecam okulary ochronne :) )
- kartonu do zabezpieczenia powierzchni pod klejonymi komponentami
- oprogramowania:
- Fusion 360
- Atom + PlatformIO (ale można tradycyjnie Arduino IDE)
- biblioteka RadioHead
Sporą część materiałów miałem po prostu na stanie, więc ciężko oszacować dokładny koszt.
„Badanie” empiryczne
Budowę zacząłem od ucięcia czterech równych kawałków pianki izolującej i oszacowania wyporności.Posłużył mi do tego ciężar znanej wcześniej masy.
W brodziku napuściłem dostatecznie dużo wody, aby pianki pływały, związałem pianki razem (coś na wzór tratwy) i zakleiłem otwory wlotowe. Następnie położyłem ciężar o masie 0.5kg na nich.
Pianki te mają stosunkowo dobrą wyporność, dlatego docinałem pianki (skracałem) tak długo, dopóki ciężar nie zaczął lekko podtapiać „tratwy”.
Z przeprowadzonego doświadczenia wynikło, że 4 kawałki pianki przycięte do 40cm długości są wystarczające.
Dwa z czterech kawałków pianki usztywniłem wpychając do środka drewnianą listewkę dociętą na wymiar.
Ważne: pianka której użyłem nie miała rozcięcia wzdłuż, było tylko lekkie nacięcie ale nierozerwane (szczelne).
Użyta kanciasta listewka 15 x 15mm i pianka izolująca (15mm wewnętrzna średnica + 9mm gruba pianka):
Projektowanie ślizgacza
Mając pewność co do wyporu pianki izolującej, zmierzyłem jej średnicę i długość, aby zamodelować ją w programie do projektowania.
Do projektowania użyłem programu Fusion 360 od Autodesk-u.
Istotne jest, że podczas projektowania nie obeszło się bez wielokrotnych iteracji i poprawek. W kolejności, w której opisuje projektowanie, mniej więcej na bieżąco drukowałem i przymierzałem elementy.
Mając zamodelowane „płozy/burty” ślizgacza, obudowałem je w dzioby, rufy i łączniki, będące jednocześnie podporami dla belek łączących lewą burtę z prawą burtą.
Postawiłem sobie za cel, aby belki łączące (i dalej omawiany napęd) przy drukowaniu zajęły maksymalnie pole robocze na nowo zbudowanej drukarce (to był pewnego rodzaju test druku – pierwszy tak obszerny płaszczyzną obiekt). Zanim jednak zaprojektowałem belki, dostosowałem proporcje rozstaw/długość tak, aby końcowa konstrukcja nie była zbyt kwadratowa w górnym rzucie.
„Na oko” ale wyszło znakomicie :) Chciałem, aby belki łączące kształtem przypominały rozciągnięty w poziomie maszt przesyłowy.
Ponieważ miałem pod ręką komponenty elektroniczne (które miały napędzać ślizgacz), zaprojektowałem na nie obudowę. Wymyśliłem sobie przeźroczystą pokrywkę :)
Mając większą część konstrukcji, przystąpiłem do projektowania napędu. Bardzo chciałem spróbować koncepcji napędu spotykanego w poduszkowcach – czyli jeden silnik napędzający i mechanizm zmiany strugi powietrza – coś jak tu:
(Obrazek z http://www.elektroda.pl/rtvforum/topic1067224.html)
Zapożyczyłem śmigło od jednego z projektantów na Thingverse, przeskalowałem je i pod wymiar zaprojektowałem mechanizm zmiany strugi powietrza oraz osłonę mającą na celu ukierunkować przepływ powietrza.
Na koniec konstrukcji ślizgacza doprojektowałem uchwyty mocujące silnik i serwo.
Ponieważ miałem wątpliwości, czy posiadany przeze mnie silnik DC (z odzysku) będzie miał siłę pchnąć konstrukcję do przodu, zostawiłem trochę miejsca na wypadek konieczności zmiany silnika na porządny bezszczotkowy z ESC.
Tak prezentuje się render całości zaprojektowanego ślizgacza :)
Projektowanie kontrolera
Projektowanie kontrolera okazało się bardzo ciekawym wyzwaniem, ponieważ chciałem, aby mój kontroler był ergonomiczny dla dłoni.
Za wzór posłużyły mi oczywiście pady od PlayStation i Xbox-a (w końcu grają tym miliony ludzi, to musi być wygodne), ale nie potrzebowałem aż tak rozbudowanego układu dla dwóch dłoni, tylko dla jednej, dlatego wykorzystałem tylko łuk dla śródręcza.
Aby kontroler był wygodny, musiał się mieścić w dłoni i wygodnie leżeć, dlatego resztę elektroniki i baterię przeniosłem poniżej linii palców tak, aby można było trzymać kontroler jedną ręką i bez problemów „nawigować”.
Na poniższym obrazku jest pokazane kolorami na jakie kawałki podzieliłem model przy druku aby uzyskać jak najdokładniejsze odzwierciedlenia model->druk.
Tyle słowem o projektowaniu konstrukcji drukowanej. W miedzy czasie, zanim poskładałem wszystko w całość, opracowywałem krok po kroku układ sterujący, który opisałem w kolejnym podpunkcie. Szczegóły montażu i zdjęcia realnych druków będą pod koniec.
Struktura projektu w Atom/PlatformIO
Projekt ślizgacza pod względem programowania rozbiłem na dwa oddzielne projekty firmware – nadajnik/odbiornik, struktura na poniższym obrazku.
Zdalna kontrola
Na początek skonfigurowałem i sparowałem transmisję pomiędzy dwoma Arduino Nano v3 za pośrednictwem modułów nrf2401l. Użyłem do tego biblioteki RadioHead (bardzo fajna i pomocna biblioteczka).
Podłączenie modułów nrf z Arduino w przypadku nadajnika i odbiornika jest identyczne, jedynie przy nadajniku zabraknie pinów GND (ale jak to obejść bez sztukowania przewodów opisuję poniżej, przy omawianiu joysticka):
1 2 3 4 5 6 7 8 9 |
moduł nrf –> arduino IRQ –> nie używany MISO –> MISO (D12) MOSI –> MOSI (D11) SCK –> SCK(D13) CSN –> SS (D10) CE –> D9 VCC –> 3V3 (koniecznie 3.3V!) GND –> DND |
Poniżej przydatny pinout modułu nrf i arduino
(Obrazek z http://www.sunrom.com/p/rf-module-2-4ghz-nrf24l01)
(Obrazek z https://forum.arduino.cc/index.php?topic=147582.0)
Osprzęt nadajnika – oprócz modułu nadawczego potrzebny był joystick. Użyłem modułu joysticka z serii RobotDyn:
(Obrazek z http://propix.com.pl/pl/p/Modul-Joystick-analogowy-Arduino-RobotDyn/1189)
Jednak zamiast zasilić joystick z 5V, zasiliłem go celowo z 3.3V. Zrobiłem to dlatego, że w Arduino Nano są tylko dwa piny GND, a potrzebowałem trzech: jeden na zasilanie, jeden dla modułu NRF i jeden dla joysticka.
Ponieważ w module joysticka GND i VCC jest „wspólna” dla wyprowadzeń, to użyłem tego modułu jako rozgałęźnika dla 3.3V i GND, żeby mieć jak zasilić nrf.
Zachowanie pełnej funkcjonalnościmodułu joysticka wymagało delikatnej zmiany odczytu z pinów analogowych, co pokażę w kodzie (fragment myJoystick.cpp → myJoystick::init() → linia analogReference).
Na poniższym obrazku jest pokazane, jak połączyłem wszystkie komponenty w nadajniku (kontrolerze).
Zamiast rysować kolorowy “makaron” oznaczyłem wyprowadzenia etykietkami, żeby było czytelnie, więc proszę zwrócić uwagę na kolory i numery.
Przed przystąpieniem do łączenia komponentów przygotowałem przewody łączące przełączniki ze źródłem zasilania oraz pozarabiałem niezbędne końcówki.
BARDZO WAŻNE: zasilanie z baterii jest podłączone do pinu VIN,czyli +9V do VIN a minus baterii do GND.
Bez obaw, Arduino posiada stabilizator LM1117-5.0 i nic się z nim nie stanie, jeżeli podłączysz zasilanie prawidłowo, według specyfikacji stabilizatora, będzie on poprawnie działał nawet przy zasilaniu do 15V. Ważne, aby zachować dla stabilizatora zależność – 1.4V ≤ Vin-Vout ≤ 10V.
Firmware nadajnika (kontrolera)
Poniżej kawałek (jak mniemam) dosyć przejrzystego kodu. Na potrzeby projektu dopisałem kilka malutkich bibliotek, dzięki którym właściwy kod jest czytelniejszy.
transmitter.ino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//wszystko dla modułu nrf #include <SPI.h> #include <RH_NRF24.h> #define CE 9 //digital 9 #define CSN 10 //digital 10 RH_NRF24 nrf24(CE, CSN); //wszystko dla modułu joysticka #include <myJoystick.h> #define xPin A6 // analog 6 #define yPin A7 // analog 7 #define cPin 8 // digital 8 myJoystick joystick(xPin,yPin,cPin); void setup() { Serial.begin(9600); while (!Serial) ; //czekaj aż serial port zostanie zainicjowany, potrzebne tylko dla Arduino Leonardo if (!nrf24.init()) Serial.println("init failed"); //niezbędne ustawienia dla modułu nrf24, wybieram kanał 1 if (!nrf24.setChannel(1)) Serial.println("setChannel failed"); if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm)) Serial.println("setRF failed"); //inicjalizacja joysticka joystick.init(); } void loop() { //wysyłanie statusu joysticka nrf24.send(joystick.getState(), joystick.getStateSize()); //odczkaj aż status zostanie wysłany nrf24.waitPacketSent(); } |
Napisana biblioteczka do obsługi joysticka:
myJoystick.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#ifndef myJoystick_h #define myJoystick_h #include <Arduino.h> #include <stdint.h> class myJoystick { private: int sensorMin = 0; // minimalna wartośc odczytana z pinu analogowego int sensorMax = 1023; // maksymalna wartośc odczytana z pinu analogowego int sensorMinMap = 255;// minimalna wartośc do mapowania stanu int sensorMaxMap = 0; // maksymalna wartośc do mapowania stanu int X,Y,C; uint8_t STATE[6]; // { '[', 'X', 'Y', 'C', ']', '\0' }; public: myJoystick(int _X_pin, int _Y_pin, int _C_pin ); void init(); void initClickPin(); int mapAxis(int axis); char getAxis(int pin); char getClick(); uint8_t *getState(); uint8_t getStateSize(); }; #endif |
myJoystick.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
#include <myJoystick.h> myJoystick::myJoystick(int _X_pin, int _Y_pin, int _C_pin ) { X=_X_pin; Y=_Y_pin; C=_C_pin; } void myJoystick::init() { initClickPin(); //ustawienie źródła referencyjnego dla ADC jako zewnętrzne //dzięki czemu przy użyciu 3.3V zachowujemy zakres odczytu od 0 do 1023 analogReference(EXTERNAL); //domyslny stan joysticka //roboczo przyjąłem koncepcję 5 stanów joysticka opisywanych od a do c {a,b,c} //a na osi X i Y oznacza minimum, na przycisku stan nie wciśnięcia //b na osi X i Y oznacza pozycję neutralną, na przycisku nie występuje //c na osi X i Y oznacza maksimum, na przycisku stan wciśnięcia STATE[0]='['; STATE[1]='b'; STATE[2]='b'; STATE[3]='c'; STATE[4]=']'; STATE[5]='\0'; } void myJoystick::initClickPin() { //ustawienie pinu jako wejściowy pinMode(C,INPUT); //ustawienie pull-up dla wybranego wejściowego pinu C (patrz http://arduino.cc/en/Tutorial/DigitalPins) digitalWrite(C,HIGH); } int myJoystick::mapAxis(int axis) { return (int)(map(axis, sensorMin, sensorMax, sensorMinMap, sensorMaxMap)); } char myJoystick::getAxis(int pin) { int val = mapAxis(analogRead(pin)); //przeskalowaną wartośc od 0 do 255 mapuję na stany a, b lub c if(val<100) { return (char)'a'; } else { if(val>=100 && val<=150) return (char)'b'; else return (char)'c'; } } char myJoystick::getClick() { return (char)((digitalRead(C)==HIGH)?('a'):('c'));// będzie HIGH (1) gdy niewciśnięte i LOW (0) gdy wciśnięte } uint8_t *myJoystick::getState() { STATE[0]='['; STATE[1]=getAxis(X); STATE[2]=getAxis(Y); STATE[3]=getClick(); STATE[4]=']'; STATE[5]='\0'; return STATE; } uint8_t myJoystick::getStateSize() { return sizeof(STATE); } |
Układ napędowo-sterujący
Mając zmontowany i zaprogramowany układ nadawczy, poskładałem i zaprogramowałem układ odbiorczy. Jako sterownika silnika napędowego użyłem modułu z mostkiem H (L298N), do zmiany kierunku ślizgacza wykorzystałem serwo MG90S. Dokładny sposób połączenia wszystkich komponentów odbiornika i układu napędowego przedstawia poniższy obrazek.
Firmware odbiornika (ślizgacza)
receiver.ino
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
//wszystko dla modułu nrf #include <SPI.h> #include <RH_NRF24.h> #define CE 9 //digital 9 #define CSN 10 //digital 10 RH_NRF24 nrf24(CE, CSN); uint8_t joystickState[6]; // { '[', 'X', 'Y', 'C', ']', '\0' }; //można też użyć długości [RH_NRF24_MAX_MESSAGE_LEN] //joystickState jest tak na prawdę buforem odbioru #define disconectionTimeLimit 1000 //ms int disconnectionCounter = 0; //wszystko dla serwo mechanizmu #include <MG90S.h> #define sPin 8 MG90S serwo(sPin); //wszystko dla motoru DC #include <DC_motor.h> #define aPin 7 #define bPin 6 DC_motor motor(aPin, bPin); void setup() { Serial.begin(9600); while (!Serial) ; //czekaj aż serial port zostanie zainicjowany, potrzebne tylko dla Arduino Leonardo if (!nrf24.init()) Serial.println("init failed"); //niezbędne ustawienia dla modułu nrf24, wybieram kanał 1 if (!nrf24.setChannel(1)) Serial.println("setChannel failed"); if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm)) Serial.println("setRF failed");<br> //inicjalizacja swerwo i silnika serwo.init(); motor.init(); } void loop() { if (nrf24.available()) { //gdy jest łącznośc if (nrf24.recv(joystickState, sizeof(joystickState))) { //sprawdzam poprawnośc przesłanej "paczki" if(joystickState[0]=='[' && joystickState[4]==']') { //resetuję licznik braku łączności disconnectionCounter = 0; //obsługa osi X - lewo/prawo switch (joystickState[1]) { case 'a': serwo.setAngle(45); break; case 'b': serwo.setAngle(90); break; case 'c': serwo.setAngle(135); break; } //obsługa osi Y - przód/tył switch (joystickState[2]) { case 'a': motor.runBackward(); break; case 'b': motor.stop(); break; case 'c': motor.runForward(); break; } //obsługa kliknięcia joystickiem if(joystickState[3]=='c') { //wykonaj akcję kliknięcia //tu do dobrego działania wymagane jest zaimplementowanie czegoś w rodzaju "debouncingu" //ponieważ pakiety z kolejnymi statusami joysticka przychodzą bardzo szybko //mi nie było potrzebne na razie obsłużenie kliknięcia ale może przydać się na przyszłość } } } }else{ //gdy łaczności nie ma - odczekaj około sekundy i wyłącz silnik aby ślizgacz nie uciekł za daleko delay(1); disconnectionCounter++; if(disconnectionCounter>=disconectionTimeLimit) { // gdyby dołożyć kompas lub GPS do konstrukcji można by zaprojektować "powrót" ale tymczasem tylko stop silników: serwo.setAngle(90); motor.stop(); } } } |
Na potrzeby projektu napisałem biblioteczkę do obsługi serwomechanizmu, bez obsługi przerwań, ponieważ biblioteka RadioHead zużywa tych samych wystąpień zegarowych i koliduje to z “gotowcem” od Arduino.
Serwo, aby obróciło się o zadany kąt, musi otrzymać odpowiedniej długości impuls na wejściu. W czasie 20us (mikrosekund, nie milisekund!) sygnału musi wystąpić impuls w stanie wysokim. W zależności od tego jak długi ten impuls będzie, o taki kąt obróci się serwo. Pozostały czas należy uzupełnić do 20us w stanie niskim. W ten sposób jest też napisana oryginalna biblioteka do serwo z tym, że używa przerwań zegarowych do odmierzania czasu.
MG90S.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//Autor: Cezary Wernik #ifndef MG90S_h #define MG90S_h #include <Arduino.h> #include <stdint.h> class MG90S { private: int impulsePeriod = 20000; //us int pulseMinLen = 544; //us int pulseMaxLen = 2400; //us int S; //wartości minimalnego i maksymalnego impulsu podpatrzyłem w oryginalnej biblioteczce, natomiast //indywidualne wartości można uzyskać mając oscyloskop i sprawdzając na jakie krótkie impulsy serwo zaczyna reagować //prawidłowo, jednak można w ten sposób uszkodzić serwo, dlatego wolałem skorzystać ze sprawdzonych wartości public: MG90S(int _S_pin); void init(); void setAngle(int angle); }; #endif |
MG90S.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
//Autor: Cezary Wernik #include <MG90S.h> MG90S::MG90S(int _S_pin) { S = _S_pin; } void MG90S::init() { pinMode(S, OUTPUT); setAngle(90); } void MG90S::setAngle(int angle) { int pulseAngle=map(angle,0,180,pulseMinLen,pulseMaxLen);//konwersja miary kątowej na czas impulsu dla serwa noInterrupts();//na chwilę wyłączam przerwania aby generowane impulsy dla serwa były właściwych długości digitalWrite(S, HIGH); delayMicroseconds(pulseAngle); digitalWrite(S, LOW); delayMicroseconds(impulsePeriod - pulseAngle);//odczekanie właściwej długości zanim zostanie wysłany kolejny impuls ustawiający //dodatkowo dodany czas : delayMicroseconds(180*impulsePeriod); //na przemieszczenie, trochę na zapas za dużo ale lepiej więcej niż mniej interrupts();//przywracam działanie przerwań } |
Żeby zachować konwencję i czystość kodu głównego, napisałem biblioteczkę dla silnika napędowego. Jest to, co prawda, bardzo uproszczona wersja tego, co można tak naprawdę zdziałać z modułem L298N, ponieważ może on obsłużyć dwa silniki DC lub jeden krokowy. Dodatkowo w przypadku DC istnieje możliwość płynnego regulowania prędkości i miękkiego startu i hamowania silnika. Nie potrzebowałem teraz aż takich udogodnień i zwyczajna zmiana kierunku obrotu silnika oraz swobodne hamowanie w zupełności wystarczało.
DC_motor.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//Autor: Cezary Wernik #ifndef DC_motor_h #define DC_motor_h #include <Arduino.h> #include <stdint.h> class DC_motor { private: int A; int B; public: DC_motor(int _A_pin, int _B_pin); void init(); void runForward(); void runBackward(); void stop(); }; #endif |
DC_motor.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//Autor: Cezary Wernik //W przypadku niejasności dlaczego ciała funkcji poniżej wyglądają w ten sposób, wyjaśniam że moduł ten działa jak mostek H //bardzo szczegółowe informacje o mostku tego typu są tu: http://www.talkingelectronics.com/projects/H-Bridge/H-Bridge-1.html //opis modułu którego użyłem znajduje się tu: https://abc-rc.pl/L298N-sterownik, pod aukcją #include <DC_motor.h> DC_motor::DC_motor(int _A_pin, int _B_pin) { A = _A_pin; B = _B_pin; } void DC_motor::init() { pinMode(A,OUTPUT); pinMode(B,OUTPUT); } void DC_motor::runForward() { digitalWrite(A,HIGH); digitalWrite(B,LOW); } void DC_motor::runBackward() { digitalWrite(A,LOW); digitalWrite(B,HIGH); } void DC_motor::stop() { digitalWrite(A,LOW); digitalWrite(B,LOW); } |
Montaż elementów drukowanych i mechanicznych, oraz o tym jak drukowałem
Jak drukowałem? – Ślizgacz drukowałem w PLA (Ekofilament) w temperaturze 215 stopni, na stole rozgrzanym do 70 stopni. Za klej do druku posłużył mi najtańszy lakier do włosów z popularnej “sieciówki z robaczkiem”.
Wydrukowane elementy łączyłem klejem szybkoschnącym (klejem cyjanowym – czymś w rodzaju popularnego SuperGlue).
Przed klejeniem oczyściłem i zmatowiłem klejone powierzchnie drobnym papierem ściernym.
Zabezpieczyłem blat, na którym kleiłem komponenty kartonem, aby niechcący nie przykleić ślizgacza do biurka na stałe :)
Podczas klejenia używałem rękawiczek gumowych – niby śmieszne, ale bardzo się przydało – jedna z tubek kleju miała słabo zgrzane opakowanie i w momencie odwrócenia tubki połowa kleju momentalnie się rozlała, rękawiczki oszczędziły trudu w rozklejaniu palców :)
Do sklejenia w pierwszej kolejności były elementy burt, dzioby, rufy, łączniki, później belki, mocowanie napędu i obudowa elektroniki.
Ważne: każda z burt ma po jednej piance z upchniętą listewką aby konstrukcja była sztywna, usztywnione pianki umocowałem po zewnętrznych stronach.
Sklejona rufa z mocowaniem napędu i łącznikiem:
Sklejone belki łączące burty lewą z prawą:
Przyklejony dziób:
Miejsce klejenia obudowy z belkami:
Niestety nie wziąłem pod uwagę faktu, że kleje cyjanowe zostawiają biały ślad od oparów. Wymyślona przeze mnie półprzeźroczysta obudowa przeźroczyste miejsca miała mieć z plastiku wyciętego z butelki. Jak zaplanowałem tak zrobiłem, niestety po kilku godzinach odkryłem dwa problemy: klej cyjanowy słabo łączył plastik butelki z filamentem PLA oraz opary kleju zmatowiły całą dociętą plastikową “szybkę”.
Zmatowienie udało się oczyścić “alkoholem” (woda pogoleniu), niestety klej cyjanowy słabo trzymał szybkę i pomógł dopiero klej na gorąco.
Podczas drukowania ważne jest, aby nie zapomnieć często czyścić stołu. Przed drukowaniem pokrywki do elektroniki zapomniałem niestety oczyścić stół, czego efektem są wzorki na powierzchni drukowanej.
Pozostałe elementy są łączone śrubkami M3 o długości 16mm, 2 szpilami M3 o długości 115mm i 2 szpilami M3 o długości 65mm.
Mocowanie silnika:
Zdecydowałem się na częściowe łączenie klejem a częściowe skręcanie śrubami ze względu na dalszą możliwość rozwoju. Założyłem, że interesujący w modyfikacji może być napęd, a pozostałe elementy są “bazą”. Cały napęd można wymienić w miejscu łączenia śrubami M4, dodatkowo łączenie to zapewnia możliwość regulacji kąta nachylania strugi powietrza.
Napęd trzyma się na dwóch uchwytach przyklejonych do rufy:
Śruba do regulacji kąta nachylania i wymiany napędu:
Śmigło jest przyklejone na stałe do wirnika silnika:
Mocowanie serwo jest na wcisk w dedykowanej szczelinie:
Przełożenie serwa na łopatki sterujące strugą powietrza odbywa się poprzez dwa orczyki zespolone drutem ze spinacza biurowego:
Łopatki miedzy sobą są połączone miedzianym drutem odzyskanym z niepotrzebnego przewodu elektrycznego, dłuższymi końcami są wciśniete w pierścień/osłonę – po odpowiednim przeszlifowaniu obracają się swobodnie bez żadnych łożysk ani sparowania:
Arduino, sterownik i zasilanie oraz przełącznik umieściłem zgodnie z planem w zaprojektowanej obudowie.
Lutownicą ze starym przepalonym grotem zrobiłem otwór na przełącznik w tylnej części obudowy.
Przełącznik w tylnej części:
Zmontowany układ nadajnika upakowałem w wydrukowanej obudowie.
Wnętrze kontrolera:
Po wpadce z drukowaniem pokrywy elektroniki na lakierze postanowiłem przetestować jak się drukuje na taśmie malarskiej:
Druk na taśmie wyszedł bardzo ładnie, taśma zostawia ładną matową fakturę na druku, ma to swój urok :)
Co istotne: taśma przy druku z PLA zachowała bardzo dobrą przyczepność, nic się nie podwijało, ale odkleić też nie było łatwo :D
Nie obeszło się bez wyższej szkoły plastyki (plastiku), trochę docinania, dowiercania, doklejania:
Przed sklejeniem i doszlifowaniem:
Oczywiście zapragnąłem mieć jakiś oryginalny malunek na kontrolerze i takim sposobem wpadłem na pomysł że pomaluję go w barwy ostrzegawczej taśmy przemysłowej. Niestety z malunku który chciałem zrobić wyszła trochę bardziej pszczółka niż „quasi-przemysłowy” kontroler ale i tak kontroler spełnia swoją założoną funkcjonalność :)
Po odpowiednich zabiegach kontroler był gotowy, spełniał założone kryterium “wygody”:
Również dopasowanie do dłoni wyszło całkiem dobrze:
Galeria
Gotowy kontroler:
Ślizgacz – widok z góry:
Ślizgacz – widok z profilu:
Ślizgacz – widok odprzodu:
Ślizgacz – widok od burty:
Obudowa elektroniki z bliska:
Napęd:
Poglądowe wymiary:
Test działania
Pod tym linkiem działanie kontrolera:
Poniżej krótkie testy pływania – gdy nagrywałem filmiki obudowa kontrolera jeszcze “się nie wydrukowała” i elektronikę kontrolera wpakowałem do pudełka po ściereczkach do telewizorów. Pudełko to było mega nieporęczne i ciężko było trzymać jednocześnie telefon. Jeśli pogoda i czas pozwoli to pojawi się więcej filmików nieco dłuższych ;)
Test 1
Test 2
Test 3 – pierwotnie komunikację realizowałem przez RF433 stąd na filmikach przewody antenek (te szare), obecnie komunikacja odbywa się po NRF24 tak jak jest opisane w całym projekcie, poprawiony jest też czas reakcji na quasi-rzeczywisty.
Wnioski i spostrzeżenia
Niewątpliwie projektowanie i montaż takiej zabawki daje mnóstwo frajdy i radości :)
Po testach wiem, że z czasem wymienię silnik na bezszczotkowy kontrolowany przez ESC, ewentualnie na jakikolwiek z większymi obrotami. Obecnie ślizgacz pływa dosyć leniwie i przy mocniejszym wietrze ma problem, ale serwo i mechanizm skrętu strugi powietrza spisują się bardzo dobrze.
Przy drukowaniu warto mieć pod ręką dwa szkła do stołu lub co każdy druk czyścić stół aby druki były idealne i estetyczne, ewentualnie używać taśmy malarskiej lub dobrego kleju do druku (np. dimafix). Lakier do włosów jako klej do druku sprawdza się gdy się nie spieszymy i często czyścimy stół drukarki.
Jestem “świeżym” drukarzem 3d, ale nie lubię gdy drukowany obiekt ma dużo powierzchni stycznych z supportem, wolę wtedy podzielić model i wydrukować w kilku kawałkach a finalnie skleić i zalakierować – tak było w przypadku obudowy kontrolera.
Do klejenia elementów PLA z PLA polecam klej cyjanowy (np. SuperGlue), natomiast do klejenia PLA z PET (filament z plastikiem z butelki) klej na gorąco, być może to był odosobniony przypadek ale po prostu u mnie PLA z PET się nie imało.
Źródła i pliki do druku
- Pliki do druku kontrolera:
https://www.thingiverse.com/thing:2473211 - Pliki do druku ślizgacza:
https://www.thingiverse.com/thing:2473228 - Kody źródłowe:
- Kod nadajnika (kontrolera):
https://bitbucket.org/CezaryWernik/speed-boat-rc-transmitter/ - Kod odbiornika (ślizgacza):
https://bitbucket.org/CezaryWernik/speed-boat-rc-receiver
- Kod nadajnika (kontrolera):
___
Dziękuję za wytrwałość w czytaniu tego trochę długiego wpisu!
Jeżeli masz pomysł na: usprawnienie/modyfikacje, zaprojektowanie jakiegoś dodatku, alternatywne napędy dla tej konstrukcji (z chęcią przetestuję inne koncepcje pasujące montażem do mojej “bazy” ), podziel się w komentarzu ;)
Nawet nie chce mi się nic pisać- projekt na 6 i do tego świetny opis – BRAWO!
Tylko małe pytanie- w jakim IDE programujesz?
Dzięki :)
Do mikrokontrolerów używam PlatformIO http://platformio.org/, to cały “ekosystem” do tego typu zastosowań.
Nie sprawia kłopotów jeżeli tylko tym się zajmujesz, schody się zaczynają gdy używasz jeszcze innych środowisk do programowania np. w Python. Poprzednie wydania PlatformIO lubiły się skonfliktować :)
Patrząc po filmach to on jest znoszony przez wiatr :)
Tak jak pisałem we wnioskach i spostrzeżeniach ;)
Z czasem wymienię silnik na porządny bezszczotkowy, a konstrukcja jest już sprawdzona z zagospodarowanym miejscem na to :)
Świetny projekt !
Daje 5 (:
Ale mam kilka uwag odnośnie elektroniki i modułu komunikacyjnego:
Ma to istotny wpływ na zasięg tych modułów. I uwierz mi, jest to KRYTYCZNE dla uzyskania normalnego zasięgu. Już się na to raz nadziałem (: . Na modułach które miały wyciągać 1 Km uzyskałem 3 m bez kondensatorów i 300 metrów z kondensatorami.
Jak sam słusznie zauważyłeś napięcie wejściowe regulatora musi być co najmniej 1.4 V wyższe od napięcia wyjściowego.
Jak wnioskuję z obrazków zasilasz całość z 4 cel niklowo-wodorkowych (NI-MH) o napięciu nominalnym 1.2V (w praktyce napięcie waha się od 1.5V do 1 V), więc napięcie wyjściowe pakietu to 6V – 4V. Czyli za mało.
Nawet jak wsadzisz tam baterie alkaliczne to napięcie będzie maksymalnie wynosić ok 6.8 V. Czyli na styk.
Jak baterie się trochę rozładują to napięcie spadnie poniżej minimum, napięcie na szynie zasilającej mikrokontrolera (5V ) spadnie poniżej 5V i zaczną się problemy.
Najlepiej jest takiej sytuacji zastosować przetwornicę Step-Up / Step-Down na 5V i podłączyć ją bezpośrednio do szyny 5V.
No i jak używasz akumulatorów to ZAWSZE należy dołożyć układ który będzie nadzorować czy napięcie nie spada poniżej wymaganego minimum, może to być chociaż dioda która zapali się kiedy napięcie będzie za niskie. Nadmierne rozładowanie akumulatora skutkuje ograniczeniem pojemności. Możesz nawet podłączyć napięcie akumulatora (oczywiście przez dzielnik napięcia) do pinu analogowego arduino i realizować tę funkcję programowo.
Ale oprócz tego projekt genialny, aż miło popatrzeć na porządnie zrobioną mechanikę (:
Hej, dzięki za taki odzew :)
Na nrf w takiej konfiguracji jaka jest opisana udało mi się osiągnąć około 50m zasięgu.
W wolnej chwili sprawdzę zasięg przy mniejszej prędkości :D
Co do kanału to nie zdarzyło mi się jeszcze mieć z tym kłopotu a testowałem w budynku gdzie w co drugim pokoju jest router, ale bardzo słuszna uwaga.
Wcześniej eksperymentowałem z RF433 zasięg był dużo lepszy około 100m do czasu aż nie uszkodziłem niechcący jednej z anten, pomimo skrupulatnych wyliczeń długości anteny nowo docięte precyzyjnie anteny nie działały już tak sprawnie jak fabryczne.
Zasilanie układu napędowo-kontrolnego – zasilam z paczki 8×1.5v, daje mi to 12v przy dobrze naładowanych bateriach.
Arduino odbiornika zasilam z 5v, które uzyskuje z modułu L298N (na pokładzie jest stabilizator), i owszem podłączam 5V do VIN ale testowałem już takie rozwiązania, stabilizator na pokładzie Arduino nie jest aż tak deterministyczny, a ATmega w Arduino jeżeli nie używa ADC to część logiczną potrafi poprawnie utrzymać w skrajnych warunkach. Ale bez obaw zabawki typu przetwornice też mam w zanadrzu gdyby na dłuższą metę były tu problemy.
Miernik do baterii/akumulatora dołożę jak zamienię silnik, myślę nad jakimś małym pakietem (LIPO+ESC+bezszczotkowiec) + sterowanie tak jak obecnie, a sygnalizacja rozładowania w kontrolerze bo przecież komunikacja obustronna :)
Dzięki za poważne potraktowanie moich uwag (:
Teraz jeszcze wpadło mi do głowy, że warto byłoby dodać do projektu obsługę wbudowanego w mikrokontroler watchdoga. Bo jak z jakiegoś powodu zawiesi się kontroler to silnik może pozostać włączony i ślizgacz odpłynie w siną dal (:
Fakt, o braku łączności pomyślałem i to obsłużyłem ale o możliwości zwiechy uC zapomniałem :D
Jaki najlepiej dac kondensator filtrujący ??
Witam. Od samego poczatku przegladania projektu pelen podziwu. Wszystko profesjonalnie… do momentu jak nie zobaczylem tego drucika co laczy “pletwy” sterowania :) Nie ma mozliwosci zastapienia tego czyms bardziej profesjonalnym ? Ogolnie +5 tylko popraw to ;)
Na lato 2018 zrobię update do Ślizgacz 2.0, tam naniosę poprawki i dodatki :)
Teraz chwilowo mam pełne ręce pracy ;)
Też w tym roku zrobiłem ślizgacza, tyle że film na razie jest tylko ze śniegu (co Ci polecam – bardzo fajna zabawa :D), ale po wodzie też pływał.
A projekt bardzo fajny, szczególnie podoba mi się koszyk na osprzęt.
Mój wygląda tak http://pfmrc.eu/index.php/topic/71579-ma%C5%82y-airboat-z-resztek/