arduinoで音を制御(録音, 再生etc)したい時用の個人的まとめです.
1. 再生
1-1. mp3を再生する
SDカードにmp3の音源を入れ, moduleを使用して再生します.
- 良: moduleのおかげで簡単に再生できる
- 悪: moduleが必要
- 悪: 用意した音源しか再生できない
参照
『FN-M16P(DFPlayer Mini)』電子工作で音楽(MP3)を鳴らすなら、これ。Arduinoから制御もできるよ。
使用したmodule
FN-M16P Embedded MP3 Audio Module(DFPlayer Mini)
code
//『 FN-M16P Embedded MP3 Audio Module 』(DFPlayer Mini)のテスト。
//start(pin8)で再生start、next(pin9)で次の曲、stop(pin10)で停止
//シリアルコマンドを送る試験
#include <SoftwareSerial.h>
#define start 8 // 置き換え(start→ ”8”)
#define next 9 // 置き換え(next→ ”9”)
#define stop 10 // 置き換え(stop→ ”10”)
#define play 11 // 置き換え(play→ ”11”)
int s1=0,s2=0,s3=0,s4=0;
void setup() {
Serial.begin (9600); //シリアルポートを開き、転送速度を9600bpsに設定
delay(1); // delay 1ms to set volume
pinMode(start,INPUT); // start(ピン8)を入力に設定
pinMode(next,INPUT); // next(ピン9)を入力に設定
pinMode(stop,INPUT); // stop(ピン10)を入力に設定
pinMode(play,INPUT); // play(ピン11)を入力に設定
//pinMode(13,OUTPUT); // 13を出力に設定
}
void loop(){
s1=digitalRead(start);
if(s1==0){ // startが押されるまで待つ
//ファイル指定再生
Serial.write(0x7E);
Serial.write(0xFF);
Serial.write(0x06);
Serial.write(0x0F); //「フォルダ指定再生」コマンド
Serial.write(0x00);
Serial.write(2); //この例では、「02」というFOLDER名が指定される
Serial.write(1); //この例では、「001.mp3」というファイル名のmp3が指定される
Serial.write(0xEF);
delay(10);
while(1){
s2=digitalRead(next);
s3=digitalRead(stop);
s4=digitalRead(play);
if(s4==0){ // playが押されるまで待つ
delay(100);
Serial.write(0x7E);
Serial.write(0xFF);
Serial.write(0x06);
Serial.write(0x0D); //再生コマンド
Serial.write(0x00);
Serial.write(0x00); //
Serial.write(0x00); //
Serial.write(0xEF);
delay(100);
}
if(s2==0){ // nextが押されるまで待つ
//次の曲へ
delay(100);
Serial.write(0x7E);
Serial.write(0xFF);
Serial.write(0x06);
Serial.write(0x01); //次曲再生コマンド
Serial.write(0x00);
Serial.write(0x00); //
Serial.write(0x00); //
Serial.write(0xEF);
delay(1000);
}
if(s3==0){ // stopが押されるまで待つ
//停止
Serial.write(0x7E);
Serial.write(0xFF);
Serial.write(0x06);
Serial.write(0x0E); //ポーズCMD
Serial.write(0x00);
Serial.write(0x00); //
Serial.write(0x00); //
Serial.write(0xEF);
delay(10);
//break;
}
}
}
}
1-2. arduinoのみで再生する
- PWMのピンを利用し, 2.5Vを中心に0~5Vで電圧を揺らすことで, PWMピンから直接再生する
- そのままのPWMだと遅くて(?)不適なのでFastPWMを利用
- PROGMEMを使用してフラッシュメモリーに書き込みます(32KBなのでプログラム部分を除くと8000Hzで最大約4秒)
- PWMなので音の振幅の解像度は8bit(256)
- 音の波形を[0,255]で表現できれば良い. 作成方法は自由(WAV音源を変換する方法を下記では紹介).
- 音源のサンプリングレートはdelayMicrosecondsで調整(例:8000Hzなら125[=1/8000]). ただし, プログラム内容によっては微調整が必要そう.
- 悪: フラッシュメモリにはconstで事前に書き込むので録音等はできない
参照
FastPWM
Arduino Nano の PWM 機能を使ってみた(FastPWM 編 その2) [Arduino]
Secrets of Arduino PWM
DelayからTimer割り込みに変更
arduinoとスピーカーだけで音を出す方法
Arduinoとスピーカだけで音声を出す [Arduino]
【Arduino】WAVまたはMP3ファイルを再生する
program memoryについて
avr/pgmspace.h : Program Space Utilities
配線
GND: スピーカーの-
3: スピーカーの+
256の音源を作る
作成例
- test.wavを用意する
- rawにformat変換
audacityでサンプリング周波数8000Hz
,その他の非圧縮ファイル
,RAW(header-less)
,Unsigned 8-bit PCM
と指定してtest.raw
を作る - ターミナルで
xxd -i sample.raw
を実行して数値に変換する -
0x7f, 0x80, 0x7f, ...
みたいな数値列(16進数)ができた
最終的な数値は127, 128, 127, ...
のように10進数であってもOK
code
(私の「あいう」の声が無限に流れますが悪しからず...)
#include <avr/pgmspace.h>
const unsigned char sample_raw[] PROGMEM = {
108,108,108,108,108,118,108,118,118,118,118,128,118,118,128,118,118,128,138,128,138,128,128,128,128,128,128,128,128,128,128,128,128,128,118,118,118,128,128,118,118,118,128,118,128,128,128,118,118,118,118,128,128,118,118,128,128,128,118,118,128,138,158,148,138,128,128,128,138,148,138,148,138,128,118,118,108,118,108,98,98,98,108,108,118,108,118,138,118,108,98,88,98,128,128,128,128,128,118,118,108,108,118,118,118,128,128,128,138,128,128,128,118,118,128,128,128,128,128,128,128,118,118,118,118,118,128,128,138,138,138,128,118,128,128,138,138,148,138,118,108,128,118,128,118,108,108,118,118,98,108,108,128,138,148,128,128,128,118,128,138,138,138,148,138,138,128,118,118,118,118,118,118,118,118,118,118,118,108,108,108,108,108,128,118,118,118,108,118,118,118,118,118,118,118,128,128,118,128,118,118,128,118,128,128,128,118,118,118,118,128,128,128,128,128,108,128,118,118,138,138,128,138,138,118,138,128,128,138,148,148,158,118,98,98,98,118,148,158,148,158,118,128,118,128,128,138,118,118,128,128,128,128,108,98,108,98,108,118,108,108,108,98,98,108,108,108,108,118,118,118,118,128,128,118,128,128,128,128,128,128,128,128,128,118,128,118,128,128,118,118,128,128,128,138,128,128,128,128,138,138,118,128,128,128,128,148,108,128,128,118,108,118,148,128,158,128,118,108,138,118,118,118,98,128,148,128,108,128,108,118,138,128,108,128,128,128,128,118,118,128,128,118,118,118,118,118,118,108,108,108,108,108,108,108,108,118,118,108,118,118,118,118,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,118,108,118,128,138,138,128,118,118,138,128,128,128,128,138,138,138,118,98,128,148,158,138,118,118,128,128,108,118,118,118,138,128,118,138,138,128,128,128,118,128,138,128,118,128,128,128,118,108,108,108,108,108,108,108,108,108,108,108,108,108,118,108,118,118,118,118,128,128,128,128,128,118,128,128,128,128,118,118,128,128,118,128,128,128,128,128,118,128,128,138,128,128,128,138,138,138,128,108,138,148,128,98,128,148,128,118,128,138,118,118,108,98,128,148,118,108,128,128,128,148,128,128,148,158,128,128,118,118,128,128,108,108,118,108,118,118,98,88,108,118,108,108,98,108,118,118,108,108,108,118,128,128,118,118,138,128,128,128,128,128,138,128,118,118,128,128,128,118,118,118,128,128,128,128,128,138,128,128,128,118,128,148,138,138,118,148,118,128,138,118,108,138,158,88,118,128,128,118,148,88,98,148,168,158,148,158,138,178,138,108,88,118,98,108,98,78,98,128,128,88,98,98,128,118,108,88,118,128,138,118,88,108,138,138,108,108,108,138,138,118,98,118,138,138,128,108,118,138,148,118,118,118,138,138,118,108,118,138,138,128,108,108,138,148,128,98,118,148,148,128,128,118,138,158,138,108,138,158,128,118,118,118,98,128,98,118,168,158,138,148,178,148,158,98,98,108,128,88,68,88,108,128,98,98,88,128,128,118,98,108,128,128,118,98,108,128,138,118,108,118,138,138,118,108,108,138,128,118,108,118,138,148,128,118,128,138,138,118,118,128,138,128,118,118,128,138,128,128,128,128,128,128,118,118,128,118,128,118,148,148,138,138,138,128,118,118,118,108,108,138,138,168,158,158,148,168,158,128,108,98,108,78,78,68,88,88,98,88,98,118,128,128,128,148,118,128,118,118,108,108,108,108,108,108,128,118,128,128,128,128,128,128,118,128,118,128,118,128,128,128,128,118,128,128,138,128,128,128,128,128,128,118,118,128,118,128,118,128,138,138,118,148,128,118,148,138,108,128,128,108,158,128,148,168,158,158,178,148,138,158,108,108,88,68,68,68,58,58,78,68,98,108,118,138,148,138,158,158,128,138,128,118,118,108,98,108,108,98,118,108,118,128,128,128,138,138,138,138,128,128,128,128,118,118,118,118,118,118,118,118,128,118,128,138,118,128,138,118,128,128,138,118,138,128,128,128,128,118,138,148,148,158,148,168,168,168,148,158,138,128,118,88,88,68,58,48,58,48,68,78,88,108,118,138,148,158,158,168,148,158,148,128,128,118,98,98,108,78,98,98,108,108,118,118,128,128,128,148,128,138,138,138,128,128,128,118,118,118,118,118,118,118,118,118,128,128,138,128,138,138,128,148,128,138,148,138,158,148,148,168,178,158,168,158,138,138,108,108,88,68,58,58,38,48,58,58,78,98,118,128,148,148,168,168,168,158,158,148,148,118,118,118,98,98,88,88,88,98,98,98,108,118,128,138,138,138,148,138,148,138,138,128,128,118,118,108,108,108,108,108,108,118,118,118,138,118,138,148,128,148,148,168,148,168,168,178,168,168,168,158,148,128,128,98,88,78,58,48,48,48,48,58,68,88,108,128,138,158,168,168,178,178,168,158,148,138,138,128,98,108,108,88,88,98,98,88,108,108,128,118,128,138,138,128,138,138,128,128,128,128,118,118,118,108,108,118,108,118,108,128,118,128,128,138,138,148,158,158,178,168,188,178,188,168,178,148,148,118,108,88,68,58,38,48,28,48,38,68,68,98,108,128,148,158,168,178,178,178,178,168,158,148,138,118,138,88,98,108,78,88,108,88,88,118,98,118,108,128,128,128,128,138,128,128,138,118,128,118,128,118,118,108,128,98,128,118,118,138,128,128,158,138,148,188,138,198,158,178,168,168,148,148,128,108,118,78,88,58,68,48,48,48,58,68,78,98,108,128,128,148,158,158,168,168,158,168,158,158,138,148,128,118,118,108,98,98,98,88,108,88,108,98,108,108,128,108,118,128,128,128,128,138,118,128,118,128,118,128,118,118,118,118,118,128,128,148,128,168,168,148,198,158,198,168,188,158,168,128,128,118,78,88,58,68,38,48,48,58,48,78,88,98,118,128,138,148,158,168,168,168,168,168,168,158,148,138,148,108,118,118,98,98,108,88,98,98,88,108,98,108,108,118,108,128,118,138,128,128,128,138,128,128,138,118,128,118,128,108,128,118,118,138,138,128,168,148,158,188,158,188,168,168,158,158,128,138,108,88,88,58,68,48,58,48,58,58,78,88,98,118,128,138,148,158,168,158,168,158,168,158,158,138,148,138,108,138,108,98,108,118,78,108,88,98,88,98,108,98,108,118,128,108,138,118,138,118,138,128,128,138,118,138,118,128,118,128,118,128,138,128,148,168,138,178,168,168,178,168,168,158,148,128,128,98,98,78,68,58,48,58,58,58,68,88,88,108,118,128,138,138,158,158,168,168,178,158,178,158,138,168,118,128,118,108,98,108,88,88,88,78,98,78,98,98,108,108,128,118,138,138,138,148,128,148,128,138,128,128,128,118,118,128,118,118,128,128,138,158,138,168,168,158,178,168,168,158,158,138,128,108,98,88,68,68,48,58,48,58,58,68,78,88,108,118,138,138,158,148,178,168,168,168,168,158,148,158,118,138,108,118,98,108,88,88,98,88,98,88,108,98,118,108,128,118,128,128,128,138,128,138,128,138,118,138,128,128,128,128,128,118,148,128,158,138,148,168,158,168,168,178,158,158,148,138,118,108,98,78,68,58,58,48,48,58,68,78,78,98,108,118,138,148,158,158,168,168,168,158,188,138,158,158,128,128,118,108,88,108,78,98,68,98,88,88,98,108,108,108,138,128,148,128,158,138,138,148,138,128,128,138,118,128,118,128,118,118,12,128,148,128,158,168,158,168,168,178,148,158,148,138,108,108,88,78,58,58,58,38,58,58,68,68,98,108,118,118,138,148,148,168,168,168,168,158,168,158,138,148,138,128,118,108,108,98,88,98,88,78,98,88,88,108,108,108,128,128,138,138,148,148,148,138,148,148,138,128,138,128,118,138,118,118,148,128,138,158,158,158,168,158,168,158,148,148,128,118,108,88,68,68,58,48,48,48,58,68,68,88,98,108,128,138,148,148,168,168,168,168,178,168,158,168,148,138,128,128,98,108,98,88,78,78,88,78,88,88,98,98,118,118,128,138,148,148,148,158,148,148,138,148,128,138,118,128,128,118,138,138,128,148,158,148,168,168,168,168,158,148,138,118,108,98,78,68,58,48,48,48,58,58,68,78,98,108,118,138,148,158,158,178,168,168,178,178,158,158,158,138,128,118,118,88,98,88,78,78,78,88,78,88,98,108,108,128,128,138,148,148,158,148,158,158,138,148,138,138,118,118,138,108,118,148,118,128,158,148,158,168,168,158,168,148,158,128,108,118,88,78,68,68,48,58,48,58,68,68,88,98,108,118,148,138,158,158,168,178,168,168,178,158,148,158,118,128,118,98,88,88,78,78,78,78,88,78,98,108,108,118,138,138,138,158,158,158,158,158,148,148,148,128,128,128,128,108,138,128,118,158,148,148,158,168,148,168,158,148,138,118,118,98,78,68,68,48,48,58,58,58,68,88,98,108,118,138,148,148,178,158,188,168,178,178,158,148,148,138,108,138,98,98,88,88,68,78,88,78,98,88,118,108,118,128,148,138,148,158,148,158,148,148,138,148,128,128,128,118,128,108,138,128,128,148,158,148,148,178,148,158,158,148,138,118,108,98,78,68,78,48,48,58,58,58,78,88,98,108,118,138,148,148,178,158,178,178,158,178,168,148,148,148,108,118,118,88,78,88,78,68,88,78,88,88,108,108,118,128,138,138,138,168,148,148,158,158,138,138,148,128,128,128,118,138,128,128,148,148,148,158,168,148,158,158,138,128,128,108,88,88,68,68,48,48,58,58,58,78,88,98,108,128,138,148,158,168,168,178,198,148,178,178,138,138,158,118,88,138,78,78,88,88,48,88,88,68,98,98,118,108,138,138,158,148,158,158,158,158,158,148,128,138,138,128,108,158,118,108,158,158,128,158,188,138,148,168,148,118,128,118,88,78,68,68,48,48,58,58,58,68,98,98,108,128,148,138,158,178,168,178,198,168,168,188,148,128,148,128,78,108,108,48,68,88,58,48,98,78,78,108,128,108,138,168,148,158,168,168,148,158,158,138,138,148,128,108,148,128,108,148,158,128,138,188,148,128,168,158,108,118,128,88,68,78,78,48,48,68,58,58,78,88,88,108,128,138,148,158,168,168,178,198,168,168,178,158,128,148,128,78,98,98,58,48,88,58,48,88,98,78,98,138,128,138,168,168,158,168,178,158,158,158,148,128,138,128,128,128,128,128,148,158,138,158,168,148,138,158,138,108,108,108,78,58,78,58,48,48,68,58,68,88,98,98,118,148,148,158,168,178,188,178,178,188,168,148,158,138,98,108,108,68,58,78,68,48,68,88,78,88,118,118,128,148,158,158,168,168,168,168,158,148,148,148,128,128,128,128,118,128,138,138,138,148,158,148,148,148,148,118,118,108,88,78,68,58,48,58,58,58,68,78,88,108,118,128,148,158,168,168,188,188,168,178,178,148,138,148,118,88,98,88,58,68,68,58,58,78,88,88,108,118,138,148,158,158,168,178,168,168,168,158,148,138,138,128,118,128,118,118,128,138,138,148,158,148,148,148,138,128,118,108,98,78,78,68,58,58,58,58,68,78,88,98,118,128,138,148,168,178,168,178,188,168,158,158,148,118,108,108,88,68,78,58,58,68,78,78,98,108,118,138,148,148,158,168,168,168,168,168,158,148,148,138,128,118,118,118,118,128,128,138,138,148,158,158,148,148,148,128,118,108,98,78,68,68,58,58,58,58,68,78,88,108,118,128,148,158,168,178,188,178,178,178,168,148,138,128,108,98,88,78,58,58,58,58,68,78,88,108,118,128,148,158,168,168,178,178,178,168,168,148,138,128,118,118,118,118,118,128,138,138,148,158,158,148,158,148,138,128,118,98,88,78,68,58,58,58,58,68,78,88,98,118,128,148,158,168,178,178,188,188,178,168,158,148,128,108,98,88,68,68,58,58,58,68,78,88,98,118,138,148,158,168,178,178,178,178,168,158,158,148,128,128,118,118,118,118,118,128,138,148,148,158,158,158,148,138,128,118,108,88,78,68,58,48,48,58,58,68,78,98,108,128,138,158,168,178,188,198,188,188,178,158,148,138,118,98,78,68,58,58,48,58,58,68,78,98,118,128,148,158,168,178,178,188,178,178,168,158,148,138,128,118,108,108,118,118,128,128,138,148,158,158,158,158,148,138,128,118,98,88,68,58,48,48,48,48,58,68,78,98,118,138,148,168,178,188,198,198,188,188,178,158,138,128,98,88,68,58,48,48,48,48,68,78,88,108,128,148,158,178,178,188,188,188,178,168,158,148,138,118,108,108,98,108,108,118,128,128,148,148,158,168,168,158,148,138,128,108
};
const unsigned int sample_raw_len = sizeof(sample_raw);
void setup() {
pinMode(3, OUTPUT);
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS20);
}
void loop(){
play();
//delay(2000);
}
void play() {
for (int i = 0; i < sample_raw_len; i++) {
OCR2B = pgm_read_byte_near(&sample_raw[i]);
delayMicroseconds(125);
}
}
2. 録音
「録音する」といってもwavを作るとかではなく, 上記の「arduinoのみで再生する」を前提にした録音です. 必要であればPC等で適宜wav等に変換していただくということで...
ざっくりいって「analog-inの数値をSD-cardに記録するだけ」です.
- micをanalog-inに接続して記録
- ECM等だとオペアンプ+電圧シフトで2.5V中心の[0V, 5V]で電圧が揺れるようにする必要がある.
- analog-inの10bitの数値を8bit(1byteで記録するため)に変換してSD cardに記録
- printlnではなくwriteを利用しbyte(16進数. 00=0, 10=16 等)で記録する.
- これは再生時に使用するreadがASCIIで読み込むため. printlnで記録すると10進数で記録されるため1桁ずつreadした後に1つ数値として復元する処理が必要になってしまい, 再生速度に間に合わなくなってしまう.
マイク
ECM等のマイクだと本来, 音を0Vを中心に+/-で微振動するのみ. arduinoのanalog inに突っ込んでもノイズと変わらないので検知できない. 故に
- 信号増幅: マイクからの信号をオペアンプ等で100倍ほど増幅し, 振幅を5V程度にする
- 電圧シフト: analog inが正値のみを受け取るため, 2.5Vを中心に[0V, 5V]で揺れるようにレベルシフトする
を行う必要がある.
自分で回路を組んでも良いが,
等のオペアンプ付のマイクモジュールを利用すると楽.
(というか, 電気回路を自分で組むのはまだ上手くいってないです... どなたか教えて欲しい)
参照
マイクモジュール
回路全体
- arduinoとマイク(ECM)のテスト1
- Arduinoで遊ぼう - エレクトレット・コンデンサ・マイクでオーディオレベルメータを作る
- ESP8266とコンデンサマイクを接続してAnalogReadで録音してBluemixで音声認識させてデバイスを制御する
マイク
オペアンプ
- オペアンプで始めるアナログ回路
- オペアンプ回路の基本設計法
- DIY Tengu on a breadboard
- マイクアンプ基本形
- 386アンプをちょっと真剣に作ってみた
- LM386 パワーアンプIC
- 秋月 LM386 オーディオアンプIC NJM386BD
書き込み
SDカード
- HiLetgo Micro SD/ TF カードモジュール シールド モジュール 6 ピン SPI [並行輸入品]
- ArduinoでSDメモリカードを読み書きする
- SPI library
- Arduino で SPI 転送テスト
- SD Library
- Using the SD library to retrieve information over a serial port
- Using the SD library to read and write to a file on a SD card
arduino
ノイズ
配線
上記のモジュールであれば,
5V: VCC (arduino以外の5V電源[電池等]を使うとノイズが減ります)
GND: GND (arduino以外の5V電源[電池等]を使うとノイズが減ります)
A0: AUDIO
でOKです.
SD cardは, 以前の記事のように
11: DI (MOSI)
12: DO (MISO)
13: CLK (SCK)
9: CS (chip select)
GND: GND
5V: VCC
で繋げばOKです(以前の記事とくらべて, 配線の並びを個人的美的感覚の関係でCSを4から9に変えました).
code
#include <SD.h>
const int chipSelect = 9;
File dataFile;
int count = 0;
void setup(){
pinMode(SS, OUTPUT);
SD.begin(chipSelect);
}
void loop(){
count++;
if(count == 1){
openSDToRecord();
}else if(count >= 10000){
closeSD();
count = 0;
}else{
recordValue();
}
}
//##########################################################
void openSDToRecord(){
SD.remove("data.txt");
dataFile = SD.open("data.txt", FILE_WRITE);
}
void recordValue(){
int valuePre = analogRead(0);
int value = int(float(valuePre)/4.0);
dataFile.write(value);
}
void closeSD(){
if (dataFile) {
dataFile.close();
}
}
録音したdataの形(確認)
DATA.TXTという形で録音したデータを保存していますが, それをPCのテキストエディタで開いてみると
76a8 bc94 9e76 6c76 8a76 9476 626c 7680
948a 6c6c 626c 7680 7680 7680 8a9e 9e76
.
.
.
という感じで16進数で保存されているのがわかります.
3. 録音した音声を再生
配線
GND: スピーカーの-
3: スピーカーの+
11: DI (MOSI)
12: DO (MISO)
13: CLK (SCK)
9: CS (chip select)
GND: GND
5V: VCC
code
#include <SD.h>
const int chipSelect = 9;
void setup(){
Serial.begin(9600);
pinMode(3, OUTPUT);
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS20);
pinMode(SS, OUTPUT);
SD.begin(chipSelect);
Serial.println(OCR2B);
}
void loop(){
File dataFile = SD.open("data2.txt");
if (dataFile) {
while (dataFile.available()) {
OCR2B = dataFile.read();
delayMicroseconds(100);
}
//Serial.println(value);
dataFile.close();
}
Serial.println(OCR2B);
delay(2000);
}
4. 再生と録音をスイッチで制御
上記の再生と録音に加えてスイッチを組み合わせることで, 簡単なサンプラーを作ることができます.
(チチチ...という謎のノイズがマイク, スピーカーにのってしまっています. 調べ中)
配線
GND: スピーカーの-
3: スピーカーの+
5V: VCC (arduino以外の5V電源[電池等]を使うとノイズが減ります)
GND: GND (arduino以外の5V電源[電池等]を使うとノイズが減ります)
A0: AUDIO
11: DI (MOSI)
12: DO (MISO)
13: CLK (SCK)
9: CS (chip select)
GND: GND
5V: VCC
5V & GND & 5: 録音スイッチ
5V & GND & 6: 再生スイッチ
code
再生後に録音する際にFastPWMを直すために
OCR2B = 0;
を追加しています.
#include <SD.h>
const int chipSelect = 9;
const int pinRecordSW = 5;
const int pinPlaySW = 6;
const int pinPlaySound = 3;
int stateRecordSW;
int countRecordSW;
int statePlaySW;
int countPlaySW;
boolean isRecordMode;
boolean isPlayMode;
File dataFile;
void setup(){
Serial.begin(9600);
pinMode(pinPlaySound, OUTPUT);
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS20);
pinMode(SS, OUTPUT);
SD.begin(chipSelect);
//pinMode(pinRecordSW, INPUT_PULLUP);
pinMode(pinRecordSW, INPUT);
pinMode(pinPlaySW, INPUT);
stateRecordSW = 0;
countRecordSW = 0;
isRecordMode = false;
statePlaySW = 0;
countPlaySW = 0;
isPlayMode = false;
}
void loop(){
readPIN();
controlRecordMode();
if (isRecordMode){
recordValue();
//delay(1000);
}
controlPlayMode();
if (isPlayMode){
playValue();
}
}
//##########################################################
//##########################################################
//##########################################################
void controlRecordMode(){
if (stateRecordSW == 1){
countRecordSW++;
if (countRecordSW == 10){
if (!isRecordMode){
if (isPlayMode){
isPlayMode = false;
closeSD();
}
isRecordMode = true;
openSDToRecord();
if (!dataFile) {
openSDToRecord();
}
} else if (isRecordMode){
isRecordMode = false;
closeSD();
}
delay(1000);
}
} else {
countRecordSW = 0;
}
}
void controlPlayMode(){
if (statePlaySW == 1){
countPlaySW++;
if (countPlaySW == 10){
if (!isPlayMode){
if (isRecordMode){
isRecordMode = false;
closeSD();
}
isPlayMode = true;
openSDToPlay();
if (!dataFile) {
openSDToPlay();
}
} else if (isPlayMode){
isPlayMode = false;
closeSD();
}
delay(1000);
}
} else {
countPlaySW = 0;
}
}
void readPIN(){
stateRecordSW = digitalRead(pinRecordSW);
statePlaySW = digitalRead(pinPlaySW);
}
void openSDToRecord(){
SD.remove("data.txt");
dataFile = SD.open("data.txt", FILE_WRITE);
Serial.println("SD was opened to Record");
}
void openSDToPlay(){
dataFile = SD.open("data.txt");
Serial.println("SD was opened to Play");
}
void recordValue(){
//int value = analogRead(0);
int valuePre = analogRead(0);
int value = int(float(valuePre)/4.0);
dataFile.write(value);
//Serial.print("Record:");
//Serial.println(value);
}
void playValue(){
while (dataFile.available()) {
OCR2B = dataFile.read();
//delayMicroseconds(150);
delayMicroseconds(150);
//int value = dataFile.read();
//Serial.println(value);
}
isPlayMode = false;
closeSD();
}
void closeSD(){
if (dataFile) {
dataFile.close();
Serial.println("SD was closed");
}
OCR2B = 0;
}
動画