AudioSwitcher - automação do que parece não ser necessário automatizar


Prefácio


Eu tenho alguns conjuntos de bons sistemas de alto-falantes soviéticos em casa. Mas essa técnica é bastante antiga e simplesmente não pode ser ligada a partir do controle remoto ou automaticamente, mas aproxima-se constantemente do amplificador de som e liga / desliga com muita preguiça. Eu resolvi esse problema. Inicialmente, o Arduino foi comprado e o projeto foi concluído, mas a qualidade do trabalho não me agradou e o projeto foi refeito para o STM32F103C8. Como resultado, obtive um dispositivo com 4 entradas de áudio, 1 saída de áudio, entrada de 220V e saída de 220V. Se houver pelo menos uma entrada de áudio ativa, uma tensão aparecerá na saída de 220V, incluindo um amplificador de som, e o canal de áudio ativo será transmitido para a saída.

Desafios de desenvolvimento


Parece simples: se o ADC não receber 0, considere o canal como ativo. Quase tudo está certo, mas só funciona se você ligar a fonte de áudio e desligar o som. Quando desligados, dispositivos diferentes produzem interferências diferentes, pois não são completamente desenergizados. E com fontes de som ruins, o microcontrolador pode captar ruídos quando o som é desligado e bastante forte. E esta é precisamente a interferência da fonte, o STMka não vê interferência na minha placa de áudio externa; além disso, o som silencioso é 0.

Como fazer você mesmo?


Vamos primeiro decidir o que precisamos. Não vou escrever o custo, porque isso depende muito da sua localização.

Do que precisamos:

  • placa de circuito
  • programador ST-Link v2
  • 1 chip STM32f103C8
  • 4 relés para mudar o canal de áudio de entrada para a saída
  • 1 relé para ligar 220V para ligar o amplificador
  • Conversor buck AC-DC 220V - 5V (pode ser retirado de uma tarifa antiga do telefone)
  • cabo de alimentação e conector para fornecer corrente ao nosso dispositivo e amplificador
  • tomada
  • resistores, capacitores e outras pequenas coisas

Naturalmente, precisamos de fios de áudio e um minijack plug com tomadas.

Eu gostaria de focar na escolha do relé ... Se tudo estiver muito claro com a escolha do relé de 220V: ele deve poder "alternar" a tensão alternada de 220V e ser controlado por 3,3V. A escolha de relés de som não é tão simples. Nem todos os relés, mesmo os de estado sólido, não causam interferência na saída, e isso é muito importante para nós. Eu moro em Minsk e não consegui encontrar nada adequado e a um preço adequado; portanto, 4 relés PVT322A foram encomendados em uma conhecida loja chinesa. Talvez na sua área você possa encontrar algo mais barato.

Esquema e fiação


Desde que começamos, continuaremos estudando os recursos de hardware. No diagrama que você pode encontrar no repositório na pasta Eagle, é necessário selecionar resistores limitadores de corrente (R4-7) para seus relés. No meu caso, são 30 ohms. Há também uma bobina L1: escolha qualquer filtro que suavize o ruído de alta frequência.

Você pode solicitar uma placa de circuito no PCBWAY ou JLCPCB. Seus preços são baixos, pedi ao JLCPCB e eles me cobraram apenas US $ 2. Ao solicitar uma placa de circuito, você precisará de arquivos gerber, poderá encontrar tudo na mesma pasta ou gerá-lo você mesmo.

Vamos para a parte do software


Não vou falar sobre como conectar o programador ao computador, instalar o ambiente de programação e o driver, porque Existem muitas dessas instruções e são extremamente acessíveis. No meu circuito são fornecidas saídas para programadores. Eu usei o Visual Studio 2017 + VisualGDB. Depois de baixar o projeto do mesmo repositório, podemos abrir o projeto. Gire imediatamente para o arquivo Settings.cpp.

Settings.cpp
#define DEBUG0 0//init USART and send all measurement values #define DEBUG1 1//init USART and send information about recognition music or not #define DEBUG2 0//just init USART #define MaxEqualToZeroValue 3 //the value which equal or less is equated to zero #define MaxAvarageForNoise (float)0.4//this is max avarage of measurement values so that the sound is considered noise for NOT active channel #define MaxAvarageForActiveNoise (float)0.06//this is max avarage of measurement values so that the sound is considered noise for active channel #define CountOfConsecutiveZeroValueForNoise 250//if count of consecutive zero values bugger it that sound is equated to noise #define MinCountOfZeroValue 550//it's minimum count of zero values to equate to music(not consecutive) #define USE_LED 1 #define LED_GPIO_PERIPH RCC_APB2Periph_GPIOC #define LED_GPIO_GROUP GPIOC #define LED_GPIO_PIN GPIO_Pin_13 #define USE_AMP 1 #define AMP_GPIO_PERIPH RCC_APB2Periph_GPIOB #define AMP_GPIO_GROUP GPIOB #define AMP_GPIO_PIN GPIO_Pin_12 


Todas as configurações neste arquivo estão documentadas, mas pararemos em cada configuração de qualquer maneira.

 #define DEBUG0 0 #define DEBUG1 1 #define DEBUG2 0 

Se atribuirmos uma unidade a DEBUG0, nosso dispositivo parará de fazer qualquer coisa, exceto que ele emitirá os valores que recebe das entradas de áudio em um formato que o SerialPortPlotter possa "digerir" pelo UART.

Se você atribuir a unidade DEBUG1, o dispositivo já estará totalmente funcional, mas exibirá algumas informações sobre o trabalho no UART. Tudo isso é necessário exclusivamente para depuração.

Atribuir DEBUG2 apenas dará a inicialização do UART. Se você não entender por que isso ocorre, então não :-)

 #define MaxEqualToZeroValue 3 

Em seguida, temos um parâmetro cujo valor correspondente ou menor será considerado zero. Como mencionado anteriormente, algumas fontes de som são de baixa qualidade e muito barulhentas.

 #define MaxAvarageForNoise (float)0.4 

Se o canal de áudio estiver atualmente inativo (ou seja, o canal que não está atualmente no modo de saída) e o valor médio de medição para um ciclo de medição nesse canal for menor que o valor desse parâmetro, o canal será considerado sem som.

 #define MaxAvarageForActiveNoise (float)0.06 

Este parâmetro é quase o mesmo que o anterior, apenas para o canal que está ativo no momento. O fato é que, quando o canal está ativo e o amplificador está funcionando, a tensão do canal de áudio cai. E se você negligenciar essa configuração, o dispositivo considerará que há som mesmo quando o fio não estiver conectado a nenhum dispositivo.

 #define CountOfConsecutiveZeroValueForNoise 250 

Este parâmetro é apenas para otimizar o consumo da CPU. Se o dispositivo encontrar um número predeterminado de zeros seguidos, ele considerará que esse sinal não é um som.

 #define MinCountOfZeroValue 550 

E este é um cenário importante. Alguns dispositivos, quando desligados, criam ruídos estranhos, mas destaquei um fator comum entre eles: eles raramente caem para zero. Por isso tive que inserir esse parâmetro. Se o número de valores zero por ciclo de medição for menor que o valor especificado, o sinal será considerado ruído.

 #define USE_LED 1 #define LED_GPIO_PERIPH RCC_APB2Periph_GPIOC #define LED_GPIO_GROUP GPIOC #define LED_GPIO_PIN GPIO_Pin_13 #define USE_AMP 1 #define AMP_GPIO_PERIPH RCC_APB2Periph_GPIOB #define AMP_GPIO_GROUP GPIOB #define AMP_GPIO_PIN GPIO_Pin_12 

Este bloco é extremamente compreensível para quem já programou microcontroladores. Ele seleciona o pino no qual o LED estará localizado e a saída para o relé de controle do amplificador. Se você não alterar meu esquema, não precisará desses parâmetros.

Vamos seguir para as seguintes configurações:

Ao abrir o arquivo main.cpp, no início da função
 int main() 
Você encontrará uma definição de várias variáveis.

Vamos nos debruçar sobre isso com mais detalhes. Existem muitos parâmetros responsáveis ​​pela configuração de hardware do microcontrolador. Nós não vamos tocá-los.

 const uint8_t channelsCount = 2; 

Este é o número de canais de entrada de áudio a serem usados.

 const uint8_t countOfIterationsForSwitch = 5; 

O número de ciclos de medição necessários para alterar o estado ativo / passivo.

 const uint8_t ADCSampleTime = ADC_SampleTime_239Cycles5; 

Este parâmetro é responsável pela qualidade da medição. Está definido como máximo, não recomendo alterá-lo.

 const uint16_t measurementsDuration = 2000; 

Este é o tempo em ms durante o qual um ciclo de medição será executado.

 const uint32_t measurementFrequencies[] = { 1000, 1000, 1000, 1000 }; 

Não sei por que, mas implementei uma função que me permite medir os canais de entrada com frequências diferentes para cada canal. Talvez alguém precise desse recurso.

Conclusão


Bem, isso é tudo. Eu descrevi todas as configurações necessárias. Resta apenas montar o circuito, compilar o projeto, preencher o firmware no microcontrolador e se alegrar.

Para concluir, gostaria de dizer que você não pode simplesmente deixar o fio de áudio de entrada "não preso" em nada, é necessário inseri-lo em qualquer dispositivo ou conectar na forma de uma tomada minijack na qual todos os contatos estão interconectados.


Se suas fontes de som são muito boas, é possível definir configurações baixas, mas mudar o estado do som pode exigir a desativação (não de uma tomada). Talvez um dia eu adicione um link ao modelo 3D do gabinete, mas até agora não tenho uma impressora 3D e o gabinete é atualmente. Mas isso é apenas por enquanto: a impressora 3D já está funcionando :-)


Este é o meu primeiro artigo, terei prazer em receber qualquer crítica fundamentada. Entendo que isso não é uma obra-prima, mas tentei o meu melhor.

Obrigado pela leitura.

UPD1: Adicionado imagens esquemáticas e de fiação no artigo.

UPD2: Adicionadas imagens esquemáticas e de fiação ao repositório, adicionadas novos comentários no código.

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


All Articles