Manos libres, pero no un teléfono. Obediente a casa cuando no hay suficientes manos

Hola comunidad!

Tenía el deseo de volver a jugar con el microcontrolador y hacer algo útil. El objetivo se formó casi de inmediato, ya que algo me molestó en el apartamento.

Como saben, una mesa de computadora es una mesa de comedor para ver Drobyshevsky o leer Giktayms / Green Cat / etc. al mismo tiempo que la cena. Pero hay un problema: generalmente salgo de la cocina con las manos ocupadas y también la espalda, porque las tazas están apiladas en 3 piezas. Encender y apagar la luz en la cocina (interruptor triple - cocina / baño / inodoro) es el hombro, la nariz y el dedo meñique. Es decir, no es conveniente de ninguna manera, pero es imposible reorganizarlo. Había una tarea que gestionar de alguna manera remota.

Todos los sensores de presencia y paso fueron descartados de inmediato; no es esa precisión, no hay control por voluntad del propietario. La solución se encuentra en el control de sonido, la voz. Diré de inmediato que no planeé hacer reconocimiento de voz, no es necesario aquí. La luz encendida por el pop se describió en Radio 80, pero no quería hacer eso. Resultó una especie de manos libres cuando las manos están ocupadas. Los detalles están en.

Pieza de hardware.


Había una placa con Atmega32 con cuarzo y periféricos SEM0007M-32A y una dispersión de electrónica.

imagen

Había un micrófono y un amplificador operacional. Para la salida, hay un transistor en un paquete sot32 en la placa, también hay un relé de 7 amperios. Todo está ensamblado en una caja para tarjetas de visita, el relé está en paralelo con el interruptor, el micrófono está oculto debajo de la salida. El esquema es común, ni siquiera lo dibujé. Solo se utiliza una entrada analógica y una salida MK discreta. SEM es redundante, pero por ahora déjalo ser.

imagen
Tablero y cables sin montar. Luego lo rehizo con mayor precisión.

imagen
El interruptor en sí, el micrófono no es visible debajo de la salida desmontada.

Busca un algoritmo.


Propósito: el sensor debe responder a una palabra, por ejemplo, " ¡luz! »Con un mínimo de código.
Tarea: identifique la palabra de comando en el contexto de posibles ruidos, golpes, clics con el mismo interruptor. Es decir, solo el análisis de amplitud no es adecuado, y el análisis espectral mostró que hay demasiados armónicos en la palabra y, por supuesto, cambian. Por lo tanto, era necesario buscar una solución simple, pero con una inmunidad al ruido aceptable. Puede hacer varios filtros de frecuencia de tiempo y una comparación con una muestra de la palabra, pero no necesita lidiar con el reconocimiento. Se decidió analizar la presencia de solo un sonido vocal, por ejemplo, el sonido "E" o "E".

imagen
El sonido es "E". Muchos armónicos son visibles, por eso el análisis es difícil.

imagen
El sonido es "A". El espectro se ve más limpio, hay una frecuencia principal.

Parte de software


Para conocer los componentes espectrales de la señal, puede usar filtros digitales. Existe un buen programa en Internet para construir filtros FIR y IIR digitales y calcular sus coeficientes: está claro y el código C se genera automáticamente.

Pero rechacé los filtros digitales.
Para un filtrado aceptable (4 o más órdenes), se obtuvieron muchos coeficientes, e incluso un flotador. Así, más todos los cálculos de filtro en el flotador:

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 }; 

El microcontrolador podría haberlo manejado, pero habría habido problemas con la depuración (no es fácil superar los límites del filtro), estos son nuevos coeficientes para calcular.

Después de algunas búsquedas, me decidí por la transformación de Fourier de frecuencia única en línea. Es decir, la clásica transformada discreta de Fourier, realizada a la llegada de cada muestra de la señal con una frecuencia de muestreo (1600 Hz), no hay paso a través de las frecuencias, solo hay una frecuencia, por lo que es fácil configurarla a través de RS-232 durante la puesta en servicio. Como resultado, el análisis se realizó para una frecuencia de 128 Hz.

Debido a las muestras cortas (bloques) y una ventana rectangular, la resolución de frecuencia es baja, lo que proporciona una sensibilidad selectiva en el rango de 114 ... 140 Hz, y este es el filtro P que quería obtener.

Primero debe comprender dónde comienza a gritar la señal de comando de voz. Para hacer esto, primero, se calcula un nivel de señal cero, a través del suavizado exponencial con una constante de suavizado 1/64. El código está abajo.

Parte del código del temporizador para el procesamiento de la señal. Frecuencia del temporizador 1600 Hz
La señal se normaliza a la media. Para determinar el nivel de intensidad del sonido, los valores absolutos de la señal también se promedian con una constante de 1/16, para el filtrado de paso alto de las medias ondas de la señal individual (esto es un análogo de RMS, pero más fácil de calcular). Superar este nivel por encima del umbral es el comienzo de un comando de voz, y comienza un análisis secuencial de 5 bloques de 135 muestras (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; //      }; ..... 

La siguiente figura muestra la señal, nivel de señal, umbral y 5 bloques.

imagen

Protección contra interferencias


La señal se divide en bloques para proteger contra un impulso: un clic o un golpe. El pulso, como saben, tiene una respuesta de frecuencia uniforme, es decir, en cualquier banda de frecuencia habrá un resultado distinto de cero y probablemente por encima del umbral. Pero el cabello es largo, pero el impulso de la mente es corto. Es decir, ya no habrá pulso en el siguiente bloque, lo que significa que el nivel en la banda de frecuencia estará por debajo del umbral. Simultáneamente con esta ventaja, los bloques cortos dan una baja resolución en frecuencia. Por lo tanto, algunas diferencias de frecuencia en la señal todavía caen en la línea de frecuencia seleccionada.

Conversión de frecuencia


En cada bloque, se realiza una transformada de Fourier de frecuencia única para una frecuencia f.

Tradicionalmente, para acelerar los cálculos, las funciones sin y cos se tabulan y escalan a -127 .. + 127.
El índice ps de la matriz si(ps) se calcula a partir del argumento sin (2 * π * f * t / T), por supuesto con un bucle invertido dentro del mismo período. El índice de pc para cos (2 * π * f * t / T) simplemente se empuja 12 posiciones hacia adelante en la misma matriz si .

Resultado Y : el nivel de la línea espectral se obtiene como la suma de los valores absolutos de las partes real e imaginaria durante un bloque.
Entonces
de la manera correcta, debes hacer la suma de los cuadrados y la raíz, pero esto es terrible para un MK de 8 bits.

En el mismo temporizador:
  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. 

Al final de cada bloque, se compara Y con un umbral, se calcula el número de bloques que excede los bloques activados por el umbral. Después de los experimentos, resultó que el número mínimo de bloques activados es 3 de 5.

imagen
Un ejemplo de intensidad espectral en bloques con un comando de voz. El equipo ha pasado.

Tres o más bloques activados se interpretan como un comando recibido correctamente. La señal en la salida discreta del MK se invierte, encendiendo o apagando la luz. Como todo el análisis tiene lugar dentro de los bloques, no hay demora en la operación después del último bloque.

El tiempo de cálculo es de aproximadamente 1600 ciclos, el temporizador se activa cada 9000 ciclos, por lo que la carga del MK es baja: hay espacio para más experimentos con reconocimiento. O puede hacer una solución completa de tamaños más pequeños y en un MK débil.

La corrección de los algoritmos se controló mediante el intercambio de variables necesarias (log) a través de RS-232 con el programa en VBasic. La frecuencia f y los umbrales se almacenan en eeprom.

Como resultado: el sensor resultó ser muy conveniente, responde a palabras de " A ", por ejemplo, " Waaau ", " Taaam ", " Laite ", " Miaaa ", " Yao-Yao " . El volumen es común para la conversación humana. La palabra " Lit " se niega obstinadamente a escuchar. Clics, golpear puertas, escalones, verter agua ignora. Ahora puedes caminar con las manos llenas tazas y platos)).

Source: https://habr.com/ru/post/es408745/


All Articles