Как сделать компас с помощью Arduino и Processing IDE
<основной класс="главный сайт" id="главный">
В этом проекте Arduino мы увидим, как мы можем сделать этот классный компас, используя Arduino, магнитометр MEMS и Processing IDE. Вот демонстрационное видео компаса:
Обзор
Все, что нам нужно для этого проекта, это магнитометр MEMS для измерения магнитного поля земли, плата Arduino и несколько перемычек. В качестве примера я буду использовать HMC5883L, 3-осевой магнитометр, встроенный в коммутационную плату GY-80.
Как работает компас
Часть Arduino
Сначала нам нужно получить данные с датчика с помощью платы Arduino по протоколу I2C. Затем, используя значения оси X и оси Y датчика, мы рассчитаем курс и отправим его значение в Processing IDE через последовательный порт. Следующий код выполнит эту работу:
/* Arduino Compass
*
* by Dejan Nedelkovski,
* www.HowToMechatronics.com
*
*/
#include <Wire.h> //I2C Arduino Library
#define Magnetometer_mX0 0x03
#define Magnetometer_mX1 0x04
#define Magnetometer_mZ0 0x05
#define Magnetometer_mZ1 0x06
#define Magnetometer_mY0 0x07
#define Magnetometer_mY1 0x08
int mX0, mX1, mX_out;
int mY0, mY1, mY_out;
int mZ0, mZ1, mZ_out;
float heading, headingDegrees, headingFiltered, declination;
float Xm,Ym,Zm;
#define Magnetometer 0x1E //I2C 7bit address of HMC5883
void setup(){
//Initialize Serial and I2C communications
Serial.begin(115200);
Wire.begin();
delay(100);
Wire.beginTransmission(Magnetometer);
Wire.write(0x02); // 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);
}
Code language: Arduino (arduino)
Если вам нужна дополнительная информация о том, как работает магнитометр MEMS и как получить от него данные, вы можете обратиться к моему руководству по датчикам MEMS.
Часть обработки IDE
Здесь сначала нам нужно получить значения заголовков, поступающие из последовательного порта. Подробнее о том, как это делается, вы можете узнать в моем руководстве по Arduino и обработке.
Компас на самом деле представляет собой изображение, точнее, состоит из нескольких прозрачных изображений, загруженных в Processing IDE. Изображения располагаются в рабочей директории скетча. После определения объектов изображений в разделе draw() с помощью функции image() мы загружаем фоновое изображение (это необязательно, вы можете использовать простой цвет для фона). Затем загружается изображение компаса, которое с помощью функции rotateZ() поворачивается со значениями заголовка. Поверх них загружается изображение стрелки компаса.
Вот код обработки IDE:
/* Arduino Compass
*
* by Dejan Nedelkovski,
* www.HowToMechatronics.com
*
*/
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
PImage imgCompass;
PImage imgCompassArrow;
PImage background;
String data="";
float heading;
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
}
Code language: Arduino (arduino)
Здесь вы можете скачать файлы из проекта, изображения и исходные коды:
Производственный процесс
- Создание монитора Ambilight с помощью Arduino
- Ультразвуковой левитационный аппарат с использованием ARDUINO
- Универсальный пульт дистанционного управления с использованием Arduino, 1Sheeld и Android
- Вольтметр своими руками с использованием Arduino и смартфона
- Измерение частоты и рабочего цикла с использованием Arduino
- Как создать настраиваемую перфорированную кнопку клавиатуры
- Сонар с использованием Arduino и отображение при обработке IDE
- Счетчик автомобилей с использованием Arduino + Обработка + PHP
- Управление яркостью светодиода с помощью Bolt и Arduino
- Простая и умная роботизированная рука с использованием Arduino