Skocz do zawartości

Eliminator odchylenia - chodzi o drgania mechaniczne


pawelKO

Pomocna odpowiedź

Dobry wieczór, 

1. Na starość zaczynam z elektroniką, przyswoiłem kurs Arduino I+II, początkujący jestem. Z tego względu do oswajania tematu używam tanich części.

2. Używam akcelerometru SEN0168 do uzyskania odchylenia od poziomu. Mam schemat podłączenia do Arduino i szkic testowy. Innej dokumentacji w sieci nie znalazłem. Chyba jest ustawiony na przeciążenia do +_16G, bo przyspieszenie ziemskie podaje jako 16 SEN-jednostek (około).

w funkcji setup() jast linia z komentarzem // range ..

 Wire.begin(); 
  Wire.beginTransmission(0x0A); // address of the accelerometer 
  // low pass filter,  
  Wire.write(0x20); 
  Wire.write(0x00);
  // range settings 
  Wire.write(0x22); 
  Wire.write(0x00);   //range  0x00 0x01 0x02 0x03  (ale nie dziala)
  Wire.endTransmission();

próbowałem wstawić inne wartości range, ale rozdzielczości to nie zmieniło. Może coś źle robię?

W funkcji loop()

Kąt odchylenia (zwany usrednienie) zliczam przez ATAN przyspieszeń X/Z czujnika (X początkowo poziome, Z pionowe). Arduino nie ma ATAN, więc używam dwóch wyrazów szer. Taylora. 

Zmiana wskazania o jedną SEN-jednostkę powoduje zmianę obliczonego kąta o ok 4 stopnie. Żeby się pozbyć szarpania serwem wynikającego z szumu, zbieram kilka pomiarów (n_usr=5) i uśredniam wynik. Potem i tak trzeba korygować wynik.

 float tankat;
  int i;
  int n_usr=5;
  float usrednienie=0;
  float delta_kat = 0;
  int delta_pozycja = 0;
  
  // akt_czas = millis();
  usrednienie=0;
  for (i=0; i<n_usr; i++)
  {  AccelerometerInit(); 
    // x_data -= 2; // korekta zera akcelerometru
     tankat= (float(x_data)-2.2)/float(z_data) ;  //tan kata skrecenia
     tankat = tankat * 57.29583  - tankat*tankat*tankat*19.0986 ;

     usrednienie+=tankat/n_usr;
  }  
  
  // korekta kata
  usrednienie *= 1.5 ;


     Dalej podaję kąt do serwa. Robię próby z pewną predykcją położenia serwa, by skompensować opóźnienie sterowania serwa względem pomiaru. Niewiele to poprawia, ale utrudnia czytanie kodu.

pozycja = 90 - int(usrednienie) ; 
 
  delta_pozycja= pozycja-old_pozycja; 
 // pozycja = old_pozycja+int(delta_pozycja*1.5) ; // predykcja 
  
  
  old_pozycja=pozycja;
  if (pozycja < 1) 
     { pozycja = 1 ; 
     }
  if (pozycja > 180 ) 
     { pozycja = 180 ;
     }
  serwomechanizm.write( pozycja );

3. 

Jak na filmie widać sukces jest umiarkowany. Dla drgań ok 2Hz to nie działa, a chciałbym. Chciałbym też bardziej złożone drgania eliminować.

Problemem jest czas.

Żeby odwzorować 2 Herce trzeba wejście próbkować teoretycznie z częstotliwością 8 Hz, a w praktyce 16-20 Hz co najmniej. Czyli obliczenia jednej pętli muszą się zmieścić w 50mSek.

Jeden odczyt danych trwa niecałe 2 millsy.

Każdy Serial.print 2 millsy.

Wołanie POW(tankat,3) dwa millsy, za to tankat*tankat*tankat nic.

Arduino potrzebuje ok 38mSekund między wyjściem z pętli a ponownym wejściem. 

 

Kończą mi się pomysły, więc poproszę uprzejmie ciężej doświadczonych o komentarze.

🙂

20210131_182831.zip

Link do komentarza
Share on other sites

Przede wszystkim przeczytaj to:

http://image.dfrobot.com/image/data/SEN0168/BMA220 datasheet.pdf

To jest pełna dokumentacja czujnika jaki masz na pokładzie. Niestety, 1/16g (czyli zakres +/-2g) to jego maksymalna rozdzielczość i możesz ją tylko pogorszyć. Do takiego zastosowania jak to Twoje coś wybrałeś bardzo źle. To żaden układ pomiarowy a raczej czujniczek orientacji ekranu w smartfonie. Wykrywa też swobodny spadek spadek (free fall) i uderzenia, ale generalnie to zabawka.

Co do komunikacji: komendy do zapisu wyglądają tu wyłącznie tak:

  • bajt adresu czujnika
  • bajt adresu rejestru wewnętrznego
  • jeden bajt danych

a więc jeśli chcesz coś do niego zapisać, możesz to robić tylko wg tego schematu, mniej więcej tak:

  Wire.beginTransmission(0x0A);     // adres czujnika
  Wire.write(0x20);                 // adres rejestru (wszystkie opisane w dokumentacji)
  Wire.write(0x00);                 // zapisywany bajt danych
  Wire.endTransmission();           // Wyslanie wszystkiego powyzszego do czujnika

  Wire.beginTransmission(0x0A);     // I jeszcze raz, ale inny rejestr i inne dane
  Wire.write(0x22); 
  Wire.write(0x01);                 //range  0x00 0x01 0x02 0x03
  Wire.endTransmission();

Niestety, jak już napisałem, zmieniając range (rozdz. 4.1.2, str. 13) czułość możesz tylko pogorszyć. Za to możesz wykorzystać wbudowany w układ filtr cyfrowy, który kosztem czasu zmniejsza szum (rozdz. 4.2.2).

Pamiętaj, że typowe analogowe serwomechanizmy modelarskie nie są demonami szybkości. Mają raczej małe silniki za to spore przekładnie, bo liczy się moment przy małej masie własnej. Nigdy nie były przewidziane do pracy w szybkich, zamkniętych elektroniką pętlach sterowania, a tylko do samolotów RC, gdzie i tak reakcja człowieka na odchylenie od zaplanowanego toru lotu jest najwolniejszym elementem. Ich typowy czas to co najmniej 1s/60°, a do tego dochodzi opóźnienie samego sposobu przesyłania do nich informacji (ramki co 20ms) i procesu dekodowania tego na sygnał do silnika. Także nawet te 2Hz będzie moim zdaniem trudne do osiągnięcia tą metodą. To już bardziej jakiś silnik krokowy (zero opóźnień, nie licząc dynamiki reszty mechaniki) albo tzw. serwo cyfrowe, specjalnie szybkie bo właśnie mające tłumić oscylacje np. ogona śmigłowca, w którym żyroskop (i odpowiedni procesorek) jest lokalnie na pokładzie. Wtedy możesz mieć nawet i 0.08s/60°.

Procesora i jego możliwości obliczeniowych nie komentuję. 

Przykłądowe serwo cyfrowe (no, drogie są, ale coś za coś):

https://www.rc4max.com/h6040_digital_heli_servo_-_high_speed,741,20059.html

Przykładowy (nie szukałem daleko) akcelerometr o sensownej rozdzielczości (0.001g) i niepowalającej cenie, żaden tam wyczynowy sensor:

https://botland.com.pl/akcelerometry/5295-lis3dh-3-osiowy-akcelerometr-cyfrowy-i2c-spi-adafruit-2809.html

 

 

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.