如何使用Arduino和处理IDE制作罗盘

在这个Arduino项目中,我们将看到我们如何使用Arduino,MEMS磁力计和处理IDE来使这块酷炫的指南针。这是指南针的示范视频:

概述


我们所需的所有项目都是MEMS磁力计,用于测量地球磁场,Arduino板和一些跳线。作为一个例子,我将使用HMC5883L,一台3轴磁力计集成在GY-80 Breakout板中。

指南针如何工作


Arduino部分

首先我们需要通过Arduino板从传感器获取数据I2C协议。然后使用传感器的X轴和Y轴值,我们将通过串行端口计算标题并将其值发送到处理IDE。以下代码将执行此作业:

/ * Arduino罗盘由德扬Nedelkovski * *, * www.HowToMechatr亚搏手机版官方下载onics.com * * / # include < Wire.h > / / I2C Arduino图书馆# define Magnetometer_mX0 0 x03 # define Magnetometer_mX1 x04 #定义Magnetometer_mZ0 0 x05 # define Magnetometer_mZ1 x06 #定义Magnetometer_mY0 0 x07 # define Magnetometer_mY1 (int mX0, mx₁,mX_out;int mY0, mY1, mY_out;int mZ0, mZ1, mZ_out;浮动航向,航向度,航向过滤,赤纬;Zm评选浮动Xm, Ym;void setup(){//初始化串行和I2C通信串行.begin(115200);Wire.begin ();延迟(100);Wire.beginTransmission(磁强计);Wire.write (0 x02); // Select mode register Wire.write(0x00); // Continuous measurement mode Wire.endTransmission(); } void loop(){ //---- X-Axis Wire.beginTransmission(Magnetometer); // transmit to device Wire.write(Magnetometer_mX1); Wire.endTransmission(); Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mX0 = Wire.read(); } Wire.beginTransmission(Magnetometer); // transmit to device Wire.write(Magnetometer_mX0); Wire.endTransmission(); Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mX1 = Wire.read(); } //---- Y-Axis Wire.beginTransmission(Magnetometer); // transmit to device Wire.write(Magnetometer_mY1); Wire.endTransmission(); Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mY0 = Wire.read(); } Wire.beginTransmission(Magnetometer); // transmit to device Wire.write(Magnetometer_mY0); Wire.endTransmission(); Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mY1 = Wire.read(); } //---- Z-Axis Wire.beginTransmission(Magnetometer); // transmit to device Wire.write(Magnetometer_mZ1); Wire.endTransmission(); Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mZ0 = Wire.read(); } Wire.beginTransmission(Magnetometer); // transmit to device Wire.write(Magnetometer_mZ0); Wire.endTransmission(); Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mZ1 = Wire.read(); } //---- X-Axis mX1=mX1<<8; mX_out =mX0+mX1; // Raw data // From the datasheet: 0.92 mG/digit Xm = mX_out*0.00092; // Gauss unit //* Earth magnetic field ranges from 0.25 to 0.65 Gauss, so these are the values that we need to get approximately. //---- Y-Axis mY1=mY1<<8; mY_out =mY0+mY1; Ym = mY_out*0.00092; //---- Z-Axis mZ1=mZ1<<8; mZ_out =mZ0+mZ1; Zm = mZ_out*0.00092; // ============================== //Calculating Heading heading = atan2(Ym, Xm); // Correcting the heading with the declination angle depending on your location // You can find your declination angle at: https://www.ngdc.noaa.gov/geomag-web/ // At my location it's 4.2 degrees => 0.073 rad declination = 0.073; heading += declination; // Correcting when signs are reveresed if(heading <0) heading += 2*PI; // Correcting due to the addition of the declination angle if(heading > 2*PI)heading -= 2*PI; headingDegrees = heading * 180/PI; // The heading in Degrees unit // Smoothing the output angle / Low pass filter headingFiltered = headingFiltered*0.85 + headingDegrees*0.15; //Sending the heading value through the Serial Port to Processing IDE Serial.println(headingFiltered); delay(50); }

如果你需要更多的细节如何MEMS磁强计的工作和如何从它获得数据,你可以检查我的MEMS传感器教程


处理IDE部分

在这里,我们需要接收来自串行端口的标题值。有关更多详细信息,您可以查看此操作Arduino和处理教程

指南针实际上是一幅图像,或者更准确地说,它是由加载到处理IDE中的多个透明图像组成的。这些图像位于草图的工作目录中。在使用image()函数在draw()部分定义了图像对象之后,我们加载了背景图像(这是可选的,您可以使用一个简单的颜色作为背景)。然后,使用rotateZ()函数加载罗盘图像,并将其与标题值一起旋转。在它们的顶部,罗盘箭头图像被加载。

这是处理IDE代码:

/ * Arduino Compass * * by dejan nedelkovski,* www.亚搏手机版官方下载www.kuaixg.com * * /导入处理。*;导入java.awt.Event.keyEvent;导入java.io.ioException;串行MyPort;pimage imgcompass;pimage imgcompassarrow;瞄准器背景;字符串数据=“”;浮动标题;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); // starts the serial communication myPort.bufferUntil('\n'); } void draw() { image(background,0, 0); // Loads the Background image pushMatrix(); translate(width/2, height/2, 0); // Translates the coordinate system into the center of the screen, so that the rotation happen right in the center rotateZ(radians(-heading)); // Rotates the Compass around Z - Axis image(imgCompass, -960, -540); // Loads the Compass image and as the coordinate system is relocated we need need to set the image at -960x, -540y (half the screen size) popMatrix(); // Brings coordinate system is back to the original position 0,0,0 image(imgCompassArrow,0, 0); // Loads the CompassArrow image which is not affected by the rotateZ() function because of the popMatrix() function textSize(30); text("Heading: " + heading,40,40); // Prints the value of the heading on the screen delay(40); } // starts reading data from the Serial Port void serialEvent (Serial myPort) { data = myPort.readStringUntil('\n');// reads the data from the Serial Port and puts it into the String variable "data". heading = float(data); // Convering the the String value into Float value }

在这里,您可以从项目,图像和源代码下载文件:

14回应

  1. 保罗

    这段代码将在Teensy3,Arduino Zero,Arduino到期,Chipkit,ESP8266和所有其他新型32位板上失败。

    问题与符号整数的两个8位无符号号码不正确。数学实际上计算了0到65535的数字,因为Wire.read()的数字为0到255.在8位AVR上,存储到16位“int”时,不正确的计算变为-32768至+32767。但在32位芯片上,计算会导致无符号0到65536,因为“int”是32位。

    “int”变量需要更改为“int16_t”以在任何32个位板上进行此操作。

    回复
  2. Sylvain.

    嗨德国,非常感谢您所有的伟大项目。足彩网女欧洲杯
    我尝试了这个,但我在第29行得到了一个空指针例外。
    你知道怎么了吗?

    回复
      • Sylvain.

        嗨Dejan,
        对不起,我不清楚。处理草图在第29行失败;有这个“null指针例外”。我试图重新计算Arduino,但仍然是错误。
        这是令人惊讶的,因为您的mems传感器代码在我的系统上都工作得很好,您的雷达项目也工作得很好。

      • Sylvain.

        对不起,我刚看过失败的细节。缺少文件compass.png,compassarrow.png和background arruction arrow.png。我怎么能得到它们?

      • Sylvain.

        嗨Dejan,我应该在你的页面上更仔细看,发现图片文件,并包含一旦包含系统工作。
        多谢!!

  3. Daniel Fernandes.

    美丽的设计,但......
    如何在TFT LCD屏幕3.2上使用它,例如,而不是计算机屏幕?谢谢

    回复
  4. Daniel Fernandes.

    嗨朋友!伟大的设计!
    我想在TFT LCD屏幕上这样做3.2“是可能的吗?
    谢谢

    回复
  5. 史蒂夫

    嗨,伟大的网站。
    请您详细解释一下如何将传感器输出转换成角度和方向。
    我正在寻找传感器的角度和方向,我将传感器移动到已知距离。
    我实际上希望将数据存储或在数据记录器中存储或看到,如角度和方向。
    如果问题如此简单和愚蠢,我对arduino很抱歉。
    谢谢

    回复

留下一个回复

您的电子邮件地址不会被公开。

受到推崇的

2019年最佳入门级示波器为初学者和爱好者

为初学者和爱好者最好的示波器

受到推崇的

8个最好的Arduino入门工具包,适合2019年初学者

初学者的8个最佳Arduino Starter Kits

受到推崇的

用于初学者和爱好者的最佳3D打印机 -  3D打印

最好的3D打印机为初学者和业余爱好者