|
|
第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/>
| |
? | 在串口監(jiān)控窗口中分別打印X、Y、Z軸輸出值,如圖所示:
| |
? | [[文件:02S11202.png|600px|縮略圖|居中]]
| |
? |
| |
? | ==Processing指南針==
| |
? | 1、測試環(huán)境<br/>
| |
? | * 硬件環(huán)境:Arduino 、電子羅盤
| |
? | * 軟件環(huán)境: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 編譯器中運(yùn)行例程代碼,會(huì)看到如下效果
| + | 在串口監(jiān)控窗口中分別打印X、Y、Z軸輸出值,如圖所示: |
? | [[文件:hm588301.jpg|750px|縮略圖|居中]] | + | [[文件:02S11202.png|600px|縮略圖|居中]] |
| | | |
| ==產(chǎn)品相關(guān)推薦== | | ==產(chǎn)品相關(guān)推薦== |
電子羅盤,又稱數(shù)字羅盤,在現(xiàn)代技術(shù)條件中電子羅盤作為導(dǎo)航儀器或姿態(tài)傳感器已被廣泛應(yīng)用。此款傳感器是三軸數(shù)字羅盤,采用I2C串行總線接口,芯片選用Honeywell HMC5883L,具有高精度,偏移抑制等特點(diǎn)。此傳感器具有12位ADC、低噪聲、自檢測、低電壓操作和寬磁場范圍等特點(diǎn),并且內(nèi)置驅(qū)動(dòng)電路,采用I2C數(shù)字接口,體積小,輕便,操作簡單。