Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Как сделать компас с помощью 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)

Здесь вы можете скачать файлы из проекта, изображения и исходные коды:


Производственный процесс

  1. Создание монитора Ambilight с помощью Arduino
  2. Ультразвуковой левитационный аппарат с использованием ARDUINO
  3. Универсальный пульт дистанционного управления с использованием Arduino, 1Sheeld и Android
  4. Вольтметр своими руками с использованием Arduino и смартфона
  5. Измерение частоты и рабочего цикла с использованием Arduino
  6. Как создать настраиваемую перфорированную кнопку клавиатуры
  7. Сонар с использованием Arduino и отображение при обработке IDE
  8. Счетчик автомобилей с использованием Arduino + Обработка + PHP
  9. Управление яркостью светодиода с помощью Bolt и Arduino
  10. Простая и умная роботизированная рука с использованием Arduino