|
|
(未显示1个用户的2个中间版本) |
第32行: |
第32行: |
| 4、测试程序<br/> | | 4、测试程序<br/> |
| <pre style='color:blue'>#include <Wire.h> | | <pre style='color:blue'>#include <Wire.h> |
− | #include <HMC5883L.h>
| + | /* |
| + | Analog input 4 I2C SDA |
| + | Analog input 5 I2C SCL |
| + | */ |
| | | |
− | HMC5883L compass;
| + | #include <Wire.h> //I2C Arduino Library |
| | | |
− | void setup() | + | #define address 0x1E //0011110b, I2C 7bit address of HMC5883 |
− | { | + | |
| + | void setup(){ |
| + | //Initialize Serial and I2C communications |
| Serial.begin(9600); | | Serial.begin(9600); |
− | | + | Wire.begin(); |
− | // Initialize HMC5883L | + | |
− | Serial.println("Initialize HMC5883L");
| + | |
− | while (!compass.begin())
| + | |
− | {
| + | |
− | Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
| + | |
− | delay(500);
| + | |
− | }
| + | |
| | | |
− | // Set measurement range | + | //Put the HMC5883 IC into the correct operating mode |
− | // +/- 0.88 Ga: HMC5883L_RANGE_0_88GA | + | Wire.beginTransmission(address); //open communication with HMC5883 |
− | // +/- 1.30 Ga: HMC5883L_RANGE_1_3GA (default)
| + | Wire.write(0x02); //select mode register |
− | // +/- 1.90 Ga: HMC5883L_RANGE_1_9GA
| + | Wire.write(0x00); //continuous measurement mode |
− | // +/- 2.50 Ga: HMC5883L_RANGE_2_5GA | + | Wire.endTransmission(); |
− | // +/- 4.00 Ga: HMC5883L_RANGE_4GA
| + | |
− | // +/- 4.70 Ga: HMC5883L_RANGE_4_7GA
| + | |
− | // +/- 5.60 Ga: HMC5883L_RANGE_5_6GA
| + | |
− | // +/- 8.10 Ga: HMC5883L_RANGE_8_1GA
| + | |
− | compass.setRange(HMC5883L_RANGE_1_3GA);
| + | |
− | | + | |
− | // Set measurement mode
| + | |
− | // Idle mode: HMC5883L_IDLE | + | |
− | // Single-Measurement: HMC5883L_SINGLE
| + | |
− | // Continuous-Measurement: HMC5883L_CONTINOUS (default)
| + | |
− | compass.setMeasurementMode(HMC5883L_CONTINOUS);
| + | |
− |
| + | |
− | // Set data rate
| + | |
− | // 0.75Hz: HMC5883L_DATARATE_0_75HZ | + | |
− | // 1.50Hz: HMC5883L_DATARATE_1_5HZ
| + | |
− | // 3.00Hz: HMC5883L_DATARATE_3HZ
| + | |
− | // 7.50Hz: HMC5883L_DATARATE_7_50HZ
| + | |
− | // 15.00Hz: HMC5883L_DATARATE_15HZ (default)
| + | |
− | // 30.00Hz: HMC5883L_DATARATE_30HZ
| + | |
− | // 75.00Hz: HMC5883L_DATARATE_75HZ
| + | |
− | compass.setDataRate(HMC5883L_DATARATE_15HZ);
| + | |
− | | + | |
− | // Set number of samples averaged
| + | |
− | // 1 sample: HMC5883L_SAMPLES_1 (default)
| + | |
− | // 2 samples: HMC5883L_SAMPLES_2
| + | |
− | // 4 samples: HMC5883L_SAMPLES_4
| + | |
− | // 8 samples: HMC5883L_SAMPLES_8
| + | |
− | compass.setSamples(HMC5883L_SAMPLES_1);
| + | |
− | | + | |
− | // Check settings
| + | |
− | checkSettings();
| + | |
| } | | } |
| | | |
− | void checkSettings() | + | void loop(){ |
− | { | + | |
− | Serial.print("Selected range: ");
| + | |
| | | |
− | switch (compass.getRange()) | + | int x,y,z; //triple axis data |
− | {
| + | |
− | case HMC5883L_RANGE_0_88GA: Serial.println("0.88 Ga"); break;
| + | |
− | case HMC5883L_RANGE_1_3GA: Serial.println("1.3 Ga"); break;
| + | |
− | case HMC5883L_RANGE_1_9GA: Serial.println("1.9 Ga"); break;
| + | |
− | case HMC5883L_RANGE_2_5GA: Serial.println("2.5 Ga"); break;
| + | |
− | case HMC5883L_RANGE_4GA: Serial.println("4 Ga"); break;
| + | |
− | case HMC5883L_RANGE_4_7GA: Serial.println("4.7 Ga"); break;
| + | |
− | case HMC5883L_RANGE_5_6GA: Serial.println("5.6 Ga"); break;
| + | |
− | case HMC5883L_RANGE_8_1GA: Serial.println("8.1 Ga"); break;
| + | |
− | default: Serial.println("Bad range!");
| + | |
− | }
| + | |
− |
| + | |
− | Serial.print("Selected Measurement Mode: ");
| + | |
− | switch (compass.getMeasurementMode())
| + | |
− | {
| + | |
− | case HMC5883L_IDLE: Serial.println("Idle mode"); break;
| + | |
− | case HMC5883L_SINGLE: Serial.println("Single-Measurement"); break;
| + | |
− | case HMC5883L_CONTINOUS: Serial.println("Continuous-Measurement"); break;
| + | |
− | default: Serial.println("Bad mode!");
| + | |
− | }
| + | |
| | | |
− | Serial.print("Selected Data Rate: "); | + | //Tell the HMC5883 where to begin reading data |
− | switch (compass.getDataRate()) | + | Wire.beginTransmission(address); |
− | { | + | Wire.write(0x03); //select register 3, X MSB register |
− | case HMC5883L_DATARATE_0_75_HZ: Serial.println("0.75 Hz"); break;
| + | Wire.endTransmission(); |
− | case HMC5883L_DATARATE_1_5HZ: Serial.println("1.5 Hz"); break;
| + | |
− | case HMC5883L_DATARATE_3HZ: Serial.println("3 Hz"); break;
| + | |
− | case HMC5883L_DATARATE_7_5HZ: Serial.println("7.5 Hz"); break;
| + | |
− | case HMC5883L_DATARATE_15HZ: Serial.println("15 Hz"); break;
| + | |
− | case HMC5883L_DATARATE_30HZ: Serial.println("30 Hz"); break;
| + | |
− | case HMC5883L_DATARATE_75HZ: Serial.println("75 Hz"); break;
| + | |
− | default: Serial.println("Bad data rate!");
| + | |
− | }
| + | |
| | | |
− | Serial.print("Selected number of samples: ");
| |
− | switch (compass.getSamples())
| |
− | {
| |
− | case HMC5883L_SAMPLES_1: Serial.println("1"); break;
| |
− | case HMC5883L_SAMPLES_2: Serial.println("2"); break;
| |
− | case HMC5883L_SAMPLES_4: Serial.println("4"); break;
| |
− | case HMC5883L_SAMPLES_8: Serial.println("8"); break;
| |
− | default: Serial.println("Bad number of samples!");
| |
− | }
| |
− |
| |
− | }
| |
− |
| |
− | void loop()
| |
− | {
| |
− | Vector raw = compass.readRaw();
| |
− | Vector norm = compass.readNormalize();
| |
− |
| |
− | Serial.print(" Xraw = ");
| |
− | Serial.print(raw.XAxis);
| |
− | Serial.print(" Yraw = ");
| |
− | Serial.print(raw.YAxis);
| |
− | Serial.print(" Zraw = ");
| |
− | Serial.print(raw.ZAxis);
| |
− | Serial.print(" Xnorm = ");
| |
− | Serial.print(norm.XAxis);
| |
− | Serial.print(" Ynorm = ");
| |
− | Serial.print(norm.YAxis);
| |
− | Serial.print(" ZNorm = ");
| |
− | Serial.print(norm.ZAxis);
| |
− | Serial.println();
| |
− |
| |
− | delay(100);
| |
− | } </pre>
| |
− |
| |
− | 5、程序效果<br/>
| |
− | 在串口监控窗口中分别打印X、Y、Z轴输出值,如图所示:
| |
− | [[文件:02S11202.png|600px|缩略图|居中]]
| |
− |
| |
− | ==Processing指南针==
| |
− | 1、测试环境<br/>
| |
− | * 硬件环境:Arduino 、电子罗盘
| |
− | * 软件环境:Arduino IDE 1.7.7、Processing 3.0.2软件
| |
− |
| |
− | 2、硬件连接<br/>
| |
− | [[文件:02S11201.png|450px|缩略图|居中]]
| |
− |
| |
− | 3、例子程序<br/>
| |
− | * Processing 例程代码
| |
− | <pre style='color:blue'>/*
| |
− | HMC5883L Triple Axis Digital Compass.
| |
− | Processing for HMC5883L_processing.ino
| |
− | Processing for HMC5883L_processing_MPU6050.ino
| |
− | Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-magnetometr-hmc5883l.html
| |
− | GIT: https://github.com/jarzebski/Arduino-HMC5883L
| |
− | Web: http://www.jarzebski.pl
| |
− | (c) 2014 by Korneliusz Jarzebski
| |
− | */
| |
− |
| |
− | import processing.serial.*;
| |
− |
| |
− | Serial myPort;
| |
− |
| |
− | // Data samples
| |
− | int actualSample = 0;
| |
− | int maxSamples = 400;
| |
− | int sampleStep = 1;
| |
− | boolean hasData = false;
| |
− |
| |
− | // Charts
| |
− | PGraphics pgChart;
| |
− | int[] colors = { #ff4444, #33ff99, #5588ff };
| |
− | String[] magneticSeries = { "XAxis", "YAxis", "ZAxis" };
| |
− | String[] headingSeries = { "Normal", "Fixed", "Smooth" };
| |
− |
| |
− | // Data for compare
| |
− | float[][] magneticValues = new float[3][maxSamples];
| |
− | float[][] headingValues = new float[3][maxSamples];
| |
− |
| |
− | // Artificial Horizon
| |
− | PGraphics pgCompassPlate;
| |
− | PImage imgCompass;
| |
− | PImage imgCompassRing;
| |
− | PImage imgCompassPlateWhite;
| |
− | PImage imgCompassPlateBlack;
| |
− | int compassWidth;
| |
− | int compassHeight;
| |
− |
| |
− | void setup ()
| |
− | {
| |
− | size(755, 550, P2D);
| |
− | background(0);
| |
− |
| |
− | // Init
| |
− | initCompass();
| |
− |
| |
− | // Serial
| |
− | myPort = new Serial(this, Serial.list()[0], 9600);
| |
− | myPort.bufferUntil(10);
| |
− | }
| |
− |
| |
− | void drawChart(String title, String[] series, float[][] chart, int x, int y, int h, boolean symmetric, boolean fixed, int fixedMin, int fixedMax, int hlines)
| |
− | {
| |
− | int actualColor = 0;
| |
− |
| |
− | int maxA = 0;
| |
− | int maxB = 0;
| |
− | int maxAB = 0;
| |
− |
| |
− | int min = 0;
| |
− | int max = 0;
| |
− | int step = 0;
| |
− | int divide = 0;
| |
| | | |
− | if (fixed) | + | //Read data from each axis, 2 registers per axis |
− | {
| + | Wire.requestFrom(address, 6); |
− | min = fixedMin;
| + | if(6<=Wire.available()){ |
− | max = fixedMax;
| + | x = Wire.read()<<8; //X msb |
− | step = hlines;
| + | x |= Wire.read(); //X lsb |
− | } else | + | z = Wire.read()<<8; //Z msb |
− | {
| + | z |= Wire.read(); //Z lsb |
− | if (hlines > 2)
| + | y = Wire.read()<<8; //Y msb |
− | {
| + | y |= Wire.read(); //Y lsb |
− | divide = (hlines - 2);
| + | |
− | } else
| + | |
− | {
| + | |
− | divide = 1;
| + | |
− | } | + | |
− |
| + | |
− | if (symmetric)
| + | |
− | {
| + | |
− | maxA = (int)abs(getMin(chart));
| + | |
− | maxB = (int)abs(getMax(chart));
| + | |
− | maxAB = max(maxA, maxB);
| + | |
− | step = (maxAB * 2) / divide;
| + | |
− | min = -maxAB-step;
| + | |
− | max = maxAB+step;
| + | |
− | } else | + | |
− | {
| + | |
− | min = (int)(getMin(chart));
| + | |
− | max = (int)(getMax(chart));
| + | |
− |
| + | |
− | if ((max >= 0) && (min <= 0)) step = (abs(min) + abs(max)) / divide;
| + | |
− | if ((max < 0) && (min < 0)) step = abs(min - max) / divide;
| + | |
− | if ((max > 0) && (min > 0)) step = (max - min) / divide;
| + | |
− |
| + | |
− | if (divide > 1)
| + | |
− | {
| + | |
− | min -= step;
| + | |
− | max += step;
| + | |
− | }
| + | |
− | }
| + | |
| } | | } |
− |
| |
− | pgChart = createGraphics((maxSamples*sampleStep)+50, h+60);
| |
− |
| |
− | pgChart.beginDraw();
| |
− |
| |
− | // Draw chart area and title
| |
− | pgChart.background(0);
| |
− | pgChart.strokeWeight(1);
| |
− | pgChart.noFill();
| |
− | pgChart.stroke(50);
| |
− | pgChart.rect(0, 0, (maxSamples*sampleStep)+49, h+59);
| |
− | pgChart.text(title, ((maxSamples*sampleStep)/2)-(textWidth(title)/2)+40, 20);
| |
− |
| |
− | // Draw chart description
| |
− | String Description[] = new String[chart.length];
| |
− | int DescriptionWidth[] = new int[chart.length];
| |
− | int DesctiptionTotalWidth = 0;
| |
− | int DescriptionOffset = 0;
| |
− |
| |
− | for (int j = 0; j < chart.length; j++)
| |
− | {
| |
− | Description[j] = " "+series[j]+" = ";
| |
− | DescriptionWidth[j] += textWidth(Description[j]+"+0000.00");
| |
− | Description[j] += nf(chart[j][actualSample-1], 0, 2)+" ";
| |
− | DesctiptionTotalWidth += DescriptionWidth[j];
| |
− | }
| |
− |
| |
− | actualColor = 0;
| |
− |
| |
− | for (int j = 0; j < chart.length; j++)
| |
− | {
| |
− | pgChart.fill(colors[actualColor]);
| |
− | pgChart.text(Description[j], ((maxSamples*sampleStep)/2)-(DesctiptionTotalWidth/2)+DescriptionOffset+40, h+50);
| |
− | DescriptionOffset += DescriptionWidth[j];
| |
− | actualColor++;
| |
− | if (actualColor >= colors.length) actualColor = 0;
| |
− | }
| |
− |
| |
− | // Draw H-Lines
| |
− | pgChart.stroke(100);
| |
− |
| |
− | for (float t = min; t <= max; t=t+step)
| |
− | {
| |
− | float line = map(t, min, max, 0, h);
| |
− | pgChart.line(40, h-line+30, (maxSamples*sampleStep)+40, h-line+30);
| |
− | pgChart.fill(200, 200, 200);
| |
− | pgChart.textSize(12);
| |
− | pgChart.text(int(t), 5, h-line+34);
| |
− | }
| |
− |
| |
− | // Draw data series
| |
− | pgChart.strokeWeight(2);
| |
− |
| |
− | for (int i = 1; i < actualSample; i++)
| |
− | {
| |
− | actualColor = 0;
| |
− |
| |
− | for (int j = 0; j < chart.length; j++)
| |
− | {
| |
− | pgChart.stroke(colors[actualColor]);
| |
− |
| |
− | float d0 = chart[j][i-1];
| |
− | float d1 = chart[j][i];
| |
− |
| |
− | if (d0 < min) d0 = min;
| |
− | if (d0 > max) d0 = max;
| |
− | if (d1 < min) d1 = min;
| |
− | if (d1 > max) d1 = max;
| |
− |
| |
− | float v0 = map(d0, min, max, 0, h);
| |
− | float v1 = map(d1, min, max, 0, h);
| |
− |
| |
− | pgChart.line(((i-1)*sampleStep)+40, h-v0+30, (i*sampleStep)+40, h-v1+30);
| |
− |
| |
− | actualColor++;
| |
− |
| |
− | if (actualColor >= colors.length) actualColor = 0;
| |
− | }
| |
− | }
| |
− |
| |
− | pgChart.endDraw();
| |
− |
| |
− | image(pgChart, x, y);
| |
− | }
| |
− |
| |
− | void initCompass()
| |
− | {
| |
− | imgCompass = loadImage("compass.png");
| |
− | imgCompassRing = loadImage("compassRing.png");
| |
− | imgCompassPlateWhite = loadImage("compassPlateWhite.png");
| |
− | imgCompassPlateBlack = loadImage("compassPlateBlack.png");
| |
− | compassWidth = imgCompass.width;
| |
− | compassHeight = imgCompass.height;
| |
− | }
| |
− |
| |
− | void drawCompass(int x, int y, float[][] head, PImage plate)
| |
− | {
| |
− | pgCompassPlate = createGraphics(compassWidth, compassWidth);
| |
− |
| |
− | float heading = head[2][actualSample-1];
| |
− | float north = 180 + heading;
| |
| | | |
− | pgCompassPlate.beginDraw(); | + | //Print out values of each axis |
− | pgCompassPlate.clear(); | + | Serial.print("x: "); |
− | pgCompassPlate.translate(100,100);
| + | Serial.print(x); |
− | pgCompassPlate.rotate(-radians(heading));
| + | Serial.print(" y: "); |
− | pgCompassPlate.image(plate, -100, -100);
| + | Serial.print(y); |
− | pgCompassPlate.endDraw();
| + | Serial.print(" z: "); |
− | | + | Serial.println(z); |
− | image(pgCompassPlate, x+30, y+30);
| + | |
− | image(imgCompass, x, y);
| + | |
− | image(imgCompassRing, x, y);
| + | |
− | | + | |
− | textAlign(CENTER);
| + | |
− | text((int)heading+" deg", x+130, y+265);
| + | |
− | textAlign(LEFT);
| + | |
− | }
| + | |
− | | + | |
− | void draw()
| + | |
− | {
| + | |
− | if (!hasData) return;
| + | |
− | | + | |
− | background(0);
| + | |
− | | + | |
− | drawChart("Magnetic field [mG]", magneticSeries, magneticValues, 10, 10, 200, false, false, 0, 0, 10);
| + | |
− | drawChart("Heading [deg]", headingSeries, headingValues, 10, 280, 200, true, true, 0, 360, 30); | + | |
− | drawCompass(480, 5, headingValues, imgCompassPlateWhite);
| + | |
− | drawCompass(480, 275, headingValues, imgCompassPlateBlack);
| + | |
− | | + | |
− | }
| + | |
− | | + | |
− | float getMin(float[][] chart)
| + | |
− | {
| + | |
− | float minValue = 0;
| + | |
− | float[] testValues = new float[chart.length];
| + | |
− | float testMin = 0;
| + | |
− | | + | |
− | for (int i = 0; i < actualSample; i++)
| + | |
− | {
| + | |
− | for (int j = 0; j < testValues.length; j++)
| + | |
− | {
| + | |
− | testValues[j] = chart[j][i];
| + | |
− | }
| + | |
− |
| + | |
− | testMin = min(testValues);
| + | |
− |
| + | |
− | if (i == 0)
| + | |
− | {
| + | |
− | minValue = testMin;
| + | |
− | } else
| + | |
− | {
| + | |
− | if (minValue > testMin) minValue = testMin;
| + | |
− | }
| + | |
− | } | + | |
− |
| + | |
− | return ceil(minValue)-1;
| + | |
− | }
| + | |
− | | + | |
− | float getMax(float[][] chart)
| + | |
− | {
| + | |
− | float maxValue = 0;
| + | |
− | float[] testValues = new float[chart.length];
| + | |
− | float testMax = 0;
| + | |
− | | + | |
− | for (int i = 0; i < actualSample; i++)
| + | |
− | {
| + | |
− | for (int j = 0; j < testValues.length; j++)
| + | |
− | {
| + | |
− | testValues[j] = chart[j][i];
| + | |
− | }
| + | |
− |
| + | |
− | testMax = max(testValues);
| + | |
− | | + | |
− | if (i == 0)
| + | |
− | {
| + | |
− | maxValue = testMax;
| + | |
− | } else
| + | |
− | {
| + | |
− | if (maxValue < testMax) maxValue = testMax;
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | return ceil(maxValue);
| + | |
− | }
| + | |
− | | + | |
− | void nextSample(float[][] chart)
| + | |
− | {
| + | |
− | for (int j = 0; j < chart.length; j++)
| + | |
− | {
| + | |
− | float last = chart[j][maxSamples-1];
| + | |
− | | + | |
− | for (int i = 1; i < maxSamples; i++)
| + | |
− | {
| + | |
− | chart[j][i-1] = chart[j][i];
| + | |
− | }
| + | |
− | | + | |
− | chart[j][(maxSamples-1)] = last;
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | void serialEvent (Serial myPort)
| + | |
− | {
| + | |
− | String inString = myPort.readStringUntil(10);
| + | |
− | | + | |
− | if (inString != null)
| + | |
− | {
| + | |
− | inString = trim(inString);
| + | |
− | String[] list = split(inString, ':');
| + | |
− | String testString = trim(list[0]);
| + | |
− | | + | |
− | if (list.length != 6) return;
| + | |
− | | + | |
− | // Magnetic field
| + | |
− | magneticValues[0][actualSample] = (float(list[0]));
| + | |
− | magneticValues[1][actualSample] = (float(list[1]));
| + | |
− | magneticValues[2][actualSample] = (float(list[2]));
| + | |
− | | + | |
− | // Headings
| + | |
− | headingValues[0][actualSample] = (float(list[3]));
| + | |
− | headingValues[1][actualSample] = (float(list[4]));
| + | |
− | headingValues[2][actualSample] = (float(list[5]));
| + | |
− | | + | |
− | if (actualSample > 1)
| + | |
− | {
| + | |
− | hasData = true;
| + | |
− | }
| + | |
− | | + | |
− | if (actualSample == (maxSamples-1))
| + | |
− | {
| + | |
− | nextSample(magneticValues);
| + | |
− | nextSample(headingValues);
| + | |
− | } else
| + | |
− | {
| + | |
− | actualSample++;
| + | |
− | }
| + | |
− | } | + | |
− | }</pre>
| + | |
− | * Arduino 例程代码
| + | |
− | <pre style='color:blue'>/*
| + | |
− | HMC5883L Triple Axis Digital Compass. Output for HMC5883L_processing.pde
| + | |
− | Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-magnetometr-hmc5883l.html
| + | |
− | GIT: https://github.com/jarzebski/Arduino-HMC5883L
| + | |
− | Web: http://www.jarzebski.pl
| + | |
− | (c) 2014 by Korneliusz Jarzebski
| + | |
− | */
| + | |
− | | + | |
− | #include <Wire.h>
| + | |
− | #include <HMC5883L.h>
| + | |
− | | + | |
− | HMC5883L compass;
| + | |
− | | + | |
− | int previousDegree;
| + | |
− | | + | |
− | void setup()
| + | |
− | {
| + | |
− | Serial.begin(9600); | + | |
− | | + | |
− | // Initialize HMC5883L
| + | |
− | while (!compass.begin())
| + | |
− | {
| + | |
− | delay(500);
| + | |
− | }
| + | |
− | | + | |
− | // Set measurement range
| + | |
− | compass.setRange(HMC5883L_RANGE_1_3GA);
| + | |
− | | + | |
− | // Set measurement mode
| + | |
− | compass.setMeasurementMode(HMC5883L_CONTINOUS);
| + | |
− | | + | |
− | // Set data rate
| + | |
− | compass.setDataRate(HMC5883L_DATARATE_30HZ);
| + | |
− | | + | |
− | // Set number of samples averaged
| + | |
− | compass.setSamples(HMC5883L_SAMPLES_8);
| + | |
− | | + | |
− | // Set calibration offset. See HMC5883L_calibration.ino
| + | |
− | compass.setOffset(0, 0);
| + | |
− | }
| + | |
− | | + | |
− | void loop()
| + | |
− | {
| + | |
− | long x = micros();
| + | |
− | Vector norm = compass.readNormalize();
| + | |
− | | + | |
− | // Calculate heading
| + | |
− | float heading = atan2(norm.YAxis, norm.XAxis);
| + | |
− | | + | |
− | // Set declination angle on your location and fix heading
| + | |
− | // You can find your declination on: http://magnetic-declination.com/
| + | |
− | // (+) Positive or (-) for negative
| + | |
− | // For Bytom / Poland declination angle is 4'26E (positive)
| + | |
− | // Formula: (deg + (min / 60.0)) / (180 / M_PI);
| + | |
− | float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI); | + | |
− | heading += declinationAngle;
| + | |
− | | + | |
− | // Correct for heading < 0deg and heading > 360deg
| + | |
− | if (heading < 0)
| + | |
− | {
| + | |
− | heading += 2 * PI;
| + | |
− | }
| + | |
− |
| + | |
− | if (heading > 2 * PI)
| + | |
− | {
| + | |
− | heading -= 2 * PI;
| + | |
− | }
| + | |
− | | + | |
− | // Convert to degrees
| + | |
− | float headingDegrees = heading * 180/M_PI;
| + | |
− | | + | |
− | // Fix HMC5883L issue with angles
| + | |
− | float fixedHeadingDegrees;
| + | |
− |
| + | |
− | if (headingDegrees >= 1 && headingDegrees < 240)
| + | |
− | {
| + | |
− | fixedHeadingDegrees = map(headingDegrees, 0, 239, 0, 179);
| + | |
− | } else
| + | |
− | if (headingDegrees >= 240)
| + | |
− | {
| + | |
− | fixedHeadingDegrees = map(headingDegrees, 240, 360, 180, 360);
| + | |
− | }
| + | |
− | | + | |
− | // Smooth angles rotation for +/- 3deg
| + | |
− | int smoothHeadingDegrees = round(fixedHeadingDegrees);
| + | |
− | | + | |
− | if (smoothHeadingDegrees < (previousDegree + 3) && smoothHeadingDegrees > (previousDegree - 3))
| + | |
− | {
| + | |
− | smoothHeadingDegrees = previousDegree;
| + | |
− | }
| + | |
| | | |
− | previousDegree = smoothHeadingDegrees;
| + | delay(250); |
− | | + | |
− | // Output
| + | |
− | Serial.print(norm.XAxis);
| + | |
− | Serial.print(":");
| + | |
− | Serial.print(norm.YAxis);
| + | |
− | Serial.print(":");
| + | |
− | Serial.print(norm.ZAxis);
| + | |
− | Serial.print(":");
| + | |
− | Serial.print(headingDegrees);
| + | |
− | Serial.print(":");
| + | |
− | Serial.print(fixedHeadingDegrees);
| + | |
− | Serial.print(":");
| + | |
− | Serial.print(smoothHeadingDegrees);
| + | |
− | Serial.println();
| + | |
− | | + | |
− | // One loop: ~5ms @ 115200 serial.
| + | |
− | // We need delay ~28ms for allow data rate 30Hz (~33ms)
| + | |
− | delay(30); | + | |
| } | | } |
| </pre> | | </pre> |
| | | |
− | 4、程序效果<br/>
| + | 5、程序效果<br/> |
− | 将 Arduino 例程代码上传到 Arduino 控制器中,然后在 Processing 编译器中运行例程代码,会看到如下效果
| + | 在串口监控窗口中分别打印X、Y、Z轴输出值,如图所示: |
− | [[文件:hm588301.jpg|750px|缩略图|居中]] | + | [[文件:02S11202.png|600px|缩略图|居中]] |
| | | |
| ==产品相关推荐== | | ==产品相关推荐== |
| [[文件:erweima.png|230px|无框|右]] | | [[文件:erweima.png|230px|无框|右]] |
− | ===例子程序下载=== | + | === 产品资料 === |
− | * 库文件及例子程序下载链接:http://pan.baidu.com/s/1pLQ9dsZ 密码:gedq
| + | 下载链接:https://pan.baidu.com/s/1HsTWYCPT-zUK8L7_o7hpWQ |
| + | 提取码:540f |
| ===产品购买地址=== | | ===产品购买地址=== |
| * [http://www.alsrobot.cn/goods-772.html 电子罗盘传感器 HMC5883L模块] | | * [http://www.alsrobot.cn/goods-772.html 电子罗盘传感器 HMC5883L模块] |
电子罗盘,又称数字罗盘,在现代技术条件中电子罗盘作为导航仪器或姿态传感器已被广泛应用。此款传感器是三轴数字罗盘,采用I2C串行总线接口,芯片选用Honeywell HMC5883L,具有高精度,偏移抑制等特点。此传感器具有12位ADC、低噪声、自检测、低电压操作和宽磁场范围等特点,并且内置驱动电路,采用I2C数字接口,体积小,轻便,操作简单。