hollywis's diary (はりうすブログ)

はりうすの活動日記です

傾きを検出してみる | 中華で始める Arduino入門日記10

こんにちは、のすけです。

中華で始める Arduino入門日記の10回目になります。

この連載は、爆安の中華製のArduino互換機を入手し、色々と苦しみながらも安い互換機でArduinoを学習してしまおうというものです。 入手の話はこちらから。

hollywis.hatenablog.com

本題

前回はブザーを鳴らしました。

hollywis.hatenablog.com

今回は、Tilt switchを利用して傾きを検出してみたいと思います。

早速始めましょう。

Tilt switch(ティルトスイッチ)を知る

Tilt switch(ティルトスイッチ)またはTilt Sencer(傾斜センサー)とも言い、文字通り傾きを検出するための 電子デバイスです。

身近なところでは、スマホで縦に持つのと、横持つのを検出するのにも利用されているのでは ないでしょうか。

こいつです。

f:id:hollywis:20151208124342j:plain

なんかコンデンサみたいな形ですね。

でも、見分けるのは簡単! 振るとカチカチいうのがティルトスイッチです。

どうやって傾きを検出してるの?

ググりました。

どうやら御察しの通り、中に入っている金属のボールが関係しているようです。

内部に接点を4つほど用意して、どの接点と金属のボールが接しているかで場合分けをしているようです。 縦に持つと4つ全てに接するけど、横にすると1つまたは2つしか接しない、などなど。

金属ボールの他に、液体を利用するものなど、様々なティルトスイッチの方式がある感じでした。

繋いでみる

このティルトスイッチには極性はなさそうです。

回路図はこんな感じです。Fritzingというソフトを使って自作してみました。

f:id:hollywis:20151208135130p:plain

使い方は後日別記事で紹介したいと思います。直感的でとても便利でした。

ソフトはこちらからダウンロードできます。 Fritzing Download

ブレッドボードの配線図はこちら。

f:id:hollywis:20151208134837j:plain

デジタルpin8にLEDと220Ωの抵抗をつけます。

アナログpin5にティルトスイッチをつけます。

実際に刺したのはこちら

f:id:hollywis:20151208154705j:plain

プログラム

実はサンプルからかなり修正しています。 分かりにくかったのでピンの指定を外だしにしたり、thresholdの設定が 説明と矛盾していたので修正したりしています。

int apin = 5; //アナログpin5を利用
int ledpin = 8; //LED pin
int threshold = 512; //閾値

void setup()
{
    pinMode(ledpin,OUTPUT);//デジタル pin8を出力設定
}
void loop()
{
    int tilt_read;  //変数tilt_readを定義
    while(1)
    {
       tilt_read = analogRead(apin); //アナログpin5から電圧を読み取って変数に格納
       if(tilt_read > threshold) //512より上なら(2.5V)
       {
          digitalWrite(ledpin,HIGH);//led点灯
       }
       else //それ以外の場合
       {
          digitalWrite(ledpin,LOW);//led消灯
       }
    }
}

analogReadでアナログpin5から値を受け取り、一定値以上だったら LEDが光ります。

analogReadで取得できる値は0~1023なので512はちょうど真ん中あたりです。 (5VのPOWERに接続しているので2.5V相当ですね)

やってみる

横にしてみたり

f:id:hollywis:20151208160447j:plain

戻してみたり

f:id:hollywis:20151208160451j:plain

また倒してみたり。。。

f:id:hollywis:20151208160456j:plain

LED変わらないんですけどーーーーーーー。

デバッグだっ!

これは、アナログの入力値をチェックしてみないことには何もわかりませんね。

前回やったシリアル出力でデバックしてみます。

int apin = 5; //アナログpin5を利用
int ledpin = 8; //LED pin
int threshold = 512; //閾値

void setup()
{
    pinMode(ledpin,OUTPUT); //デジタル pin8を出力設定
    Serial.begin(9600);        // シリアル通信設定
}
void loop()
{
    int tilt_read;  //変数tilt_readを定義
    while(1)
    {
       tilt_read = analogRead(apin); //アナログpin5から電圧を読み取って変数に格納
       Serial.println(tilt_read);

       if(tilt_read > threshold) //512より上なら(2.5V)
       {
          digitalWrite(ledpin,HIGH);//led点灯
       }
       else //それ以外の場合
       {
          digitalWrite(ledpin,LOW);//led消灯
       }
    }
}

そして、実行後にシリアルモニタを開いてみると、、

はやっ

ものすごいスピードで、電圧が変わっていることがわかります。 しかも値が512超え、512以下を繰り返していました。

つまり、超高速で点滅しているため結局LEDがついているようにしか見えない!

ということのようです。

果てしない検証の結果

アナログピンを色々変えてみたり、ティルトスイッチを抜いてみたり、閾値を変えてみたり、delayを入れてみたりとしながら シリアルモニタと睨めっこしてデバックを繰り返しました。

その結果、私の環境での設定値はこれじゃね? というのが出ました。

  • thresholdは900

  • 最後にdelayを60ms入れる

最終プログラムはこちら

int apin = 5; //アナログpin5を利用
int ledpin = 8; //LED pin
int threshold = 900; //閾値

void setup()
{
    pinMode(ledpin,OUTPUT); //デジタル pin8を出力設定
    Serial.begin(9600);        // シリアル通信設定
}
void loop()
{
    int tilt_read;  //変数tilt_readを定義
    while(1)
    {
       tilt_read = analogRead(apin); //アナログpin5から電圧を読み取って変数に格納
       Serial.println(tilt_read);

       if(tilt_read > threshold) 
       {
          digitalWrite(ledpin,HIGH);//led点灯
       }
       else //それ以外の場合
       {
          digitalWrite(ledpin,LOW);//led消灯
       }
       delay(60);
    }
}

どうがんばっても、傾けた状態でも1023の電圧を記録してしまうため傾けたら点滅 、普通の状態なら安定して点灯くらいまでしか出来ませんでした。

パーツが悪いのか、私の配線が悪いのか、プログラムが悪いのか。。

どうせLEDが点くか消えるかの2値なんだから、わざわざアナログ値を1024段階取得する意味はあまりない気がしますが。

ふぅ、お疲れ様でした。

次回はチャプター9のPotentiometer(回転角による可変抵抗器)を使ってみたいと思います。