前回、SPRESENSEのADCで心拍データをキャプチャしましたが、DC取り込みなので体動で大きくレベルが変化していました。そこで、今回はSPRESENSEのマイク入力に心拍センサーを接続してデータを取り込んでみました。マイク入力はAC入力なので電気的にDC成分をカットできます。





SPRESENSEチップのデータシートを見るとマイク入力のレンジは0.9V(±0.45V)なので、ADCの0.7Vよりレンジが広く優秀です。





試しに、モノラル16k/16bitをSDカードに録音?してみたのですが、とにかくデータが取れすぎる。心拍センサーのノイズを拾いまくりです。





なので、冒頭の動画は1024サンプルの平均をとってさらに平均をとったデータの128サンプルで平均をとるという贅沢すぎるデータ処理をしています。



#include <Audio.h>

AudioClass *theAudio;

void setup() {
int ret;

Serial.begin(115200);
Serial.println("Init Audio Library");
theAudio = AudioClass::getInstance();
theAudio->begin();

Serial.println("Init Audio Recorder");
/* Select input device as AMIC */
theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);

theAudio->initRecorder(AS_CODECTYPE_PCM, "/mnt/spif/BIN", AS_SAMPLINGRATE_16000, AS_CHANNEL_MONO);

Serial.println("Capturing start!");
theAudio->startRecorder();

}

#define AVE_WINDOW 128
int16_t average[AVE_WINDOW];

static int num = 0;
void loop()
{
static const int32_t buffer_sample = 1024;
static const int32_t buffer_size = buffer_sample * sizeof(int16_t);
static char frame[buffer_size];
uint32_t read_size;

int err = theAudio->readFrames(frame, buffer_size, &read_size);
if (err != AUDIOLIB_ECODE_OK && err != AUDIOLIB_ECODE_INSUFFICIENT_BUFFER_AREA) {
printf("Error err = %d\n", err);
sleep(1);
theAudio->stopRecorder();
exit(1);
}

int16_t *buf = (int16_t*)frame;
int32_t sum = 0;
for (int i = 0; i < buffer_sample; ++i) {
sum += buf[i];
}

average[num] = sum / buffer_sample;
if (++num >= AVE_WINDOW) num = 0;

if (num == 0) {
sum = 0;
for (int i = 0; i < AVE_WINDOW; ++i) {
sum += average[i];
}
int16_t output = sum / AVE_WINDOW;
Serial.println(output);
}
}



マイク入力はゲインも設定できるので、AC限定ですがADCとしては非常に優秀です。皆さんもつかってみてはいかがでしょう?







SONY SPRESENSE メインボード CXD5602PWBMAIN1

  • 出版社/メーカー: スプレッセンス(Spresense)
  • メディア: Tools & Hardware



SONY SPRESENSE 拡張ボード CXD5602PWBEXT1

  • 出版社/メーカー: スプレッセンス(Spresense)
  • メディア: Tools & Hardware