免提,但没有电话。 没有足够的双手时要听话

您好,社区!

我希望再次摆弄微控制器并做一些有用的事情。 几乎是在我的公寓里打扰了我的目标。

如您所知,电脑桌是观看Drobyshevsky或阅读Giktayms / Green Cat等的餐桌。 在晚餐的同时。 但是有一个问题-我通常会双手忙着走出厨房,然后回来, 因为杯子被 分成 3个部分。 打开和关闭厨房中的灯(三联开关-厨房/浴室/卫生间)是肩膀,鼻子,小手指。 也就是说,无论如何都不方便,但是不可能重新布置它。 有一项任务以某种方式进行远程管理。

所有存在和通过的传感器都立即被撤消-准确性不高,所有者无法控制。 解决方案可以在声音控制,语音中找到。 我将立即说我不打算进行语音识别,这里不需要。 80年代电台曾描述过流行音乐打开的灯,但我不想这么做。 事实证明,当手忙时,免提。 详细信息在。

硬件部分。


有一块带有Atmega32的板,带有石英和外围设备SEM0007M-32A,以及一些电子设备。

图片

有一个麦克风和一个运算放大器。 对于输出,板上的sot32封装中有一个晶体管,还有7安培的继电器。 一切都被组装到一个名片盒中,继电器与开关并联,麦克风隐藏在插座下方。 该方案很普通,我什至没有画。 仅使用一个模拟输入和一个离散MK输出。 SEM是多余的,但现在就让它成为现实。

图片
电路板和未组装的电线。 然后他更准确地重做了。

图片
开关本身,麦克风在拆除的插座下不可见。

搜索算法。


目的:传感器必须响应一个单词,例如“ light! »用最少的代码。
任务:在可能的噪音,敲打,点击相同的开关的背景下识别命令字。 也就是说,仅进行幅度分析是不合适的,而频谱分析表明单词中的谐波过多,并且它们当然会发生变化。 因此,有必要寻找一种简单的解决方案,但具有可接受的抗噪能力。 您可以制作几个时频滤波器,并与单词样本进行比较,但是您无需进行识别。 决定仅分析元音的存在,例如声音“ E”或“ E”。

图片
声音是“ E”。 可见许多谐波,因此分析很困难。

图片
声音是“ A”。 频谱看起来更干净,有一个主频率。

软件部分


为了知道信号的频谱成分,可以使用数字滤波器。 互联网有一个很好的程序,用于构建数字FIR和IIR滤波器并计算其系数-很明显,该程序可以自动生成C代码。

但是我拒绝了数字滤波器
对于可接受的滤波(4个或更多个阶),可以获得许多系数,甚至是浮点数。 这样,加上浮点数中的所有过滤器计算:

float ACoef[NCoef+1] = { 0.00000347268864059354, 0.00000000000000000000, -0.00001389075456237415, 0.00000000000000000000, 0.00002083613184356122, 0.00000000000000000000, -0.00001389075456237415, 0.00000000000000000000, 0.00000347268864059354 }; float BCoef[NCoef+1] = { 1.00000000000000000000, -7.09708794063733790000, 22.77454294680684300000, -43.03321836036351300000, 52.29813665034108500000, -41.84199842886619100000, 21.53121088556695300000, -6.52398963450972500000, 0.89383378261285684000 }; 

微控制器可能已经处理了,但是调试会出现问题-突破滤波器的界限并不容易-这些是要计算的新系数。

经过一些搜索,我决定在线进行单频傅立叶变换。 也就是说,经典的离散傅里叶变换是在以采样频率(1600 Hz)到达信号的每个样本时执行的,没有频率通过,只有一个频率,因此在调试过程中很容易通过RS-232对其进行配置。 结果,对128Hz的频率进行了分析。

由于样本(块)短且窗口矩形,所以频率分辨率较低,因此选择性灵敏度在114 ... 140 Hz范围内, 这是我想要获得的P滤波器。

首先,您需要了解语音命令信号在哪里开始尖叫 。 为此,首先,通过使用平滑常数为1/64的指数平滑来计算零信号电平。 代码如下。

定时器代码的一部分,用于信号处理。 计时器频率1600 Hz
信号归一化为平均值。 为了确定声强水平,还对信号的绝对值求平均值,其常数为1/16,以便对单个信号半波进行高通滤波(这是RMS的模拟,但更易于计算)。 超过此阈值水平是语音命令的开始,并且开始对5个块的135个样本(84.3 ms)进行顺序分析。

 // Timer 0 output compare interrupt service routine interrupt [TIM0_COMP] void timer0_comp_isr(void) { a = adc_data[0] << 2 ; //       4   . a0 = (a0*63 + a+ 63) >> 6; // .   "0".   10%  150  ae = (int)(a - a0); // a = ae; //      . ae = abs(ae); if (ae < 32) { //      ae = 0; }; d = (int)((15 * (long int) d + ae + 15) >> 4); //  .  //   10%  35  if (d > 100) { //    if (snd == 0) { Yz=0; snd++; } //    PORTB.1 = 1; //      }; ..... 

下图显示了信号,信号电平,阈值和5个块。

图片

干扰防护


信号被分为多个块,以防止脉冲(喀嗒声或敲击声)。 如您所知,脉冲具有均匀的频率响应,也就是说,在任何频带中都将产生非零结果,并且可能会超过阈值。 但是头发很长,但是头脑的冲动很短。 也就是说,在下一个块中将不再有脉冲,这意味着频带中的电平将低于阈值。 同时具有这一优势,短块会降低频率分辨率 。 因此,信号中的某些频率差仍然落入所选频率线。

频率转换


在每个块中,对一个频率f执行单频傅里叶变换。

传统上,为了加快计算速度,将sin和cos函数制成表格并缩放为-127 .. + 127。
si(ps)数组的ps索引是根据参数sin(2 *π* f * t / T)计算得出的,当然,在同一时间段内也会发生环回。 将cos(2 *π* f * t / T)的pc索引简单地在同一si数组中向前推12个位置。

结果Y-频谱线的电平是一个块期间实部和虚部的绝对值的总和。
所以
以正确的方式,您需要对平方和根进行求和,但这对于8位MK来说是很糟糕的。

在同一计时器中:
  a_si = (long int) (a * si[ps]) >> 4; // a*sin a_co = (long int) (a * si[pc]) >> 4; // a*cos Ysi = Ysi + a_si ; // Yco = Yco + a_co; Y = (labs(Ysi) + labs(Yco)) >> 7; //   128    int    rs-232. 

在每个块的末尾,将Y与阈值进行比较,计算出超过阈值的块数-触发的块。 经过实验后,发现触发块的最小数量为5分之3。

图片
语音命令块中频谱强度的示例。 团队已经通过。

三个或更多触发块被解释为正确接收的命令。 MK离散输出上的信号被反转,从而打开或关闭灯。 由于整个分析都在这些块内进行,因此在最后一个块之后没有操作延迟。

计算时间约为1600个周期,每9000个周期将调用一次计时器,因此MK的负载很低-仍有进行识别实验的空间。 或者,您可以在MK较弱的情况下提供较小尺寸的完整解决方案。

通过与VBasic上的程序通过RS-232交换必要变量(对数)来控制算法的正确性。 频率f和阈值存储在eeprom中。

结果:该传感器变得非常方便,它响应来自“ A ”的单词,例如Waau ”,“ Taaam ”,“ Laite ”,“ Miaaa ”,“ Yao-Yao 。 音量是人类对话的常态。 “ 点燃 ”这个词固执地拒绝听。 点击,敲门,台阶,倒水忽略。 现在,您可以带着满手的杯子和盘子走路))。

Source: https://habr.com/ru/post/zh-CN408745/


All Articles