Spisu treści:
- Krok 1: Lista komponentów
- Krok 2: Montaż
- Krok 3:
- Krok 4: Następnie, używając tej samej metody, zabezpieczyłem serwomechanizm rolkowy. Części są specjalnie zaprojektowane, aby łatwo pasowały do serw MG995
- Krok 5: Następnie, używając tej samej metody, zabezpieczyłem serwomechanizm rolkowy. Części są specjalnie zaprojektowane, aby łatwo pasowały do serw MG995
- Krok 6: Połączenia
- Krok 7: Połączenie z układem scalonym regulatora napięcia 7805
- Krok 8: Kodowanie
- Krok 9: Kiedy wszystkie komponenty są połączone, wygląda podobnie do tego obrazu
- Krok 10: Teraz włóż całą bazę do puszki na żywność
- Krok 11: Kiedy wszystkie przewody i komponenty są umieszczone w puszce na żywność, następnie przyłóż pistolet do kleju do podstawy płyty piankowej
- Krok 12: Wniosek
2025 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2025-01-13 06:58
Witam wszystkich, Nazywam się Harji Nagi. Obecnie jestem studentem drugiego roku studium elektronikę i inżynierię komunikacyjną w Pranveer Singh Institute Of Technology, Kanpur (UP). Interesuję się robotyką, arduino, sztuczną inteligencją i elektroniką analogową.
Słowo „gimbal” definiuje się jako obrotową podporę, która umożliwia obrót dowolnego obiektu w jednej osi. Tak więc trójosiowy gimbal pozwala każdemu obiektowi zamontowanemu na gimbalu być niezależnym od ruchu osoby trzymającej gimbala. Gimbal dyktuje ruch obiektu, a nie tego, który go niesie.
Składa się z 3 serwomotorów MG996R do sterowania 3-osiowego oraz podstawy, na której zostanie umieszczony czujnik MPU6050, Arduino i bateria. Służy do ustabilizowania kamery bez wibracji. 3-osiowy gimbal zapewnia stabilizację ruchu kamery, nawet jeśli osoba, która ją trzyma, porusza się w górę iw dół, w lewo i w prawo, do przodu i do tyłu. Nazywamy to stabilizacją odchylenia, pochylenia i przechyłu.
Krok 1: Lista komponentów
Lista komponentów to:
1) Arduino Uno
2) Akumulator 8 V, 1,5 A do zasilania Arduino Uno
3) 7805 Regulator napięcia Ic lub możesz użyć konwertera buck
4) MPU 6050
5) 3 * (silniki SERWO MG995)
6) Przewody połączeniowe
Inne urządzenia:
1) lutownica
2) pistolet do kleju
3) Wiertarka
4) jedzenie może
Zamiast używać breadborad, użyłem małej niestandardowej płytki perf dla dodatniego i ujemnego połączenia magistrali
Krok 2: Montaż
Rdzeń piankowy, płyta piankowa lub płyta piankowa pokryta papierem to lekki i łatwy do cięcia materiał używany do montażu silnika serwo oraz do wykonywania modeli w skali.
Najpierw wykonałem DIY wsporniki w kształcie litery L do montażu serwomotoru za pomocą płyty piankowej.
Krok 3:
Montaż gimbala był dość łatwy. Zacząłem od zamontowania serwomechanizmu odchylenia, czujnika MPU 6050 i wyłącznika ON-OFF. Za pomocą śrub i nakrętek przymocowałem go do podstawy
Krok 4: Następnie, używając tej samej metody, zabezpieczyłem serwomechanizm rolkowy. Części są specjalnie zaprojektowane, aby łatwo pasowały do serw MG995
Krok 5: Następnie, używając tej samej metody, zabezpieczyłem serwomechanizm rolkowy. Części są specjalnie zaprojektowane, aby łatwo pasowały do serw MG995
Krok 6: Połączenia
Na schemacie można użyć konwertera buck lub układu scalonego regulatora napięcia 7805 do konwersji 8V na 5 V. Mikrokontroler, który jest podany na schemacie to Arduino Nano, można również użyć Arduino Uno, Arduino Mega.
Piny SCL i SDA MPU 6050 są podłączone do pinów Arduino Analog A5 i A4. (piny SCL i SDA mogą się różnić, więc sprawdź arkusz danych dla pinów SCl i SDA dla innego mikrokontrolera)
Krok 7: Połączenie z układem scalonym regulatora napięcia 7805
Ten schemat obwodu dotyczy podłączenia regulatora napięcia 7805 ic, podłącz baterię 8V do Vin, a otrzymasz napięcie wyjściowe 5V.
Krok 8: Kodowanie
Musisz uwzględnić następujące biblioteki:
1)#includeKliknij tutaj, aby pobrać plik zip
2)#includeKliknij tutaj, aby pobrać plik zip
Po pobraniu pliku zip dodaj bibliotekę zip w szkicu arduino
Dla kodu
/*
DIY Gimbal - MPU6050 Arduino Tutorial Code oparty na przykładzie MPU6050_DMP6 z biblioteki i2cdevlib autorstwa Jeffa Rowberga: https://github.com/jrowberg/i2cdevlib */ // I2Cdev i MPU6050 muszą być zainstalowane jako biblioteki lub.cpp/ Pliki.h // dla obu klas muszą znajdować się w ścieżce dołączania projektu #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" //#include "MPU6050.h" // nie jest konieczne, jeśli używasz pliku dołączanego MotionApps / / Biblioteka Arduino Wire jest wymagana, jeśli implementacja I2Cdev I2CDEV_ARDUINO_WIRE // jest używana w I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif #include // domyślny adres I2C klasy to 0x68 // może być konkretnym adresem I2C przekazany jako parametr tutaj // AD0 low = 0x68 (domyślnie dla płytki ewaluacyjnej SparkFun i InvenSense) // AD0 high = 0x69 MPU6050 mpu; //MPU6050 mpu(0x69); // <-- użyj dla AD0 high // Zdefiniuj 3 serwosilniki Servo servo0; Serwo serwo1; Serwo serwo2; pływak poprawny; intj = 0; #define OUTPUT_READABLE_YAWPITCHROLL #define INTERRUPT_PIN 2 // użyj pinu 2 na Arduino Uno i większości płyt bool blinkState = false; // kontrola/stan MPU vars bool dmpReady = false; // ustaw true jeśli inicjowanie DMP powiodło się uint8_t mpuIntStatus; // przechowuje aktualny bajt stanu przerwania z MPU uint8_t devStatus; // zwróć status po każdej operacji urządzenia (0 = sukces, !0 = błąd) uint16_t packetSize; // oczekiwany rozmiar pakietu DMP (domyślnie 42 bajty) uint16_t fifoCount; // liczba wszystkich bajtów znajdujących się aktualnie w FIFO uint8_t fifoBuffer[64]; // bufor pamięci FIFO // orientacja/ruch vars Quaternion q; // [w, x, y, z] kontener kwaternionowy VectorInt16 aa; // [x, y, z] pomiary czujnika przyspieszenia VectorInt16 aaReal; // [x, y, z] pomiary bezgrawitacyjnego czujnika przyspieszenia VectorInt16 aaWorld; // [x, y, z] world-frame accel pomiary czujnika VectorFloat grawitacja; // [x, y, z] wektor grawitacji float euler[3]; // [psi, theta, phi] Euler kąt kontenera float ypr[3]; // [odchylenie, skok, przechylenie] kontener zboczenia/pochylenia/przechylenia i wektor grawitacji // struktura pakietu dla demonstracji czajnika InvenSense uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' }; // ======================================================== ================ // === PROCEDURA WYKRYWANIA PRZERWANIA === // ===================== =========================================== niestabilny bool mpuInterrupt = false; // wskazuje, czy pin przerwania MPU osiągnął stan wysoki void dmpDataReady() { mpuInterrupt = true; } // ========================================== ========== // === KONFIGURACJA POCZĄTKOWA === // ====================== =========================================== void setup() { // dołącz do magistrali I2C (biblioteka I2Cdev nie robi tego automatycznie) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); Wire.setClock(400000); // Zegar I2C 400kHz. Skomentuj tę linię, jeśli masz problemy z kompilacją #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // zainicjuj komunikację szeregową // (wybrano 115200, ponieważ jest to wymagane do wyjścia Demo Teapot, // ale zależy to // od Ciebie w zależności od projektu) Serial.begin(38400); podczas (!Serial); // czekaj na wyliczenie Leonardo, inni kontynuują natychmiast // inicjowanie urządzenia //Serial.println(F("Inicjowanie urządzeń I2C…")); mpu.initialize(); pinMode(PRZERWANIE_PIN, WEJŚCIE); devStatus = mpu.dmpInitialize(); // podaj tutaj swoje własne przesunięcia żyroskopu, przeskalowane dla minimalnej czułości mpu.setXGyroOffset(17); mpu.setYGyroOffset(-69); mpu.setZGyroOffset(27); mpu.setZAccelOffset(1551); // ustawienie fabryczne 1688 dla mojego testowego układu // upewnij się, że działa (zwraca 0, jeśli tak) if (devStatus == 0) { // włącz DMP, teraz, gdy jest gotowy // Serial.println(F("Włączanie DMP…")); mpu.setDMPEwłączony(prawda); attachInterrupt(digitalPinToInterrupt(PINTERRUPT_PIN), dmpDataReady, WSCHODZĄCY); mpuIntStatus = mpu.getIntStatus(); // ustaw naszą flagę DMP Ready, aby główna funkcja loop() wiedziała, że może jej użyć //Serial.println(F("DMP gotowy! Oczekiwanie na pierwsze przerwanie…")); dmpReady = prawda; // uzyskaj oczekiwany rozmiar pakietu DMP do późniejszego porównania packSize = mpu.dmpGetFIFOPacketSize(); } else { // BŁĄD! // 1 = ładowanie pamięci początkowej nie powiodło się // 2 = aktualizacja konfiguracji DMP nie powiodła się // (jeśli ma się zepsuć, zwykle kod to 1) // Serial.print(F("Inicjalizacja DMP nie powiodła się (kod ")); //Serial.print(devStatus); //Serial.println(F(")")); } // Zdefiniuj piny, do których podłączone są 3 serwomotory servo0.attach(10); servo1.attach(9); servo2.attach(8); } // ========================================== ========== // === GŁÓWNA PĘTLA PROGRAMU === // ==================== ============================================ void loop() { / / jeśli programowanie nie powiodło się, nie próbuj nic robić, jeśli (!dmpReady) return; // czekaj na przerwanie MPU lub dodatkowe pakiety dostępne podczas (!mpuInterrupt && fifoCount < pakietRozmiar) { if (mpuInterrupt && fifoCount
= 1024) {
// zresetuj, abyśmy mogli kontynuować czysto mpu.resetFIFO(); fifoCount = mpu.getFIFOCount(); Serial.println(F("Przepełnienie FIFO!")); // w przeciwnym razie sprawdź przerwanie gotowości danych DMP (powinno się to zdarzać często) } else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) { // czekaj na poprawną dostępną długość danych, powinno być BARDZO krótkie oczekiwanie (dostępny pakiet fifoCount 1 / / (pozwala nam to natychmiast przeczytać więcej bez czekania na przerwanie) fifoCount -= packageSize; // Pobierz wartości odchylenia, skoku i przechyłu #ifdef OUTPUT_READABLE_YAWPITCHROLL mpu.dmpGetQuaternion(&q, fifoBuffer);mpu.dmpGetGravity(&gravity, &q);.dmpGetYawPitchRoll(ypr, &q, &gravity); // Wartości odchylenia, nachylenia, przechyłu - radiany na stopnie ypr[0] = ypr[0] * 180 / M_PI; ypr[1] = ypr[1] * 180 / M_PI; ypr[2] = ypr[2] * 180 / M_PI; // Pomiń 300 odczytów (proces autokalibracji) if (j <= 300) { correct = ypr[0]; // Odchylenie zaczyna się od wartości losowej, więc przechwyć ostatnią wartość po 300 odczytach j++; } // Po 300 odczytach else { ypr[0] = ypr[0] - poprawnie; // Ustaw Odchylenie na 0 stopni - odejmij ostatnią losową wartość Odchylenia od bieżącej wartości, aby Odchylenie 0 stopni es // Mapuj wartości czujnika MPU6050 od -90 do 90 na wartości odpowiednie dla sterowania serwo od 0 do 180 int servo0Value = map(ypr[0], -90, 90, 0, 180); int servo1Value = map(ypr[1], -90, 90, 0, 180); int servo2Value = map(ypr[2], -90, 90, 180, 0); // Kontroluj serwa zgodnie z orientacją MPU6050 servo0.write(servo0Value); servo1.write(servo1Value); servo2.write(servo2Value); } #endif } }
Na koniec używając funkcji zapisu, wysyłamy te wartości do serwomechanizmów jako sygnały sterujące. Oczywiście możesz wyłączyć serwo Yaw, jeśli chcesz tylko stabilizację osi X i Y i użyć tej platformy jako gimbala kamery
Krok 9: Kiedy wszystkie komponenty są połączone, wygląda podobnie do tego obrazu
Krok 10: Teraz włóż całą bazę do puszki na żywność
Krok 11: Kiedy wszystkie przewody i komponenty są umieszczone w puszce na żywność, następnie przyłóż pistolet do kleju do podstawy płyty piankowej
Krok 12: Wniosek
Zwróć uwagę, że jest to dalekie od dobrego gimbala. Ruchy nie są płynne, ponieważ te serwa nie są do tego przeznaczone. Gimbale z prawdziwymi kamerami wykorzystują specjalny typ silnika BLDC, aby uzyskać płynne ruchy. Rozważ więc ten projekt tylko w celach edukacyjnych.
To by wszystko na ten samouczek, mam nadzieję, że Ci się podobał i nauczyłeś się czegoś nowego. Zapraszam do zadawania pytań w sekcji komentarzy poniżej i nie zapomnij sprawdzić moich kolekcji projektów