Если не работает HMC5983

Если не работает HMC5983

Сообщение Userpc1010 » 11 ноя 2017, 21:22

Купил на aliexpress датчик hmc5983 где было указанно что датчик полный аналог hmc5883L только лишь с температурной компенсацией когда он пришёл распаял гребёнку и принялся его тестировать но никаких признаков жизни с примером от hmc5883L тогда загрузил i2c сканер тоже ничего стал проверять провода и распайку но ничего не помогало брал заведомо рабочий скетч но датчик мёртвый ничего не показывает шина тоже молчит, и случайно просматривая другие магнитометры заметил, что у низ есть странный припой а именно на моей плате есть отметки рядом с дорожками: 1) I2C 2) дорожка по середине 3) SPI и причём на других платах они замкнуты припоем ( i2C и дорожка по середине) также замкнут был 3v3 и CS две нижние дорожки. После этого подключил на всякий случай vin контакт к 3В ( сомневался на счёт 3в3 и CS ) тогда стабилизатор начал жутко нагреваться и пришлось выключить ))). Подключил vin к 5в и I2C сканер показал устройство с адресом 0x1C тогда я загрузил стандартный пример для HMC5883L но он не заработал, в примере был указан адрес 0x1E поменял его на 0x1C тоже ничего ( вот такая полная совместимость ). Но сканер то видит устройство взял скетч с примера для компаса исправил 0x1E на 0x1C и он заработал! Пошли изменяющиеся данные и они реагировали приближение к сенсору магнита))). Информации по устройству мало, выложу этот удачный скетч для проверки сразу скажу в нём нет никакой калибровки и он не компенсирует углы тонгажа и крена а значит при наклонах показания будут неточные, чтобы это исправить нужно использовать магнитометр в месте с гироскопом и акселерометром для компенсации углов наклона и снимать с них углы тонгажа и крена только в месте гироскоп+акселерометр+магнитометр можно добиться внятных показаний от этих приборов. И ещё оси у магнитометра иногда не совпадают с осями гироскопа и акселерометра.

Скетч для проверки магнитометра HMC5983:

Код: Выделить всё
#include <Wire.h> //I2C Arduino Library
#define Magnetometer_mX0 0x03 
#define Magnetometer_mX1 0x04 
#define Magnetometer_mZ0 0x05 
#define Magnetometer_mZ1 0x06 
#define Magnetometer_mY0 0x07 
#define Magnetometer_mY1 0x08 
int mX0, mX1, mX_out;
int mY0, mY1, mY_out;
int mZ0, mZ1, mZ_out;
float heading, headingDegrees, headingFiltered, declination;
float Xm,Ym,Zm;
#define Magnetometer 0x1C //I2C 7bit address of HMC5883 тут было 0x1E
void setup(){
  //Initialize Serial and I2C communications
  Serial.begin(115200);
  Wire.begin();
  delay(100);
 
  Wire.beginTransmission(Magnetometer);
  Wire.write(0x02); // Select mode register
  Wire.write(0x00); // Continuous measurement mode
  Wire.endTransmission();
}
void loop(){
 
  //---- X-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mX1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1)   
  {
    mX0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mX0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1)   
  {
    mX1 = Wire.read();
  }
  //---- Y-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mY1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1)   
  {
    mY0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mY0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1)   
  {
    mY1 = Wire.read();
  }
 
  //---- Z-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mZ1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1)   
  {
    mZ0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mZ0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1);
  if(Wire.available()<=1)   
  {
    mZ1 = Wire.read();
  }
 
  //---- X-Axis
  mX1=mX1<<8;
  mX_out =mX0+mX1; // Raw data
  // From the datasheet: 0.92 mG/digit
  Xm = mX_out*0.00092; // Gauss unit
  //* Earth magnetic field ranges from 0.25 to 0.65 Gauss, so these are the values that we need to get approximately.
  //---- Y-Axis
  mY1=mY1<<8;
  mY_out =mY0+mY1;
  Ym = mY_out*0.00092;
  //---- Z-Axis
  mZ1=mZ1<<8;
  mZ_out =mZ0+mZ1;
  Zm = mZ_out*0.00092;
  // ==============================
  //Calculating Heading
  heading = atan2(Ym, Xm);
 
  // Correcting the heading with the declination angle depending on your location
  // You can find your declination angle at: http://www.ngdc.noaa.gov/geomag-web/
  // At my location it's 4.2 degrees => 0.073 rad
  declination = 0.073;
  heading += declination;
 
  // Correcting when signs are reveresed
  if(heading <0) heading += 2*PI;
  // Correcting due to the addition of the declination angle
  if(heading > 2*PI)heading -= 2*PI;
  headingDegrees = heading * 180/PI; // The heading in Degrees unit
  // Smoothing the output angle / Low pass filter
  headingFiltered = headingFiltered*0.85 + headingDegrees*0.15;
  //Sending the heading value through the Serial Port to Processing IDE
  Serial.println(headingFiltered);
 
  delay(50);
}
Последний раз редактировалось Userpc1010 18 фев 2018, 16:38, всего редактировалось 6 раз(а).
Userpc1010
 
Сообщения: 6
Зарегистрирован: 01 авг 2017, 19:53

Re: Если не работает HMC5983

Сообщение Userpc1010 » 18 фев 2018, 16:11

Примерная функция для компенсации наклонов магнитометра, на разных датчиках придётся поэкспериментировать с осями т.к. они могут не совпадать, начать стоит с того что-бы были более мене адекватные показания на ровном столе подбирая оси магнитометра (функция должна указывать азимут в градусах его можно сравнить с показаниями механического компаса либо на смартфоне) если показания на столе правильные значит оси магнитометра настроены верно и можно приступить к осям IMU сенсора (например MPU 6050) тут важно что-бы не только совпали оси тонгажа и крена но ещё и наклоны что-бы при наклоне в вверх учитывалось отклонение вверх а не в низ на практике это выражается в отрицательных и положительных значениях от датчика после настройки показания от датчиков не помешало-бы отфильтровать т.к. они довольно таки сильно скачут:

На всякий случай ссылки на сопутствующие библиотеки "там-же" есть видео где более подробно всё сказано.
ссылка на библиотеку MPU 5060
ссылка на библиотеку HMC5883L


Код: Выделить всё
#include <Wire.h>
#include <HMC5883L.h>
#include <MPU6050.h>

HMC5883L compass;
MPU6050 mpu;

float heading1;
float heading2;

void setup()
{
  Serial.begin(9600);

  // Initialize MPU6050
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    delay(500);
  }

  // Enable bypass mode
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true) ;
  mpu.setSleepEnabled(false);

  // Initialize Initialize HMC5883L
  while (!compass.begin())
  {
    delay(500);
  }

  // Set measurement range
  compass.setRange(HMC5883L_RANGE_1_3GA);

  // Set measurement mode
  compass.setMeasurementMode(HMC5883L_CONTINOUS);

  // Set data rate
  compass.setDataRate(HMC5883L_DATARATE_30HZ);

  // Set number of samples averaged
  compass.setSamples(HMC5883L_SAMPLES_8);

  // Set calibration offset. See HMC5883L_calibration.ino
  compass.setOffset(0, 0);
}

// No tilt compensation
float noTiltCompensate(Vector mag)
{
  float heading = atan2(mag.YAxis, mag.XAxis);
  return heading;
}
 
// Функция компенсации наклона датчика
float tiltCompensate(Vector mag, Vector normAccel)
{
  // Pitch & Roll
 
  float roll;
  float pitch;
 
  roll = asin(normAccel.YAxis);   //если функцию использовать в другом проекте сюда нужен угол в радианах а магнитометра в мили Гауссах
  pitch = asin(-normAccel.XAxis);

  if (roll > 0.78 || roll < -0.78 || pitch > 0.78 || pitch < -0.78)// при наклоне более 45град компенсация теряет эффективность
  {
    return -1000;
  }
 
    // Some of these are used twice, so rather than computing them twice in the algorithem we precompute them before hand.
  float cosRoll = cos(roll);
  float sinRoll = sin(roll); 
  float cosPitch = cos(pitch);
  float sinPitch = sin(pitch);
 
  // Tilt compensation
  float Xh = mag.XAxis * cosPitch + mag.ZAxis * sinPitch;
  float Yh = mag.XAxis * sinRoll * sinPitch + mag.YAxis * cosRoll - mag.ZAxis * sinRoll * cosPitch;
 
  float heading = atan2(Yh, Xh);//На выходе должен получится угол в градусах.
   
  return heading;
}

// Correct angle
float correctAngle(float heading)
{
  if (heading < 0) { heading += 2 * PI; }
  if (heading > 2 * PI) { heading -= 2 * PI; }

  return heading;
}

void loop()
{
  // Read vectors
  Vector mag = compass.readNormalize();
  Vector acc = mpu.readScaledAccel(); 

  // Calculate headings
  heading1 = noTiltCompensate(mag);
  heading2 = tiltCompensate(mag, acc);
 
  if (heading2 == -1000)
  {
    heading2 = heading1;
  }

   // Угол магнитного склонения нужен что-бы показывать географический северный полюс.
  // Set declination angle on your location and fix heading
  // You can find your declination on: http://magnetic-declination.com/
  // (+) Positive or (-) for negative
  // For Bytom / Poland declination angle is 4'26E (positive)
  // Formula: (deg + (min / 60.0)) / (180 / M_PI);
  float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI);// А можно просто в онлайн калькуляторе перевести в десятичный вид )))
  heading1 += declinationAngle;
  heading2 += declinationAngle;
 
  // Correct for heading < 0deg and heading > 360deg
  heading1 = correctAngle(heading1);
  heading2 = correctAngle(heading2);

  // Convert to degrees
  heading1 = heading1 * 180/M_PI;
  heading2 = heading2 * 180/M_PI;

  // Output
  Serial.print(heading1);
  Serial.print(":");
  Serial.println(heading2);

  delay(100);
}

Userpc1010
 
Сообщения: 6
Зарегистрирован: 01 авг 2017, 19:53

Re: Если не работает HMC5983

Сообщение YuryP » 06 мар 2018, 23:16

Для именно чипа 5983 есть своя библиотека (я её правда не пробовал): https://github.com/arduino/HMC5983
Но у меня прекрасно работает универсальная библиотека: https://github.com/DFRobot/DFRobot_QMC5883
YuryP
 
Сообщения: 1
Зарегистрирован: 06 мар 2018, 23:10


Вернуться в Сенсоры и датчики

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron
© 2009-2017 |  О проекте  |  Политика Конфиденциальности  |