首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将Arduino罗盘信号转换为可用航向

将Arduino罗盘信号转换为可用航向
EN

Stack Overflow用户
提问于 2020-02-18 00:51:20
回答 1查看 1.5K关注 0票数 0

背景

我从亚马逊买了一个带有QMC5883芯片的Arduino磁力仪/指南针,但是我得到的轴承输出与我在网上找到的计算结果不符。串行输出似乎是合理的(相位差90°的正弦),但我为计算得到的方位所得到的数字不符合他们的预期。我将串行输出存储为一个.csv文件,以便在Excel中通过360°时绘制磁强计的响应:

响应与预期大致相同-Z保持大致稳定(除了几个由电缆引起的摆动!),X和Y变化的正弦通过360°。(请记住,我不能用手以恒定的速度转动磁强计,这就是为什么曲线如此不稳定的原因)。

然而,下面是计算标题的图表;结果应该在-180°到+180°之间:

正如你所看到的,它只变化在-60°到-160°之间,而且每个轴承读数并不是唯一的,因为它是由磁强计的两个不同的旋转给出的。所使用的代码中的具体计算(全部在底部)是:

代码语言:javascript
运行
复制
bearing =180*atan2(y,x)/3.141592654;    //values will range from +180 to -180°
bearing +=0-(19/60);    //Adjust for local magnetic declination

问题

我不知道这个计算有什么问题,因为它在几个不同的来源中使用,我想知道如何将我得到的读数转换到一个1比1的可用范围,而不是多到1,比如-180°到+180°或者0°到360°。

以下是代码:

代码语言:javascript
运行
复制
//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);
} 
EN

回答 1

Stack Overflow用户

发布于 2020-04-18 18:09:44

对于阅读这一问题的其他人:

OP忘记实现x、y、z平滑和范围外值删除。这是如何实现的,以及它是如何实现的--看看这个QMC5883指南针库的源代码

QMC5883L指南针是一个使用QMC5583L系列芯片卡作为指南针的Arduino库。

它支持:

  • 得到XYZ轴的值。
  • 计算方位角。
  • 得到16点方位方位方向(0 - 15)。
  • 获得16点方位方位名称(N,NNE,NE,ENE,E,ESE,SE,SSE,S,SSW,SW,WSW,W,WNW,NW,NW,NNW)
  • 通过滚动平均和最小/最大去除平滑XYZ读数。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60272297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档