Would you like to see this post in English?
Motivação
Neste post eu mostrarei a biblioteca Arduino que eu escrevi para o módulo FM TEA5767N.
Em meus primeiros experimentos com o TEA5767N em um protoboard eu usei as bibliotecas de Simon Monk e Andy Karpov. Seus códigos me ajudaram muito a entender como controlar o TEA5767N.
E então, antes de construir uma aplicação mais completa, eu senti a necessidade de organizar um pouco meu código e, com a ajuda das notas de aplicação do TEA5767N, eu encapsulei os comandos em vários métodos convenientes.
Estrutura de dados
Para enviar ou receber comandos do TEA5767N existem sempre 5 bytes envolvidos. Mesmo que você precise reenviar apenas um bit, todos os 5 bytes devem ser enviados. Então eu mantive a transmissão e recepção de bytes de dados com atributos de instância do objeto, como visto abaixo.
Os bytes de transmissão são inicializados no método privado initializeTransmissionData() com as opções mais comuns e sua chamada sendo chamada pelo construtor. Os comentários foram removidos para tornar a leitura mais agradável.
Agora podemos mudar apenas um ou dois bits e enviar todos os cinco bytes com os valores que eles tinham e não foram afetados pela mudança. Por exemplo, um método para acionar o mudo (desligar o som), tem que manipular apenas um bit dos cinco bytes de transmissão antes de reenviá-los:
E para ativar o som novamente:
E a maioria dos métodos é assim, ligando e desligando bits.
E como dito antes, existem também cinco bytes que podem ser lidos do módulo TEA5767N. Eles são armazenados no array reception_data e dependendo da operação existe a necessidade de atualizar o array transmission_data também de maneira que fiquem em sincronismo. Aqui está um exemplo:
Nota: Wire é uma biblioteca que lida com comunicação I2C.
Algoritmos
Lendo as notas de aplicação do TEA5767N, você irá encontrar fórmulas e algoritmos para configurar e ler a frequencia das estações. Por exemplo, para selecionar uma estação é necessário primeiro calcular a injeção hi / lo que consiste em selecionar a frequencia que, somada e subraída de um delta, oferece um melhor nível de sinal. Delta é uma constante que representa 450 kHz.
E com este valor de injeção, o código pode chamar a fórmula que calcula o PLL de 14 bits que representam a estação selecionada:
Note que antes dos dados serem enviados, eles são armazenados no array transmission_data para que fique sempre atualizado.
Procurando estações
Antes de efetivamente iniciar uma procura, algumas coisas precisam ser configuradas: se a procura é para cima ou para baixo, o nível de sinal que deve parar a procura, e é recomendado deixar o rádio mudo para que o usuário não ouça aquele som irritante de estação sendo trocada.
Para escolher se a procura da estação é para cima ou para baixo, é necessário mudar apenas um bit do array transmission_data:
Existem três níveis de parada de procura: baixo (lo), médio (mid), e alto (high):
Configurar um destes níveis é uma questão de mudar dois bits no array transmission_data.
E para efetivamente começar a procura, depois de configurar a direção e o nível, você apenas chama o método searchNext().
O que este método faz é:
- Adicionar ou subtrair 100 kHz da estação corrente (para que a busca não encontre a estação atual novamente), dependendo da direção;
- Configura o bit de procura;
- Espera pelo resultado da procura;
- Quando a procura termina, verifica se o limite de banda foi alcançado ou não;
- Atualiza o array transmission_data com a nova frequencia selecionada;
- Desliga o bit de procura;
- Retorna o status do limite de banda;
search_next() não deixa o rádio mudo antes de procurar e é útil para depuração. Para deixar o rádio mudo antes de procurar você pode chamar o método mute() ou você pode chamar um método mais conveniente: searchNextMuting().
Este método apenas encapsula o método searchNext() com chamadas ao ligar e desligar o mudo e também retorna se o limite de banda foi atingido.
Dois outros métodos úteis de procura são startSearchFromBeginning() e startSearchFromEnd(). O que eles fazem é configurar a direção e a frequencia de inicio de busca antes de chamar searchNext(). Eu usei estes métodos em um projeto para escanear e registrar todas as estações disponíveis. Esse projeto será mostrado em meu próximo post.
E como você pode imaginar, existem as versões com função mudo.
Conclusão
Graças à possibilidade de escrever esta biblioteca em C++, uma linguagem orientada a objetos, eu pude escrever métodos mais coesos que são fáceis de usar por outro software cliente. Desta maneira, usando esta biblioteca você pode construir seu sistema passo a passo enquanto testa as funções do módulo. Separando os métodos em membros públicos e privados também ajuda a entender como a biblioteca deve ser usada.
Outra boa prática que você pode encontrar nesta biblioteca é a escolha cuidadosa dos nomes das variáveis e dos métodos. Eles revelam a intenção, qual é o papel da variável e o que os métodos fazem.
Muito obrigado!
Muito obrigado por ler!
Por favor me diga se esta biblioteca ajudou você de alguma forma em seus projetos.
Para seguir minhas atualizações a esta biblioteca, e meus outros projetos:
1,482 total views, 2 views today