用户工具

站点工具


knowledge:electronic:2019032101

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
knowledge:electronic:2019032101 [2023/07/06 08:12] – [“Sound detection” module based on an LM393] obknowledge:electronic:2019032101 [2023/07/07 05:32] (当前版本) – [Summary] ob
行 40: 行 40:
 我从同一家当地商店买了这个。这一款与HXJ-17类似,但更简单。它有一个一圈电位器,没有模拟输出。让它有助于了解是否有响亮的声音。 我从同一家当地商店买了这个。这一款与HXJ-17类似,但更简单。它有一个一圈电位器,没有模拟输出。让它有助于了解是否有响亮的声音。
  
-===== Analyzing analog input =====+===== 分析模拟输入 =====
  
-As the first step, I would suggest you take some time to analyze the analog output of your module to see the baseline and amplitude. I have used the following Arduino function to gather data:+作为第一步,我建议您花一些时间分析模块的模拟输出,以查看基线和幅度。我使用以下 Arduino 函数来收集数据
  
 <code> <code>
行 74: 行 74:
 </code> </code>
  
-You can then make some sounds at different volume levels and see how your average, min, max and span values respond. Looking at the result you might see that you need to adjust the gain potentiometer such that you utilize the max span for your sound levels while not overdoing it so not to clip your signal.+然后,您可以以不同的音量发出一些声音,并查看平均值、最小值、最大值和跨度值的响应情况。查看结果,您可能会发现需要调整增益电位器,以便利用声级的最大跨度,同时不要过度使用,以免削波信号。 
 +===== 使用 3.3V 参考电压和自由运行实现精确采样 ===== 
 +Arduino 的 AnalogRead 功能可以轻松获取模拟引脚的数字值。它是在考虑单个样本收集的情况下实施的。在对声音进行采样时,以恒定的速率采样并准确地采样每个样本非常重要。为了实现这两个属性,我们进行以下操作。
  
-===== Implementing accurate sampling with 3.3V reference and free running ===== +首先,我们将配置 ADC 以使用 3.3V 作为模拟参考电压。原因是 3.3V 通常比 5V 更稳定。5V 电压可能会上下波动,尤其是当 Arduino 从 USB 连接获取电源时。3.3V 来自 Arduino 板上的线性稳压器,可以连接到 Arduino 的 ARef 引脚。这会校准我们的 ADC,将 至 3.3V 范围的模拟输入映射到 至 1024 范围的数字值。为了在电子层面实现这一点,您需要为模块提供 3.3V 电压并将 Arduino ARef 引脚连接到 3.3V。确保您的模块能够在此电压下运行。 
- +使用以下代码来配置此模式:
-The analogRead function of Arduino makes it simple to get a digital value of an analog pin. It was implemented with single sample collection in mind. When sampling sound it is important to take our samples at a constant rate and to take each sample accurately. To achieve these two properties we will change a couple of things. +
- +
-First, we will configure the ADC to use 3.3V as the analog reference voltage. The reason for this is that the 3.3V is usually more stable than the 5V. The 5V can fluctuate up and down especially when the Arduino is getting its power from the USB connection. The 3.3V is coming from a linear regulator on the Arduino board and can be connected to the ARef pin of the Arduino. This calibrates our ADC to map the to 3.3V range of the analog input to the to 1024 range of the digital values. For this to happen on the electronics level you need to feed your module with 3.3V and to connect the Arduino ARef pin to 3.3V. Make sure that your module is capable of operating at this voltage. +
- +
-Use the following code to configure this mode:+
  
 <code> <code>
行 88: 行 85:
 </code> </code>
  
-Second, we will configure the ADC to work in free-running” mode and read the sample values directly from internal registers, bypassing analogRead. As mentioned, analogRead is designed to read one value at a time and will perform initialization of the ADC for each read, something that we better eliminate. This will allow us to get a sampling rate that is more predictable.+其次,我们将配置 ADC 自由运行模式工作,并直接从内部寄存器读取样本值,绕过analogRead。如前所述,analogRead 被设计为一次读取一个值,并且将为每次读取执行 ADC 的初始化,我们最好消除这种情况。这将使我们能够获得更可预测的采样率。
  
-Setup free-running” mode with this code:+使用以下代码设置自由运行模式:
  
 <code> <code>
行 103: 行 100:
 </code> </code>
  
-Read a batch of samples with this code:+使用以下代码读取一批示例:
  
 <code> <code>
行 117: 行 114:
 </code> </code>
  
-Third, you can also adjust the speed of the ADC. By default the ADC is running at 1:128 of the MCU speed (mode #7). Each sample takes the ADC about 13 clock cycles to get processed. So by default we get 16Mhz/128/13=9846Hz sampling. If we want to sample at double the rate we can change the divider to be 64 instead.+第三,还可以调整ADC的速度。默认情况下,ADC 以 MCU 速度的 1:128 运行(模式 #7)。每个样本需要 ADC 大约 13 个时钟周期来处理。所以默认情况下我们得到 16Mhz/128/13=9846Hz 采样。如果我们想以双倍的速率采样,我们可以将分频器更改为 64
  
-Here is an example of how to set divider to 32 (mode #5) which equals a sampling rate of 16Mhz/32/13~=38Khz:+以下是如何将分频器设置为 32(模式#5)的示例,它等于 16Mhz/32/13~=38Khz 的采样率:
  
 <code> <code>
行 133: 行 130:
 </code> </code>
  
-You can see all three of these code snippets implemented together in the source code of the project at github.+您可以在 github 项目的源代码中看到所有这三个代码片段一起实现。
  
-With this logic in place we can get decent waveform data for the Arduino to process.+有了这个逻辑,我们就可以获得合适的波形数据供 Arduino 处理。
  
-===== Sound level measurement =====+===== 声级测量 =====
  
-==== Theory ====+==== 理论 ====
  
-The sound level is defined as the amplitude of the waveform and can be measured per set of samples which represent a part of a signal.+声级定义为波形的幅度,可以根据代表信号一部分的样本集进行测量。
  
 {{:knowledge:electronic:pasted:20190321-124543.png|Peak Envelopes}} {{:knowledge:electronic:pasted:20190321-124543.png|Peak Envelopes}}
  
-For an ideal sine signal, the amplitude would be the max sample, but in practice it is easy for some samples to be outliers and to affect the max value significantly. For this reason it is more practical to use a metric that takes all the sample values into account. You can use an average, but it is more common to use Root Mean Square (RMS) which will give more weight” to  higher values.+对于一个理想的正弦信号来说,振幅应该是最大的样本值。但在实际应用中,有些样本可能成为异常值,并且会对最大值产生显著影响。因此,更实际的做法是使用一个考虑所有样本值的度量标准。你可以使用平均值,但更常见的是使用均方根(RMS),它会给较高的值赋予更多的权重
  
-The relationship between amplitude and RMS for sine waves is known and is amplitude= sqrt(2)*RMS. If we assume that a sound waveform is similar to a sine waveform we can use this relationship to estimate a stable amplitude based on an RMS value that we calculate.+振幅和均方根(RMS)之间的关系是已知的,可以表示为振幅= sqrt(2)*RMS。如果我们假设声音波形与正弦波形相似,我们可以利用这个关系来基于计算得到的均方根值估计一个稳定的振幅。
  
 {{:knowledge:electronic:pasted:20190321-124605.png|Waveform with an RMS envelope}} {{:knowledge:electronic:pasted:20190321-124605.png|Waveform with an RMS envelope}}
  
-The values we are dealing with are relative and not absolute. After all we are using some value of gain to tune the volume levels to our digital 10bit range. It is very common to work with relative values when processing sound waveforms. The volume is then measured as a ratio from some other reference point” value. A common unit used to express the ratio is decibel (dB). Resulting a formula:+我们处理的数值是相对值,而不是绝对值。毕竟,我们使用一定的增益值来调整音量水平到我们的10位数字范围内。处理声音波形时,使用相对值是非常常见的。音量通常被测量为与其他参考点值的比率。用于表达该比率的常用单位是分贝 (dB)。得出一个公式:
  
 dB=10*log10(v/v0) dB=10*log10(v/v0)
  
-Where dB is the level is dB units, is the sample value and v0 is the reference value.+其中dB为电平,单位为dBv为样本值,v0为参考值。
  
-Since sound pressure is a field quantity a ratio of squares is used and the value “2” in the log becomes “20” [due to log(a^b)=b*log(a)] :+由于声压是一个场量,因此使用平方比,并且对数中的值“2”变为“20”[由于 log(a^b)=b*log(a)]
  
 dB=20*log10(v/v0) dB=20*log10(v/v0)
  
-I was trying to achieve relative measurements, I chose v0 as the max possible amplitude (1024/for a 10bit ADC). This yields dB measurements which are specific to a certain gain and my device, but as long as the gain remains fixed, I can take several measurements and make valid comparisons between them. If you are looking to measure absolute sound levels you would need to calculate your level relative to a standard agreed sound pressure baseline value of 20 micropascals, which is the typical threshold of perception of an average human. Practically, this is typically done by attaching a special calibration device to the microphone. The device generates sound at a fixed dB level and you can adjust your calculations such that your dB measurement matches the dB value of the calibration device.+我试图实现相对测量,我选择 v0 作为最大可能幅度(10 位 ADC 为 1024/2)。这会产生一个特定增益于我的设备的 dB 测量值,只要增益保持固定,我就可以进行多次测量并在它们之间进行有效比较。如果您想要测量绝对声级,你需要将你的水平相对于一个标准约定的声压基准值进行计算,这个基准值通常是20微帕,这是普通人感知的典型阈值。实际上,这通常是通过将特殊的校准设备连接到麦克风来完成的。该设备生成固定分贝级别的声音,您可以调整计算,使 dB 测量结果与校准设备的 dB 值相匹配。
  
-When using a reference value that is higher than your samples (max amplitude), your dB values would be negative and smaller as you approach the max.+当使用低于样本(感知阈值)的参考值时,您的 dB 值将是正值,并且随着接近最大值而变大。
  
-When using a reference value that is lower than your samples (threshold of perception), your dB values would be positive and larger as you approach the max.+有几个因素会影响实践中的测量而使这一情况变得更加复杂。首先,人耳对所有频率的敏感度并不相同。通常会对不同频段应用不同的权重。一种这样的测量单位被称为dBA,但还有其他一些略微不同的权重。其次,您的麦克风可能不会对所有频率都具有相同的灵敏度。第三,您的扬声器可能无法以相同的精确水平再现所有频率。这些复杂性需要非常精确和昂贵的设备以及特殊的校准程序,以便能够根据标准正确测量声级。要知道,这篇文章介绍的测量声级的能力非常有限,仅适合粗略的相对测量。 
 +===== 执行 =====
  
-To make this even more complex, several factors affect measurement in practice. First, the human ear is not equally sensitive to all frequencies. It is typical to apply different weights to different frequency ranges. One such a unit of measurement is called dBA, but there are others with slightly different weights. Second, your microphone might not have equal sensitivity to all frequencies. Third, your speakers might not have equal ability to reproduce all frequencies at the same exact level. These complexities require very accurate and expensive equipment together with special calibration procedures to be able to measure sound levels correctly per standards. You need to understand that your ability to measure sound level with the setup described here is pretty rudimentary and suitable for rough relative measurements only. +让我们回顾一下,我们的值是 到 1024,代表 [-max,max],其中 1024/2=512 “0”。我们将检索并处理样本一段时间,其中标准定义 秒为,125 毫秒为。对于每个样本,我们将测量从“0”到样本值的距离,即该样本的幅度。然后我们可以对最大值、平均值和 RMS 进行简单的计算。我们标度上的值可以归一化成最大幅度的百分比或使用 dB 或两者兼而有之。这是相关的代码示例:
- +
-===== Implementation ===== +
- +
-Let’s recap that our values are to 1024 which stand for [-max,max] with 1024/2=512 being “0”. We will retrieve and process sample for some time, where the standard defines second as Slow” and 125ms as Fast. For each sample, we will measure the distance from the “0” to the sample value, which is the amplitude of that sample. Then we can do simple calculations for max, average and RMS. The values on our scale can be normalized” to percentage of max amplitude or using dB or both. Here is a relevant code sample:+
  
 <code> <code>
行 222: 行 216:
 </code> </code>
  
-So now with proper module and calibration you can measure sound level of different events or devices and compare them one to the other.+因此,现在通过适当的模块和校准,您可以测量不同事件或设备的声级,并将它们相互比较。
  
-===== Frequency analysis with FHT =====+===== 使用 FHT 进行频率分析 =====
  
-What if you want to break” the sound into individual frequencies and measure or visualize each individual frequency? Can this be done with Arduino? The answer is that it can be done relatively easily thanks to some existing libraries. To turn signals from a time domain to a frequency domain you would generally use a Fourier transform. Such transforms are used for signals of different types, sound, images, radio transmissions, etc. Each signal type has its own properties and the transform that best suits a sound signal is the Discrete Hartley Transform (DHT). DHT will work with discrete, real values which form our waveform. To implement DHT we will use Fast Hartley Transform (FHT) and specifically the ArduinoFHT library.+如果您想将声音分解为单独的频率并测量或可视化每个单独的频率,该怎么办?这可以用Arduino来完成吗?答案是肯定的,使用一些现有的库,这可以相对容易地完成。要将信号从时域转换到频域,通常会使用傅里叶变换。这种变换用于不同类型的信号,声音、图像、无线电传输等。每种信号类型都有其自己的属性,最适合声音信号的变换是离散哈莱特变换(DHT)。DHT 将使用形成波形的离散真实值。为了实现 DHT,我们将使用快速莱特利变换 (FHT),特别是ArduinoFHT 
  
-The Arduino FHT library works with vectors of 16 to 256 samples. This size is denoted as N. In this project I will be using N=256 to achieve maximum resolution, but you may use smaller values if you are short on memory or processing power.+Arduino FHT 库可处理 16 至 256 个样本的向量。该大小表示为 N。在这个项目中,我将使用 N=256 来实现最大分辨率,但如果内存或处理能力不足,您可以使用较小的值
  
-First, the algorithm takes real numbers and results in N/2 complex numbers. Then we can pass the data to another function to calculate the magnitude of the complex numbers to get N/2 bins. In the end we get N/2 bins, each covering a frequency range of sampling_rate/N Hz. The highest value of the last bin will be sampling_rate/. The reasons for this relate to signal processing theory, specifically aliasing and Nyquist law. In practice, if you want to avoid any strange effects, such as higher frequencies folding” over lower frequencies, you will need to make sure to use a sampling rate that is twice the highest frequency you expect to have in the sound signal. Otherwise you are not sampling fast enough. You should also not over sample, as it will result in low ADC accuracy and wasting of FHT bins on ranges that don’t appear in the signal. I found the value of 20Khz to be a good upper frequency based on the range of my microphone and on the range of typical human hearing. As a result the, sampling at 38.4Khz (divider=32) seemed optimal. +首先,该算法接受N个实数,并得到N/2个复数。然后我们可以将数据传递给另一个函数,计算复数的幅度,得到N/2个频率区间。最终,我们得到N/2个频率区间,每个区间覆盖sampling_rate/N Hz的频率范围。最后一个区间的最大值将为sampling_rate/2。这与信号处理理论,特别是混叠和奈奎斯特定律有关。在实践中,如果你想避免任何奇怪的效果,比如更高频率的折叠到较低频率上,你需要确保使用的采样率是期望声音信号中最高频率的两倍。否则,你的采样速度不够快。你也不应该过度采样,因为这会导致低ADC精度,并浪费在信号中不存在的FHT频率区间。我发现基于我的麦克风范围和典型人类听力范围,20KHz的值是一个不错的上限频率。因此,以38.4KHz(分频器=32)进行采样似乎是最佳选择。 
- +因此对于N=256和采样率为38.4KHz,我们得到128个150Hz的频率区间,其中第一个区间保存了0-150Hz的幅度值,最后一个区间保存了19050-19200Hz的幅度值。现在我们可以专注于我们感兴趣的特定频率区间,通过串行连接发送所有频率区间的值,存储这些值,以某种方式显示它们等等。 
-So for N=256 and sampling_rate=38.4Khz we get 128 150hz bins with the first been holding the magnitude value of 0-150hz and the last bin holding the magnitude value of 19050-19200hz. We can now focus on specific bins that interest us, send the values of all the bins over serial connection, store the values, display them in some way, etc. +使用数据的有趣方法之一是使用分析器进行可视化,尤其是在故障排除和开发时。将以下 FHT 示例代码加载到 Arduino 或根据您的需要进行调整。它获取样本,对数据运行 FHT,并通过串行以二进制形式发送。您的 Arduino 应连接到运行 Processing 开发环境的计算机。在处理中,加载“FHT 128 通道分析器项目。我必须对项目进行更改以使其与Processing 3.0 兼容。为此,将对“size”函数的调用从“setup”函数中移至名为“settings”的新函数。
- +
-One of the fun ways to use the data, especially when troubleshooting and developing is to visualize with an analyser. Load the following FHT example code to the Arduino or adapt it to your needs. It gets the samples, runs FHT on the data and sends it in binary form over serial. Your Arduino should be connected to a computer running Processing development environment. In Processing, load the “FHT 128 channel analyser” project. I had to make a change to the project to make it compatible with Processing 3.0 . To do so, move the call to “size” function from within the “setup” function to a new function called “settings”.+
  
 {{:knowledge:electronic:pasted:20190321-124951.png|Analyzer}} {{:knowledge:electronic:pasted:20190321-124951.png|Analyzer}}
  
-Another way to analyze the data is for the Arduino to send it over serial in textual form, let it run for some time, then copy it from the serial monitor and paste it in a spreadsheet. For example using a code that is similar to this: +分析数据的另一种方法是 Arduino 以文本形式通过串行发送数据,让它运行一段时间,然后从串行监视器复制数据并将其粘贴到电子表格中。例如,使用类似于以下的代码:
 <code> <code>
 void MeasureFHT() void MeasureFHT()
行 273: 行 264:
 </code> </code>
  
-Then you can format the data in a spreadsheet, such as Excel, as a “3-D Surface” mesh graph. For example, see a graph of a Frequency Sweep from 1hz to 5000hz as captured and analyzed by the Arduino and FHT+然后,您可以将电子表格(例如 Excel)中的数据格式化为“3-D 曲面网格图。例如,查看 Arduino 和 FHT 捕获并分析从 1hz 到 5000hz 的频率扫描图:
 {{:knowledge:electronic:pasted:20190321-125044.png|Mesh of FHT frequency sweep}} {{:knowledge:electronic:pasted:20190321-125044.png|Mesh of FHT frequency sweep}}
  
-===== Summary =====+===== 概括 =====
  
-My code for this project can be found at github for you to experiment with.+我的这个项目的代码可以在 github 上找到,供你尝试。
  
-The Arduino can be used for relative sound level measurement and for frequency analysis/visualization. One just needs a microphone to match the use case, an Arduino, some coding and optionally the FHT library. Have fun and let me know in the comments if you make something nice using such a setup.+Arduino 可用于相对声级测量和频率分析/可视化。只需要一个与用例匹配的麦克风、一个 Arduino、一些编码以及可选的 FHT 库。祝你玩得开心,如果你使用这样的设置做了一些不错的事情,请在评论中告诉我。
  
 https://blog.yavilevich.com/2016/08/arduino-sound-level-meter-and-spectrum-analyzer/ https://blog.yavilevich.com/2016/08/arduino-sound-level-meter-and-spectrum-analyzer/
  
  
knowledge/electronic/2019032101.1688631176.txt · 最后更改: 2023/07/06 08:12 由 ob