Вопрос по GY-271 (QMC5883)

forfrends
Offline
Зарегистрирован: 24.02.2015

Всем привет! имеется модуль Цифрового компаса QMC5883L. Установил несколько библиотек: Mecha_QMC5883L и DFRobot_QMC5883, покрутил в руках, вроде работает, циферки в мониторе порта бегут и меняются в зависимости от поворота/наклона датчика.

Мне нужно сделать определение "верха" и "низа". То есть мне нужно его встроить в устройство, чтобы при перевороте устройства понимать где верх. Высокая точность не нужна, так как корпус будет прямоугольным, и на ребро его никто ставить не будет.

Подскажите, как это реализовать? Что-то сообразить не могу. Проблема в том что при перевороте меняются значения у всех трех осей, так как положение в пространстве может поменяться как угодно... и это вводит меня в какой-то ступор.

вот пример из библиотеки от DFRobot_QMC5883:

/*!
 * @file QMC5883_readRaw.cpp
 * @brief show raw data
 * @n 3-Axis Digital Compass IC
 *
 * @copyright	[DFRobot](http://www.dfrobot.com), 2017
 * @copyright	GNU Lesser General Public License
 *
 * @author [dexian.huang](952838602@qq.com)
 * @version  V1.0
 * @date  2017-7-3
 */

#include <Wire.h>
#include <DFRobot_QMC5883.h>

DFRobot_QMC5883 compass;

int minX = 0;
int maxX = 0;
int minY = 0;
int maxY = 0;
int offX = 0;
int offY = 0;

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

  // Initialize Initialize QMC5883
  while (!compass.begin()){
    Serial.println("Could not find a valid QMC5883 sensor, check wiring!");
    delay(500);
  }
  if(compass.isHMC() ){
    Serial.println("Initialize HMC5883");
    compass.setRange(HMC5883L_RANGE_1_3GA);
    compass.setMeasurementMode(HMC5883L_CONTINOUS);
    compass.setDataRate(HMC5883L_DATARATE_15HZ);
    compass.setSamples(HMC5883L_SAMPLES_8);
  }else if(compass.isQMC()){
    Serial.println("Initialize QMC5883");
    compass.setRange(QMC5883_RANGE_2GA);
    compass.setMeasurementMode(QMC5883_CONTINOUS); 
    compass.setDataRate(QMC5883_DATARATE_50HZ);
    compass.setSamples(QMC5883_SAMPLES_8);
  }
}

void loop()
{
  Vector mag = compass.readRaw();
  Serial.print(mag.XAxis);
  Serial.print(":");
  Serial.print(mag.YAxis);
  Serial.print(":");
  Serial.println(mag.ZAxis);
}

На выходе вот это:

-2550.00:11790.00:-10248.00
-2550.00:11790.00:-10244.00
-2550.00:11790.00:-10244.00
-1805.00:10420.00:-10240.00
-920.00:9092.00:-10240.00
-860.00:9110.00:-10244.00
-2680.00:7700.00:-7684.00
-3022.00:8416.00:-7680.00
-5314.00:11740.00:-7680.00
-6700.00:12430.00:-7684.00
-6378.00:11317.00:-5888.00
-6240.00:10840.00:-5124.00
-6391.00:10785.00:-4868.00
-7750.00:10290.00:-2564.00
-7750.00:10290.00:-2564.00
-7750.00:10290.00:-2564.00
-11131.00:12299.00:-768.00
-10465.00:13871.00:0.00
-12700.00:13950.00:-4.00
-12700.00:13950.00:-4.00
-12700.00:13950.00:-4.00
-12700.00:13950.00:-4.00
-12700.00:13950.00:-4.00
-12700.00:13950.00:-4.00
-11680.00:12890.00:5116.00
-11680.00:12890.00:5116.00
-11680.00:12890.00:5116.00
-11680.00:12890.00:5116.00
-11680.00:12890.00:5116.00
-11680.00:12890.00:5116.00
-12300.00:15080.00:7676.00
-11748.00:14003.00:8448.00
-10460.00:11490.00:10236.00
-10460.00:11490.00:10236.00
-10460.00:11490.00:10236.00
-10460.00:11490.00:10232.00
-10182.00:11436.00:10752.00
-8995.00:11439.00:12800.00
-9040.00:12185.00:12800.00
-9260.00:12420.00:12796.00
-9260.00:12420.00:12796.00
-7770.00:7790.00:15356.00
-7770.00:7790.00:15356.00
-7770.00:7790.00:15356.00
-7770.00:7790.00:15356.00
-6636.00:8574.00:15360.00
-6054.00:8742.00:15360.00
-6298.00:8661.00:15360.00
-6280.00:8490.00:15356.00
-6420.00:8810.00:15360.00
-6630.00:9290.00:15356.00
-6630.00:9290.00:15356.00
-6630.00:9290.00:15356.00
-4340.00:9040.00:17916.00
-4340.00:9040.00:17916.00
-4340.00:9040.00:17916.00
-4604.00:8878.00:17920.00
-4780.00:8770.00:17916.00
-2899.00:6754.00:17920.00
-5030.00:8970.00:17916.00
-5021.00:8949.00:17920.00
-5000.00:8900.00:17916.00
-5000.00:8900.00:17916.00
-5000.00:8900.00:17916.00
-5000.00:8900.00:17912.00
-5000.00:8900.00:17916.00
-5000.00:8900.00:17916.00
-5000.00:8900.00:17916.00
-5000.00:8900.00:17916.00
-6440.00:8828.00:15872.00
-6800.00:8810.00:15352.00
-6800.00:8810.00:15356.00
-6800.00:8810.00:15356.00
-6800.00:8810.00:15356.00
-6800.00:8810.00:15356.00
-6800.00:8810.00:15356.00
-6800.00:8810.00:15352.00
-6800.00:8810.00:15356.00
-8040.00:9114.00:14336.00
-9900.00:9570.00:12796.00
-9900.00:9570.00:12796.00
-9900.00:9570.00:12796.00
-9842.00:9664.00:13056.00
-7790.00:5200.00:15356.00
-7790.00:5200.00:15356.00
-7790.00:5200.00:15356.00
-7790.00:5200.00:15356.00
-9734.00:8764.00:13056.00

Вот пример из Mecha_QMC5883L:

#include <Wire.h>
#include <MechaQMC5883.h>

MechaQMC5883 qmc;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  qmc.init();
  //qmc.setMode(Mode_Continuous,ODR_200Hz,RNG_2G,OSR_256);
}

void loop() {
  int x, y, z;
  int azimuth;
  //float azimuth; //is supporting float too
  qmc.read(&x, &y, &z,&azimuth);
  //azimuth = qmc.azimuth(&y,&x);//you can get custom azimuth
  Serial.print("x: ");
  Serial.print(x);
  Serial.print(" y: ");
  Serial.print(y);
  Serial.print(" z: ");
  Serial.print(z);
  Serial.print(" a: ");
  Serial.print(azimuth);
  Serial.println();
  delay(100);
}

Вот что на выходе при попытке "аккуратно" перевернуть датчик "вверх ногами":

x: -1458 y: -1715 z: 435 a: 229
x: -1461 y: -1682 z: 450 a: 229
x: -1450 y: -1680 z: 480 a: 229
x: -1442 y: -1705 z: 461 a: 229
x: -1422 y: -1690 z: 515 a: 229
x: -1491 y: -1670 z: 466 a: 228
x: -1545 y: -1710 z: 308 a: 227
x: -1637 y: -1760 z: 66 a: 227
x: -1712 y: -1737 z: -265 a: 225
x: -1707 y: -1755 z: -630 a: 225
x: -1632 y: -1778 z: -888 a: 227
x: -1686 y: -1652 z: -840 a: 224
x: -1700 y: -1442 z: -1031 a: 220
x: -1668 y: -1295 z: -1132 a: 217
x: -1458 y: -1168 z: -1408 a: 218
x: -1230 y: -1112 z: -1592 a: 222
x: -933 y: -1075 z: -1710 a: 229
x: -466 y: -1115 z: -1815 a: 247
x: 22 y: -1183 z: -1737 a: 271
x: 361 y: -1246 z: -1605 a: 286
x: 485 y: -1283 z: -1541 a: 290
x: 600 y: -1238 z: -1436 a: 295
x: 713 y: -1290 z: -1382 a: 298
x: 772 y: -1380 z: -1305 a: 299
x: 838 y: -1432 z: -1223 a: 300
x: 787 y: -1445 z: -1261 a: 298
x: 667 y: -1468 z: -1385 a: 294
x: -17 y: -1191 z: -1712 a: 269
x: -872 y: -1117 z: -1677 a: 232
x: -1493 y: -1360 z: -1323 a: 222
x: -1720 y: -1440 z: -1036 a: 219
x: -1851 y: -1501 z: -662 a: 219
x: -1848 y: -1491 z: -87 a: 218
x: -1646 y: -1476 z: 383 a: 221
x: -1368 y: -1466 z: 692 a: 226
x: -1165 y: -1427 z: 853 a: 230
x: -1028 y: -1387 z: 933 a: 233
x: -940 y: -1367 z: 1001 a: 235
x: -896 y: -1372 z: 996 a: 236
x: -911 y: -1375 z: 977 a: 236
x: -921 y: -1395 z: 973 a: 236
x: -940 y: -1380 z: 985 a: 235
x: -950 y: -1382 z: 968 a: 235
x: -926 y: -1385 z: 982 a: 236
x: -926 y: -1377 z: 998 a: 236
x: -940 y: -1370 z: 982 a: 235
x: -940 y: -1377 z: 966 a: 235
x: -950 y: -1355 z: 973 a: 234
x: -975 y: -1357 z: 955 a: 234
x: -1227 y: -1382 z: 826 a: 228
x: -1597 y: -1427 z: 453 a: 221
x: -1776 y: -1468 z: 93 a: 219
x: -1861 y: -1390 z: -136 a: 216
x: -1900 y: -1365 z: -563 a: 215
x: -1597 y: -1360 z: -1288 a: 220
x: -1093 y: -1337 z: -1635 a: 230
x: -531 y: -1320 z: -1806 a: 248
x: 227 y: -1292 z: -1691 a: 279
x: 572 y: -1273 z: -1527 a: 294
x: 833 y: -1258 z: -1305 a: 303
x: 940 y: -1253 z: -1143 a: 306
x: 1008 y: -1238 z: -1060 a: 309
x: 975 y: -1198 z: -1125 a: 309
x: 757 y: -938 z: -1433 a: 308
x: 585 y: -787 z: -1546 a: 306
x: 502 y: -680 z: -1586 a: 306
x: 507 y: -611 z: -1576 a: 309
x: 510 y: -650 z: -1581 a: 308
x: 515 y: -631 z: -1576 a: 309
x: 526 y: -603 z: -1567 a: 311

 

rkit
Offline
Зарегистрирован: 23.11.2016

По компасу - никак.

forfrends
Offline
Зарегистрирован: 24.02.2015

С датчика получаются данные по осям  X, Y и Z (углы наклона/поворота). Вот еще пример:

#include <Wire.h> //I2C Arduino Library
#define addr 0x0D //I2C Address for The HMC5883

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

  Wire.beginTransmission(addr); //start talking
  Wire.write(9); // Set the Register
  Wire.write(1); // Write value to register
  Wire.endTransmission();
}

void loop() {
  int x, y, z; //triple axis data

  Wire.beginTransmission(addr);
  Wire.write(1);              // start reading from first register
  Wire.requestFrom(addr, 6);  // request 6 bytes from device
  while (Wire.available())
  {
    x = Wire.read() << 8; //MSB  x
    x |= Wire.read(); //LSB  x
    y = Wire.read() << 8; //MSB  z
    y |= Wire.read(); //LSB z
    z = Wire.read() << 8; //MSB y
    z |= Wire.read(); //LSB y
  }
  Wire.endTransmission();

  Serial.print("[");
  Serial.print(x);
  Serial.print(",");
  Serial.print(y);
  Serial.print(",");
  Serial.print(z);
  Serial.println("]");

  delay(250);
}

 

rkit
Offline
Зарегистрирован: 23.11.2016

Нет, он показывает нэ вектор магнитного поля. Углы поворота это крен, тангаж и рыскание.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Для определения переворота лежащего или горизонтально двигающегося устройства проще всего акселерометр использовать,  а если устройство постоянно тормозит/ускоряется по высоте то плюс еще гироскоп нужен будет.

 

rkit
Offline
Зарегистрирован: 23.11.2016

asam пишет:

а если устройство постоянно тормозит/ускоряется по высоте то плюс еще гироскоп нужен будет.

Фнч хватит за глаза. А гироскоп в такой ситуации кроме нулей ничего не покажет.

forfrends
Offline
Зарегистрирован: 24.02.2015

Объект будет лежать статично. Только время от времени его будут брать и ложить на место. Мне просто нужно узнать какой стороной он будет к верху

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

forfrends пишет:

Объект будет лежать статично. Только время от времени его будут брать и ложить на место. Мне просто нужно узнать какой стороной он будет к верху

Ну тогда простейший акселерометер идеальное решение.