工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ArduinoとProcessingで作るリアルタイムデジタルコンパス

このArduinoプロジェクトでは、Arduino、MEMS磁力計、Processing IDEを使ってクールなコンパスを作る方法を紹介します。コンパスのデモ動画はこちら:

概要

このプロジェクトに必要なのは、地球磁場を測定するMEMS磁力計、Arduinoボード、ジャンパーワイヤーだけです。例として、GY-80ブレークアウトボードに搭載されたHMC5883L(3軸磁力計)を使用します。

コンパスの仕組み

Arduino部分

まず、I2CプロトコルでArduinoボード経由でセンサーからデータを取得します。次に、センサーの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);
  // 位置に応じた偏角で方位を補正
  // 偏角はこちらで確認: https://www.ngdc.noaa.gov/geomag-web/
  // 私の場所では4.2度 => 0.073 rad
  declination = 0.073;
  heading += declination;
  // 符号が反転した場合の補正
  if(heading <0) heading += 2*PI;
  // 偏角加算による補正
  if(heading > 2*PI)heading -= 2*PI;
  headingDegrees = heading * 180/PI; // 方位角(度単位)
  // 出力角の平滑化 / ローパスフィルター
  headingFiltered = headingFiltered*0.85 + headingDegrees*0.15;
  // シリアルポート経由でProcessing IDEに方位値を送信
  Serial.println(headingFiltered);
  delay(50);
}

MEMS磁力計の仕組みやデータ取得方法について詳しく知りたい場合は、私のMEMSセンサーチュートリアルをご覧ください。

Processing IDE部分

ここではまず、シリアルポートから送られてくる方位値を受信します。詳細については、私のArduinoとProcessingチュートリアルをご覧ください。

コンパスは実際には画像、より正確にはProcessing IDEに読み込まれた複数の透過画像で構成されています。画像はスケッチの作業ディレクトリに配置する必要があります。draw()セクションで画像オブジェクトを定義した後、image()関数を使って背景画像(オプション、単色背景でも可)を読み込みます。次にコンパス画像を読み込み、rotateZ()関数で方位値に合わせて回転させます。その上にコンパスの矢印画像を読み込みます。

Processing 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); // シリアル通信開始
  myPort.bufferUntil('\n');
}
void draw() {
  image(background,0, 0); // 背景画像読み込み
  pushMatrix();
  translate(width/2, height/2, 0); // 座標系を画面中心に移動、中心で回転させるため
  rotateZ(radians(-heading)); // Z軸周りにコンパスを回転
  image(imgCompass, -960, -540); // コンパス画像読み込み、座標系が移動したため -960x, -540y(画面サイズの半分)に配置
  popMatrix(); // 座標系を元の位置 0,0,0 に戻す
  image(imgCompassArrow,0, 0); // コンパス矢印画像読み込み、popMatrix()のおかげでrotateZ()の影響を受けない
  textSize(30);
  text("Heading: " + heading,40,40); // 画面に方位値を表示
  delay(40);
}
// シリアルポートからデータ読み取り開始
void serialEvent (Serial myPort) {
  data = myPort.readStringUntil('\n');// シリアルポートからデータを読み取り、String変数 "data" に格納
  heading = float(data); // String値をFloat値に変換
}

プロジェクトファイル、画像、ソースコードはこちらからダウンロードできます:

製造プロセス

  1. Arduinoで作るモニター用Ambilightシステム:没入感アップの自作ガイド
  2. Arduinoで超音波レベーション(浮遊)装置を自作:ステップバイステップガイド
  3. Arduinoと1Sheeldで作る万能Androidリモコン──IR制御で家電を一括操作
  4. Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
  5. Arduino UNOで周波数とデューティサイクルを高精度測定
  6. Arduinoで作るパンチングキーボードボタン:ストレス解消カスタムキー
  7. Arduino超音波センサーとProcessingで作るリアルタイム距離測定ソナー
  8. スマート駐車場カウンター:Arduino、Processing、PHPでリアルタイム車両管理
  9. Bolt IoTとArduino UNOでLED輝度をシームレス制御
  10. スマートなArduino制御ロボットアームの製作:簡単DIYチュートリアル
  11. PHPベースのWebインターフェースでArduino Unoを制御する構築ガイド