■考察■
今までも動いていたけどノイズに埋もれてわからなかった、というのが真相だと思います。動かなかったバージョンでは100-10000回のカウントを終えるとLoopを抜けていました。これはESP-WROOM-02にはWDTがついていて、約1秒間loop()から抜けないとリセットがかかるのです。
何となくloop()抜けてもすぐに帰ってくるんだろ、ぐらいに考えていたんですが、これが想定以上に大きくて、抜けるたびに処理が止まってノイズとなっていました。loopから抜けるのをやめてESP.wtdFeed()にしたところ、かすかなノイズは入りますがマイクの前の音声がちゃんとADCから出力されるようになりました。
■ソース■
loopの値は100(サンプリング周波数10khz)ぐらいが良いようで、10(100khz)だとDACに出力するためのブランクの比率が著しいノイズとなり1000(1khz)にすると割れて何が何だか、という感じでした。また、countとして++だけでなく--も入れてみたところ、音量がかなり大きくなりました。100の場合で値は-100〜+100まで振れるので、精度は8bit、速度は10khzということになります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ESP_Digital_MIC_To_DAC | |
// by koichi kurahashi 2016-06-08 | |
// | |
// read SPM0405HD4H and write to MCP4921 | |
// | |
// Thanks: | |
// http://www.pwv.co.jp/~take/TakeWiki/index.php?arduino%2FDACを試す | |
// arduino/DACを試す | |
// | |
#include <Arduino.h> | |
#include <SPI.h> | |
extern "C" { | |
#include <user_interface.h> | |
} | |
// | |
// SPM0405 | |
// | |
#define kOutClock 5 // to CLK | |
#define kInSignal 4 // from DAT | |
// L/R is connected to GND -> down edge mode | |
// | |
// DAC MCP4921 | |
// | |
// GPIO 13 - Pin 5 SDI | |
// 14 - 4 SCK | |
// 15 - 3 !CS | |
// 16 - 8 LDAC | |
// 1, 9, 11, 13 - Vcc | |
// 12 - Gnd | |
// 1 - 0.1uF - 13 | |
// | |
const int kPinLatchDAC = 16; | |
void setup() { | |
// put your setup code here, to run once: | |
Serial.begin(230400); | |
pinMode(kOutClock, OUTPUT); | |
pinMode(kInSignal, INPUT); | |
setupDac(); | |
} | |
// DAC init | |
// | |
void setupDac() { | |
// set pinMode | |
pinMode(kPinLatchDAC, OUTPUT); | |
pinMode(SS, OUTPUT); | |
// init SPI for DAC | |
SPI.begin(); | |
SPI.setBitOrder(MSBFIRST); | |
SPI.setClockDivider(SPI_CLOCK_DIV8); | |
SPI.setDataMode(SPI_MODE0); | |
} | |
// | |
// loop | |
// | |
const int kMaxLoop = 100; | |
const int kMaxDAC = 4095; | |
const int kMaxRate = 2000 / kMaxLoop; | |
const int kMaxOffset = kMaxDAC / 2; | |
const int kOutLoop = 10000 / kMaxLoop; | |
long a, b; // dummy wait | |
void loop() { | |
// int min = 32767; | |
// int max =-32767; | |
while (1) { | |
for (int i = 0; i < kOutLoop; i++) { | |
int count = 0; | |
for (int l = 0; l < kMaxLoop; l++) { // 25n | |
digitalWrite(kOutClock, LOW); // low 212.5n | |
a++; b++; | |
if (digitalRead(kInSignal) == HIGH) { | |
count++; | |
} | |
else { | |
count--; | |
} | |
if (l < kMaxLoop - 1) { | |
digitalWrite(kOutClock, HIGH); // high=225.0n | |
digitalWrite(kOutClock, HIGH); // high=225.0n | |
} | |
} | |
count = count * kMaxRate + kMaxOffset; | |
outputToDAC(count); | |
// if (count > max) max = count; | |
// if (count < min) min = count; | |
} | |
// Serial.print(min); | |
// Serial.print(","); | |
// Serial.println(max); | |
ESP.wdtFeed(); | |
} | |
} | |
void outputToDAC(uint16_t inData) { | |
inData = inData & 0xfff; | |
digitalWrite(kPinLatchDAC, HIGH); | |
digitalWrite(SS, LOW); | |
SPI.transfer16(inData | 0x3000); | |
digitalWrite(SS, HIGH); | |
digitalWrite(kPinLatchDAC, LOW) ; | |
} |
お騒がせしました&ありがとうございました>電子工作部各位殿
もうちょっと高速のCPUが使えれば、DAC出力その他のための中断を回避できるので、もっといい音になると思います。現状で160Mhzクロックの32bit CPUなので、これより上のCPUを用意するよりはFPGAで作るべきものだと思います。約400円で専用チップ売ってるんですけどねw
ちなみにマイクの性能には「14bit相当・10khz」とのこと。うーん、どういう演算処理をすればそういう信号が得られるのでしょう。思いついたらまた試してみます。
■使用部品紹介という名のCM■
今回の実験では、![]() |
同社サイトより |
スイッチサイエンス「Board1 ver.1.0」ESP-WROOM-02搭載モジュール、
同社サイトより |
同社サイトより |
を使用しました。
マイクモジュールとアンプへの3v3はBoard1搭載の安定化電源から供給しています。何かと電源にシビアなESPですが、(プログラムのバグ以外では)安定して動作しています。
タフな電源にしといてよかった…と設計者は胸をなでおろすのであった(完)。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。