Column >【Arduino】テープLEDと加速度センサで遊んでみる
2016/10/7 【Arduino】テープLEDと加速度センサで遊んでみる

この前、テープLEDというものを手に入れたので、テープLEDと加速度センサ、Arduino Unoを使って
下のようなプログラムを作ってみました。



左手に持っているカプセルの中に加速度センサを入れておいて、
それを転がすことで光の位置が移動するようになっています。
また、普段は赤色の光を出していますがセンサがひっくり返ると
青い光を出すようにしてみました。

作り方を以下に書いていきます。






1. 使用したLEDテープとセンサ


今回使ったLEDテープは、
SSCI-013994というものです。

長さは1mで、5v電源、GND、DO/DIの3つを繋げば操作することができます。
Arduino用のライブラリもあるので、特に難しいことを考えなくても動かせました。



加速度センサは、MMA7361LCというものを使いました。

X,Y,Zの3軸を測ることが可能で、
計測する範囲は±1.5Gまでと±6Gまでの2種類のモードを使うことができます。

アナログ出力のセンサなので、電圧から重力加速度(G)への変換は
Arduino側のプログラムで行わないといけませんが、
やり方さえわかれば特に問題なくできると思います。

他には5vで動くテープLEDと違い、2.2v~3.6vまでの範囲でしか動作しないことと、
デフォルトではスリープモードになっているので、
それを解除しないと動作しないということに注意すれば大丈夫かなという感じです。



2. 回路の接続


次は、LEDテープ、加速度センサ、Arduino Unoの3つを繋げます。
LEDテープの端には元からはんだが乗っていたので、そこに導線を繋いでいきます。



加速度センサは、X軸、Y軸、Z軸、GND、電源の5つの線を繋げます。
コネクタを基板にはんだ付けして、そこにセンサを挿しました。

このセンサは他にも落下を検出するピンと
計測する値の範囲を切り替えるピンがありますが、
今回は傾けて使うので、重力加速度は大体±1G以内に収まるだろうということで
落下検出のピンと1.5G/6G切り替えのピンは使わないことにしました。

また、このセンサにはスリープピンというものがついていて、
このピンに入力がない場合はセンサが動作しないようになっているのですが、
この機能も特に使い道はないかなと思ったので、
はんだ付けの部分で電源と一まとめにしました。

センサは操作しやすいように、ガチャガチャなんかで使われているカプセルの中に入れました。
ちょうどいい感じで穴が開いていたので、そこに導線を通します。

中でセンサがずれるのを抑えるためにティッシュを詰めてあります。


LEDテープやセンサに繋いだ導線の先端部分にはArduinoに挿すためのオスピンを
つける必要がありますが、圧着工具を持ってないので
はんだでくっつけた後にセロテープを巻いて絶縁しました。

ちょっと無理やり感が漂ってる気がしないでもないですが、
一個人が趣味で作ってるものなので
動けばいいんだよ動けばぁ!という精神でやっていきます。


最後に導線をArduinoに挿していきます。
部品側とArduino側の対応は以下の通りです。

部品側Arduino側
LEDテープ5V5V
LEDテープDO/DI6番ピン
LEDテープGNDGND
加速度センサ電源3.3V
加速度センサX軸A0
加速度センサY軸A1
加速度センサZ軸A2
加速度センサGNDGND



そんな感じでハード部分は終了です!


3. ライブラリの導入


次はプログラムを組んでいきますが、その前にテープLEDのArduino用ライブラリを導入します。

まずはGitHubのページに入り、zipファイルをダウンロードします。
ダウンロードしたファイルのファイル名はAdafruit_NeoPixel.zipという名前に変更しておきます。



次にArduinoのIDEを開いて、スケッチ>Include Library>Add .ZIP Library と進んで
先程ダウンロードした.zipファイルを選択すればライブラリを入れることができます。



4. プログラム
4-1. センサ入力


ここからは実際にプログラムを書きます。

プログラムは大きく分けてセンサの入力部分と
LEDテープの出力部分の2つなのですが、
センサの入力部分のプログラムは下のような感じです。
int gravity[3] = { 0 }; // 0:x軸, 1:y軸, 2:z軸
const int analog_pin[3] = {A0, A1, A2};

void setup() {
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
}

void loop() {
  readSensor();
}

void readSensor(){
  for(int i = 0; i < 3; i++){
    gravity[i] = analogRead(analog_pin[i]);
    // LEDが60個なので0~59の範囲にする
    gravity[i] = map(gravity[i], 150, 525, 0, 59);
  }
}
アナログピンからの入力をgravityという配列に入れています。
analogRead()関数を使うと、0~5Vの電圧を0~1023の値に変換しますが、
加速度センサの電源電圧は3.3Vを使っているので、
加速度センサで1.5Gを検出した際は、3.3Vの電圧がかかって
1023×3.3÷5 ≒ 675となります。

そのため、この加速度センサをどう扱ってもanalogReadで読み取る値の範囲は
0 ~ 675くらいだと考えられますが、傾けて使うだけなら1Gを超えることは
ほとんどないだろうと思ったので、両端の値の範囲を狭めて
150 ~ 525という風にしてあります。

そして、使うLEDテープは60個あるので、150 ~ 525までの値を
0 ~ 59までの値に割り振ることによりセンサの傾きで
それぞれのLEDをえらべるようにします。


4-2. LEDテープ出力


次にLEDテープの出力を行う部分のプログラムを書きます。
先程ダウンロードしたライブラリに入っていたstrandtestの中身を
色々と使いまわして作りました。



#include < Adafruit_NeoPixel.h >
#ifdef __AVR__
  #include < avr/power.h >
#endif

#define PIN 6
#define NUMPIXELS 60

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  for(int i = 0; i < NUMPIXELS; i++){
    strip.setPixelColor(i, strip.Color(0, 0, 0));
  }
  for(int i = 0; i < 5; i++){
    if(gravity[2] > 30){
      strip.setPixelColor(gravity[0] + i - 2, Wheel((i*10) & 255));
    }else{
      strip.setPixelColor(gravity[0] + i - 2, Wheel(((i*10)+128) & 255));
    }
  }
  strip.show();
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color((255 - WheelPos * 3) / 3, 0, WheelPos);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos, (255 - WheelPos * 3) / 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos, (255 - WheelPos * 3) / 3, 0);
}
センサの入力で得たLEDの位置を中心として5個のLEDを光らせています。
strip.setPixelColor()関数に光らせたいLEDの位置と光の色を引数として与えていき
strip.show()を呼ぶことで実際にLEDが光ります。
Wheel()関数には、0~255の値を与えると赤~緑~青の色を返すようになっています。
値が255を超えてはいけないので、255とのAND演算を行うことで
値が確実に255以下になるようにしています。





追記


テープLEDの光をLeapmotionでも操作できるようにしてみました。
http://sssignal.web.fc2.com/column/column17.html
こちらも合わせてどうぞ!
    Please
    Share!
  • feedly
  • facebook
  • twitter
  • hatena bookmark
  • pocket
  • Google plus

inserted by FC2 system