Skocz do zawartości

Poszukiwana biblioteka do MPU6050


Pomocna odpowiedź

Napisano

Witam, szukam Linda do mpu6050 ale takiego żeby mi odrazu na stopnie przeliczalo...już kilka przetestowałem i same gołe dane mam, jak np. Radiany na sekundy itp...jesli ktoś ma coś to będę bardzo wdzięczny...😉

A sprawdzałeś to?

Nie używa DMP. Nie pamiętam, czy zwraca kąty w stopniach czy w radianach, ale radiany na stopnie w razie czego chyba potrafisz przeliczyć...

(edytowany)
11 minut temu, ethanak napisał:

Ale radiany na stopnie w razie czego chyba potrafisz przeliczyć...

Raczej tak, choć krótkim wzorem na wszelki wypadek nie pogardzę...straszna d*** ze mnie w te klocki...

Ps...już wiem...Radiany razy PI

Edytowano przez farmaceuta
(edytowany)

Niestety ta biblioteka jakoś dziwnie działa...zmiana kątów jest prawidłowa tylko podczas szybkiego ruchu mpu...jeśli przewracam powoli to się nic nie zmienia...😕 O ch** tu chodzi z tymi libsami...czyżby nie było nic dla świerzaków którzy nie potrafią przeliczać surowych danych?😢

Edytowano przez farmaceuta
14 minut temu, farmaceuta napisał:

zmiana kątów jest prawidłowa tylko podczas szybkiego ruchu mpu...jeśli przewracam powoli to się nic nie zmienia...

Bo dane z żyroskopu są 16-bitowe, i jak powoli przewracasz to są w okolicy zera. Niestety - bib;lioteka nie pozwala na ustawianie czułości.

Powiem szczerze: przestałem stosować biblioteki do 6050, wolę napisać własny kod. 

(edytowany)
23 minuty temu, ethanak napisał:

Powiem szczerze: przestałem stosować biblioteki do 6050, wolę napisać własny kod. 

Jak się umie to napewno lepiej...😜 No ok...już znalazłem prościutki kod bez libsa i przelicza mi te osrane stopnie z tym że w jednej osi mam zakres 180 stopni a w drugiej liczy do 90 i zaczyna od nowa...można to jakoś zmienić na te 180? 

I drugie pytanie...do kompensacji magnetometru potrzebuje tylko stopni? Czy akcelerometr też potrzebny?

#include<Wire.h>
const int MPU_addr1 = 0x68;
float xa, ya, za, roll, pitch;



void setup() {
  Wire.begin();                                      //begin the wire communication
  Wire.beginTransmission(MPU_addr1);                 //begin, send the slave adress (in this case 68)
  Wire.write(0x6B);                                  //make the reset (place a 0 into the 6B register)
  Wire.write(0);
  Wire.endTransmission(true);                        //end the transmission
  Serial.begin(9600);
}

void loop() {
  
  Wire.beginTransmission(MPU_addr1);
  Wire.write(0x3B);  //send starting register address, accelerometer high byte
  Wire.endTransmission(false); //restart for read
  Wire.requestFrom(MPU_addr1, 6); //get six bytes accelerometer data
  int t = Wire.read();
  xa = (t << 8) | Wire.read();
  t = Wire.read();
  ya = (t << 8) | Wire.read();
  t = Wire.read();
  za = (t << 8) | Wire.read();
// formula from https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing
  roll = atan2(ya , za) * 180.0 / PI;
  pitch = atan2(-xa , sqrt(ya * ya + za * za)) * 180.0 / PI; //account for roll already applied

  Serial.print("roll = ");
  Serial.print(roll,1);
  Serial.print(", pitch = ");
  Serial.println(pitch,1);


  delay(400);
}

 

Edytowano przez farmaceuta
(edytowany)

@ethanak pomocy...mam ten mpu przyklejony do serwa, za pomoica kontrolera pid chce zeby podczas obracania tym serwem mpu utrzymywal swoje polozenie ustalone...powierdzmy 20 stopni w danej osi...kombinuje ale mam straszne oscylacje i do tego mpu nawet nie jest blisko swojej pozycji a calkiem gdzies ucieka...

#include<Wire.h>
const int MPU_addr1 = 0x68;
float xa, ya, za, roll, pitch;

#include <Servo.h>

Servo myservo; 

//************************************************
#include <PID_v1.h>

double Setpoint, Input, Output;

double Kp=2, Ki=0, Kd=1;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
//***************************************************************************************

void setup() {
    myservo.attach(10);  // attaches the servo on pin 9 to the servo object

//******************************************************************************************
 Setpoint = 0;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(0, 400);
 // *******************************************************************************************
  Wire.begin();                                      //begin the wire communication
  Wire.beginTransmission(MPU_addr1);                 //begin, send the slave adress (in this case 68)
  Wire.write(0x6B);                                  //make the reset (place a 0 into the 6B register)
  Wire.write(0);
  Wire.endTransmission(true);                        //end the transmission
  Serial.begin(9600);
}

void loop() {
  
  Wire.beginTransmission(MPU_addr1);
  Wire.write(0x3B);  //send starting register address, accelerometer high byte
  Wire.endTransmission(false); //restart for read
  Wire.requestFrom(MPU_addr1, 6); //get six bytes accelerometer data
  int t = Wire.read();
  xa = (t << 8) | Wire.read();
  t = Wire.read();
  ya = (t << 8) | Wire.read();
  t = Wire.read();
  za = (t << 8) | Wire.read();
// formula from https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing
  roll = atan2(ya , za) * 180.0 / PI;
  pitch = atan2(-xa , sqrt(ya * ya + za * za)) * 180.0 / PI; //account for roll already applied

  Serial.print(roll,1);
 // Serial.print(", pitch = ");
   Serial.print("      ");

 // ****************************************************************************************
  Input = roll;
  myPID.Compute();
    Serial.println(Output);
    //analogWrite(10, Output);
    int pu = map(Output, 0, 400, 180, 0);
    myservo.write(pu);
 // *****************************************************************************************

  delay(20);
}

 

Edytowano przez farmaceuta
22 godziny temu, farmaceuta napisał:

pomocy...

Dużo nie pomogę bo to nie moja działka, ale...

22 godziny temu, farmaceuta napisał:

mam straszne oscylacje i do tego mpu nawet nie jest blisko swojej pozycji a calkiem gdzies ucieka...

Podejrzewam, że problem leży w tym, iż akcelerometr wcale nie pokazuje odchylenia od pionu/poziomu, tylko aktualne przyspieszenie; a to przy dość szybkim ruchu serwa może być niespecjalnie związane z aktualną pozycją (fizyka się kłania, takie tam bezwładności, siły odśrodkowe i podobne nudy). Dużo pewniejsze jest korzystanie z obu źródeł (akcelerometr i żyroskop, tak jak w poprzedniej bibliotece). Możesz zrobić eksperyment: napisz prosty program, który wyrzuca z siebie wartość obliczonego kąta i zacznij zmieniać pozycję serwa.

I pamiętaj o tym, że dane żyroskopu są aktualizowane co pewien czas (zależny od ustawień rejestrów) i warto w jakiś sposób synchronizować odczyt (np. używając pinu INT).

 

  • Lubię! 1
(edytowany)

Nie wiem czy dobrze kombinuje ale masz tam wydzielona funkcję do swojego czujnika 

// ************************************************************************************************************
// I2C Gyroscope ITG3200 / ITG3205 / ITG3050 / MPU3050
// ************************************************************************************************************
// I2C adress: 0xD2 (8bit)   0x69 (7bit)
// I2C adress: 0xD0 (8bit)   0x68 (7bit)
// principle:
// 1) VIO is connected to VDD
// 2) I2C adress is set to 0x69 (AD0 PIN connected to VDD)
// or 2) I2C adress is set to 0x68 (AD0 PIN connected to GND)
// 3) sample rate = 1000Hz ( 1kHz/(div+1) )
// ************************************************************************************************************
#if defined(ITG3200) || defined(ITG3050) || defined(MPU3050)
#if !defined(GYRO_ADDRESS)
  #define GYRO_ADDRESS 0X68
  //#define GYRO_ADDRESS 0X69
#endif

void Gyro_init() {
  i2c_writeReg(GYRO_ADDRESS, 0x3E, 0x80);                 //PWR_MGMT_1    -- DEVICE_RESET 1
  delay(5);
  i2c_writeReg(GYRO_ADDRESS, 0x16, 0x18 + GYRO_DLPF_CFG); //Gyro CONFIG   -- EXT_SYNC_SET 0 (disable input pin for data sync) ; DLPF_CFG = GYRO_DLPF_CFG ; -- FS_SEL = 3: Full scale set to 2000 deg/sec
  delay(5);
  i2c_writeReg(GYRO_ADDRESS, 0x3E, 0x03);                 //PWR_MGMT_1    -- SLEEP 0; CYCLE 0; TEMP_DIS 0; CLKSEL 3 (PLL with Z Gyro reference)
  delay(100);
}

void Gyro_getADC () {
  i2c_getSixRawADC(GYRO_ADDRESS,0X1D);
  GYRO_ORIENTATION( ((rawADC[0]<<8) | rawADC[1])>>2 , // range: +/- 8192; +/- 2000 deg/sec
                    ((rawADC[2]<<8) | rawADC[3])>>2 ,
                    ((rawADC[4]<<8) | rawADC[5])>>2 );
  GYRO_Common();
}
#endif

Zostaje Ci podmienić funkcje i2c

EDIT Oj przepraszam wrzuciłem funkcje do mpu3050... Ehh nie poprawię tego bo z telefonu źle się to robi. Ale i tak dosyć łatwo jest wydzielić funkcje dla twojego czujnika 

 

 

Edytowano przez _LM_
  • Pomogłeś! 1

@_LM_ kod który wkleiłem działa dobrze...w sensie pokazuje stopnie normalnie, no ale po dodaniu tego pid'a to serwo nawet nie chce się zbliżyć do zadanej wartości...w skrócie ja to zrobiłem tak, setpoint na 20°, input to wyjście danych z mpu, a output ustawiony na zakres 0-400 które później jest przemalowane na 0-180 dla serwa...chyba ten pod świruje, niestety nie zdążyłem sprawdzić tak jak @ethanak radził bo laptop mi padł...echhhh

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...