Имеется необходимость измерения спектральных параметров звука с нескольких микрофонов установленных на закрытом канале. В первую очередь интересно замерить задержку во времени прохождения звуковой волны между двумя и более микрофонами с высокой точностью.
При этом измерение необходимо осуществлять достаточно локально, то есть микрофон должен иметь малые размеры приёмника по сравнению с длиной волны.
Диапазон частот 100..2000 Гц (длины волн при нормальных условиях около 3-0.15м).
В качестве микрофонов могут быть использованы следующие микрофоны:
В связи с этим возникает вопрос выбора подходящего микрофона.
Подключение электретного микрофона к МК
Согласно https://qna.habr.com/q/669863, для схемы на рисунке 1 требуется резистор 2 кОм для 3,3в и конденсатор неполярный ёмкостью более 1 мкф.
Если методики и рекомендации по расчёту номинала резистора и конденсатора?
Микроконтроллер.
Были испытаны возможности двух разных микроконтроллеров без задействования всего потенциала за счёт использования оптимизация обращения к регистрам.
STM32F401RE, среда Mbed, библиотека Mbed v6.17, частота дискретизации составила 82370 Гц.
У данной реализации считывателя сигнала с микрофонов есть два ограничения, расширение которых является перспективным.
Сигналы с разных микрофонов, уже пробовал получать и обрабатывать в Matlab, кому нужно могу выложить код скрипта.
Спектры в векторном формате emf для лучшего качества сохранил в pdf.
По итогу есть ряд вопросов:
При этом измерение необходимо осуществлять достаточно локально, то есть микрофон должен иметь малые размеры приёмника по сравнению с длиной волны.
Диапазон частот 100..2000 Гц (длины волн при нормальных условиях около 3-0.15м).
В качестве микрофонов могут быть использованы следующие микрофоны:
- Электронные микрофоны малого диаметра (∅6-10 мм, соотношение диаметра и длины волны в худшем случае 15), пример EM6050;
- Микрофоны на технологии MEMS, (∅1 мм, соотношение диаметра и длины волны в худшем случае 150), пример SMD02718C4O4C-38VSM2718AB-N30-B3F;
- Цифровые микрофоны на технологии MEMS со в строенным усилителем и АЦП, пример im69d130.
- Пьезоэлектрические датчики (Пьезоэлектрические излучатели) (∅26мм, соотношение диаметра и длины волны в худшем случае 5,7), пример
В связи с этим возникает вопрос выбора подходящего микрофона.
Подключение электретного микрофона к МК
Согласно https://qna.habr.com/q/669863, для схемы на рисунке 1 требуется резистор 2 кОм для 3,3в и конденсатор неполярный ёмкостью более 1 мкф.

Микроконтроллер.
Были испытаны возможности двух разных микроконтроллеров без задействования всего потенциала за счёт использования оптимизация обращения к регистрам.
- Atmega2560 в составе Arduino mega (16 МГц);
- STM32F401RE в составе STM NUCLEO (84 МГц);
C++:
#define LEN_SMPL 3000
int* sample = new int[LEN_SMPL];
int* sample2 = new int[LEN_SMPL];
int n = 0, sm = 0;
unsigned long t1 = 0, t2 = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(2000000); ///921600
analogReference(INTERNAL1V1);
}
void loop() {
t1 = micros();
for (n = 0; n < LEN_SMPL; n++) {
sample[n] = analogRead(A0);
sample2[n] = analogRead(A1);
}
t2 = micros();
Serial.println("Time read " + String(t2 - t1));
t1 = micros();
/*
for (n = 0; n < LEN_SMPL; n++) {
Serial.println(analogRead(A0));
}
t2 = micros();
Serial.println( String(t2 - t1));
//Serial.println("Time rw " + String(t2 - t1));
//delay(10000);
// for (n = 0; n < LEN_SMPL; n++) {
// sm = analogRead(A0);
// Serial.write(sm, sizeof( sm ));
// }
// t2 = micros();
// Serial.println("Time rwrite" + String(t2 - t1));
// Serial.println("sizeof" + String(sizeof( sm )));
// delay(10000);
*/
t1 = micros();
for (n = 0; n < LEN_SMPL; n++) {
Serial.print(sample[n]);
Serial.print(sample2[n]);
}
t2 = micros();
Serial.println("\nTime write " + String(t2 - t1));
// put your main code here, to run repeatedly:
}
C++:
/* mbed Microcontroller Library
* Copyright (c) 2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*/
#include "mbed.h"
#include "mbed_mem_trace.h"
#include <string>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#defineLEN_SMPL10000
// Blinking rate in milliseconds
#defineBLINKING_RATE5000ms
#definemicrosus_timestamp_t
Timer timer;
AnalogIn ain0(A0);
AnalogIn ain1(A1);
AnalogIn vrefint(ADC_VREF);
AnalogIn tempint(ADC_TEMP);
BufferedSerial pc(USBTX, USBRX,115200);
uint64_t t1 = 0, t2 = 0;
uint16_t* sample0 = new uint16_t[LEN_SMPL];
uint16_t* sample1 = new uint16_t[LEN_SMPL];
int n = 0, sm = 0;
Kernel::Clock::time_point start_time,end_time;
int main()
{
mbed_stats_heap_t heap_stats;
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
// DWT->LAR = 0xC5ACCE55;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
printf("Hello, World!\n");
printf("Vref(f): %f, Vref : %u, Temperature : %u\r\n",
vrefint.read(), vrefint.read_u16(), tempint.read_u16());
// Initialise the digital pin LED1 as an output
DigitalOut led(LED1);
while (true) {
uint32_t start_cycles = DWT->CYCCNT;
start_time = Kernel::Clock::now();
for (n = 0; n < LEN_SMPL; n++) {
sample0[n] = ain0.read_u16();
sample1[n] = ain1.read_u16();
}
end_time = Kernel::Clock::now();
uint32_t end_cycles = DWT->CYCCNT;
auto elapsed_time = end_time - start_time;
ThisThread::sleep_for(100ms);
printf("Time read: %lld milliseconds\n", elapsed_time.count());
// Вычисляем время выполнения в тактах
uint32_t elapsed_cycles = end_cycles - start_cycles;
printf("Time read: %lu CPU cycles\n", elapsed_cycles);
// Если нужно перевести такты в микросекунды:
uint32_t cpu_frequency = SystemCoreClock; // Частота процессора в Гц
float elapsed_time_us = (float)elapsed_cycles / (cpu_frequency / 1000000.0f);
printf("Time read: %f microseconds\n", elapsed_time_us);
printf("cpu_frequency %lu \n", cpu_frequency);
mbed_stats_heap_get(&heap_stats);
printf("Heap size: %lu / %lu bytes max %lu \r\n", heap_stats.current_size, heap_stats.reserved_size, heap_stats.max_size);
t1 = micros();
led = !led;
//ThisThread::sleep_for(BLINKING_RATE);
start_time = Kernel::Clock::now();
for (n = 0; n < LEN_SMPL; n++) {
printf("%d %d\n",sample0[n],sample1[n]);
}
end_time = Kernel::Clock::now();
elapsed_time = end_time - start_time;
printf("\nTime write: %lld microseconds\n", elapsed_time.count());
}
}
У данной реализации считывателя сигнала с микрофонов есть два ограничения, расширение которых является перспективным.
- Увеличение частоты дискретизации, за счёт оптимизации считывания сигнала;
- Уменьшение времени вывода считанных цифровых значений в com port, либо за счёт повышения скорости передачи у серийного порта, либо за счёт отказа от кодирования чисел в ASCII.
Сигналы с разных микрофонов, уже пробовал получать и обрабатывать в Matlab, кому нужно могу выложить код скрипта.
Спектры в векторном формате emf для лучшего качества сохранил в pdf.
По итогу есть ряд вопросов:
- Какой микрофон лучше использовать для имеющейся задачи?
- Если методики и рекомендации по расчёту номинала резистора и конденсатора при подключении электретного микрофона?
- Как увеличить частоту дискретизации и стоит ли?
- Как увеличить скорость передачи данных на ПК?