123d CircuitsとArduino実機で電子工作(5)

2017年3月23日(木)
青柳 良介福田 紘也

はじめに

今回は、これまでに解説した内容を駆使して、誕生日等の記念日に使えるプレゼントボックス(図1、図2)の電子工作を紹介します。今回のポイントは、主に以下の3点です。

  • 電子工作で生活をより楽しく
  • 光と音と動を組み合わせることで様々なことが実現できる
  • 誕生日やクリスマス、お正月などシーンに合わせて使い分けることができる

ぜひ、大切な人のお祝いをするときのサプライズとして利用してみてください!

用意するもの

  • Maruduino UNO R3(図3)
    今回はマルツエレック社が提供するArduino互換ボードで、Arduino UNOと同等の性能を搭載しながら安価で提供されている「Maruduino」を使用します。
  • ブレッドボード
  • マイクロサーボ SG92R(図4)
  • 焦電型赤外線センサー PSUP7C-02-NCL-16-1 フラット・薄型(図5)
  • 圧電ブザー(図6)
    圧電ブザーは圧電振動板を金属板に張り付けて作られています。ここに電圧が印加されると振動が生じることで音が発生する仕組みを応用しています。周波数が高くなると音程も高くなります。
  • LED(赤色・青色・黄色)
  • DCプラグ付バッテリースナップ(縦型)
  • アルカリ乾電池 9V形
  • ジャンパーワイヤ オス-オス
  • 2ピンジャンパーワイヤ オス-メス
  • 回路図をシミュレーションしてみよう

    これまでと同様に手戻りを少なくするため、まずは123d Circuitsでシミュレーションしてみましょう。実体配線図と使用するパーツは下図の通りです(図7、図8)。基本的には、これまでに解説した内容を駆使すれば設計できるので、分からない部分があれば、これまでの連載を読み返してみてください。

    配線が終了したら、画面上部の「Code Editor」をクリックして、以下のスケッチを記述します。

    #include 
    
    Servo myservo;  // create servo object to control a servo
    // twelve servo objects can be created on most boards
    
    #define SNS1 2
    #define BZ1 3
    #define LED1 4
    #define LED2 5
    #define LED3 6
    #define LED4 7
    #define LED5 8
    
    #define SV1 9
    
    int servo_pos = 0;
    
    boolean phase = false;
    long current_time = 0;
    long interval_time = 200;
    int led_position = 0;
    
    int nlength = 28; // the number of notes
    char notes[] = "GGAGcB GGAGdc GGxecBA yyecdc";
    
    int beats[] = { 2, 2, 8, 8, 8, 16, 1, 2, 2, 8, 8, 8, 16, 1, 2, 2, 8, 8, 8, 8, 16, 1, 2, 2, 8, 8, 8, 16 };
    int tempo = 150;
    // sub
    void playTone(int ntone, int duration) {
      for (long i = 0; i < duration * 1000L; i += ntone * 2) {
    
        digitalWrite(BZ1, HIGH);
        delayMicroseconds(ntone);
        digitalWrite(BZ1, LOW);
        delayMicroseconds(ntone);
      }
    }
    //
    void playNote(char note, int duration) {
      char names[] = {'C', 'D', 'E', 'F', 'G', 'A', 'B',
                      'c', 'd', 'e', 'f', 'g', 'a', 'b',
                      'x', 'y'
                     };
    
      int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014,
                      956,  834,  765,  593,  468,  346,  224,
                      655 , 715
                    };
    
      int SPEE = 5;
    
      // play the tone corresponding to the note name
    
      for (int i = 0; i < 17; i++) {
        if (names[i] == note) {
          int newduration = duration / SPEE;
          playTone(tones[i], newduration);
        }
      }
    }
    // sub
    void merody() {
      for (int i = 0; i < nlength; i++) {
        if (notes[i] == ' ') {
          delay(beats[i] * tempo); // rest
        } else {
          playNote(notes[i], beats[i] * tempo);
        }
        // pause between notes
        delay(tempo);
      }
    }
    //
    void detect() {
      phase = true;
    }
    // sub
    void led_control() {
      if (millis() >= (current_time + interval_time) ) {
        current_time = millis();
        led_position ++ ;
        switch (led_position) {
          case 1 : digitalWrite(LED1, HIGH);
            break;
          case 2 : digitalWrite(LED2, HIGH);
            break;
          case 3 : digitalWrite(LED3, HIGH);
            break;
          case 4 : digitalWrite(LED4, HIGH);
            break;
          case 5 : digitalWrite(LED5, HIGH);
            break;
          default: digitalWrite(LED1, LOW);
            digitalWrite(LED2, LOW);
            digitalWrite(LED3, LOW);
            digitalWrite(LED4, LOW);
            digitalWrite(LED5, LOW);
            led_position = 0;
            phase = false;
            break;
        }
      }
    }
    //sub
    void open_lid() {
      for (servo_pos = 0; servo_pos <= 90; servo_pos += 1) { // goes from 0 degrees to 180 degrees
        // in steps of 1 degree
        myservo.write(servo_pos);              // tell servo to go to position in variable 'pos'
        delay(50);
      }
      delay(500);
    
    }
    
    void close_lid() {
      // waits 15ms for the servo to reach the position
      for (servo_pos = 90; servo_pos >= 0; servo_pos -= 1) { // goes from 180 degrees to 0 degrees
        myservo.write(servo_pos);              // tell servo to go to position in variable 'pos'
        delay(50);                       // waits 15ms for the servo to reach the position
      }
      delay(500);
    }
    
    // start main
    void setup() {
      pinMode(BZ1, OUTPUT);
      pinMode(SNS1, INPUT_PULLUP);
      pinMode(BZ1, OUTPUT);
      pinMode(LED1, OUTPUT);
      pinMode(LED2, OUTPUT);
      pinMode(LED3, OUTPUT);
      pinMode(LED4, OUTPUT);
      pinMode(LED5, OUTPUT);
      pinMode(LED_BUILTIN, OUTPUT);
    
      myservo.attach(SV1);
      myservo.write(0);
      attachInterrupt(digitalPinToInterrupt(SNS1), detect, FALLING);
    }
    
    void loop() {
      //open_lid();
      if (phase == true) {
        open_lid();
        while (phase == true) {
          led_control();
          merody();
        }
        close_lid();
      }
      //close_lid();
      delay(5000);
    }

    ここで「#define」について少し解説します。「#define 定数名 値」は、プログラム中の定数に対して名前を付けるための構文です。例えば、「#define SNS1 2」の場合はコンパイル時に「SNS1」と記述されている部分がすべて「2」という値に置き換えられます。これにより頻発する定数名をまとめて変更できるので、タイプミスも防ぐことができます。

    このスケッチでは、以下の流れでプログラムが動きます。

    ①焦電センサーで物体を感知するとスイッチが入る
    ②マイクロサーボが作動する(箱を開く)
    ③LEDが光る
    ④LED点灯している間は圧電ブザーから曲が流れる
    ⑤曲が終わると2つ目のLEDも点灯し再度曲が流れる
    ⑥ ③~⑤を5回繰り返す
    ⑦LEDが消える
    ⑧マイクロサーボが作動する(箱を閉じる)

    実機で試してみよう

    いかがですか。うまくシミュレーションできたでしょうか。それでは、今度はMaruduinoの実機で動作させてみましょう。

    プレゼントボックスを作るために、以下の材料の準備も進めます。

    • 箱(100円ショップ等で入手)
    • スチレンボード(100円ショップ等で入手)
    • 文字シール(100円ショップ等で入手)

    今回は、焦電センサーが人を感知すると自動で箱のフタを開閉するようにしたいので、フタ付きの箱を使っています。箱の底にMaruduinoとブレッドボードを置き、箱のフタ付近にマイクロサーボを取り付けて、LEDをスチレンボード上に配線します(図9)。今回は誕生日を祝うシーンを想定しているため、お祝いする人の名前を文字シールでボード上に貼り、名前の文字の上にもLEDを配置しています。

    準備ができたら、プレゼントボックスを動作させてみましょう(図10)。

    なお、実際の動作を確認するための動画を用意しましたので、こちらも参考にしてください。また、実機をお持ちでない方は、動画を見てイメージしていただければと思います。

    今回は比較的シンプルな構造にしましたが、工夫次第でもっといろいろな機能が考えられると思います。ぜひ皆さん自身でも取り組んでみてください。

    おわりに

    今回は、これまでに解説した電子工作を組み合わせてプレゼントボックスを作りました。ここでは誕生日を想定しましたが、光や曲を変えればクリスマスやお正月などシーンに合わせてカスタマイズできます。ぜひ、大切な人をお祝いするときのサプライズなどに利用してみてください!

    次回からは、日本製の登場で再び注目を集めているRaspberry Piを使用した電子工作を解説していきます。お楽しみに!

    本連載の電子工作キットを販売しています!

    本連載で紹介した電子工作をスグに試せる電子工作キットを販売しています。
    記事内の画像や説明だけではもの足りない、という方は、本キットを通してお手元で確認してみてはいかがでしょうか。きっと、電子工作の楽しさをもっと実感できるはずです!

    電子工作キットは、下記のWebサイトから購入できます!

    商品サイトはこちら→→https://blooomin.stores.jp/

    Blooomin代表。半導体ベンチャーや米系通信機器メーカーを経て、組み込みシステムのコンサルディングからフィジカル・コンピューティングのコンテンツ開発などに従事。ハードやソフトにおける設計から保守までの勘所を横断的に網羅しております。
    Blooomin:https://blooomin.com
    S&F PARTNERS副社長。素材メーカーを経てコンサルティング会社で事業開発に従事。その後、ベンチャーにてIoTサービスの企画・運営。現在はロボットプログラミング教室の運営やIoTサービスの企画・開発を展開。S&F PARTNERS:http://www.sf-partners.jp/

    連載バックナンバー

    Think ITメルマガ会員登録受付中

    Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

    Think ITメルマガ会員のサービス内容を見る

    他にもこの記事が読まれています