wiki:movable_sd_speaker

動く超音波スピーカーを作ってみました。

サーボモーターを使って動かせる超指向性超音波スピーカーキットの土台を作ってみました。

超音波スピーカーの展示を行ったところ、スピーカーを固定してしまうと設置角度によって音が聞こえる人と聞こえない人が出てしまいした。
それが超音波スピーカーの特性なので、聞こえる人と聞こえない人が出て当然なのですが、音が出ていることに気が付いてもらえないと話にならないので、
スピーカーの向きを変えられるようにしました。

筐体はSDプリンタで出力しました。使用したフィラメント素材はABSです。

使用した部品のリストです。(スイッチサイエンスで入手可能なものにはリンクがあります。)

  • 超指向性超音波スピーカーキット x 1セット
  • Arduino Esplora x 1個
  • Arduino Pro Mini 328 5V 16MHz x 1個
  • OKL-T/6-W12N-C使用 小型高効率DCDCコンバータ可変電源キット(降圧) x 1個
  • ユニバーサル基板(C基板) x 1枚
  • サーボモータ FUTABA S3003 x 2個
  • ステレオミニジャック(パネル取り付けタイプ) x 2個
  • ステレオミニプラグ(ケーブル付き) x 2本
  • DCジャック(2.1mm パネル用)
  • DCプラグ(2.1mm ケーブル付き) x 1本
  • 滑り止めゴムシート x 4枚
  • カグスベール x 1枚
  • フランジブッシュ(80F-1003) x 1個
  • プラネジ (M3x15) x 7本
  • プラナット M3 x 7個
  • 皿ネジ(M2x10) x 8本
  • ナベネジ(M2x8) x 4本
  • ナベネジ(M3x8) x 6本
  • 電源用ケーブル(赤黒) 数十センチ分
  • 通信用ケーブル(赤黒白) 数十センチ分
  • 3pin コネクタ x 2個
  • 3pin ピンヘッダ x 3個
  • スズメッキ線
  • ABSボンド

まず最初に超音波スピーカーをとめるための固定板を3Dプリンタで出力しました。

3Dプリンタのフィラメント消費を抑えるために2枚に分けて出力して、それぞれをABSボンドで接着しました。

サーボモータと超音波スピーカーとアンプを板に取り付けます。

スピーカーの支えを作り、サーボホーンとフランジブッシュを取り付けます。
底面にはカグスベールをはって、サーボホーンを取り付けました。

土台にもサーボを取り付けます。

組み立てるとこのようになります。

土台の中身です。
超音波スピーカーの電源電圧はDC12Vです。Arduino Pro Miniとサーボモータは5Vで動作させるので12Vから5Vを作るためのDCDCコンバータを搭載しています。

写真の上部にある2つのコネクタがDCジャックとステレオミニジャックです。DCジャックにはDC12Vを入力して、超音波スピーカーのアンプ基板とDCDCコンバータに電源を供給します。
ステレオミニジャックはそのまま超音波スピーカーのアンプ基板の信号入力に接続されています。
写真の下部にあるステレオミニジャックはArduino Esploraとの通信用に使いました。

スケッチ

ArduinoEsploraからのコマンドをArduinoProMiniで受け取ってサーボモータを動かしています。
Esploraのスライダの位置でジョイスティックで動かすモードと加速度センサで動かすモードを切り替えられるようにしました。

Arduino Pro Mini用

#include <Servo.h>
Servo myservo[2];
char rcvData = 0;
int servo_angle[2];
void setup()
{
    myservo[0].attach(3);
    myservo[1].attach(7); 
    Serial.begin(9600);
    myservo[0].write(90);
    myservo[1].write(90);
}

void loop()
{
    servo_angle[0] = 0;
    servo_angle[1] = 0;
    if(Serial.available() > 0){
        rcvData = Serial.read();
        if(rcvData == 'x'){
            while(!Serial.available()){}
            rcvData = Serial.read() - '0';
            servo_angle[0] = rcvData * 100;
            while(!Serial.available()){}
            rcvData = Serial.read() - '0';
            servo_angle[0] += rcvData * 10;
            while(!Serial.available()){}
            rcvData = Serial.read() - '0';
            servo_angle[0] += rcvData;
            
            if(servo_angle[0] >= 0 && servo_angle[0] <= 180){
                myservo[0].write(servo_angle[0]);
                Serial.print("SERVO X "); 
                Serial.print(servo_angle[0]);   
            }
        }
        else if(rcvData == 'y'){
            while(!Serial.available()){}
            rcvData = Serial.read() - '0';
            servo_angle[1] = rcvData * 100;
            while(!Serial.available()){}
            rcvData = Serial.read() - '0';
            servo_angle[1] += rcvData * 10;
            while(!Serial.available()){}
            rcvData = Serial.read() - '0';
            servo_angle[1] += rcvData;
            
            if(servo_angle[1] >= 0 && servo_angle[1] <= 180){
                myservo[1].write(servo_angle[1]);
                Serial.print("SERVO Y ");
                Serial.println(servo_angle[1]); 
            }
        }   
    }
}

Arduino Esplora用

#include <Esplora.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(11,3);

unsigned long x_angle = 90;
unsigned long y_angle = 90;
int x_stick = 90;
int y_stick = 90;
int x_trim = 20;
int y_trim = 0;
double x_temp = 0.0;
double y_temp = 0.0;
int x_stick2 = 90;
int y_stick2 = 90;
int x_demo = 90;
int y_demo = 90;
int add = 1;
int demo_speed = 100;
void setup()
{
    Serial.begin(9600);
    mySerial.begin(9600);
}

void loop()
{
    int i = 0;
    
    int x_axis = Esplora.readAccelerometer(X_AXIS);
    int y_axis = Esplora.readAccelerometer(Y_AXIS);
    int value = Esplora.readSlider();
    int x_joy = Esplora.readJoystickX();
    int y_joy = Esplora.readJoystickY();
    int uButton = Esplora.readButton(SWITCH_UP);
    int dButton = Esplora.readButton(SWITCH_DOWN);
    int rButton = Esplora.readButton(SWITCH_RIGHT);
    int lButton = Esplora.readButton(SWITCH_LEFT);

    if(value > 812){
    
        x_axis = map(x_axis, -180,180,0,180);
        y_axis = map(y_axis, -180,180,0,180);
    
        x_angle = (x_angle * 3 + x_axis) / 4;
        y_angle = (y_angle * 3 + y_axis) / 4;
                
   
        Serial.print("x");
        if(x_angle < 10){
            Serial.print("00");
            Serial.print(x_angle);
        }
        else if(x_angle < 100){
            Serial.print("0");
            Serial.print(x_angle);    
        }
        else{
            Serial.print(x_angle);    
        }
        Serial.print("y");
        if(y_angle < 10){
            Serial.print("00");
            Serial.println(y_angle);
        }
        else if(y_angle < 100){
            Serial.print("0");
            Serial.println(y_angle);    
        }
        else{
            Serial.println(y_angle);    
        }
   
        mySerial.print("x");
        if(x_angle < 10){
            mySerial.print("00");
            mySerial.print(x_angle);
        }
        else if(x_angle < 100){
            mySerial.print("0");
            mySerial.print(x_angle);    
        }
        else{
            mySerial.print(x_angle);    
        }
        mySerial.print(",");
    
    
        mySerial.print("y");
        
        if(y_angle < 10){
            mySerial.print("00");
            mySerial.println(y_angle);
        }
        else if(y_angle < 100){
            mySerial.print("0");
            mySerial.println(y_angle);    
        }
        else{
            mySerial.println(y_angle);    
        }
        mySerial.print(",");
        delay(20);
    }
    
    
    else if(value < 212){
        x_joy = map(x_joy,-512,511,180,0);
        y_joy = map(y_joy,-512,511,180,0);
        x_stick = (x_stick * 3 + x_joy)/4;
        y_stick = (y_stick * 3 + y_joy)/4;
        
        if(x_stick > 85 && x_stick < 95) x_stick = 90;
        if(y_stick > 85 && y_stick < 95) y_stick = 90;
        
        x_temp = x_temp + (x_stick - 90) / 50.0;
        y_temp = y_temp + (y_stick - 90) / 50.0;
        
        if((x_temp + 90) >= 180) x_temp = 90.0;
        else if((x_temp + 90) <= 0) x_temp = -90.0;
        if((y_temp + 90) >= 180) y_temp = 90.0;
        else if((y_temp + 90) <= 0) y_temp = -90.0;
        
        x_stick2 = x_temp + 90;
        y_stick2 = y_temp + 90;                
        
        mySerial.print("x");
        Serial.print("x");
        if(x_stick2 < 10){
            mySerial.print("00");
            mySerial.print(x_stick2);
            Serial.print("00");
            Serial.print(x_stick2);
        }
        else if(x_stick2 < 100){
            mySerial.print("0");
            mySerial.print(x_stick2);  
            Serial.print("0");
            Serial.print(x_stick2);  
        }
        else{
            mySerial.print(x_stick2);
            Serial.print(x_stick2);  
        }
        mySerial.print("y");
        Serial.print("y");
        if(y_stick2 < 10){
            mySerial.print("00");
            mySerial.println(y_stick2);
            Serial.print("00");
            Serial.println(y_stick2);
        }
        else if(y_stick2 < 100){
            mySerial.print("0");
            mySerial.println(y_stick2);
            Serial.print("0");
            Serial.println(y_stick2);
        }
        else{
            mySerial.println(y_stick2);
            Serial.println(y_stick2);
        }
        delay(20);        
        
    }
    
    else{
        if(x_demo >= 150) add = -1;
        else if(x_demo <= 50) add = 1;
        
        x_demo += add;
        delay(demo_speed);

        if(uButton == LOW){
            while(1){
                uButton = Esplora.readButton(SWITCH_UP);
                if(uButton == HIGH) break;
            }
            y_demo += 5;
            if(y_demo >= 180) y_demo = 180;    
        }
        if(dButton == LOW){
            while(1){
                dButton = Esplora.readButton(SWITCH_DOWN);
                if(dButton == HIGH) break;
            }
            y_demo -= 5;
            if(y_demo <= 0) y_demo = 0;    
        }
        if(rButton == LOW){
            while(1){
                rButton = Esplora.readButton(SWITCH_RIGHT);
                if(rButton == HIGH) break;
            }
            demo_speed += 10;
            if(demo_speed >= 200) demo_speed = 200; 
                
        }
        if(lButton == LOW){
            while(1){
                lButton = Esplora.readButton(SWITCH_LEFT);
                if(lButton == HIGH) break;
            }
            demo_speed -= 10;
            if(demo_speed <= 20) demo_speed = 20;
        }
        mySerial.print("x");
        Serial.print("x");
        if(x_demo < 10){
            mySerial.print("00");
            mySerial.print(x_demo);
            Serial.print("00");
            Serial.print(x_demo);
            
        }
        else if(x_demo < 100){
            mySerial.print("0");
            mySerial.print(x_demo);    
            Serial.print("0");
            Serial.print(x_demo);
        }
        else{
            mySerial.print(x_demo);
            Serial.print(x_demo);
        }
        mySerial.print("y");
        Serial.print("y");
        if(y_demo < 10){
            mySerial.print("00");
            mySerial.println(y_demo);
            Serial.print("00");
            Serial.println(y_demo);
        }
        else if(y_demo < 100){
            mySerial.print("0");
            mySerial.println(y_demo);
            Serial.print("0");
            Serial.println(y_demo);
        }
        else{
            mySerial.println(y_demo);
            Serial.println(y_demo);
        }
        delay(20);     
    }
}

STLファイル

SD_speaker1.stl SD_speaker2.stl SD_speaker3.stl SD_speaker4.stl

Last modified 2 years ago Last modified on May 14, 2015 2:59:33 PM

Attachments (16)

Download all attachments as: .zip