== Making the direction of super directional speaker remotely adjustable == I made a base with servo motors for[https://international.switch-science.com/catalog/1842/ the super directional speaker] to make the speaker face different directions.[[BR]] Some of you may have seen it at our booth during the Maker Faire Tokyo 2014.[[BR]] We actually brought this speaker to the MFT2013, but it was not clear to the visitors how this speaker was super directional.[[BR]] 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]] [[Image(s-SDspeaker.jpg)]] Arduino Esplora is used as console.[[BR]] I used 3D printer to make the base to hold the speaker kit in place.[[BR]] [[Image(s-SD_speaker.jpg)]] [[Image(s-SD_speaker2.jpg)]] 3Dプリンタのフィラメント消費を抑えるために2枚に分けて出力して、それぞれをABSボンドで接着しました。[[BR]] [[Image(s-SD_speaker10.jpg)]] サーボモータと超音波スピーカーとアンプを板に取り付けます。 [[Image(s-SD_speaker3.jpg)]] [[Image(s-SD_speaker9.jpg)]] スピーカーの支えを作り、サーボホーンとフランジブッシュを取り付けます。[[BR]] 底面にはカグスベールをはって、サーボホーンを取り付けました。 [[Image(s-SD_speaker8.jpg)]] [[Image(s-SD_speaker4.jpg)]] [[Image(s-SD_speaker11.jpg)]] 土台にもサーボを取り付けます。[[BR]] 組み立てるとこのようになります。 [[Image(s-SD_speaker5.jpg)]] [[Image(s-s-SD_speaker7.jpg)]] 土台の中身です。[[BR]] 超音波スピーカーの電源電圧はDC12Vです。Arduino Pro Miniとサーボモータは5Vで動作させるので12Vから5Vを作るためのDCDCコンバータを搭載しています。[[BR]] [[Image(s-SDspeaker2_.jpg)]] 写真の上部にある2つのコネクタがDCジャックとステレオミニジャックです。DCジャックにはDC12Vを入力して、超音波スピーカーのアンプ基板とDCDCコンバータに電源を供給します。[[BR]] ステレオミニジャックはそのまま超音波スピーカーのアンプ基板の信号入力に接続されています。[[BR]] 写真の下部にあるステレオミニジャックはArduino Esploraとの通信用に使いました。[[BR]] == スケッチ == ArduinoEsploraからのコマンドをArduinoProMiniで受け取ってサーボモータを動かしています。[[BR]] Esploraのスライダの位置でジョイスティックで動かすモードと加速度センサで動かすモードを切り替えられるようにしました。[[BR]] === Arduino Pro Mini用 === {{{ #include 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 #include 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ファイル === [http://doc.switch-science.com/mft2014/SD_speaker1.stl SD_speaker1.stl] [http://doc.switch-science.com/mft2014/SD_speaker2.stl SD_speaker2.stl] [http://doc.switch-science.com/mft2014/SD_speaker3.stl SD_speaker3.stl] [http://doc.switch-science.com/mft2014/SD_speaker1.stl SD_speaker4.stl]