16
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

sound with arduino

Last updated at Posted at 2018-01-15

arduinoで音を制御(録音, 再生etc)したい時用の個人的まとめです.

最終的には録音/再生ができるようにしています.
動画

setting_rec-play.jpg

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_test.ino
//『 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の音源を作る

作成例

  1. test.wavを用意する
  2. rawにformat変換
    audacityでサンプリング周波数8000Hz, その他の非圧縮ファイル, RAW(header-less), Unsigned 8-bit PCMと指定してtest.rawを作る
  3. ターミナルでxxd -i sample.rawを実行して数値に変換する
  4. 0x7f, 0x80, 0x7f, ...みたいな数値列(16進数)ができた

最終的な数値は127, 128, 127, ...のように10進数であってもOK

code

(私の「あいう」の声が無限に流れますが悪しからず...)

sound-out_arduino.ino
#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]で揺れるようにレベルシフトする

を行う必要がある.
自分で回路を組んでも良いが,

等のオペアンプ付のマイクモジュールを利用すると楽.
(というか, 電気回路を自分で組むのはまだ上手くいってないです... どなたか教えて欲しい)

参照

マイクモジュール

回路全体

マイク

オペアンプ

書き込み

SDカード

arduino

ノイズ

配線

上記のモジュールであれば,

マイク.
 5V: VCC (arduino以外の5V電源[電池等]を使うとノイズが減ります)
GND: GND (arduino以外の5V電源[電池等]を使うとノイズが減ります)
 A0: AUDIO

でOKです.
SD cardは, 以前の記事のように

SD_card.
 11: DI (MOSI)
 12: DO (MISO)
 13: CLK (SCK)
  9: CS (chip select)
GND: GND
 5V: VCC

で繋げばOKです(以前の記事とくらべて, 配線の並びを個人的美的感覚の関係でCSを4から9に変えました).

code

rec.ino
#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のテキストエディタで開いてみると

DATA.TXT
76a8 bc94 9e76 6c76 8a76 9476 626c 7680
948a 6c6c 626c 7680 7680 7680 8a9e 9e76
.
.
.

という感じで16進数で保存されているのがわかります.

3. 録音した音声を再生

配線

スピーカー.
GND: スピーカーの-
  3: スピーカーの+
SD_card.
 11: DI (MOSI)
 12: DO (MISO)
 13: CLK (SCK)
  9: CS (chip select)
GND: GND
 5V: VCC

code

sound-out_sd-rec-data.ino
#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
SD_card.
 11: DI (MOSI)
 12: DO (MISO)
 13: CLK (SCK)
  9: CS (chip select)
GND: GND
 5V: VCC
スイッチ.
5V & GND & 5: 録音スイッチ
5V & GND & 6: 再生スイッチ

setting_rec-play.jpg

code

再生後に録音する際にFastPWMを直すために

  OCR2B = 0;

を追加しています.

rec-play.ino
#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;
}

動画

16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?