wiki:super-directional-speaker

Version 4 (modified by rumi, 4 years ago) (diff)

--

Making the direction of super directional speaker remotely adjustable

I made a base with servo motors forthe super directional speaker to make the speaker face different directions.
Some of you may have seen it at our booth during the Maker Faire Tokyo 2014.

We actually brought this speaker to the MFT2013, but it was not clear to the visitors how this speaker was super directional. Super directional ultrasonic speaker sends the sound only straight out, meaning you can hear the audio only if you are right in front of the speaker. To feel this effect clearly, I made the remote controlled base so that the speaker can face different directions.[[BR]

筐体は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ボンドで接着しました。

No image "s-SD_speaker10.jpg" attached to super-directional-speaker

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

No image "s-SD_speaker9.jpg" attached to super-directional-speaker

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

No image "s-SD_speaker8.jpg" attached to super-directional-speaker

No image "s-SD_speaker4.jpg" attached to super-directional-speaker No image "s-SD_speaker11.jpg" attached to super-directional-speaker

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

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

No image "s-SD_speaker5.jpg" attached to super-directional-speaker No image "s-s-SD_speaker7.jpg" attached to super-directional-speaker

土台の中身です。
超音波スピーカーの電源電圧はDC12Vです。Arduino Pro Miniとサーボモータは5Vで動作させるので12Vから5Vを作るためのDCDCコンバータを搭載しています。
No image "s-SDspeaker2_.jpg" attached to super-directional-speaker

写真の上部にある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

Attachments (12)

Download all attachments as: .zip