Преобразование сигнала компаса Arduino в полезный курс - PullRequest
0 голосов
/ 18 февраля 2020

Справочная информация

Я купил магнитометр / компас Arduino с микросхемой QMC5883 от Amazon, однако вывод подшипника, который я получаю, не соответствует расчетам, которые я нашел в Интернете , Последовательный вывод кажется правдоподобным (синусоиды с разностью фаз 90 °), но числа, которые я получаю для рассчитанного подшипника, не соответствуют тому, что они должны. Я сохранил последовательный вывод в виде CSV-файла, чтобы построить график отклика магнитометра при повороте на 360 ° в Excel:

Magnetometer X,Y,Z response when turned through 360°

Ответ был примерно таким, как ожидалось - Z остается примерно устойчивым (за исключением нескольких колебаний, вызванных кабелем!), X и Y изменяются синусоидально на 360 °. (Помните, что я не мог повернуть магнитометр с постоянной скоростью рукой, поэтому кривые так неустойчивы).

Однако ниже приведен график того, какой курс был рассчитан; результаты должны были находиться в диапазоне от -180 ° до + 180 °:

enter image description here

Как вы можете видеть, он изменяется только от -60 ° до -160 ° и каждое показание подшипника не уникально, поскольку оно дается двумя различными вращениями магнитометра. Специфический c расчет в используемом коде (полностью внизу):

bearing =180*atan2(y,x)/3.141592654;    //values will range from +180 to -180°
bearing +=0-(19/60);    //Adjust for local magnetic declination

Вопрос

Я не могу понять, что не так с расчет, поскольку он используется в нескольких различных источниках, и я хотел бы знать, как преобразовать полученные значения в пригодный для использования диапазон, который составляет один к одному вместо многих к одному, например от -180 ° до +180 ° или 0 ° до 360 °.

Вот код:

//There are several differences between the QMC5883L and the HMC5883L chips
//Differences in address: 0x0D for QMC5883L; 0x1E for HMC5883L
//Differences in register map (compare datasheets)
//Output data register differences include location of x,y,z and MSB and LSB for these parameters
//Control registers are also different (so location and values for settings change)

#include <Wire.h> //I2C Arduino Library

#define addr 0x0D //I2C Address for The QMC5883L (0x1E for HMC5883)

double scale=1.0;

void setup() {
// double scaleValues[9]={0.00,0.73,0.92,1.22,1.52,2.27,2.56,3.03,4.35};
// scale=scaleValues[2];
//initialize serial and I2C communications
Serial.begin(9600);
Wire.begin();

Wire.beginTransmission(addr); //start talking to slave
Wire.write(0x0B); 
Wire.write(0x01); 
Wire.endTransmission();

Wire.beginTransmission(addr); //start talking to slave
Wire.write(0x09);
Wire.write(0x1D);
Wire.endTransmission();
}

void loop() {

int x, y, z; //triple axis data

//Tell the QMC what regist to begin writing data into
Wire.beginTransmission(addr);
Wire.write(0x00); //start with register 00H for QMC5883L
Wire.endTransmission();

double bearing=0.00;
//Read the data.. 2, 8 bit bytes for each axis.. 6 total bytes
Wire.requestFrom(addr, 6);
//read 6 registers in order; register location (i.e.00H)indexes by one once read
if (6 <= Wire.available()) {
//note the order of following statements matters
//as each register will be read in sequence starting from data register 00H to 05H
//where order is xLSB,xMSB,yLSB,yMSB,zLSB,zMSB
//this is different from HMC5883L!
//data registers are 03 to 08 
//where order is xMSB,xLSB,zMSB,zLSB,yMSB,yLSB
x = Wire.read(); //LSB x; 
x |= Wire.read()<<8; //MSB x; bitshift left 8, then bitwise OR to make "x" 
// x*=scale;
y = Wire.read(); //LSB y 
y |= Wire.read()<<8; //MSB y; 
// y*=scale;
z = Wire.read(); //LSB z; irrelevant for compass 
z |= Wire.read()<<8; //MSB z; 
// z*=scale;

bearing =180*atan2(y,x)/3.141592654;//values will range from +180 to -180 degrees
bearing +=0-(19/60);//Adjust for local magnetic declination
}

// Show Values
//Serial.print("X:");
Serial.print(x);
//Serial.print("    Y: ");
Serial.print(",");
Serial.print(y);
//Serial.print("    Z: ");
Serial.print(",");
Serial.print(z);
//Serial.print("    B: ");
Serial.print(",");
Serial.println(bearing);

delay(500);
} 

1 Ответ

1 голос
/ 18 апреля 2020

Для других читающих этот вопрос:
ОП забыл реализовать сглаживание ax, y, z и удаление значений вне области видимости. Как этого добиться и как это сделать, смотрите в исходном коде библиотеки компаса QMC5883 :


QMC5883L Compass - это библиотека Arduino для использования в качестве компаса чиповых плат серии QMC5583L .

Поддерживается:

  • Получение значений оси XYZ.
  • Расчет азимута.
  • Получение 16-ти точечного направления азимутального направления (0 - 15 ).
  • Получение имен азимутальных азимутов в 16 точек (N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW)
  • Сглаживание показаний XYZ посредством скользящего усреднения и удаления мин / макс.
...