ここでのアイデアは、Air Guitarを弾くのと同じように、両手で操作できるウェアラブルバーチャルギターを作ることです。それは2週間のプロジェクトの間に作成されプロトタイプ化されました。
目的は本物のギターを弾く感覚を得ることです。 AIRduinoのギターは1手袋と1本の棒で作られています。手袋は、音を鳴らすためのトーンとスティックを設定するために使用されます。
このようなトリックを実行するために、加速度計と超音波センサーを使用しました(概念の説明については手順1を参照)。
それがどのように機能するかについてのより正確なアイデアを得るためにビデオデモを見て、そしてあなた自身のものを作るために機能するようになってください!
AIRduinoチーム:
David Fournier、Jean-Louis Giordano、Monireh Sanaei、Maziar Shelbaf、そしてGustav Sohtell。
用品:
ステップ1:概念の説明
Air Guitarは右利き用のギターとして機能するはずです。
ギターコントローラーは2つの部分、左側のコントローラーと右側のコントローラーに分けられます。
プレイヤーは左手のコントローラーで指を曲げてグローブを押すと音の高さを変えることができます。
右側のコントローラーはスティックで表現されており、エアーギターのサウンドをトリガーするためにはこれを振る必要があります。
ギターの首の異なるフレットをシミュレートして、プレイヤーはトーンをピッチするために右手と左手の間の距離を変えることもできます。
そのようなトリックを実行するために、主なコンポーネントは、スティックの揺れを「感じる」ための加速度計、右手とスティックの間の距離を測定するためのハッキングされた超音波センサー、そして手袋を作るための導電性布です。
結局のところ、それはおもちゃを作るのはかなり簡単です。唯一のトリッキーな部分は、いくらかの器用さを必要とする超音波センサーハックでしょう。指示を理解するため、そしてあなたが何かをめちゃくちゃにしてギターが最終的にはうまくいかないときにあなたが間違ったことを見つけるためにもいくつかの基本的な電子技術が必要になります。私たちはそこにいました。 :-)
ステップ2:買い物リスト
これはあなたがあなた自身のAIRduinoギターを作るのに必要なもののリストです:
1.ワイヤー:残念ながらこのプロトタイプバージョンにはたくさんあります。それらは2つの手袋とArduinoの部品をつなぐのに使われてきました。それを無線にすることによってデザインのこの部分を改善すること自由に感じなさい!
2.加速度計:揺れを検出するために右手の棒で使用されます。 3軸加速度計を使用しましたが、1軸で十分です
3.超音波センサー:プレーヤーの両手の間の距離を測定するのに使用され、私達はParallax#28015を使用しました
4.導電性とストレッチ素材:手袋を組み立てる、
5. Arduino:すべてを扱うギターの核心Arduino Diecimilaはうまくいきます。
6.ポテンショメータ:いくつかの設定を調整するために、1Kオームから1Mオームまでの最大の何かを持つポテンショメータはOKです。
ホットメルト接着剤:物事をまとめるための便利な方法、
8. 3.5 mmメスジャック:オーディオ出力に使用されます。
9.古典的な電子製品:抵抗器(10k)、コンデンサ(10uF)、LED、およびarduino用のある種の電源。 (9V電池はちょうどいいです)。
ステップ3:回路図
これがAIRduinoギターの電子回路図です。
お分かりのように、理解するのはとても簡単で、それゆえ構築するのも簡単です。
どのコンポーネントがどこに使用されるのかを知りたい場合は、画像を見てください。あなたがおそらく理解するように、これは決して拡大縮小することではありません。ケーブルは回路図に示されているよりもはるかに長いです。
また、超音波センサーのエミッタがスティックにあり、レシーバーが左側にあることに気付いたかもしれません。それは私が先に述べたトリッキーな部分です:あなたはそれをセンサーボードから分離するために超音波センサーユニットから超音波エミッターをはずさなければなりません。
これについては後の手順で詳しく説明します。それでは仕事に行きましょう!
ステップ4:手袋を作る
この手袋には、1つの超音波受信機と4つのボタンがあります。それでおしまい!
超音波受信機は下の写真のいくつかで見えるブラックボックスにあります。
手袋はちょうどArduinoのボード上の地面に接続されている1つの大きな領域を持っています。指が手のひらに押し付けられると、指の上の導電性布地と手のひらとの間に接続が形成される。
以下は2つの異なる手袋モデルの写真です。 1つは取り外し可能な指を持っています、そしてそれは非常に小さいと非常に大きい手で両方のプレーヤーを可能にします。もう一方のモデルは標準手袋に直接縫い付けられています。私は2番目のバージョンをお勧めします、それは構築するのがより簡単で、そして置くのがより簡単です。
ステップ5:コード
必要なArduinoのコードは次のとおりです。
リアルタイムサウンド生成の部分はこの素晴らしいチュートリアルから取られています。
------------------------------------------------------
//波形を含む配列
//ギターの音
char波形 =
{125, 148, 171, 194, 209, 230, 252, 255,
253, 244, 235, 223, 207, 184, 169, 167,
163, 158, 146, 131, 126, 129, 134, 127,
105, 80, 58, 51,38, 22, 12, 2, 10, 35,
58, 75, 89, 103, 120, 141, 150, 148, 145,
144, 140, 129, 116, 105, 95, 86, 75, 72,
73, 76, 88, 103, 117, 121, 120, 115, 120,
143, 159, 162, 156, 155, 163, 184, 202,
214, 215, 211, 213, 212, 205, 196, 182,
162, 142, 118, 99, 84, 68, 54, 40, 28,
19, 10, 7, 0, 0, 5, 9, 14, 21, 33,
49, 59, 65, 75, 92, 110};
//この波形を使って
//出力の音量
char waveformVolume =
{125, 148, 171, 194, 209, 230, 252, 255,
253, 244, 235, 223, 207, 184, 169, 167,
163, 158, 146, 131, 126, 129, 134, 127,
105, 80, 58, 51,38, 22, 12, 2, 10, 35,
58, 75, 89, 103, 120, 141, 150, 148, 145,
144, 140, 129, 116, 105, 95, 86, 75, 72,
73, 76, 88, 103, 117, 121, 120, 115, 120,
143, 159, 162, 156, 155, 163, 184, 202,
214, 215, 211, 213, 212, 205, 196, 182,
162, 142, 118, 99, 84, 68, 54, 40, 28,
19, 10, 7, 0, 0, 5, 9, 14, 21, 33,
49, 59, 65, 75, 92, 110};
//避けるためにバッファとして使用される配列
//誤った正確な距離
//測定
unsigned int distance_buffer = {16000、
16000, 16000, 16000, 16000, 16000, 16000,
16000, 16000, 16000, 16000, 16000, 16000,
16000, 16000, 16000};
const int distance_length = 3;
int distance_index = 0;
// 2オクターブのオーバーフロー値
int frequency = {39、42、44、47、
50, 52, 56, 59, 63, 66, 70, 74, 79,
84, 89, 94, 100, 105, 112, 118, 126,
133, 141, 149};
//初期ピッチ
int pitch = 160;
//初期音量と加速度
//パラメータ
int lastAcc = 0。
フロートボリューム= 0。
//ピン3のオーディオ再生
バイトスピーカーピン= 3。
//位置のインデックス変数
//波形
揮発性バイトwaveindex = 0
揮発性バイト現在値= 0。
//超音波センサーに使用されるピン
const int pingPin = 7;
//ポテンショメータ用のピン
const int sustainPin = 1;
const int sensitivityPin = 2;
//左の各指のピン
//手
const int finger1 = 9。
const int finger2 = 10。
const int finger3 = 11。
const int finger4 = 12;
int fingerValue = 0。
長さ、インチ、cm。
void setup(){
pinMode(3、OUTPUT); //ピン3のスピーカー
pinMode(finger1、INPUT);
pinMode(finger2、INPUT);
pinMode(finger3、入力)。
pinMode(finger4、入力)。
/**************************
PWMオーディオ設定
****************************/
// Timer2を高速PWMモードに設定します
//(PWM周波数を2倍にする)
bitSet(TCCR2A、WGM21)。
bitSet(TCCR2B、CS20)。
bitClear(TCCR2B、CS21)。
bitClear(TCCR2B、CS22)。
//そのレジスタに割り込みを有効にする
//設定されています
sei();
/*************************
タイマ1割り込み構成
*************************/
//割り込みを無効にします
//レジスタが設定されている
cli();
/ *通常のポート動作、ピンが切断されています
タイマー操作から(Break PWM)* /
bitClear(TCCR1A、COM1A1);
bitClear(TCCR1A、COM1A1);
bitClear(TCCR1A、COM1A1);
bitClear(TCCR1A、COM1A1);
/ *モード4、レジスタで設定されたTOP付きCTC
OCR1Aの可変タイミングを設定することができます
に新しい値を書き込むことによる割り込み
OCR1A * /
bitClear(TCCR1A、WGM10)。
bitClear(TCCR1A、WGM11)。
bitSet(TCCR1B、WGM12)。
bitClear(TCCR1B、WGM13)。
/ *クロックプリスケーラを/ 8に設定します。 * /
bitClear(TCCR1B、CS10)。
bitSet(TCCR1B、CS11)。
bitClear(TCCR1B、CS12)。
/ *の強制出力比較を無効にする
チャンネルAとB * /
bitClear(TCCR1C、FOC1A)。
bitClear(TCCR1C、FOC1B)。
/ *アウトプットコンペアを初期化
Aを160に設定して
初期ピッチ* /
OCR1A = 160。
//インプットキャプチャ割り込みを無効にする
bitClear(TIMSK1、ICIE1);
//出力を無効にする
// B一致割り込みを比較
bitClear(TIMSK1、OCIE1B);
//出力を有効にする
//一致割り込みの比較
bitSet(TIMSK1、OCIE1A)。
//オーバーフロー割り込みを無効にする
bitClear(TIMSK1、TOIE1);
//割り込みを有効にする
//レジスタが設定されました
sei();
}
//タイマーオーバーフローハンドラ
ISR(TIMER1_COMPA_vect){
/ * timer1 ISR。毎回
スピーカピンを
波形の次の値周波数
変調は、
連続した呼び出しの間のタイミング
この機能、例えば1KHzトーンの場合
実行するようにタイミングを設定する
スルー波形 1000回
二番目の。 * /
// waveindexに到達したらリセットする
//配列の終わり
if(waveindex> 102){
waveindex = 0;
}
//出力値を設定します
if(音量> 0.03){
analogWrite(スピーカーピン、
waveformVolume waveindex);
}
waveindex ++;
//ピッチを更新する
OCR1A =ピッチ。
}
void loop()
{
//対話を無効にし、pingを送信する
//メッセージを送って答えを待つ。
cli();
pinMode(pingPin、OUTPUT);
digitalWrite(pingPin、LOW);
delayMicroseconds(2)。
digitalWrite(pingPin、HIGH);
delayMicroseconds(5)。
digitalWrite(pingPin、LOW);
duration = pulseIn(pingPin、HIGH、2000);
sei();
//時間を距離に変換します
//センチメートル
//バッファに保存
distance_buffer distance_index ++
%distance_length =期間/ 20;
//バッファ内で最短のものを探す
//距離測定
cm = 16000。
for(int i = 0; i <distance_length; i ++){
cm = min(cm、distance_buffer i);
}
//どの指が押されているか確認する
fingerValue = 5。
if(!digitalRead(finger4)){
fingerValue = 4;
}
if(!digitalRead(finger3)){
fingerValue = 3;
}
if(!digitalRead(finger2)){
fingerValue = 2;
}
if(!digitalRead(finger1)){
fingerValue = 1;
}
//サスティンを更新して
//感度値
フロートサスティン=
map(analogRead(sustainPin)、0、
1024, 101, 130) / 100.0;
int感度=
map(analogRead(sensitivityPin)、
0, 1024, 100, 200);
//ボリュームを更新する
ボリューム=ボリューム/サスティン。
if(音量<0){
ボリューム= 0。
}
//加速度計を確認する
int acc = analogRead(0);
int accDiff = lastAcc - acc;
//音量値を更新します
if(accDiff> 5 *(200 - 感度)){
ボリューム+ =(フロート)
pow(accDiff、
感度/ 100.0)/ 50000;
}
lastAcc = acc;
//音量が1以下であることを確認します
if(音量> .95){
容積= 0.95。
}
//波形の音量を更新する
for(int i = 0; i <= 102; i ++){
waveformVolume i =
((Waveform i - 127)* Volume)+ 127;
}
//距離に応じて音程を設定する
//両手の間
//指が押された
if(cm <102 && cm> 0){
if(cm> 30){
ピッチ=周波数7 +
((((cm - 30)/ 24)* 4 + fingerValue - 1);
その他{
ピッチ=マップ(cm、0、30、39、79)。
}
その他{
ピッチ=周波数7 +
((((102 - 30)/ 24)* 4 + fingerValue - 1);
}
//信号がバウンスしないように遅延させる
遅延(50)。
}
------------------------------------------------------