NeoPixelリングでジャイロスコープを楽しむ
コンポーネントと消耗品
> |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
このプロジェクトについて
このチュートリアルでは、 MPU6050 を使用します ジャイロスコープ、 NeoPixel リングと Arduino 傾斜角に対応するLEDを点灯するデバイスを構築します。
これはシンプルで楽しいプロジェクトで、ブレッドボードに組み立てられます。手順に従うと、ビデオで見たものを作成できます。ジャイロスコープとNeoPixelリングについて学ぶための良いチュートリアルです。
minの他のチュートリアルで見た興味のために、このチュートリアルを作成しています。このチュートリアルでは、単純なLEDをNeoPixelリングに置き換えました。リングはAdafruitライブラリを介して使用する方が簡単で、間違いなくより壮観です。
したがって、これらのコンポーネントが周りにある場合、これはそれらを利用するための優れた方法です。デバイスの構築を段階的に説明し、最後のステップでどのように機能するかを説明します。
ステップ1:必要なもの <図>
パーツ
1. Arduino Pro Mini 328P
2.ブレッドボード
3.MPU6050ジャイロスコープ
4. 24 NeoPixelLEDリング
5.4つの電池を備えた4xAA電池パック
6. U字型ジャンパーケーブル(オプション)。これらのジャンパーケーブルを使用したのは、ブレッドボードで見栄えが良く、LEDがこのように見やすくなっているためです。あなたは約4ドルでebayで140の箱を見つけることができます。これらのケーブルがない場合は、デュポンワイヤーと交換できます。
ツール:
1. arduino prominiをプログラムするためのUSB-シリアルFTDIアダプターFT232RL
2. Arduino IDE
スキル:
1.はんだ付け
3.基本的なarduinoプログラミング
ステップ2:組み立て <図> <図>
接続を簡単に視覚化できるように、フリッツの回路図をfzz形式で添付しました。
1.写真に示すように、ネオピクセルリングの背面に3本のオスピンをはんだ付けする必要があります
-プラスピンをはんだ付けします
-地面をはんだ付けします
-データ入力ピンをはんだ付けします
2.次に、4xバッテリーホルダーにブレッドボードに接続する方法が必要です。簡単な解決策は、2本のオスのデュポンワイヤーをその端子にはんだ付けすることです。
3.ブレッドボードを準備します。
-画像のように、ネオピクセルリング、マイクロコントローラー、ジャイロスコープをブレッドボードに配置します
-すべてのマイナス線を配置します:マイクロコントローラー、ネオピクセルリング、ジャイロへ
-すべてのプラス線を配置します:マイクロコントローラー、ネオピクセルリング、ジャイロへ
-すべてのデータワイヤを配置します:
*からマイクロコントローラー、ジャイロへのSDAとSCL
*マイクロコントローラーからネオピクセルリングへのピンD6
-電源を入れる前に、すべての接続を再確認してください
-オプションでダクトテープを使用して、ブラッドボードの背面にバッテリーパックをテープで固定し、所定の位置に保持して携帯性を高めます
ステップ3:コードとキャリブレーション
最初 2つのライブラリをダウンロードしてインストールする必要があります:
1.ネオピクセルを制御するAdafruitネオピクセルライブラリモミ
2.ジャイロスコープ用のMPU6050ライブラリ
これらは、手間のかかる作業を行う2つの優れたライブラリです!
ネオピクセルの詳細はこちら
次に ここからライブラリをダウンロードしてインストールするか、以下からコピーしてください:
#include "I2Cdev.h" #include #include "MPU6050_6Axis_MotionApps20.h" #include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 const int MAX_ANGLE =45; const int LED_OFFSET =12; MPU6050 mpu; Adafruit_NeoPixelストリップ=Adafruit_NeoPixel(NUM_LEDS、NEOPIXED_CONTROL_PIN、NEO_RBG + NEO_KHZ800); unsigned long lastPrintTime =0; bool初期化=false; // DMPの初期化が成功した場合はtrueに設定しますuint8_tmpuIntStatus; // MPUからの実際の割り込みステータスバイトを保持しますuint8_tdevStatus; //各デバイス操作後にステータスを返します(0 =成功、!0 =エラー)uint16_t packetSize; //予想されるDMPパケットサイズ(デフォルトは42バイト)uint16_t fifoCount; //現在FIFOにあるすべてのバイトのカウントuint8_tfifoBuffer [64]; // FIFOストレージバッファQuaternionq; // [w、x、y、z]クォータニオンコンテナVectorFloat重力; // [x、y、z]重力ベクトルfloat ypr [3]; // [ヨー、ピッチ、ロール]ヨー/ピッチ/ロールコンテナと重力ベクトルvolatile bool mpuInterrupt =false; // MPU割り込みピンがハイになったかどうかを示します
voidsetup(){Serial.begin(9600); Serial.println( "プログラムが開始されました");初期化=initializeGyroscope(); strip.begin(); } void loop(){if(!initialization){return; } mpuInterrupt =false; mpuIntStatus =mpu.getIntStatus(); fifoCount =mpu.getFIFOCount(); if(hasFifoOverflown(mpuIntStatus、fifoCount)){mpu.resetFIFO();戻る; } if(mpuIntStatus&0x02){while(fifoCount 0){lightLeds(y、z、0、5、0、89); } else if(y <0およびz <0){lightLeds(y、z、6、12、89、0); } else if(y> 0およびz <0){lightLeds(y、z、13、19、0、89); } else if(y> 0およびz> 0){lightLeds(y、z、20、24、89、0); }} void lightLeds(int x、int y、int fromLedPosition、int toLedPosition、int fromAngle、int toAngle){double angle =(atan((double)abs(x)/(double)abs(y))* 4068)/ 71; int ledNr =map(angle、fromAngle、toAngle、fromLedPosition、toLedPosition); printDebug(x、y、ledNr、angle); uint32_t色; for(int i =0; i position + LED_OFFSET){return position + LED_OFFSET; }戻り位置+ LED_OFFSET-NUM_LEDS; } void printDebug(int y、int z、int lightLed、int angle){if(millis()-lastPrintTime <500){return; } Serial.print( "a ="); Serial.print(angle); Serial.print( ";"); Serial.print( "ll ="); Serial.print(lightLed); Serial.print( ";"); Serial.print( "y ="); Serial.print(y); Serial.print( ";"); Serial.print( "z ="); Serial.print(z); Serial.println( ";"); lastPrintTime =millis(); } bool initializeGyroscope(){Wire.begin(); TWBR =24; mpu.initialize(); Serial.println(mpu.testConnection()?F( "MPU6050接続に成功しました"):F( "MPU6050接続に失敗しました")); Serial.println(F( "Initializing DMP ...")); devStatus =mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if(devStatus!=0){Serial.print(F( "DMP初期化に失敗しました(コード")); Serial.println(devStatus); return false;} mpu.setDMPEnabled(true); Serial.println(F( "Enabling割り込み検出(Arduino外部割り込み0)... ")); attachInterrupt(0、dmpDataReady、RISING); mpuIntStatus =mpu.getIntStatus(); Serial.println(F(" DMP準備完了!最初の割り込みを待機中... " )); packetSize =mpu.dmpGetFIFOPacketSize(); return true;} void dmpDataReady(){mpuInterrupt =true;}
コードをアップロードする:
FTDIアダプターを使用して、コードをarduinoにアップロードします。
電源(バッテリー)を接続します
キャリブレーション:
ここで調整する最も重要なことは、「LED_OFFSET」定数です。私の例では12です。ボードに電力を供給した後、LEDがボードを傾ける方向に点灯するように、これを0から23に調整する必要があります。
どのように機能するかについて詳しく知りたい場合は、次のステップを確認してください
ステップ4:仕組み(オプション) <図>
最初 MPU6050ジャイロスコープについての少しの情報。これはMEMSジャイロスコープです(MEMSは微小電気機械システムの略です)。
各タイプのMEMジャイロスコープには、何らかの形の振動コンポーネントがあり、そこから加速、つまり方向の変化を検出できます。これは、運動量保存の法則に従って、振動する物体は同じ平面内で振動し続けることを好み、振動の偏差を使用して方向の変化を導き出すことができるためです。
ジャイロには、独自のマイクロコントローラーが含まれており、いくつかの凝った計算によってロール、ピッチ、ヨーを計算します。
しかし、ジャイロの生データはノイズとドリフトに悩まされているため、外部ライブラリを使用して物事をスムーズにし、クリーンで使用可能なデータを提供しました。
ネオピクセル 個別にアドレス指定可能で、バンドとリングにチェーンされたRGBLEDです。これらは5Vで動作し、独自の回路を備えているため、ネオピクセルに電力を供給し、データラインを使用して通信するだけで済みます。通信は、クロックとデータを含む単一のデータラインで行われます(詳細はこちら)。 Adafruitは、ネオピクセルリングと対話するためのクリーンなライブラリを提供します。
コード
l oop()の内部 関数MPU6050_6Axis_MotionApps20ライブラリが呼び出されます。ライブラリにジャイロスコープからの新しいデータがある場合、ライブラリは redrawLeds(x、y、z)を呼び出します。 ヨー、ピッチ、ロールを表す3つの引数
redrawLeds の内部 ():
-私たちは2つの軸に焦点を当てています:y、z
-両方の軸を-MAX_ANGLEから+ MAX_ANGLEに制限し、最大角度を45に定義し、変更可能です
-360度を4つの象限に分割し、それぞれに対して次のようにlightLeds()関数を呼び出します。
* yが負、zが正の第1象限は、LEDを0から5まで制御し、角度は0から89までになります
。* yが負、zが負の第2象限制御LEDは6から12で、角度は89から0になります
* ... etc
- lightLeds 内 関数
*アークタンジェントを使用して2軸に基づいて角度を計算しています(添付の画像を確認してください)
* arduinoマップ機能を使用して表示につながったものを計算しています
* 2つのLEDを除くすべてのLEDストリップをリセットします。1つは前に計算したLED位置に対応し、1つは前のLED位置に対応します(フェード効果を示すため)
* normalizeLedPosition()という関数を使用しています ネオピクセルキャリブレーションを考慮に入れます。ネオピクセルリングは自由に回転でき、ジャイロスコープと位置合わせする必要があるため、キャリブレーションは便利です。
*牽引軸も印刷しています。LEDには光と角度があります
数学
角度を決定するために使用されるLEDリングと三角関数を使用して写真を添付しました。
コード
arduinoコード
https://github.com/danionescu0/arduino/tree/master/projects/neopixel_ring_gyroscope 回路図
Sketch_gMlSrk3rCX.fzz 製造プロセス