2009年11月29日

Arduino_002_Synthesizer制作

■Arduino_002_Synthesizer制作

■使用OS>Windows Vista


<Synthesizer制作>

Arduinoを使用し、単体で音がなるSynthesizerを制作する。

以下参考レジュメ

Auduino synth project

http://blog.makezine.com/archive/2008/11/audiuno_synth_project.html

コードが自分には難解であった為、

まずプロトタイプの制作をし、追ってコードを理解し改良を加えていく事にした。

08/11/27 プロトタイプ制作
08/12/4 コード読解 メロディ



<Auduino synth project>


#include
#include

uint16_t syncPhaseAcc;
uint16_t syncPhaseInc;
uint16_t grainPhaseAcc;
uint16_t grainPhaseInc;
uint16_t grainAmp;
uint8_t grainDecay;
uint16_t grain2PhaseAcc;
uint16_t grain2PhaseInc;
uint16_t grain2Amp;
uint8_t grain2Decay;

#define SYNC_CONTROL (4)
#define GRAIN_FREQ_CONTROL (0)
#define GRAIN_DECAY_CONTROL (2)
#define GRAIN2_FREQ_CONTROL (3)
#define GRAIN2_DECAY_CONTROL (1)

#define LED_PIN 13
#define LED_PORT PORTB
#define LED_BIT 5

#if defined(__AVR_ATmega168__)
#define PWM_PIN 3
#define PWM_VALUE OCR2B
#else
#define PWM_PIN 11
#define PWM_VALUE OCR2
#endif
#define PWM_INTERRUPT SIG_OVERFLOW2

uint16_t antilogTable[] = {
64830,64132,63441,62757,62081,61413,60751,60097,59449,58809,58176,57549,56929,56316,55709,55109,
54515,53928,53347,52773,52204,51642,51085,50535,49991,49452,48920,48393,47871,47356,46846,46341,
45842,45348,44859,44376,43898,43425,42958,42495,42037,41584,41136,40693,40255,39821,39392,38968,
38548,38133,37722,37316,36914,36516,36123,35734,35349,34968,34591,34219,33850,33486,33125,32768
};
uint16_t mapPhaseInc(uint16_t input) {
return (antilogTable[input & 0x3f]) >> (input >> 6);
}

uint16_t midiTable[] = {
17,18,19,20,22,23,24,26,27,29,31,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73,
77,82,86,92,97,103,109,115,122,129,137,145,154,163,173,183,194,206,218,231,
244,259,274,291,308,326,346,366,388,411,435,461,489,518,549,581,616,652,691,
732,776,822,871,923,978,1036,1097,1163,1232,1305,1383,1465,1552,1644,1742,
1845,1955,2071,2195,2325,2463,2610,2765,2930,3104,3288,3484,3691,3910,4143,
4389,4650,4927,5220,5530,5859,6207,6577,6968,7382,7821,8286,8779,9301,9854,
10440,11060,11718,12415,13153,13935,14764,15642,16572,17557,18601,19708,20879,
22121,23436,24830,26306
};
uint16_t mapMidi(uint16_t input) {
return (midiTable[(1023-input) >> 3]);
}

uint16_t pentatonicTable[54] = {
0,19,22,26,29,32,38,43,51,58,65,77,86,103,115,129,154,173,206,231,259,308,346,
411,461,518,616,691,822,923,1036,1232,1383,1644,1845,2071,2463,2765,3288,
3691,4143,4927,5530,6577,7382,8286,9854,11060,13153,14764,16572,19708,22121,26306
};

uint16_t mapPentatonic(uint16_t input) {
uint8_t value = (1023-input) / (1024/53);
return (pentatonicTable[value]);
}


void audioOn() {
#if defined(__AVR_ATmega168__)
TCCR2A = _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS20);
TIMSK2 = _BV(TOIE2);
#else
TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
TIMSK = _BV(TOIE2);
#endif
}


void setup() {
pinMode(PWM_PIN,OUTPUT);
audioOn();
pinMode(LED_PIN,OUTPUT);
}

void loop() {
syncPhaseInc = mapPentatonic(analogRead(SYNC_CONTROL));
grainPhaseInc = mapPhaseInc(analogRead(GRAIN_FREQ_CONTROL)) / 2;
grainDecay = analogRead(GRAIN_DECAY_CONTROL) / 8;
grain2PhaseInc = mapPhaseInc(analogRead(GRAIN2_FREQ_CONTROL)) / 2;
grain2Decay = analogRead(GRAIN2_DECAY_CONTROL) / 4;
}

SIGNAL(PWM_INTERRUPT)
{
uint8_t value;
uint16_t output;

syncPhaseAcc += syncPhaseInc;
if (syncPhaseAcc < syncPhaseInc) {
grainPhaseAcc = 0;
grainAmp = 0x7fff;
grain2PhaseAcc = 0;
grain2Amp = 0x7fff;
LED_PORT ^= 1 << LED_BIT;
}

grainPhaseAcc += grainPhaseInc;
grain2PhaseAcc += grain2PhaseInc;

value = (grainPhaseAcc >> 7) & 0xff;
if (grainPhaseAcc & 0x8000) value = ~value;
output = value * (grainAmp >> 8);

value = (grain2PhaseAcc >> 7) & 0xff;
if (grain2PhaseAcc & 0x8000) value = ~value;
output += value * (grain2Amp >> 8);

grainAmp -= (grainAmp >> 8) * grainDecay;
grain2Amp -= (grain2Amp >> 8) * grain2Decay;

output >>= 9;
if (output > 255) output = 255;

PWM_VALUE = output;
}


< 回路図 >


wsoo1.png

<コード読解>

●C言語での宣言(#?)はパソコンが考えてアルディーノに書き込む前に実行する前準備、指示
●C言語とは ○○語をアルディーノ語に翻訳するにあたっての通訳への指示

#include //ソースファイルの中に外部ライブラリファイルを挿入することこの場合をインクルードしている
#include 

uint16_t syncPhaseAcc;//16進数
uint16_t syncPhaseInc;
uint16_t grainPhaseAcc;
uint16_t grainPhaseInc;
uint16_t grainAmp;
uint8_t grainDecay;//8進数
uint16_t grain2PhaseAcc;
uint16_t grain2PhaseInc;
uint16_t grain2Amp;
uint8_t grain2Decay;


#define SYNC_CONTROL (4)//#define 定数名 値 を定義している analog in4
#define GRAIN_FREQ_CONTROL (0)//analog in0
#define GRAIN_DECAY_CONTROL (2)//analog in2
#define GRAIN2_FREQ_CONTROL (3)//analog in3
#define GRAIN2_DECAY_CONTROL (1)//analog in1

#define LED_PIN 13
#define LED_PORT PORTB
#define LED_BIT 5

#if defined(__AVR_ATmega168__)//#if defined(シンボル名) シンボルが定義されているときに実行するプリプロセッサ命令
// #ifは、#endif までの文の並びをコンパイル(人間がプログラミング言語を用いて作成したソフトウェアの設計図((ソースコード))を、コンピュータ上で実行可能な形式((オブジェクトコード))に変換すること)する
#define PWM_PIN 3
#define PWM_VALUE OCR2B
#else// それ以外の場合はこうする
#define PWM_PIN 11
#define PWM_VALUE OCR2
#endif//if文終わり
#define PWM_INTERRUPT SIG_OVERFLOW2


uint16_t antilogTable[] = {
64830,64132,63441,62757,62081,61413,60751,60097,59449,58809,58176,57549,56929,56316,55709,55109,
54515,53928,53347,52773,52204,51642,51085,50535,49991,49452,48920,48393,47871,47356,46846,46341,
45842,45348,44859,44376,43898,43425,42958,42495,42037,41584,41136,40693,40255,39821,39392,38968,
38548,38133,37722,37316,36914,36516,36123,35734,35349,34968,34591,34219,33850,33486,33125,32768
};
uint16_t mapPhaseInc(uint16_t input) {
return (antilogTable[input & 0x3f]) >> (input >> 6);//return文で計算した値を返す  できたよ、はいどうぞと返す
}


uint16_t midiTable[] = {
17,18,19,20,22,23,24,26,27,29,31,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73,
77,82,86,92,97,103,109,115,122,129,137,145,154,163,173,183,194,206,218,231,
244,259,274,291,308,326,346,366,388,411,435,461,489,518,549,581,616,652,691,
732,776,822,871,923,978,1036,1097,1163,1232,1305,1383,1465,1552,1644,1742,
1845,1955,2071,2195,2325,2463,2610,2765,2930,3104,3288,3484,3691,3910,4143,
4389,4650,4927,5220,5530,5859,6207,6577,6968,7382,7821,8286,8779,9301,9854,
10440,11060,11718,12415,13153,13935,14764,15642,16572,17557,18601,19708,20879,
22121,23436,24830,26306
};
uint16_t mapMidi(uint16_t input) {
return (midiTable[(1023-input) >> 3]);//return文で計算した値を返す
}


uint16_t pentatonicTable[54] = {
0,19,22,26,29,32,38,43,51,58,65,77,86,103,115,129,154,173,206,231,259,308,346,
411,461,518,616,691,822,923,1036,1232,1383,1644,1845,2071,2463,2765,3288,
3691,4143,4927,5530,6577,7382,8286,9854,11060,13153,14764,16572,19708,22121,26306
};

uint16_t mapPentatonic(uint16_t input) {
uint8_t value = (1023-input) / (1024/53);
return (pentatonicTable[value]);// ここではpentatonicTableのvalue(実数)値を返す
}


void audioOn() {
#if defined(__AVR_ATmega168__)// 条件を満たしたとき実行される文
// 31.25kHzでセットアップ
TCCR2A = _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS20);
TIMSK2 = _BV(TOIE2);
#else// それ以外の場合はこうする
// ATmega8は異なったregister(レジスタ=記憶クラス)をもっている
TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
TIMSK = _BV(TOIE2);
#endif
}

void setup() {//セットアップ
pinMode(PWM_PIN,OUTPUT);//設定したいピンの番号を出力に設定
audioOn();
pinMode(LED_PIN,OUTPUT);
}
// buttonPinを繰り返しチェックして、
// その状態をシリアルで送信する

void loop() {//繰り返し実行 なんでも繰り返せる ベルトコンベア

syncPhaseInc = mapPentatonic(analogRead(SYNC_CONTROL));//analogRead(pin) 指定したアナログピンから値を読み取る
grainPhaseInc = mapPhaseInc(analogRead(GRAIN_FREQ_CONTROL)) / 2;
grainDecay = analogRead(GRAIN_DECAY_CONTROL) / 8;
grain2PhaseInc = mapPhaseInc(analogRead(GRAIN2_FREQ_CONTROL)) / 2;
grain2Decay = analogRead(GRAIN2_DECAY_CONTROL) / 4;
}

SIGNAL(PWM_INTERRUPT)
{
uint8_t value;
uint16_t output;

syncPhaseAcc += syncPhaseInc;
if (syncPhaseAcc < syncPhaseInc) { // 条件を満たしたとき実行される
// 次のgrainを始める時間
grainPhaseAcc = 0;
grainAmp = 0x7fff;
grain2PhaseAcc = 0;
grain2Amp = 0x7fff;//0xは16進数 進数指定をしている
LED_PORT ^= 1 << LED_BIT; // digitalWriteを使用するより速い
}

// grain oscillatorsのフェーズを増加
grainPhaseAcc += grainPhaseInc;
grain2PhaseAcc += grain2PhaseInc;

// 三角形波にフェーズを変換
value = (grainPhaseAcc >> 7) & 0xff;
if (grainPhaseAcc & 0x8000) value = ~value;
// 現在のgrain幅で増えて、サンプルを手に入れる
output = value * (grainAmp >> 8);

// 二番目のgrain(粒)を繰り返す
value = (grain2PhaseAcc >> 7) & 0xff;
if (grain2PhaseAcc & 0x8000) value = ~value;
output += value * (grain2Amp >> 8);

// grain振幅は様々なサンプルによって使い分ける…との事w
grainAmp -= (grainAmp >> 8) * grainDecay;
grain2Amp -= (grain2Amp >> 8) * grain2Decay;

// 必要なら、切り取って、利用可能な範囲に出力について合わせて調整してください
output >>= 9;
if (output > 255) output = 255;

// Output to PWM これはanalogWriteを使用するより速い
PWM_VALUE = output;
}


<三角波を用いる>

上のコードを元に新たに組みなおす

●メロディをつける事は可能になった

●三角波はできなかった


#include

#include

uint16_t syncPhaseAcc;

uint16_t syncPhaseInc;
uint16_t grainPhaseAcc;
uint16_t grainPhaseInc;
uint16_t grainAmp;
uint8_t grainDecay;

uint16_t grain2PhaseAcc;
uint16_t grain2PhaseInc;
uint16_t grain2Amp;
uint8_t grain2Decay;

#define SYNC_CONTROL (4)

#define LED_PIN 13
#define LED_PORT PORTB
#define LED_BIT 5

#if defined(__AVR_ATmega168__)

#define PWM_PIN 3
#define PWM_VALUE OCR2B
#else
#define PWM_PIN 11
#define PWM_VALUE OCR2
#endif
#define PWM_INTERRUPT SIG_OVERFLOW2

uint16_t antilogTable[] = {
//
};

uint16_t pentatonicTable[] = {
0,200,400,600,800,1000,1200,1400,1600,1800,2000,2200,2400,2600,2800,3000,3200,3400,3600,3800,4000,4200,4400,4600,4800,5000,5200,
5400,5600,5800,5600,5400,5200,5000,4800,4600,4200,4000,3800,3600,3400,3200,3000,2800,2600,2400,2200,2000,1800,1600,
1400,1200,1000,800,600,400,200,0,
};

uint16_t mapPentatonic(uint16_t input) {
uint8_t value = (1023-input) / (1024/53);
return (pentatonicTable[value]);
}


void audioOn() {
#if defined(__AVR_ATmega168__)
TCCR2A = _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS20);
TIMSK2 = _BV(TOIE2);
#else
TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
TIMSK = _BV(TOIE2);
#endif
}


void setup() {
pinMode(PWM_PIN,OUTPUT);

audioOn();
pinMode(LED_PIN,OUTPUT);
}

void loop() {
syncPhaseInc = mapPentatonic(analogRead(SYNC_CONTROL));//analogRead(pin) }

SIGNAL(PWM_INTERRUPT)
{
uint8_t value;
uint16_t output;

syncPhaseAcc += syncPhaseInc;
if (syncPhaseAcc < syncPhaseInc) {
grainPhaseAcc = 0;
grainAmp = 0x7fff;
grain2PhaseAcc = 0;
grain2Amp = 0x7fff;
LED_PORT ^= 1 << LED_BIT;
}
}

<プロトタイプ>

int soundPin = 4 ; // digital PIN 4
int ledPin = 3 ; // LED1
int d8 = 8 ; //digital PIN 8 = SW2
int d9 = 9 ; //digital PIN 9 = SW3

//ドレミの周波数 Hz
int soundhz[] = { 262, 294, 330, 349, 393, 440, 494, 523 } ;
//ドレミの半周期を計算していれる
int cycle2[8] ;

void setup()
{
pinMode(soundPin,OUTPUT) ;
pinMode(ledPin,OUTPUT) ;
digitalWrite(ledPin, LOW) ; //ブートローダから立ち上がったら点灯

pinMode(d8, INPUT) ;
digitalWrite(d8, HIGH) ; //プルアップしている http://www9.plala.or.jp/fsson/NewHP_elc/elc/elc4_Pullup.html
pinMode(d9, INPUT) ;
digitalWrite(d9, HIGH) ; //同上

//あらかじめここで周波数ごとのHIGH/LOWの期間を計算
for (int i = 0; i < 8; i++) {
cycle2[i] = 1000L*1000 / soundhz[i] / 2 ;
}
}

void soundOut(int idx)
{
int n ;
int t ;
//ここで半周期を計算すると遅いのでノイズがでてしまう
t = cycle2[idx] ;

for (n = 0; n < 10; n++) { //10は適当
digitalWrite(soundPin,HIGH) ;
delayMicroseconds(t) ;
digitalWrite(soundPin,LOW) ;
delayMicroseconds(t);
}
}

void loop()
{
if(digitalRead(d8) == LOW)
soundOut(0);

if(digitalRead(d9) == LOW)
soundOut(7);

}

2009年11月12日

11.11 [WORKSHOP] Dirty Electronics  John Richards 無事終了しました!!

2009.11.11 [WORKSHOP] Dirty Electronics  John Richards  無事終了いたしました!!



参加してくださった多くの方々へ、お手伝いなどご協力いただき、円滑に進行でき無事終了できたこと心から感謝いたします。
ありがとうございました!





おかげさまで運営側も楽しくworkshopを堪能させていただきました!


今回、ストリーミング配信していた映像を多少ながら録画しておりましたので先行的に
アップロードさせていただきます。是非ご確認ください

YouTube-1

YouTube-2

なにかありましたらfaboまでご連絡ください!近日中に写真と編集映像を公開予定です。もうしばらくお待ちください。

では次回はMTM04に参加予定ですので、大岡山にて!!よろしくお願いいたします

2009年10月28日

10.28 [WORKSHOP] Dirty Electronics  John Richards 詳細決定しました!

前回のライブ&レクチャーに引き続き、第二回企画として今回はworkshopを行いたいと思います!

詳細はこちら

日時:2009.11.10(火) 15:00〜

会場:東京工芸大学 厚木キャンパス 3号館1階ギャラリー

定員:東京工芸大学から15名 外部から10名(調整あり)

参加費:無料

申し込み:氏名(ふりがな)、住所、年齢、電話番号、Email等の連絡先、 所属を揃えて 
kougei.fabo@gmail.com 
へお送りください。

fabo presents "WorkShop"第2弾。
今回はイギリスから音楽家のJohn Richards氏をお招きして、電子楽器を制作するワークショップを予定しております。たくさんの参加、お待ちしております!

宜しくお願い致します!!

2009年10月25日

10.22 水田拓郎さんのライブ&レクチャー無事終了!


無事ライブ&レクチャーを終える事が出来ました。

参加して下さった皆さんありがとうございました!!

2009年度のfaboの初めての試みでしたが、開場に45人 ストリーミングWEB上に20人弱と約70名の方に見て頂き、うれしい限りです。

現在、写真の方と映像の方を編集中です。

出来次第こちらに追記したいと思います!

次回はUKを中心に、活動中のJohn RichardsさんのDirty Electronicsのworkshopです!

近日中に公開予定ですのでこちらも宜しくお願い致します!

2009年10月10日

10.10 WEB公開

2009年度 fabo workshop 運営のWEBが完成しました。

こちらにイベントの掲載をしていきますので、興味のあるイベントがありましたら

kogei.fabo@gmail.com
までご連絡ください!!

09.28 水田拓郎さんのイベント詳細が決定しました!

2009年09月08日

MTM04 に出展予定です!!

MTM02MTM03と引き続き、今のところではありますがMTM04にも出展予定です!!




現在faboは誠意を込めて製作中でございます。前回のMakeもおかげ様で盛況でしたが今回は更なる盛況と前進を目指して頑張っています。





また、次回に出展に関する情報などもアップしていきたいと思っておりますので、暇な時にでもサイトを覗いていただけるとうれしいです。 よろしくお願いします。

2009年05月27日

MTM03 出展してきました!

今回、去年秋のMTM02に引き続いて、MTM03にも出展してきました。


都内でもインフルエンザが見つかったとのことで大丈夫かなと思いましたが、人でいっぱいでした。


ご来場くださった皆様ありがとうございました

二日間通して、WS-01, 布タイロフォン、Super Recorder 、Lilypad crown , Untitled の五作品とMARIO Sampler 前回出展したGame Boya を 展示しました。

おかげさまで、盛況でした。

IMG_0097.jpg

IMG_0106.jpg


IMG_0112.jpg


IMG_0125.jpg


IMG_0089.jpg

個人的には全体の次回作、期待してくださる方が多数いらっしゃいました。うれしい限りです。 今、イメージを組み立てているところで、早々に準備に入るつもりです。 夏ごろに何らかのリリースをすることが目標、6月中には見通しをアップできると良いと考えています。 こちらのサイトに、情報をアップしてゆきますので、時々見にいらしてください。

二日間本当にたくさんのことがあり、まだ情報がまとまりきらず混乱中です。


次回のイベントは、シンセ多そうですね。今回のような修羅場にならないように、早めに準備をしたいと思います。

ちなみに面白かったもので写真が残っている物をあげてみようかと思います。

ATmarquinoをラジコンにした戦車で遊べるコーナーを作っていました。

IMG_0098.jpg


戦車の制御には2つのコントローラを使います。一つが移動用、もう一つが大砲の制御用です。上下角や左右回転、弾の発射ができます。

ニコニコ技術部の アイロンビーズですね。

IMG_0117.jpg

SFCのゲームを思い出します。

載せると言ってもこれだけしか写真がなく以上ですが、


とても雰囲気良く楽しませて頂きました。

オライリーの方々や同じブースの方にはお世話になりました。

また、他の出展者の方からのアドバイスや来場してくれた方々の反応にも

刺激を頂きモチベーションもあがりました。

ありがとうございます。

次回も参加の方向で何か作っていきたいと思います。

先ほどもいいましたが
こちらのサイトに情報をアップしてゆきますので、時々見にいらしてください。

ではでは

2009年04月05日

Arduino Flash+Funnel -サーボ制御- 

今回はFunnelを使ってPWMの平均化、制御について検討。



PWMの平均化の実験としてFlash+Funnelでサーボ制御を行う。


とりあえず


参考になるサンプルから少しずつ読解していく感じでいきたいとおもいます。


サーボ制御のAS3のサンプルはなかなか見つからずとりあえず参考になるものが見つかったので


参照して自分なりに組み替えて再挑戦。

なんとか微動しながらサーボ制御に成功。


写真撮り忘れてしまったので近日中にいきます

http://gainer.cc/forum/index.php?topic=255.0



///////////////////////////////////////////////

ArduinoServoTest

.as

//////////////////////////////////////////////

package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import funnel.*;

public class ArduinoServoTest extends Sprite
{
private var servo:Port; //ポートから”servo”と言う変数に値を送る
private var jog:Port; //ポートから”jog”と言う変数に値を送る
private var myTimer:Timer; //ディレイ用のタイマーを設定(Timer)
private var seconds:Number; //時間の関数を設定:値は小数点まで表示(Number)

public function ArduinoServoTest() {
var config:Configuration = Arduino.FIRMATA;//arduinoをFIRMATAで制御できるように設定
config.setDigitalPinMode(11, PWM);//aruduinoのデジタルイン11番にPWMの値を設定

var aio:Arduino = new Arduino(config);//arduinoのオブジェクトを生成
servo = aio.digitalPin(11);//servoはarduinoのデジタルアウト11番から値をもらう
var jog:Port = aio.analogPin( 0 );//jogはarduinoのアナログイン0番から値をもらう
myTimer =new Timer(100);//timerを生成。timerは100ミリ秒で設定
jog.addEventListener(PortEvent.CHANGE, onChange );//
myTimer.addEventListener(TimerEvent.TIMER, onTimer);//タイマーのイベントをonTimerと言う名目で設定
myTimer.start();//タイマーをスタート

aio.addEventListener(FunnelEvent.READY, trace);
aio.addEventListener(FunnelErrorEvent.REBOOT_ERROR, trace);
aio.addEventListener(FunnelErrorEvent.CONFIGURATION_ERROR, trace);
aio.addEventListener(FunnelErrorEvent.ERROR, trace);


}
//値が変わったとき変換
private function onChange(e:Event):void {
jog = Port( e.target );
trace( jog.value );
seconds = (jog.value) *1.2;
}
//100mm秒で値を生成。
private function onTimer (event:TimerEvent):void{
var count:int = myTimer.currentCount;
servo.value = seconds;

}
}
}

/////////////////////////////////////////////////

前回PWMが制御できないと悩んでいましたが、今回なぞが解けました気がします。


参照

10行目 private var jog:Port; //ポートから”jog”と言う変数に値を送る
16行目 config.setDigitalPinMode(11, PWM);//aruduinoのデジタルイン11番にPWMの値を設定

20行目 var jog:Port = aio.analogPin( 0 );//jogはarduinoのアナログイン0番から値をもらう

22行目 jog.addEventListener(PortEvent.CHANGE, onChange );//jogでもらった値を変換するイベントを作る。(値に変化が起こったときイベントが起こる)

次に16行目、デジタルインの11番にPWMを設定します。
20行目 ”jog”アナログイン0番から値をもらうように設定します。 これでjogはPWMの値になったわけですか。
ほう。

そして 22行目 値が変わるごとにイベントを発生させることで可変抵抗で変わっていく抵抗値に応じてASが反応してサーボに信号をおくるわけですな。

ふーむつかえそうです

2009年04月03日

maxとarduinoの通信 001

環境
MacOS10.4.11
1.5GhzPPC

http://www.arduino.cc/playground/Interfacing/MaxMSP

のサイトより

SimpleMessageSystemというファイルをダウンロードする。
http://www.arduino.cc/playground/uploads/Code/SimpleMessageSystem.zi


解凍後、フォルダごと
app \ arduino \ hardware \ libraries \ SimpleMessageSystem
となるように入れる。

fabomax01.jpg


その後、arduinoを起動。
File > examples に SimpleMessageSystemがあるかを確認し、
実行して出てきたプログラムをarduinoに書き込み

以下プログラム


#include

void setup()
{
200 with the USB version, that's 12x faster
Serial.begin(9600);
}

void loop()
{

if (messageBuild() > 0) {
switch (messageGetChar()) {
case 'r':
readpins();
break;
case 'w':
writepin();
}

}

}

void readpins(){

switch (messageGetChar()) {

case 'd':

messageSendChar('d');
for (char i=2;i<14;i++) {
messageSendInt(digitalRead(i));
}
messageEnd();
break;

case 'a':

messageSendChar('a');
for (char i=0;i<6;i++) {
messageSendInt(analogRead(i));
}
messageEnd();

}

}

void writepin() {

int pin;
int state;

switch (messageGetChar()) {

case 'a' :

pin = messageGetInt();
state = messageGetInt();
pinMode(pin, OUTPUT);
analogWrite(pin, state);
break;


case 'd' :

pin = messageGetInt();
state = messageGetInt();
pinMode(pin,OUTPUT);
digitalWrite(pin,state);

}

}

書き込みに成功したら、 libraries \ SimpleMessageSystem\MaxMspExample\SimpleMessageSystem_analogin.mxb を開く。

fabomax02.jpg

maxwindow にエラーが表示されている場合、 printボタンを押しserialを確認。

fabomax03.jpg

オブジェクト内のserialを書き換える。


fabomax04.jpg

これでmax上のトグルからpin13のLEDが制御できれば成功。

*これでarduinoが認識しない場合、arudinoのプッシュスイッチを押す事で認識するはず。


〜改良パッチ編〜


先ほど使用したmaxのパッチの改良版が以下からダウンロードできる。
http://blog.soundsorange.net/category/gear-hardware/

ダウンロードしたフォルダ内のファイルを
libraries \ SimpleMessageSystem\MaxMspExample
内に上書きして保存


SimpleMessageSystem.mxbを開き、先程の要領でserialを書き換える。

*なおサンプルファイルのpin13を光らせるオブジェクトの書き方が間違っているので修正。


fabomax05.jpg


fabomax06.jpg


この改良パッチによってdigtal inにも対応できるようになった。