Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'akcelerometr'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - DIY
    • Projekty - DIY roboty
    • Projekty - DIY (mini)
    • Projekty - DIY (początkujący)
    • Projekty - DIY w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie

Kategorie

  • Quizy o elektronice
  • Quizy do kursu elektroniki I
  • Quizy do kursu elektroniki II
  • Quizy do kursów Arduino
  • Quizy do kursu STM32L4
  • Quizy do pozostałych kursów

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Imię


Strona

Znaleziono 5 wyników

  1. Jako, że jestem wielkim fanem gier komputerowych to nieuniknione było to, że w pewnym momencie spróbuję w jakiś sposób połączyć swoje zainteresowanie elektroniką oraz grami. W taki sposób narodził się pomysł na projekt, który przyjął nazwę "Fly And Shoot". Projekt złożony jest z dwóch części: Programistyczna - stworzenie samej aplikacji oraz gry. Postawiłem tutaj na prostotę i postanowiłem zrobić grę, w której lecąc statkiem kosmicznym musimy omijać/zestrzeliwać nadlatujące asteroidy. Taki typ gry wydał mi się idealny aby można było z nią połączyć drugą część projektu czyli część: Elektroniczna - polegająca na stworzeniu pada dzięki któremu będzie można sterować statkiem. W tym przypadku aby sterowanie nie okazało się banalne, postanowiłem, że pad będzie opierał się na akcelerometrze, a sterować będzie można wychylając go w odpowiednie strony. Tak o to prezentowała się koncepcja mojej gry: PAD DO GRY Do stworzenia pada postanowiłem użyć dwóch głównych komponentów: akcelerometru MMA7660FC oraz mikrokontrolera Arduino Nano v3. Założenie było proste: akcelerometr analizuje swoje wychylenie i przesyła zebrane dane do Arduino poprzez protokół I2C, następnie Arduino serializuje dane w odpowiedni format i przesyła je poprzez UART do komputera, w którym to dalsze działanie przejmuje aplikacja. Dodatkowym elementem, który postanowiłem jeszcze dodać był zwykły przycisk, który potem mógłbym wykorzystać np. do odczytu strzału. Na podstawie powyższych założeń stworzyłem schemat elektroniczny pada: Na podstawie schematu złożyłem układ na płytce stykowej: Na początku miał to być tylko prototyp, jednak okazał się on na tyle wygodny do trzymania, iż uznałem że nie ma sensu specjalnie lutować tych kilku komponentów. Osobiście uznałem, że kanciasty prostokątny kształt nadaje padowi trochę retro stylu, w szczególności jeśli ktoś kiedyś miał styczność z NESem 😄 : Oczywiście można było wszystko schować w jakąś kanciastą obudowę, jednak nie mam jeszcze doświadczenia z takimi rzeczami, więc stworzenie ślicznych obudów do wszystkich moich projektów zostawiam na przyszłość. Na podstawie dokumentacji akcelerometru oraz biblioteki Wire.h dla Arduino napisałem mały program, który łączył się z modułem, a następnie odczytywał zwracane dane i konwertował je na stopnie. Na jego podstawie mogłem potwierdzić działanie modułu: Kolejnym krokiem stało się przesłanie danych do komputera. Uznałem, że najlepszym sposobem będzie połączenie wszystkich danych w tzw. "ramkę" i przesłanie jej w całości do komputera. Moja ramka przyjęła następującą postać: Tworząc ramkę na początku umieszcza się nagłówek, który pozwala aplikacji odbierającej dane rozpoznać, że to właśnie z nią ma do czynienia. W kolejnych polach umieściłem dane, które chciałem przesłać: 'accX' i 'accY' oznaczające wychylenie akcelerometru/pada w osi X oraz Y (pominąłem Z, ponieważ było one zbędne w przypadku mojej gry) oraz 's' mówiące o tym czy wciśnięty został przycisk. Na końcu ramki umieszczone zostało pole na sumę kontrolną CRC8. Po co? W moim przypadku głównie w celu edukacyjnym, jednak na pewno jest ono przydatne w bardziej krytycznych węzłach komunikacyjnych, gdyż zapewnia integralność danych. W skrócie działa to tak, że na podstawie wszystkich wysyłanych danych mikrokontroler oblicza sumę kontrolną i przesyła ją razem z danymi. Następnie program, który odbiera dane ponownie na ich podstawie oblicza sumę kontrolną takim samym algorytmem i porównuje ją z sumą kontrolną, którą uzyskał razem z danymi - jeśli się zgadzają oznacza to, że przesłane dane nie zostały zakłamane i są prawdziwe. W tym momencie konieczne stało się przejście do drugiego etapu projektu, czyli aplikacji. APLIKACJA Z GRĄ Na początku postanowiłem stworzyć graficzny projekt aplikacji oraz gry. Poszczególne elementy, które sobie wymyśliłem wyglądają następująco: Do stworzenia aplikacji z grą postanowiłem użyć środowiska Qt: czemu akurat Qt? Bo nigdy wcześniej nie miałem z nim styczności, a chciałem je poznać 🙂. Na początku bardzo pomocny okazał się Kurs Qt z Forbota - to właśnie on pomógł mi stworzyć pierwsze okna i zaimplementować połączenie i komunikację z Arduino: W dalszej części postanowiłem najpierw zająć się oknem z wykresami, aby mieć pewność, że dane które odczytuje mają sens. W tym celu musiałem zaimplementować funkcje, które odczytywały moją ramkę danych i sprawdzały ich integralność. Następnie stworzyłem wykresy za pomocą narzędzi udostępnianych przez Qt: Po potwierdzeniu, że wszystkie dane są odczytywane poprawnie przyszedł czas na stworzenie gry. W pierwszej kolejności stworzyłem scenę, na której umieściłem obrazek gracza i stworzyłem możliwość jego poruszania. Uzyskanie satysfakcjonującego efektu nie było zbyt proste. Testowałem różne rozwiązania, aż w końcu mój wybór stanął na funkcji y = 2*sqrt(x) [y - prędkość gracza, x - wychylenie akcelerometru]. Użycie takiej funkcji do konwersji wychyleń akcelerometru na prędkość gracza pozwoliło mi uzyskać szybką reakcję w przypadku małych wychyleń przy jednoczesnym ograniczeniu maksymalnej prędkości w przypadku dużych wychyleń. W kolejnym kroku stworzyłem kilka obrazków dla przeszkód (aby miały różne wielkości) i napisałem funkcję, która tworzyła je w losowych miejscach ponad górną krawędzią ekranu. Nadanie im prędkości w dół wywołało iluzję poruszania się statku gracza. Następnie zaimplementowałem wykrywanie kolizji obiektów i tym samym dodałem system żyć oraz punktów dla gracza: Przy okazji stworzyłem jeszcze obiekt odpowiadający za pocisk, który potrafił niszczyć nadlatujące przeszkody. Na końcu dodałem okienko końca gry w przypadku utraty wszystkich żyć, które pozwalało na jej restart: Po stwierdzeniu, że wszystko działa jak należy nadszedł czas na ostatni krok: upiększenia graficzne. Do tej pory wszystkie elementy były tylko prowizorycznymi kształtami. Jako, że nie mam wielkiego talentu artystycznego, to postanowiłem poszukać darmowych paczek obrazków w internecie. Po znalezieniu zestawu obrazków użyłem ich do stworzenia prostych animacji, które zaimplementowałem w grze. Efekt końcowy wygląda następująco: PODSUMOWANIE Projekt nauczył mnie sporo o tworzeniu aplikacji z użyciem Qt. Wykorzystanie elektroniki do stworzenia kontrolera do gry dodatkowo umiliło naukę - w szczególności, że efekt końcowy wyszedł całkiem nieźle. Nie jest to gra na długie godziny, ale potrafiła zatrzymać na odrobinę czasu wszystkich, którym dałem wypróbować swój kontroler. Na koniec dorzucam link do repozytorium: https://github.com/Wirgiliusz/FlyAndShoot oraz filmik prezentujący działanie gry wraz z padem:
  2. Witam, pytanie może niekoniecznie o sprawdzenie schematu ale o sprawdzenie pewnego wzoru. Otóż ostatnio sporządziłem sobie względem pewnego zestawu ewaluacyjnego Analog Devices wzmacniacz do piezoelektrycznego czujnika przyspieszeń drgań. Sprawa była względnie bardzo prosta ponieważ dobór elementów oparłem o reference manual do TEGO zestawu. Natomiast po doborze elementów okazało się, że coś nie działa. Chodzi tutaj prawdopodobnie o częstotliwości graniczne. Wzmacniacz ładunkowy Analog Devices jest podobnej konstrukcji co prosty integrator: Natomiast w nocie katalogowej AD dolna częstotliwość graniczna opisana jest tym samym wzorem co górna częstotliwość graniczna filtru dolnoprzepustowego. Sprawdzałem w praktyce i albo ja czegoś nie rozumiem albo faktycznie tak jest ponieważ wzmacniacz z ustawioną częstotliwością graniczną na ok. 7000 Hz (R3 = 1MΩ, C2 = 22pF) przepuszcza cały sygnał z wzorcowego źródła drgań 79,6 Hz - 1g peak. Natomiast jeśli ufać nocie katalogowej sygnał ten nie powinien być przepuszczany. Stosując się do tego, że AD uważa to za dolną częstotliwość graniczną zmieniłem R3 na 10 MΩ i C2 na 1nF i tutaj na wyjściu wzmacniacza nie było już nic (f graniczna = 15,9 Hz). Ktoś może potwierdzić czy dobrze rozumiem, że AD się pomylili ? Dołączam również plik excelowy z obliczeniami (obliczenia zgodnie z notą AD) -> Integrator.zip
  3. Siemka wszystkim. Mam takowy problemik, że odczytując dane z akcelerometru odczyt na osi Z nie wskazuje realnej wartości przyśpieszenia. Na obrazku mamy odczyty z poszczególnych osi (w jednostkach G). Widać że na osi Z jest odczyt przekraczający 1G. Gdy obrócę sensor o 180 stopni tak aby oś Z zmieniła zwrot to odczyt na niej wynosi poniżej 1G. Wynika z tego jakby do ozi Z był dodany pewien offset. Czujnik to MPU 9255. Z czego to może wynikać i jak temu zaradzić? Poniżej wstawiam też kodzik. Dzięki za pomoc😀 //settings accelerometer and gyroscope HAL_I2C_Mem_Write(&i2c, 0xD0, 27, I2C_MEMADD_SIZE_8BIT, &Settings,1,1000); HAL_I2C_Mem_Write(&i2c, 0xD0, 28, I2C_MEMADD_SIZE_8BIT, &Settings,1,1000); HAL_I2C_Mem_Write(&i2c, 0xD0, 55, I2C_MEMADD_SIZE_8BIT, &BypassEnable,1,1000); //Power Down mode HAL_I2C_Mem_Write(&i2c, 0x18, 0x0A, I2C_MEMADD_SIZE_8BIT, &SettingsM,1,1000); HAL_Delay(100); //16 bit output mode 2 HAL_I2C_Mem_Write(&i2c, 0x18, 0x0A, I2C_MEMADD_SIZE_8BIT, &SettingsL,1,1000); //16 bit 8Hz while (1) { //A X HAL_I2C_Mem_Read(&i2c, 0xD0, 59, I2C_MEMADD_SIZE_8BIT, &DAHx,1,100); HAL_I2C_Mem_Read(&i2c, 0xD0, 60, I2C_MEMADD_SIZE_8BIT, &DALx,1,100); //A Y HAL_I2C_Mem_Read(&i2c, 0xD0, 61, I2C_MEMADD_SIZE_8BIT, &DAHy,1,100); HAL_I2C_Mem_Read(&i2c, 0xD0, 62, I2C_MEMADD_SIZE_8BIT, &DALy,1,100); //A Z HAL_I2C_Mem_Read(&i2c, 0xD0, 63, I2C_MEMADD_SIZE_8BIT, &DAHz,1,100); HAL_I2C_Mem_Read(&i2c, 0xD0, 64, I2C_MEMADD_SIZE_8BIT, &DALz,1,100); //G X HAL_I2C_Mem_Read(&i2c, 0xD0, 67, I2C_MEMADD_SIZE_8BIT, &DGHx,1,100); HAL_I2C_Mem_Read(&i2c, 0xD0, 68, I2C_MEMADD_SIZE_8BIT, &DGLx,1,100); //G Y HAL_I2C_Mem_Read(&i2c, 0xD0, 69, I2C_MEMADD_SIZE_8BIT, &DGHy,1,100); HAL_I2C_Mem_Read(&i2c, 0xD0, 70, I2C_MEMADD_SIZE_8BIT, &DGLy,1,100); //G Z HAL_I2C_Mem_Read(&i2c, 0xD0, 71, I2C_MEMADD_SIZE_8BIT, &DGHz,1,100); HAL_I2C_Mem_Read(&i2c, 0xD0, 72, I2C_MEMADD_SIZE_8BIT, &DGLz,1,100); do { HAL_I2C_Mem_Read(&i2c, 0x18, 0x02, I2C_MEMADD_SIZE_8BIT, &ST1,1,100); } while (!(ST1&0x01)); //0x0C - adress AK8963, 0x03-0x08 => HLx-HHz HAL_I2C_Mem_Read(&i2c, 0x18, 0x03, I2C_MEMADD_SIZE_8BIT, &HLx,1,100); HAL_I2C_Mem_Read(&i2c, 0x18, 0x04, I2C_MEMADD_SIZE_8BIT, &HHx,1,100); HAL_I2C_Mem_Read(&i2c, 0x18, 0x05, I2C_MEMADD_SIZE_8BIT, &HLy,1,100); HAL_I2C_Mem_Read(&i2c, 0x18, 0x06, I2C_MEMADD_SIZE_8BIT, &HHy,1,100); HAL_I2C_Mem_Read(&i2c, 0x18, 0x07, I2C_MEMADD_SIZE_8BIT, &HLz,1,100); HAL_I2C_Mem_Read(&i2c, 0x18, 0x08, I2C_MEMADD_SIZE_8BIT, &HHz,1,100); HAL_I2C_Mem_Read(&i2c, 0x18, 0x09, I2C_MEMADD_SIZE_8BIT, &H,1,100); //accelerometer Ax = (int16_t)(DAHx << 8 | DALx); Ay = (int16_t)(DAHy << 8 | DALy); Az = (int16_t)(DAHz << 8 | DALz); //gyroscope Gx = (int16_t)(DGHx << 8 | DGLx); Gy = (int16_t)(DGHy << 8 | DGLy); Gz = (int16_t)(DGHz << 8 | DGLz); //magnetometer Hx= (int16_t)(HHx << 8 | HLx); Hy= (int16_t)(HHy << 8 | HLy); Hz= (int16_t)(HHz << 8 | HLz); Ax_g = (float)Ax/16384.0; Ay_g = (float)Ay/16384.0; Az_g = (float)Az/16384.0; Gx_g = (float)Gx/131.0; Gy_g = (float)Gy/131.0; Gz_g = (float)Gz/131.0; printf("Ax = %f Ay = %f Az = %f Gx = %f Gy = %f Gz = %f\n", Ax_g, Ay_g, Az_g, Gx_g, Gy_g, Gz_g); HAL_Delay(200); }
  4. Cześć, chciałbym przedstawić projekt, który wykonałem jako pracę inżynierską. Jej celem było skonstruowanie inklinometru (miernika służącego do pomiaru kąta przechyłu), w którym kąt wyznaczany był przy pomocy akcelerometru typu MEMS. Uzyskane wartości przyspieszenia i kąt przechyłu wyświetlane są na wyświetlaczu LCD. Jednym z założeń było wykorzystanie czujnika z wyjściem analogowym oraz czujnika z wyjściem cyfrowym. Dlatego do projektu wybrałem model MMA7361 oraz ADXL345. Innymi czynnikami wyboru tych elementów była m.in. dostępność, cena, nieduży zakres pomiarowy (aby uzyskać jak największą czułość) ale przynajmniej 1g (co odpowiada kątowi przechyłu 90°). Spis treści: Założenia Projekt struktury sprzętowej Projekt obwodu drukowanego Wykonanie i uruchomienie miernika przechyłu Wyznaczenie kąta, algorytm działania miernika i oprogramowanie Wyniki testów miernika ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1. Założenia Koncepcja modułu inklinometru zakładała użycie mikrokontrolera, do którego podłączone zostały akcelerometry. Czujnik cyfrowy ADXL345 komunikuje się za pomocą magistrali I2C lub SPI, natomiast czujnik MMA7361 posiada wyłącznie wyjścia analogowe, dlatego konieczne było wykorzystanie przetwornika analogowo-cyfrowego. Dodatkowo mikrokontroler odpowiadał za obsługę przycisków, portu szeregowego i sterowanie wyświetlaczem. Działanie układu inklinometru oparto na popularnym mikrokontrolerze ATmega328 zaimplementowanym w module Uno Plus firmy WaveShare, który jest w pełni kompatybilny z Arduino Uno R3. Zdecydowałem się na wykorzystanie klonu Arduino z powodu zdecydowanie niższej ceny układu (w promocji zapłaciłem ok. 45 zł) i jednocześnie pewnych przydatnych rozwiązań w nim zastosowanych, m.in. popularniejsze złącze micro USB, przycisk reset naciskany z boku, przetwornik ADC, itd. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 2. Projekt struktury sprzętowej Na rysunkach poniżej przedstawiono wykorzystane wyprowadzenia platformy Uno Plus wraz ze złączami służącymi do podłączenia zaprojektowanych modułów. Do podłączenia wyświetlacza LCD ze sterownikiem HD44780 wykorzystano wyprowadzenia na listwę typu goldpin (złącza JP3 i JP4). W celu regulacji kontrastu użyto potencjometr o wartości 10kΩ (R2). Wyświetlacz zasilany jest napięciem 5V. Przyciski – podłączone do złącza JP5 zostały programowo „podciągnięte” do stanu wysokiego poprzez wyprowadzenia I/O mikrokontrolera. Rozpoznanie wciśnięcia przycisku występuje w chwili wykrycia stanu niskiego na linii portu, który występuje po zwarciu do masy. Czujnik ADXL345 zasilany jest napięciem 3,3V. Napięcie zasilające jest filtrowane przez kondensator tantalowy o wartości 10µF i dwa kondensatory 0,1µF. W celu uruchomienia komunikacji za pomocą magistrali I2C należało wybrać układ przez podanie stanu wysokiego na wejście CS oraz zapewnić stan wysoki na liniach SCL i SDA, co zrealizowano przez zastosowanie rezystorów podciągających o wartości 10kΩ. Podłączając pin SDO do masy (stan logiczny niski) wskazano, że układ posiada na magistrali I2C adres o wartości 0x53 (alternatywnie podając stan wysoki adres miałby wartość 0x1D). W układzie połączeń czujnika MMA7361 wejście Sleep jest wewnętrznie ustawione w stan niski, co wprowadza płytkę w stan uśpienia i niski pobór energii. Aby uruchomić czujnik należy do tego wejścia podać stan wysoki, np. za pomocą podłączenia do napięcia zasilania 3,3V, jak zostało zrobione to w projekcie. W przypadku potrzeby kontroli nad trybem Sleep należałoby podłączyć to wejście do mikrokontrolera za pomocą wyprowadzeń I/O i odpowiednio sterować (pamiętając o poziomach napięć, gdyż UNO PLUS pracuje z napięciem +5V). Podłączenie wejść g-Select i 0g-Detect jest opcjonalnie. Wejście g-Select jest wewnętrznie ustawione w stan niski, który odpowiada ustawieniu czułości na zakres ±1.5g (800 mV/g). Wejście 0g-Detect wystawia napięcie na poziom wysoki gdy wszystkie osie wskazują przyspieszenie równe 0g. Dzieje się tak kiedy płytka znajduje się w stanie spadku swobodnego. Z powodu braku potrzeby użycia tych funkcji (jak najmniejszy zakres pomiarowy jest bardziej odpowiedni w projekcie inklinometru) wejścia te pozostawiono niepodłączone. Wyjścia X, Y i Z akcelerometru zostały podłączone odpowiednio przez złącze JP2, do wejść A0, A1 i A2 mikrokontrolera, które są wejściami przetwornika A/C. Uwzględniając napięcie zasilania akcelerometrów (3,3V) oraz zakres analogowych sygnałów wyjściowych, dla przetwornika analogowo – cyfrowego wybrano zewnętrzne napięcie referencyjne o wartości 3,3 V (wejście AREF podłączono do napięcia 3,3V), a w oprogramowaniu mikrokontrolera wybrano zewnętrzne napięcie referencyjne. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 3. Projekt obwodu drukowanego Dla wybranych czujników przyspieszenia zaprojektowano i wykonano dwie osobne płytki PCB, o jednakowych wymiarach 40x30 mm. Wymiary płytek wynikały z potrzeby ich dopasowania do stanowiska testowego w laboratorium. Oba układy przetworników posiadają 14 wyprowadzeń i zamknięte są w obudowie LGA-14.W projekcie zastosowano elementy pasywne SMD. Z uwagi na małe rozmiary układów scalonych minimalna odległość między ścieżkami wynosi 10 mils. Ścieżki zasilające mają szerokość 24 mils, a ścieżki sygnałowe 20 mils. Na niewykorzystanej powierzchni płytka została wypełniona masą. Z płytki czujnika ADXL wyprowadzone są 4 sygnały: VCC (zasilanie układu), GND (masa układu), SCL (linia zegarowa) i SDA (linia danych). Z płytki czujnika MMA wyprowadzonych jest 5 sygnałów: VCC (zasilanie układu), GND (masa układu), A0 (wyjście napięciowe osi X), A1 (wyjście napięciowe osi Y) i A2 (wyjście napięciowe osi Z). ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 4. Wykonanie i uruchomienie miernika przechyłu Płytki PCB z czujnikami wykonano metodą termotransferu. Dodatkowo zostały umieszczone napisy na warstwie ścieżek w postaci nazwy wykorzystanego czujnika na danej płytce. Montaż elementów wykonano wykorzystując stację lutowniczą typu HotAir. Z powodu projektu płytki jednowarstwowej, dodatkowo dokonano potrzebne połączenia za pomocą przewodów. Do połączenia płytek czujników z układem mikrokontrolera zastosowano przewody ze złączami 6-pinowymi i gniazdami kątowymi typu goldpin przymocowanymi do nakładki prototypowej. Na nakładce prototypowej znalazły się również klawiatura, listwy służące do montażu wyświetlacza LCD i badania napięć wyjściowych czujnika analogowego oraz potencjometr do regulacji kontrastu wyświetlacza LCD. Rysunek poniżej przedstawia zmontowany i uruchomiony miernik przechyłu z podłączonymi czujnikami zasilany poprzez port micro USB. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 5. Wyznaczenie kąta, algorytm działania miernika i oprogramowanie Funkcja wyboru odczytu danych wykorzystuje trzy przyciski. Algorytm jest trochę ubogi ale do projektu wystarczył. Pomiar przyspieszenia z wykorzystaniem czujnika analogowego MMA7361 polega na wyznaczeniu wartości napięcia na wyjściach osi akcelerometru za pomocą 10-bitowego przetwornika analogowo-cyfrowego, a następnie wykonywane są obliczenia realizujące skalowanie czujnika. Wyznaczenie napięcia polega na pomnożeniu wyniku bitowego i napięcia referencyjnego, a następnie podzielenie przez 1023 (10-bitowy przetwornik, 210) xV_analog=(float(xADC)*3.3/1023); yV_analog=(float(yADC)*3.3/1023); zV_analog=(float(zADC)*3.3/1023); W celu otrzymania wartości przyspieszenia w jednostkach „g” dokonano odpowiedniego skalowania. Od zmierzonej wartości napięcia odjęto wartość 1,65 V, która jest połową wartości napięcia zasilania czujnika i odpowiada wartości napięcia przy przyspieszeniu wynoszącym zero. W następnym kroku uwzględniono czułość czujnika (800mV/g). Wartość przyspieszenia wyliczono posługując się wzorami: xG_analog=(xV_analog-1.65)/0.800; yG_analog=(yV_analog-1.65)/0.800; zG_analog=(zV_analog-1.65)/0.800; Czujnik cyfrowy ADXL345 do poprawnego działania, przed bezpośrednim odczytem danych, wymaga pewnych ustawień, które realizowane są na podstawie dostępnych w dokumentacji technicznej mapie i definicji rejestrów. Ustawienie to odbywa się poprzez zapis do rejestrów czujnika odpowiednich wartości bitowych i w programie przyjmował następujący format: ustawI2C(adres_czujnika, adres_rejestru, wartość); Adres akcelerometru ADXL345 to 0x53 i może dzielić magistralę z innymi urządzeniami dopóki ma unikalny adres. Wszystkie wartości liczbowe podawane są w systemie szesnastkowym: ustawI2C(0x53, 0x2D, 0x08); // do rejestru POWER_CTL, o adresie 0x2D, wpisano wartość 0x08, która inicjalizuje tryb gotowości do pomiaru, ustawI2C(0x53, 0x31, 0x08); // do rejestru DATA_FORMAT (adres 0x31) wpisano wartość 0x08 ustawiając wybrane parametry takie jak rozdzielczość i czułość czujnika, ustawI2C(0x53, 0x2C, 0x08); // do rejestru BW_RATE (adres 0x2C) wpisano wartość 0x08 ustawiając częstotliwość pomiaru na 50Hz. Dane wyjściowe z czujnika odczytywane są z sześciu 8-bitowych rejestrów, po dwa dla każdej osi. Każdy wynik jest reprezentowany za pomocą dwóch bajtów. Funkcja odczytu danych przez magistralę I2C ma postać: odczytI2C(0x53, 0x32, buffer, 6); - odczyt danych z czujnika zaczynając od rejestru DATAX0 (adres 0x32) i kończąc na rejestrze DATAZ1 (adres 0x37). Następnie za pomocą odpowiednich funkcji, dwa odczytane bajty dla danej osi czujnika łączone są w jedną zmienną. Uzyskana w ten sposób wartość bitowa mnożona jest przez współczynnik skali, wynoszący w tym przypadku 3,9 mg/LSB, i otrzymywana jest wartość przyspieszenia w jednostkach „g”. xG_digital = xBit_digital * 0.0039; // -256=-1g, 0=0g, 256=1g yG_digital = yBit_digital * 0.0039; zG_digital = zBit_digital * 0.0039; Na podstawie otrzymanych wartości przyspieszeń z czujników wyliczany jest kąt przechyłu wykorzystując odpowiednie wzory. Dokładny kąt nachylenia może być mierzony tylko wtedy, gdy na przyspieszeniomierz działa wyłączenie siła grawitacji. Działanie innych sił, np. ruchu, powoduje dodatkowe przeciążenia, uniemożliwiając prawidłowe ustalenie nachylenia. Pomiar przechyłu można dokonać wykorzystując nawet jedną oś, lecz wyniki naznaczone są pewnymi ograniczeniami, których opis może pominę. Wykorzystując trzy osie, do ustalenia orientacji czujnika względem ziemi, kąt nachylenia wektora siły grawitacji może być w pełni określony. Czułość jest stała dlatego kąty mogą być dokładnie zmierzone bez względu na położenie czujnika. Dane przesyłane pomiędzy interfejsem UART i USB przyjmują format opisany w tabeli. Wybierając polecenie uruchomienia transmisji pomiędzy urządzeniami aktualne wartości z czujników wysyłane są na bieżąco do momentu przerwania transmisji przez użytkownika. Wysyłane dane są w postaci znakowej i posiadają 4- znakowy nagłówek i pole danych. ASTY (ASensorTYpe) – oznaczający typ czujnika, BACC (BACCeleration) – oznaczający przyspieszenie, CANG (CANGle) – oznaczający kąt przechyłu. Po nagłówku wysyłany jest separator w postaci znaku „ ; ”, a następnie pole danych zakończone znakiem „ ; ”. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 6. Wyniki testów miernika Badania przeprowadzono na stanowisku przeznaczonym do badania czujników przechyłu – bazując na równi pochyłej. Wartości kąta przechyłu wyznaczone zostały na podstawie zależności trygonometrycznych w trójkącie prostokątnym. W skrócie. Dwie deski połączone zawiasem. Na jednej desce przyklejona miarka. Na drugiej desce na nitce o stałej długości zawieszony pion murarski. Podnosząc jedną deskę pion dzięki sile grawitacji tworzył kąt prosty, a z miarki odczytywano wartość wyznaczoną przez nić. Z otrzymanych proporcji wyliczano dokładny kąt. Z racji już długiego tekstu może pominę szczegółowy fragment kalibracji. Więc tak w skrócie: Akcelerometry MEMS w swojej strukturze zawierają elementy, które mogą swobodnie się poruszać, dlatego są o wiele bardziej wrażliwe na powstałe naprężenia mechaniczne niż inne elementy półprzewodnikowe. Naprężenia mogą powstawać m.in. podczas montażu czujnika i komponentów na obwodzie drukowanym. W celu wyeliminowania błędów w pomiarze należy wykonać kalibrację czujników. Dzięki rejestrom OFSX, OFSY i OFSZ możliwe jest wprowadzenie korekty wyników w czujniku cyfrowym ADXL345. Wartość przechowywana w tych rejestrach jest automatycznie dodawana do mierzonego przyspieszenia i kompensuje błędy pomiaru. Kalibracja czujnika analogowego polega na wyznaczeniu maksymalnych i minimalnych napięć pojawiających się na wyjściach osi pomiarowych poprzez obrót wokół ich płaszczyzn. Wartość maksymalna pojawi się gdy na oś będzie działać przyspieszenie +1g, natomiast wartość minimalna w przypadku działania przyspieszenia wynoszącego -1g. Zakładając, że czułość zmienia się symetrycznie, od 0 do +1g oraz od 0 do -1g, można wyznaczyć jej dokładną wartość dodając do siebie wartości napięcia maksymalnego i minimalnego, a następnie dzieląc je przez 2. Pomiary wykonano laboratoryjnym multimetrem cyfrowym. Wykonane badania wykazały, że maksymalna różnica pomiędzy kątami rzeczywistymi, a kątami wskazanymi przez inklinometr wynoszą maksymalnie 1°. Błąd pomiędzy wskazaniami miernika może wynikać m.in. z braku wykonania urządzenia w pełni profesjonalnych warunkach, a otrzymany wynik błędu jest satysfakcjonującym rezultatem. Dodatkowo do pełnego, stabilnego badania położenia i wyeliminowania błędów pomiaru należy zastosować połączenie akcelerometru, żyroskopu i magnetometru. Ostatnie zdjęcia prezentują działanie inklinometru. Na pierwszym zdjęciu pomiar dokonywany jest za pomocą czujnika MMA7361. Można zauważyć, że płytka leży prawie poziomo - kąt 6,8°. Z kolei na drugim zdjęciu płytka z czujnikiem ADXL345 ustawiona jest prawie pod kątem 45°. Dzięki za doczytanie do końca. Pozdrawiam :)
  5. Witam, próbuję uruchomić akcelerometr LIS3DHH ( https://www.st.com/en/mems-and-sensors/lis3dhh.html) na zestawie Nucleo F411RE (https://www.st.com/en/evaluation-tools/nucleo-f411re.html). Czujnik mam w postaci adaptera STEVAL-MKI180V1 (https://www.st.com/en/evaluation-tools/steval-mki180v1.html). Konfigurację dla mikrokontrolera generuję za pomocą CubeMX 5.0.1 z bibliotekami HAL dla rodziny STM32F4, w wersji 1.23.0. Próbę uruchomienia czujnika rozpocząłem od wykorzystania bibliotek: https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/lis3dhh_STdC, a dokładnie od przykładu: read_data_simple.c. Po dużej liczbie nieudanych prób komunikacji, maksymalnie uprościłem przykład. Aktualnie próbuję odczytać wartość rejestru WHO_AM_I. Adres rejestru to: 0x0F. Podczas odczytu danych, bit SMB adresu powinien mieć wartość 1, więc modyfikuję adres rejestru do wartości 0x8F. Wartość rejestru WHO_AM_I powinna wynosić 0x11, a ja otrzymuję wartość 0x00. Wszystkie linie SPI są sprzętowo podciągnięte do plusa zasilania, za pomocą wewnętrznych rezystorów mikrokontrolera. Korzystam z SPI2. Jego konfiguracja to: CPOL = High, CPHA = 2 Edge, prędkość: 1.3125 Mbits/s. Sygnał CS jest generowany programowo. Poniżej przedstawiam fragment kodu źródłowego odpowiedzialnego za inicjalizację SPI oraz próbę odczytania rejestru WHO_AM_I. Inicjalizacja SPI: void MX_SPI2_Init(void) { hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi2) != HAL_OK) { Error_Handler(); } } [Próba odczytu zawartości rejestru WHO_AM_I (zawarte w funkcji main): MX_GPIO_Init(); MX_SPI2_Init(); HAL_Delay(10); HAL_StatusTypeDef status; uint8_t reg = 0x0F; // Adres rejestru WHO_AM_I uint8_t bufp[3]; uint16_t len = 1; reg |= 0x80; // Informacja, ze przeprowadzany bedzie odczyt danych HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); // Aktywacja SPI status = HAL_SPI_Transmit(&LIS3DHH_HANDLE, ®, 1, 1000); // Wyslanie adresu do odczytu status = HAL_SPI_Receive(&LIS3DHH_HANDLE, bufp, len, 1000); // Odbior zawartosci adresu HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); // Dezaktywacja SPI W załączniku przedstawiam przebiegi uzyskane z analizatora stanów logicznych, plik konfiguracyjny dla CubeMX oraz kod źródłowy programu testowego. Dodam, że testy przeprowadzałem na dwóch czujnikach, oraz dodatkowo na zestawie z mikrokontrolerem STM32F103 (blue PCB). Modyfikowałem na wiele sposobów konfigurację SPI oraz odczyt rejestrów. Efekt za każdym razem taki sam. Czy ktoś ma pomysł co robię nie tak, że za każdym razem otrzymuję wartość zero z rejestru WHO_AM_I? Test_LIS3DHH_F4.zip
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.