亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino 实时数字罗盘:HMC5883L + Processing 可视化教程

项目概述

利用 Arduino 读取 HMC5883L 三轴磁力计(MEMS 磁强计)数据,经串口发送至 Processing IDE,实时渲染旋转指针罗盘界面。硬件极简:仅需磁力计模块(如 GY-80 板载 HMC5883L)、Arduino、杜邦线。

工作原理

Arduino 端:数据采集与航向角计算

  1. 通过 I2C 读取 HMC5883L 的 X、Y、Z 三轴原始值(16 位有符号整数)。
  2. 按数据手册灵敏度(0.92 mG/LSB)换算为高斯值。
  3. 航向角 heading = atan2(Y, X)(弧度),加入磁偏角修正(可在 NOAA 官网 查询当地磁偏)。
  4. 归一化至 0~2π,转换为度数。
  5. 一阶低通滤波平滑输出:headingFiltered = 0.85*headingFiltered + 0.15*headingDegrees。
  6. 以 115200 波特率经串口逐行发送 headingFiltered。
/* Arduino 罗盘 - HMC5883L
 * 作者:Dejan Nedelkovski, www.HowToMechatronics.com
 */
#include <Wire.h>
#define Magnetometer 0x1E // HMC5883L I2C 7-bit 地址
// 寄存器地址
#define Magnetometer_mX0 0x03
#define Magnetometer_mX1 0x04
#define Magnetometer_mY0 0x07
#define Magnetometer_mY1 0x08
#define Magnetometer_mZ0 0x05
#define Magnetometer_mZ1 0x06

int mX0, mX1, mX_out; int mY0, mY1, mY_out; int mZ0, mZ1, mZ_out;
float heading, headingDegrees, headingFiltered, declination;
float Xm, Ym, Zm;

void setup() {
  Serial.begin(115200);
  Wire.begin(); delay(100);
  // 配置连续测量模式
  Wire.beginTransmission(Magnetometer);
  Wire.write(0x02); // 模式寄存器
  Wire.write(0x00); // 连续测量
  Wire.endTransmission();
}

void loop() {
  // 读取 X 轴
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mX1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1); if (Wire.available()) mX0 = Wire.read();
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mX0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1); if (Wire.available()) mX1 = Wire.read();
  // 读取 Y 轴
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mY1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1); if (Wire.available()) mY0 = Wire.read();
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mY0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1); if (Wire.available()) mY1 = Wire.read();
  // 读取 Z 轴(本项目未用)
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mZ1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1); if (Wire.available()) mZ0 = Wire.read();
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mZ0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer, 1); if (Wire.available()) mZ1 = Wire.read();

  // 合成 16 位有符号值
  mX1 = mX1 << 8; mX_out = mX0 + mX1; Xm = mX_out * 0.00092;
  mY1 = mY1 << 8; mY_out = mY0 + mY1; Ym = mY_out * 0.00092;
  mZ1 = mZ1 << 8; mZ_out = mZ0 + mZ1; Zm = mZ_out * 0.00092;

  // 计算航向角
  heading = atan2(Ym, Xm);
  declination = 0.073; // 示例:4.2° 磁偏角,需替换为当地值
  heading += declination;
  if (heading < 0) heading += 2*PI;
  if (heading > 2*PI) heading -= 2*PI;
  headingDegrees = heading * 180/PI;

  // 低通滤波
  headingFiltered = headingFiltered * 0.85 + headingDegrees * 0.15;

  Serial.println(headingFiltered);
  delay(50);
}

Processing 端:可视化渲染

  1. 准备三张透明 PNG 图片:背景(可选)、罗盘盘面、指针,置于 sketch 目录。
  2. setup() 中加载图片、打开串口(修改 COM4 为实际端口)、设置缓冲直到换行符。
  3. draw() 循环:绘制背景 → 平移坐标系至屏幕中心 → rotateZ(-heading) 旋转罗盘盘面 → 恢复坐标系 → 绘制固定指针 → 显示数值。
  4. serialEvent() 读取串口字符串,转 float 赋值 heading。
/* Processing 罗盘可视化
 * 作者:Dejan Nedelkovski, www.HowToMechatronics.com
 */
import processing.serial.*;

Serial myPort;
PImage imgCompass, imgCompassArrow, background;
String data = "";
float heading = 0;

void setup() {
  size(1920, 1080, P3D); // 可改为你的屏幕分辨率
  smooth();
  imgCompass = loadImage("Compass.png");
  imgCompassArrow = loadImage("CompassArrow.png");
  background = loadImage("Background.png");
  myPort = new Serial(this, "COM4", 115200); // 修改端口号
  myPort.bufferUntil('\n');
}

void draw() {
  image(background, 0, 0);
  pushMatrix();
  translate(width/2, height/2, 0);
  rotateZ(radians(-heading));
  image(imgCompass, -width/2, -height/2);
  popMatrix();
  image(imgCompassArrow, 0, 0);
  textSize(30);
  text("Heading: " + heading, 40, 40);
  delay(40);
}

void serialEvent(Serial myPort) {
  data = myPort.readStringUntil('\n');
  if (data != null) heading = float(trim(data));
}

校准与进阶提示

项目文件(图片、源码)可在文末下载。动手做一个桌面罗盘,感受地磁的指引吧!

制造工艺

  1. 用 Arduino 打造绚丽显示器 Ambilight 系统
  2. 用 Arduino 制作超声波悬浮装置:分步指南
  3. 基于 Arduino、1Sheeld 与红外控制的万能安卓遥控器
  4. Arduino 与智能手机打造智能电压表——简单易做的 DIY 项目
  5. 基于Arduino UNO的精准频率与占空比测量
  6. 自制可拳击的可编程键盘按钮:基于 Arduino 与压电元件的分步指南
  7. Arduino 声纳实时测距与 Processing 可视化
  8. 智能停车计数系统:Arduino + Processing + PHP 实时车位追踪上云
  9. Bolt IoT + Arduino UNO 实现 6 路 LED 无级调光
  10. DIY 智能 Arduino 机械臂:主从控制与动作记忆教程
  11. 构建基于 PHP 的 Web 界面控制 Arduino Uno
  12. 使用 Arduino Nano 和 RDA8057M 制作紧凑型 FM 收音机