{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "オリジナルの作成:2015/04/19\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 電子コンパス\n", "地磁気センサHM5883Lを使って電子コンパスに挑戦しました。\n", "\n", "ライブラリの作成はlbeDuinoの環境で行い、そのままArduino(3.3V版)でも動いています。\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### HM5883Lモジュール\n", "いろんなところからHM5883Lを使ったモジュールが販売されていますが、 今回はマルツパーツの3軸ディジタルコンパス用地磁気センサモジュールを使用しました。\n", "\n", "- http://www.marutsu.co.jp/pc/i/135436/\n", "\n", "このモジュールは、以下のようなピン配置になっており、トラ技2014/02の 【特集 最軽量!8ピンDIP ARMエントリ誕生】内で紹介されている実験基板 のI2Cソケットモジュールと同じ配置になっています。 *1\n", "\n", "- 4番ピン:GND\n", "- 5番ピン:SCL\n", "- 6番ピン:SDA\n", "- 8番ピン:VDD(3.3V)\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### I2Cソケットシールド\n", "I2Cソケットシールドを以下の様に作成しました。今回はプルアップ抵抗のジャンパーを省略しました。\n", "\n", "\n", "\n", "出来上がったI2Cソケットシールド\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## HM5883Lクラス\n", "鈴木哲哉さんの著書 作って遊べるArduino互換機 を参考に、以下のメソッドを実装しました。\n", "\n", "```C++\n", "class HMC5883L {\n", "public:\n", " HMC5883L(PinName sda, PinName scl);\n", " void setup();\n", " void setGain(int gain);\n", " void writeReg(int reg, int val); // レジスタに値を書き込む\n", " int readReg(int reg); // レジスタの値を取得\n", " void measure(); // 測定を実行\n", " float getAbs(); // 全磁力を返す\n", " float getHead(); // 北からの方位角を返す(単位 度)\n", " float x, y, z; // 測定地(単位 mGa)\n", "private:\n", " I2C i2c;\n", " float ax, ay, az; // 測定データを保持\n", "};\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### HM5883Lの座標\n", "HM5883Lモジュールのx, y, zの座標系は以下の通りです。\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 動作確認\n", "以下のようなサンプルプログラム(スケッチ)で動作を確認しました。\n", "\n", "```C++\n", "#include \"lbed.h\"\n", "#include \"AQCM0802.h\"\n", "#include \"HMC5883L.h\"\n", "\n", "// D13番ピンにLEDを接続\n", "DigitalOut led(D13);\n", "// D8番ピンSDA, D9番ピンSCL\n", "AQCM0802 lcd(D8, D9);\n", "HMC5883L sensor(D8, D9);\n", "\n", "// タクトスイッチ\n", "DigitalIn sw1(D2);\n", "DigitalIn sw2(D3);\n", "\n", "int showHead = 0;\n", "\n", "void setup() {\n", " sw1.mode(PullUp);\n", " sw2.mode(PullUp);\n", " lcd.setup();\n", " sensor.setup();\n", " sensor.setGain(1);\n", " lcd.print(\"HMC5883L setup\");\n", " wait_ms(1000);\n", "}\n", "\n", "void loop() {\n", " led = !led;\n", " lcd.cls();\n", " lcd.locate(0, 1);\n", " sensor.measure();\n", " if (!sw1) {\n", " showHead = !showHead;\n", " }\n", " if (showHead) {\n", " lcd.locate(0, 0);\n", " lcd.print(\"Head:\");\n", " lcd.print(sensor.getHead(), 1);\n", " lcd.locate(0, 1);\n", " lcd.print(\"Absolute:\");\n", " lcd.print(sensor.getAbs(), 1);\n", " }\n", " else {\n", " lcd.locate(0, 0);\n", " lcd.print(\"X:\");\n", " lcd.print(sensor.x, 1);\n", " lcd.locate(0, 1);\n", " lcd.print(\"Y:\");\n", " lcd.print(sensor.y, 1);\n", " }\n", " wait_ms(500);\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 出力について\n", "X, Yを出力すると、Yの値が1回転してもすべてマイナスの値になるなど、結果が不可解です。 しかし、Arduinoの例題を実行しても同じ傾向がみられました。(古いArduinoのファイルで修正が必要)\n", "\n", "- http://sfecdn.s3.amazonaws.com/datasheets/Sensors/Magneto/HMC5883.pde\n", "\n", "以下の様に変更しました。\n", "\n", "```C++\n", "/*\n", "An Arduino code example for interfacing with the HMC5883\n", "\n", "by: Jordan McConnell\n", " SparkFun Electronics\n", " created on: 6/30/11\n", " license: OSHW 1.0, http://freedomdefined.org/OSHW\n", "\n", "Analog input 4 I2C SDA\n", "Analog input 5 I2C SCL\n", "*/\n", "\n", "#include //I2C Arduino Library\n", "\n", "#define address 0x1E //0011110b, I2C 7bit address of HMC5883\n", "\n", "void setup(){\n", " //Initialize Serial and I2C communications\n", " Serial.begin(9600);\n", " while (!Serial) {\n", " ; // wait for serial port to connect. Needed for Leonardo only\n", " }\n", " Wire.begin();\n", " \n", " //Put the HMC5883 IC into the correct operating mode\n", " Wire.beginTransmission(address); //open communication with HMC5883\n", " Wire.write(0x02); //select mode register\n", " Wire.write(0x00); //continuous measurement mode\n", " Wire.endTransmission();\n", "}\n", "\n", "void loop(){\n", " \n", " int x,y,z; //triple axis data\n", "\n", " //Tell the HMC5883 where to begin reading data\n", " Wire.beginTransmission(address);\n", " Wire.write(0x03); //select register 3, X MSB register\n", " Wire.endTransmission();\n", " \n", " \n", " //Read data from each axis, 2 registers per axis\n", " Wire.requestFrom(address, 6);\n", " if(6<=Wire.available()){\n", " x = Wire.read()<<8; //X msb\n", " x |= Wire.read(); //X lsb\n", " z = Wire.read()<<8; //Z msb\n", " z |= Wire.read(); //Z lsb\n", " y = Wire.read()<<8; //Y msb\n", " y |= Wire.read(); //Y lsb\n", " }\n", " \n", " //Print out values of each axis\n", " Serial.print(\"x: \");\n", " Serial.print(x);\n", " Serial.print(\" y: \");\n", " Serial.print(y);\n", " Serial.print(\" z: \");\n", " Serial.println(z);\n", " \n", " delay(250);\n", "}\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.13" } }, "nbformat": 4, "nbformat_minor": 2 }