Treine um modelo de redes neurais no PC, converta para TensorFlow Lite Micro e execute inferência em tempo real no Arduino Nano 33 BLE Sense.
Visão Geral
Um classificador de gestos que usa o acelerômetro e giroscópio do Arduino Nano 33 BLE Sense para reconhecer 3 movimentos (punch, flex e idle) diretamente no microcontrolador — sem conexão com a internet, sem servidor externo.
Instalar bibliotecas Arduino e configurar o Python virtual env.
Gravar amostras de gestos com coleta_dados.ino e salvar em CSV.
Executar o notebook 01_treinamento_tensorflow.ipynb com Keras.
Quantizar para int8 com o notebook 02_conversao_tflite.ipynb.
Exportar model_data.h e norm_params.h para o Arduino.
Compilar inferencia_gestos.ino e testar gestos em tempo real.
Projeto
Organize os arquivos desta forma antes de começar:
Dependências
Driver oficial para o IMU integrado (acelerômetro + giroscópio + magnetômetro).
Biblioteca do curso de TinyML de Harvard/Google com TensorFlow Lite Micro já empacotado. Buscar por "TinyMLibrary" ou "Harvard" na Library Manager.
Utilizar a Harvard_TinyMLx (não a "Arduino_TensorFlowLite" original).
O construtor MicroInterpreter dessa versão exige 5 argumentos, incluindo
um ErrorReporter*. O sketch inferencia_gestos.ino já está
adaptado para essa API.
# Ativar o ambiente virtual
source env/bin/activate
# Instalar dependências principais
pip install tensorflow numpy pandas scikit-learn matplotlib
| Pacote | Finalidade | Versão testada |
|---|---|---|
tensorflow | Treinamento Keras + conversão TFLite | 2.x / 2.16 |
numpy | Manipulação de arrays e normalização | 1.26+ |
pandas | Leitura e pré-processamento dos CSV | 2.x |
scikit-learn | Train/test split e métricas | 1.4+ |
matplotlib | Visualização dos resultados | 3.8+ |
Tutorial
Siga as etapas abaixo na ordem indicada.
Abra o Arduino IDE, vá em Sketch → Include Library → Manage Libraries… e instale:
Após instalar, reinicie o Arduino IDE para que as bibliotecas sejam reconhecidas corretamente.
Carregue o sketch coleta_dados.ino no Arduino Nano 33 BLE Sense.
Abra o Serial Monitor a 115200 baud e realize cada gesto
conforme solicitado. Os dados IMU (aX, aY, aZ, gX, gY, gZ) serão impressos
no monitor.
Use o script salvar_dados.py para capturar e salvar
automaticamente em dados/punch.csv, dados/flex.csv
e dados/idle.csv:
# Ativar venv
source env/bin/activate
# Salvar amostras (ajuste a porta serial conforme seu sistema)
python salvar_dados.py --porta /dev/ttyACM0 --gesto punch --amostras 50
python salvar_dados.py --porta /dev/ttyACM0 --gesto flex --amostras 50
python salvar_dados.py --porta /dev/ttyACM0 --gesto idle --amostras 50
Cada janela de captura contém 119 leituras × 6 features (aX·aY·aZ·gX·gY·gZ),
totalizando 714 valores por amostra. Esse valor está definido em
norm_params.h como kNumSamples.
Com o ambiente virtual ativado, abra o Jupyter e execute o notebook:
jupyter notebook notebooks/01_treinamento_tensorflow.ipynb
O notebook realiza:
norm_mean.npy / norm_std.npy)EarlyStopping e ModelCheckpointAo final, o modelo é salvo em outputs/best_model.keras.
Execute o segundo notebook:
jupyter notebook notebooks/02_conversao_tflite.ipynb
O notebook automaticamente:
outputs/gesture_int8.tflitearduino/inferencia_gestos/model_data.h com o modelo como array Carduino/inferencia_gestos/norm_params.h com médias e desvios padrãoA quantização reduz o modelo de float32 para 8 bits, diminuindo o tamanho em ~4× e acelerando a inferência no Cortex-M4 do Nano 33 BLE Sense, que não possui FPU de 64 bits.
Confirme que os três arquivos coexistem na pasta
arduino/inferencia_gestos/:
Abra norm_params.h e confirme que kNumSamples,
kNumFeatures e kNumClasses batem com o que
foi usado no treinamento.
No Arduino IDE, abra arduino/inferencia_gestos/inferencia_gestos.ino.
Selecione a placa correta:
/dev/ttyACM0 no Linux)// Pressione Ctrl+U para compilar e fazer upload
Se aparecer erro sobre número de argumentos no construtor
MicroInterpreter, certifique-se de estar usando a biblioteca
Harvard_TinyMLx (não Arduino_TensorFlowLite) e que o sketch
declara um tflite::MicroErrorReporter passado como 5º argumento.
Abra o Serial Monitor a 115200 baud. O Arduino aguardará um movimento brusco (threshold = 2,5 g) como gatilho, capturará 119 amostras, normalizará, e imprimirá o resultado:
====================================
TinyML — Classificador de Gestos
Arduino Nano 33 BLE Sense
====================================
Modelo: 12748 bytes
Arena: 32 KB
Input dim: 714
Classes: punch, flex, idle
====================================
Realizando gestos — aguardando...
→ Gesto: punch (94.3%) | tempo de inferência: 18.42 ms
Scores: punch=94.3% flex=3.1% idle=2.6%
O LED RGB indica visualmente: vermelho = punch, verde = flex, azul = idle, amarelo = incerto.
Links Úteis
A prática desta Parte 1 é baseada no tutorial oficial do Arduino e nos materiais do curso de TinyML de Harvard/Google.
Solução de Problemas
| Erro | Causa provável | Solução |
|---|---|---|
micro_log.h: No such file |
Header inexistente na Harvard_TinyMLx | Remover a linha #include "tensorflow/lite/micro/micro_log.h" |
MicroInterpreter expects 6 arguments |
API diferente entre versões da lib | Passar error_reporter como 5º arg; usar MicroErrorReporter |
TFLITE_SCHEMA_VERSION not declared |
Constante ausente na Harvard_TinyMLx | Substituir verificação por if (model == nullptr) |
| Classificação sempre "idle" | Normalização inconsistente | Confirmar que norm_params.h foi gerado com os mesmos dados de treino |
| IMU não inicializa | Biblioteca errada ou placa incorreta | Verificar se a placa selecionada é "Arduino Nano 33 BLE" (não "Nano 33 IoT") |
AllocateTensors() failed |
Arena de 32 KB insuficiente | Aumentar kTensorArenaSize para 48 * 1024 |