Franzininho Smart Home

Participantes:

Ewerton Leandro de Sousa

Resumo do projeto:

Desenvolver um controlador inteligente, comandado por voz, capaz de acionar diferentes cargas utilizando uma rede neural embarcada no próprio microcontrolador ESP32-S2 utilizando a biblioteca do TensorFlow Lite Micro.

Descrição do projeto:

Nos últimos anos tem crescido o números de dispositivos inteligentes em nosso dia a dia, neste  projeto vou desenvolver uma placa que possa ser utilizada para o acionamento de dispositivos diversos por comando de voz.

A ideia é desenvolver uma versão simplificada de um assistente virtual como Google Smart Home, Alexa Echo Dot com o diferencial de funcionar sem o uso de internet, ou processamento externo.

A ideia inicial era que o dispositivo fosse capaz de reconhecer 10 comandos de voz diferentes, mas durante o desenvolvimento esse número foi reduzido para 4 comandos devido a limitações de memória do ESP32-S2. Os comandos de voz escolhidos para o projeto foram as palavras franzininho, ligar, desligar e uma classe genérica utilizada para a classificação de qualquer comando de voz diferente do três anteriores.

 

Histórico do desenvolvimento:

O histórico do desenvolvimento do projeto foi dividido em duas partes, a descrição do hardware e a descrição do software.

 

Hardware:

O hardware do projeto foi todo desenvolvido utilizando módulo, visando reduzir a complexidade e tempo de desenvolvimento.

Abaixo temos a primeira versão desenvolvida, para essa etapa utilizamos o Fritzing.

 

Na versão final do projeto foram feitas apenas 3 mudanças:

  • A troca relé de estado sólido por relé um mecânico;
  • A adição de dois botões de comando;
  • A inclusão de um circuito de filtragem LC para a alimentação do microfone INMP441.

A troca do relé foi uma adaptação, pois estava sem relé de estado sólido no momento.

Os botões foram adicionados durante a fase de desenvolvimento para teste, mas sendo uma opção de acionamento alternativa ao comando de voz.

O filtro LC na alimentação do microfone INMP-441, foi uma melhoria implementada para eliminar um ruído constante observado nas gravações e também relatado no vídeo, “ESP32 Audio Input – INMP441 and SPH0645 MEMS I2S Breakout Boards” (link).

Foram feitos alguns testes conforme imagens abaixo e apesar de os surtos terem um pico de alguns milivolts a utilização do filtro LC na entrada alimentação removeu os ruídos constantes que apareciam nas gravações.

A utilização desse filtro é importante pois a rede neural pode acabar interpretando que esses surtos (ruídos) são uma característica do som de uma ou mais classes.

Para o diagrama final do projeto, resolvi utilizar EasyEDA.

Componentes:

  • 1x Franzininho WiFi – Datasheet ESP32-S2-Wroom;
  • 1x JQ6500;
  • 1x INMP-441 – Datasheet;
  • 1x BC548 – Datasheet;
  • 1x 1N4007 – Datasheet;
  • 1x Relé 5v;
  • 2x Tactil Push Button;
  • 2x Resistores de 10k 1/8w;
  • 1x Resistor de 1k 1/8w;
  • 1x Capacitor eletrolítico de 220uF 10v;
  • 1x Incutor de 220uH;
  • 2x Barras de pinos fêmea;
  • 1x Alto-falante;
  • 1x Borne KF 128, KF 301 ou KRE 180 com 3 vias.

Lista de alguns componentes na Mouser Eletronics 🛒(AccessID: 8e62e495f0).

Foi desenvolvida uma PCB e apesar de o projeto utilizar muitos módulos a placa ficou compactar medindo aproximadamente 6,2 x 9,7 cm.

Infelizmente nem todos os componentes têm um modelo 3D no EasyEDA, então a visualização 3D ficou sem alguns componentes, mas mesmo assim dá para ter uma boa ideia do resultado final do projeto antes de efetuar a montagem.

O módulo do Franzininho WiFi foi substituído por módulo genérico de ESP32 e o módulo INMP441 foi substituído pelo seu chip apenas.

Também desenvolvi um case 3D no Tinkercad, mas ainda precisa de algumas muitas melhorias.  🙂

Falta incluir na tampa do case: os furos para o alto-falante, os botões e o relé.

Resultado final do projeto montado no case.

 

 

Software/Firmware:

O projeto é composto por 3 softwares, o firmware do Franzininho WiFi, um servidor HTTP escrito em NodeJS e um notebook escrito na plataforma do Google Colab em Python para o treinamento da rede neural com TensorFlow.

Todos os arquivos e códigos estão disponíveis no GitHub no repositório Jornada do Desenvolvimento 2021.

O código do firmware foi todo desenvolvido utilizando a IDE do Arduino e está dividido em 8 arquivos.


Optei por desenvolver um único código que tem dois modos de operação, um modo para a geração do dataset de treinamento da rede neural e um modo para a inferência.

No vídeo abaixo faço uma breve visão do código:

 

JQ6500 – Upload

No projeto foi utilizado um módulo MP3 player JQ6500-16P, esse módulo tem uma memória flash embutida que é utilizada para armazenar os arquivos de áudios. Para salvar os arquivos de áudios na memória flash do J6500 precisamos utilizar um programa chamado “Music Update tool”, que também está disponível no repositório GitHub mas também pode ser baixado no site do fabricante.

Abaixo temos o passo a passo para salvar os arquivos de áudio no módulo JQ6500, inicialmente precisamos conectar o módulo a uma porta USB do computador.

Selecionar os arquivos de áudio em formato MP3.

E clique no botão “Flash” para enviar para a placa.

Se não ocorrer nenhum erro, podemos desconectar da porta USB e conectar ao nosso projeto.

Firmware – Modo Coleta

A primeira etapa do projeto é a criação de uma base de dados(dataset) para o treinamento da rede neural, para isso precisamos gravar o nosso firmware com o modo de coleta.

Abaixo segue o fluxograma do firmware para o modo de coleta de dados.

Nesse modo de operação o ESP32-S2 vai efetuar a leitura ininterruptamente do INMP-441 e verificar se foi captado algo possível comando de voz, caso seja detectado algum possível comando de voz efetua os cálculos das FFT’s para a geração do espectrograma do áudio captado e posterior envio para o servidor HTTP.

Na linha 4 definimos o MODO de operação do microcontrolador, zero para coleta e um para inferência.

Demonstração rápida da execução do código em modo de coleta:

 

Explicação rápida do código do servidor HTTP:

 

Treinamento da Rede Neural (TensorFlow)

Para o treinamento da rede neural foi utilizado a plataforma do Google Colab, mas também pode ser feito o treinamento em um PC local.

Demonstração da execução do notebook e treinamento da rede neural:

 

Abaixo temos o diagrama da rede neural desenvolvida no projeto.

 

Link para o dataset: Dataset

Link para o Jupyter Notebook no serviço do Google Colaboratory: Notebook

 

Firmware – Modo Predição

No modo de predição a placa do Franzininho WiFi vai captar os possíveis comandos de voz captados pelo INMP-441 e classifica em um dos 4 comandos treinados: “Franzininho”, “Ligar”, “Desligar” e “Outros”. Boa parte do código é similar ao modo de operação coleta, tendo apenas o trecho de código responsável pelo envio para servidor sendo substituído pelo código responsável pela inferência da rede neural.

Abaixo segue o fluxograma para o modo de operação de predição:

Demonstração do projeto sendo executado em modo de predição:

 

Ao longo do desenvolvimento do projeto foram feitos vários testes, seguindo as etapas de coleta, treinamento e validação. Foram feitos testes com diferentes métodos de coleta de amostras, diferentes redes neurais, diferentes parâmetros de treinamento e o melhor resultado obtido foi esse apresentado no projeto, mas é importante ressaltar que ainda há muitas melhorias que podem ser feitas.

Outro ponto de atenção é com relação a palavras com sufixo, prefixo e radicais parecidos, como no nosso projeto a palavra “ligar” e a palavra “desligar” que apresentam o mesmo radical e como em alguns momentos podemos não captar a palavra completa pode acabar gerando muito na classificação dessas duas classes.

Para minimizar erros com comandos com palavras parecidas pode se utilizar uma lógica de exclusão de modo a complementar a classificação da rede neural, por exemplo se o relé está acionado e o modelo detectar a palavra “Ligar” podemos entender nesse caso que o comando na realidade foi “Desligar” e o contrário também é válido se o relé está desativado e a rede neural prediz que a palavra foi “Desligar” podemos entender que o comando correto na realidade foi ligar.

 

Referências:

Atomic14. ESP32 Audio Input – INMP441 and SPH0645 MEMS I2S Breakout Boards. Youtube, 11 de set. de 2020. Disponível em: <https://www.youtube.com/watch?v=3g7l5bm7fZ8>. Acesso em: 02 de nov. de 2021

That Project. ESP32 | INMP441 | Tutorial – [Part.0] Set up I2S for Microphone. Youtube, 24 de fev. de 2020. Disponível em: <https://www.youtube.com/watch?v=m8LwPNXqK9o>. Acesso em: 02 de nov. de 2021.

Atomic14. ESP32 Audio DMA Settings Explained – dma_buf_len and dma_buf_count. Youtube, 20 de abr. de 2021. Disponível em: <https://www.youtube.com/watch?v=ejyt-kWmys8>. Acesso em: 01 de dez. de 2021.

Atomic14. ESP32 Audio Input Using I2S and Internal ADC. Youtube, 17 de ago. de 2020. Disponível em: <https://www.youtube.com/watch?v=pPh3_ciEmzs>. Acesso em: 01 de nov. de 2021.

TensorFlow, TensorFlow, 2021. Disponível em: <https://www.tensorflow.org/?hl=pt-br>. Acesso em: 01 de nov. de 2021.

TinyML, TinyML, 2021. Disponível em: <https://www.tinyml.org/>.

Placa Franzininho WiFi, Franzininho, 2021. Disponível em: <https://docs.franzininho.com.br/docs/franzininho-wifi/franzininho-wifi/>. Acesso em: 01 de nov. de 2021.

Doshi, Ketan. Audio Deep Learning Made Simple: Sound Classification, Step-by-Step. Towards Data Science,  2021. Disponível em: <https://towardsdatascience.com/audio-deep-learning-made-simple-sound-classification-step-by-step-cebc936bbe5>. Acesso em: 10  de out. de 2021.

Simone. Easy Tensorflow TinyML on ESP32 and Arduino. Eloquent Arduino, 2020. Disponível em: <https://eloquentarduino.github.io/2020/01/easy-tinyml-on-esp32-and-arduino/>. Acesso em 10 de out. de 2021.

Simone. EloquentTinyML. GitHub, 2021. Disponível em: <https://github.com/eloquentarduino/EloquentTinyML>. Acesso em: 10 de out. de 2021.

Lenail, Alexander. NN-SVG. Alexlenail, 2021. Disponível em: <http://alexlenail.me/NN-SVG/AlexNet.html>. Acesso em: 20 de dez. de 2021.

Holmes, Chris. JQ6500_Serial ESP32. Github, 2021. Disponível em: <https://github.com/holmser/JQ6500_Serial_ESP32>. Acesso em: 15 de dez. de 2021.