Neste tutorial, você vai aprender como implementar um sistema de reconhecimento de gestos (usando o sensor APDS‑9960) e de sons (microfone mini) diretamente em um ESP32, aproveitando o poder do TinyML com TensorFlow Lite for Microcontrollers.

Índice:
1. Visão geral do projeto
- Coleta de dados
- Gestos: movimentos da mão (↑, ↓, ←, →) pelo APDS‑9960.
- Sons: cliques e estalos captados pelo microfone MAX9814.
- Treinamento TinyML
- Criação de dataset anotado.
- Treinamento de rede leve em Python/Colab.
- Conversão para TensorFlow Lite for Microcontrollers (TFLM).
- Firmware no ESP32
- Integração das bibliotecas do TFLM.
- Leitura do sensor e inferência em tempo real.
Ao final, você terá um dispositivo capaz de reconhecer gestos de mão e detectar cliques, podendo acionar LEDs, relés ou enviar dados via MQTT para dashboards web.
2. Materiais necessários
Item |
---|
Placa ESP32‑S3 UNO |
Sensor de gestos APDS‑9960 |
Módulo microfone MAX9814 |
Cabo USB‑C para ESP32 |
Protoboard |
Jumpers |
Computador com Python e Google Colab |
3. Coleta de dados
Preparando o ESP32 para captura
- Instale a ESP-IDF ou Arduino IDE com suporte ao ESP32‑S3.
- Conecte o sensor APDS‑9960 e o módulo MAX9814 à protoboard:
ESP32‑S3 UNO APDS‑9960 MAX9814 ───────────── ───────────── ──────────── 3.3 V VCC VCC GND GND GND SDA (GPIO21) SDA SCL (GPIO22) SCL OUT (A0) — (não será usado aqui) GPIO34 — OUT
- Abra um sketch Arduino para coletar dados brutos:
#include <Wire.h> #include "SparkFun_APDS9960.h" SparkFun_APDS9960 apds = SparkFun_APDS9960(); const int micPin = 34; void setup() { Serial.begin(115200); Wire.begin(); apds.init(); apds.enableGestureSensor(true); } void loop() { if (apds.isGestureAvailable()) { uint8_t gesture = apds.readGesture(); Serial.print("Gesto: "); Serial.println(gesture); } int micValue = analogRead(micPin); Serial.print("Microfone: "); Serial.println(micValue); delay(100); }
- No monitor serial, registre sequências de gestos (por exemplo 20 repetições de cada direção) e cliques (bater palmas ou pressionar um interruptor próximo ao microfone) em arquivos
.csv
. Nomeie colunas comolabel
efeature_1, feature_2, …
.
4. Treinamento TinyML
Ambiente de desenvolvimento
- Crie um notebook Google Colab com ambiente Python 3.x.
- Instale bibliotecas:
!pip install numpy pandas tensorflow matplotlib
Preparando o dataset
- Faça o upload dos arquivos
.csv
coletados. - Carregue os dados em um DataFrame Pandas:
import pandas as pd df = pd.read_csv('gestos.csv') df_sounds = pd.read_csv('sons.csv')
- Combine e normalize features:
from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler X = pd.concat([df.drop('label', axis=1), df_sounds.drop('label', axis=1)]) y = pd.concat([df['label'], df_sounds['label']]) scaler = StandardScaler() X_norm = scaler.fit_transform(X) X_train, X_test, y_train, y_test = train_test_split( X_norm, y, test_size=0.2, stratify=y)
Definindo e treinando o modelo
import tensorflow as tf
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(X_train.shape[1],)),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(16, activation='relu'),
tf.keras.layers.Dense(len(y.unique()), activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model.fit(X_train, y_train, epochs=30,
validation_data=(X_test, y_test))
print("Acurácia final:", history.history['val_accuracy'][-1])
Conversão para TensorFlow Lite Micro
converter = tf.lite.TFLiteConverter.from_keras_model(model)
# Quantização inteira para microcontroladores
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with open('modelo_gestos_sons.tflite', 'wb') as f:
f.write(tflite_model)
5. Integração no firmware do ESP32
Preparando bibliotecas
- Baixe e instale a biblioteca TensorFlow Lite for Microcontrollers via Library Manager ou manualmente.
- Inclua o modelo convertido em seu código (adicione
modelo_gestos_sons.tflite
na pastadata/
ousrc/
).
Sketch completo de inferência
#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "modelo_gestos_sons_data.h" // gerado pelo xxd
// Reservar memória para o interpreter
const int kTensorArenaSize = 8 * 1024;
uint8_t tensor_arena[kTensorArenaSize];
void setup() {
Serial.begin(115200);
// Inicializar sensores (APDS‑9960 e MAX9814)
// ...
}
void loop() {
float input_data[NUM_FEATURES];
// Preencher input_data com leituras dos sensores
// input_data[0..X] = ...
// Configurar interpreter
static tflite::MicroErrorReporter micro_error_reporter;
static tflite::AllOpsResolver resolver;
const tflite::Model* model = tflite::GetModel(modelo_gestos_sons_tflite);
static tflite::MicroInterpreter interpreter(
model, resolver, tensor_arena, kTensorArenaSize, µ_error_reporter);
interpreter.AllocateTensors();
// Preencher tensor de entrada
float* input = interpreter.input(0)->data.f;
for (int i = 0; i < NUM_FEATURES; ++i) input[i] = input_data[i];
// Executar inferência
interpreter.Invoke();
float* output = interpreter.output(0)->data.f;
// Encontrar maior probabilidade
int prediction = max_element(output, output + NUM_CLASSES) - output;
Serial.print("Predição: ");
Serial.println(prediction);
delay(200);
}
Testando e ajustando
- Faça upload do sketch e abra o monitor serial.
- Execute gestos e clique perto do microfone; observe as predições.
- Se necessário, colete mais dados e refine o modelo.
Dicas de otimização
- Reduza a complexidade: experimente camadas menores (8→8→N) para caber em menos memória.
- Quantização agressiva: aplique quantização de peso e ativação para 8 bits.
- Pré‑processamento on‑chip: mova filtragens ou médias móveis para o firmware, reduzindo variância de entrada.
Conclusão e próximos passos
Você criou um sistema TinyML completo: coleta de dados, treinamento, conversão e deploy em um ESP32‑S3 UNO, utilizando sensores adquiridos na Saravati. Com essa base, é possível expandir para:
- Reconhecimento de mais gestos ou sons complexos.
- Envio de eventos por Wi‑Fi/MQTT para dashboards ou apps móveis.
- Integração com atuadores (motores, LEDs, relés).
Para continuar evoluindo seus projetos, acesse nosso catálogo completo em saravati.com.br e encontre todos os componentes necessários, de microcontroladores a sensores e módulos de comunicação. Qualquer dúvida ou sugestão, deixe um comentário no blog!