前回、ようやくArduinoを繋ぐ事ができたので、LEDを光らせて何か作ってみようと思います。せっかくopenFrameworksからコントロールしているのでPC側の機能を使った物ということで、マイクで拾った音量をLEDで表示してみます。
■サンプルの内容
まず、firmataExampleを見てLEDのon/offの方法を調べます。
□ testApp.h
ofArduino というのがArduinoを管理してくれるクラスですね。
□testApp.cpp - setup
ard.connectで接続開始しています。前回ハマったのはこのドライバ名(?)でした。
□testApp.cpp - update
接続チェックかな。
□testApp.cpp - setupArduino
ピンのモード設定。ARD_OUTPUT=デジタル出力用、ARD_ANALOG=アナログ入力用、ARD_PWM=PWM出力用。PWMというのは、デジタル出力を細かくOn/Offする事で階調を表現する事。たとえば、LEDを1秒間に0.1秒点灯、0.1秒消灯を5回繰り返せば、常につけている場合と比べて、半分の明るさになる。
□testApp.cpp - updateArduino
Arduinoオブジェクトをアップデートしています。ard.sendPwm()で、Pin11に50%〜100%の明るさになるようにPWMを送っています。
□testApp.cpp - draw
ard.getAnalog(0)で、pin0(半固定抵抗)のアナログ入力の値を取得しています。
という事で、以下の命令でコントロールする事ができます。簡単!便利!
: 送る : 受け取る
デジタル:sendDigital:getDigital
アナログ:sendPwm:getAnalog
(sendPwmはアナログを出力するわけではありません)
■音量を扱ったサンプル
LEDのコントロールが分かったところで、今度は音量を取得する方法を探します。examplesにaudioInputExampleというのがあるので、開いてみます。PCのマイクの音を周波数別に表示しているみたいです。
□ testApp.h
float * left、float * right、左右の音量が格納されます。周波数ごとの配列として使われます。
□testApp.cpp - setup
ofSoundStreamSetup(0,2,this, 44100, 256, 4);
left = new float[256];
right = new float[256];
音の入出力のセットアップですね。周波数を256段階に分けて取り込みます。
□testApp.cpp - draw
left[]とright[]に入っている値を使って、波形を描画しています。
□testApp.cpp - audioReceived
引数として渡されるinputに左右の値が交互に入っているみたいですね。それを分けて、left,rightに入れています。
音量を直接取り出す命令が分からなかったのですが、left,rightに入っている全ての値を合算すれば、全体の音量になるはず。多分。
■組み合わせる
以上でそれぞれ必要な準備と使い方が分かったので、新しいプロジェクトを作って、各要素をコピーしてきます。
testApp.h
testApp.cpp
■Arduino側の配線
テストでLEDを1つ点けましたが、ほぼ一緒です。2〜6Pinの5個になっただけです。0と1Pinは書き込みのために使われているので空けています。(ん?今回は書き込みしないから使ってもいいのかな・・?)
■動画
■サンプルの内容
まず、firmataExampleを見てLEDのon/offの方法を調べます。
□ testApp.h
ofArduino というのがArduinoを管理してくれるクラスですね。
□testApp.cpp - setup
ard.connectで接続開始しています。前回ハマったのはこのドライバ名(?)でした。
□testApp.cpp - update
接続チェックかな。
□testApp.cpp - setupArduino
ピンのモード設定。ARD_OUTPUT=デジタル出力用、ARD_ANALOG=アナログ入力用、ARD_PWM=PWM出力用。PWMというのは、デジタル出力を細かくOn/Offする事で階調を表現する事。たとえば、LEDを1秒間に0.1秒点灯、0.1秒消灯を5回繰り返せば、常につけている場合と比べて、半分の明るさになる。
□testApp.cpp - updateArduino
Arduinoオブジェクトをアップデートしています。ard.sendPwm()で、Pin11に50%〜100%の明るさになるようにPWMを送っています。
□testApp.cpp - draw
ard.getAnalog(0)で、pin0(半固定抵抗)のアナログ入力の値を取得しています。
という事で、以下の命令でコントロールする事ができます。簡単!便利!
: 送る : 受け取る
デジタル:sendDigital:getDigital
アナログ:sendPwm:getAnalog
(sendPwmはアナログを出力するわけではありません)
■音量を扱ったサンプル
LEDのコントロールが分かったところで、今度は音量を取得する方法を探します。examplesにaudioInputExampleというのがあるので、開いてみます。PCのマイクの音を周波数別に表示しているみたいです。
□ testApp.h
float * left、float * right、左右の音量が格納されます。周波数ごとの配列として使われます。
□testApp.cpp - setup
ofSoundStreamSetup(0,2,this, 44100, 256, 4);
left = new float[256];
right = new float[256];
音の入出力のセットアップですね。周波数を256段階に分けて取り込みます。
□testApp.cpp - draw
left[]とright[]に入っている値を使って、波形を描画しています。
□testApp.cpp - audioReceived
引数として渡されるinputに左右の値が交互に入っているみたいですね。それを分けて、left,rightに入れています。
音量を直接取り出す命令が分からなかったのですが、left,rightに入っている全ての値を合算すれば、全体の音量になるはず。多分。
■組み合わせる
以上でそれぞれ必要な準備と使い方が分かったので、新しいプロジェクトを作って、各要素をコピーしてきます。
testApp.h
#ifndef _TEST_APP
#define _TEST_APP
#include "ofMain.h"
class testApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void setupArduino();
void updateArduino();
// Arduino
ofArduino ard;
bool bSetupArduino; // flag variable for setting up arduino once
// Sound
void audioReceived (float * input, int bufferSize, int nChannels);
float * left;
float * right;
};
#endif
testApp.cpp
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
ofSetVerticalSync(true);
ofSetFrameRate(60);
ofBackground(255,255,255);
// Arduino setup
ard.connect("/dev/tty.usbserial-A7005OBP", 57600);
bSetupArduino = false;
// Sound setup
ofSoundStreamSetup(0,2,this, 44100, 256, 4);
left = new float[256];
right = new float[256];
}
//--------------------------------------------------------------
void testApp::setupArduino(){
// 全てのPinをデジタル出力モードに設定
for (int i = 0; i < 13; i++){
ard.sendDigitalPinMode(i, ARD_OUTPUT);
}
}
//--------------------------------------------------------------
void testApp::update(){
if ( ard.isArduinoReady()){
// 1st: setup the arduino if haven't already:
if (bSetupArduino == false){
setupArduino();
bSetupArduino = true; // only do this once
}
// 2nd do the update of the arduino
updateArduino();
}
}
//--------------------------------------------------------------
void testApp::updateArduino(){
ard.update();
}
//--------------------------------------------------------------
void testApp::draw(){
// draw the left:
ofSetColor(0x333333);
ofRect(0, 0, ofGetWidth(), ofGetHeight() );
ofSetColor(0xFFFFFF);
for (int i = 0; i < 256; i++){
ofSetLineWidth(4);
ofLine(i*4, ofGetHeight()/2, i*4, ofGetHeight()/2+left[i]*100.0f);
}
if (!ard.isArduinoReady()){
cout << "arduino not read" << endl;
} else {
float volume = 0;
for (int i = 0; i < 256; i++){
volume += left[i];
}
volume *= 100;
for (int j = 1; j<6; j++) {
if (volume > j * 30) {
ard.sendDigital(j+1, 1);
}else {
ard.sendDigital(j+1, 0);
}
}
}
}
//--------------------------------------------------------------
void testApp::audioReceived (float * input, int bufferSize, int nChannels){
for (int i = 0; i < bufferSize; i++){
left[i] = input[i*2];
right[i] = input[i*2+1];
}
}
■Arduino側の配線
テストでLEDを1つ点けましたが、ほぼ一緒です。2〜6Pinの5個になっただけです。0と1Pinは書き込みのために使われているので空けています。(ん?今回は書き込みしないから使ってもいいのかな・・?)
■動画
Comments
Post a Comment