HMC5883L模块具有两个配置寄存器,配置寄存器A用来配置该装置设置的数据输出速率和测量配置;配置寄存器 B 设置装置的增益。
模式寄存器则是用来设定装置的操作模式,有连续测量模式,单一测量模式和闲置模式等。具体的情况可以查阅HMC5883L数据手册。

下面我们对HMC5883L的寄存器进行配置。
#define HMC5883_REG_X_MSB 0x03 //输出X寄存器A中存储测量结果中的MSB(高位数据)
#define HMC5883_REG_X_LSB 0x04 //输出X寄存器B中存储测量结果中的MSB(低位数据)
#define HMC5883_REG_Z_MSB 0x05 //输出Y寄存器A中存储测量结果中的MSB(高位数据)
#define HMC5883_REG_Z_LSB 0x06 //输出Y寄存器B中存储测量结果中的MSB(低位数据)
#define HMC5883_REG_Y_MSB 0x07 //输出Z寄存器A中存储测量结果中的MSB(高位数据)
#define HMC5883_REG_Y_LSB 0x08 //输出Z寄存器B中存储测量结果中的MSB(低位数据)
/* CRA */
#define HMC5883_REG_CRA_MS_MASK 0x03
#define HMC5883_REG_CRA_MS_NORAL 0x00 // default
#define HMC5883_REG_CRA_MS_XYZ_P 0x01
#define HMC5883_REG_CRA_MS_XYZ_N 0x02
#define HMC5883_REG_CRA_MS_REV 0x03
#define HMC5883_REG_CRA_DO_Hz_MASK 0x1C
#define HMC5883_REG_CRA_DO_Hz_0_75 0x00
#define HMC5883_REG_CRA_DO_Hz_1_5 0x04
#define HMC5883_REG_CRA_DO_Hz_3 0x08
#define HMC5883_REG_CRA_DO_Hz_7_5 0x0C
#define HMC5883_REG_CRA_DO_Hz_15 0x10 // default
#define HMC5883_REG_CRA_DO_Hz_30 0x14
#define HMC5883_REG_CRA_DO_Hz_75 0x18
#define HMC5883_REG_CRA_DO_Hz_NONE 0x1C
#define HMC5883_REG_CRA_MA_MASK 0x60
#define HMC5883_REG_CRA_MA_AVG_1 0x00
#define HMC5883_REG_CRA_MA_AVG_2 0x20
#define HMC5883_REG_CRA_MA_AVG_4 0x40
#define HMC5883_REG_CRA_MA_AVG_8 0x60 // default
#define HMC5883_REG_CRA_RUN_MASK 0x80
/* CRB */
#define HMC5883_REG_GN_GA_MASK 0xE0
#define HMC5883_REG_GN_0_88_G1370 0x00
#define HMC5883_REG_GN_1_30_G1090 0x20 // default
#define HMC5883_REG_GN_1_90_G820 0x40
#define HMC5883_REG_GN_2_50_G660 0x60
#define HMC5883_REG_GN_4_00_G440 0x80
#define HMC5883_REG_GN_4_70_G390 0xA0
#define HMC5883_REG_GN_5_60_G330 0xC0
#define HMC5883_REG_GN_8_10_G230 0xE0
/* MODE */
#define HMC5883_REG_MODE_MR_MASK 0x03
#define HMC5883_REG_MODE_MR_CON 0x00
#define HMC5883_REG_MODE_MR_SIG 0x01 // default
#define HMC5883_REG_MODE_MR_IDLE1 0x02
#define HMC5883_REG_MODE_MR_IDLE2 0x03
/* read addr*/
#define HMC5883_ADDR 0X3C
/*-------------------------------------------------------------
IIC地址:0X3C
配置寄存器A:0X00 (用于配置该装置设置的数据输出速率和测量配置)
配置寄存器B: 0X01 (用于设置装置的增益)
模式寄存器: 0X02 (用来设定装置的操作模式)
---------------------------------------------------------------*/
/* IIC read x y z data > buf */
I2CWriteNByteVal(IIC_HMC5883,HMC5883_REG_X_MSB,0,0);
I2CReadNByte(IIC_HMC5883,6,buf);
/* buf > short x y z */
x = buf[0];
x <<= 8;
x |= buf[1];
z = buf[2];
z <<= 8;
z |= buf[3];
y = buf[4];
y <<= 8;
y |= buf[5];
在角度计算公式的使用上,atan2函数+180,atan函数+90;
这里计算的原理就是通过获取的X,Y,Z值代入公式进行计算;笔者这边+360,主要是因为芯片焊在板子上之后,方向与原来的方向反了180度,所以在这里+360如何进行逻辑判断。如果不知道自己的方向有没有相反,可以用手机的指南针功能进行对比。
//atan2求出的angle取值范围为[-180,180]
angle_xy = atan2(y,x)*(180/3.14159265)+180;
angle_xz = atan2(x,z)*(180/3.14159265)+180;
angle_yz = atan2(y,z)*(180/3.14159265)+180;
//atan求出的angle取值范围为[-90,90]
angle_xy = atan(y,x)*(180/3.14159265)+90;
angle_xz = atan(x,z)*(180/3.14159265)+90;
angle_yz = atan(y,z)*(180/3.14159265)+90;
/* 将芯片焊到板子上时,测量方位时正常方位的反面,因而在原有基础上多加180度旋转,再进行判断 */
obj.xy_angle_val = atan2(obj.val_y,obj.val_x) * (180 / 3.14159265) + 360;
if(obj.xy_angle_val > 360){
obj.xy_angle_val = obj.xy_angle_val - 360;
}
obj.xz_angle_val = atan2(obj.val_x,obj.val_z) * (180 / 3.14159265) + 360;
if(obj.xz_angle_val > 360){
obj.xz_angle_val = obj.xz_angle_val - 360;
}
obj.yz_angle_val = atan2(obj.val_y,obj.val_z) * (180 / 3.14159265) + 360;
if(obj.yz_angle_val > 360){
obj.yz_angle_val = obj.yz_angle_val - 360;
这边主要通过东南西北,东北西北东南西南,8个方位各个方位的角度区域来推算出相对应的方向。
/* 通过枚举先定义出8个方位 */
enum direction_type_em {
DIRECTION_NE = 0,
DIRECTION_E,
DIRECTION_SE,
DIRECTION_S,
DIRECTION_SW,
DIRECTION_W,
DIRECTION_NW,
DIRECTION_N,
};
/* 再通过角度范围判断,赋值相应的枚举值 */
unsigned char get_direction(void)
{
if (obj.xz_angle_val >= 22 && obj.xz_angle_val <= 67) {
obj.direction = DIRECTION_NE;
} else if (obj.xz_angle_val >= 68 && obj.xz_angle_val <= 111) {
obj.direction = DIRECTION_E;
} else if (obj.xz_angle_val >= 112 && obj.xz_angle_val <= 157) {
obj.direction = DIRECTION_SE;
} else if (obj.xz_angle_val >= 158 && obj.xz_angle_val <= 201) {
obj.direction = DIRECTION_S;
} else if (obj.xz_angle_val >= 202 && obj.xz_angle_val <= 247) {
obj.direction = DIRECTION_SW;
} else if (obj.xz_angle_val >= 248 && obj.xz_angle_val <= 291) {
obj.direction = DIRECTION_W;
} else if (obj.xz_angle_val >= 292 && obj.xz_angle_val <= 337) {
obj.direction = DIRECTION_NW;
} else {
obj.direction = DIRECTION_N;
}
return obj.direction;
}
/* 通过枚举值赋值相应的字符串,实现通过角度判断方位 */
char* get_direction_str()
{
switch(get_direction()) {
case DIRECTION_NE: return "NE";
case DIRECTION_E: return "E";
case DIRECTION_SE: return "SE";
case DIRECTION_S: return "S";
case DIRECTION_SW: return "SW";
case DIRECTION_W: return "W";
case DIRECTION_NW: return "NW";
case DIRECTION_N: return "N";
}
return 0;
}
众所周知,地球是椭圆的,因而我们获取到的全方位数据并非圆形而是椭圆形。因而我们需要将获取到的数据进行校准成圆形。

//偏移校正
Xoffset = (Xmax + Xmin)/2;
Yoffset = (Ymax + Ymin)/2;
Zoffset = (Zmax + Zmin)/2;
//系数校正
Kx = 1;
Ky = (Xmax - Xmin)/(Ymax - Ymin);
Kz = (Xmax - Xmin)/(Zmax - Zmin);
//将椭圆模型校准成圆形后,获取的x,y,z值
x = Kx * (x - Xoffset);
y = Ky * (y - Yoffset);
z = Kz * (z - Zoffset);
在经过一系列的参数校正后,我们获取到的数据,经过数据采集分析,数据接近圆形(但并非完全的圆形)
*在磁力计校准过程中,我们可以在校准前用如下方法判断磁力计当前状态是否正确:
磁力计的X轴指向正北时,磁力计的寄存器X轴此时输出最大值
磁力计的X轴指向正南时,X轴应该有最小值。
磁力计的Y轴指向正北时,磁力计的寄存器Y轴此时应该输出最小值;
磁力计的X轴指向正南时,Y轴应该有最大值。

硬磁干扰是指固定在磁力计所在机体的表面物质产生的固定方向的干扰。
硬磁干扰会导致磁力计所采集的数据形成的圆球偏离球心。
软磁干扰是指固定在磁力计所在机体的表面物质所产生的混乱地磁场的干扰,也就是磁场干扰的方面不是固定的。
软磁干扰会导致磁力计所采集的数据形成圆球变成椭球。
电路板上的马达和喇叭、
含有铁钴镍等金属材料如:屏蔽罩、螺丝、电阻、LCD背板及外壳
在使用传感器側不要使用含铁磁材料(如铁做的插针、插座以及铁材料的导线),这些材料不仅会干扰被测磁场,而且材料的剩磁会导致零位误差。直接将导线焊在传感器板上,不用接插件渡。
如果想要将芯片手工焊在板子上,那么记住要找个技术好的师傅,这个芯片还是挺考验技术的!此外,如果想要用这块芯片做项目,那么在电路设计的时候,记住连接这块芯片的电容要与数据手册上的数值相对应,否则你可能读不到数据然后怀疑自己的程序有问题。两个电容,一个是4.7uf,一个是0.22uf,注意啦,不一样可能读不出数据。
从两个电子罗盘的数据手册上看,两个模块在寄存器上还是有差异的,具体的话不多说,看下图:

从模块的芯片丝印来看,两者的丝印是不同的。
HMC5883L的丝印为L883,QMC5883L的丝印正常为HA5883,大家一定要记住!
首先,HMC5883L是进口的芯片,QMC5883L为国产仿制芯片,在价格上差异就不小,其次,根据研发经验来看,国产QMC5883L芯片在稳定性方面就差不少。所以在购买的时候大家要记住差异。

好啦,感谢小伙伴的查阅,在技术方面,有兴趣的小伙伴可以一起探讨一下。
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty