Skip to Content

Começar com o XIAO MG24 Sense

Começar com o XIAO MG24 Sense

O XIAO MG24 Sense é uma das placas da série XIAO da Seeed Studio, combinando um microcontrolador Silicon Labs EFR32MG24 potente com sensores integrados como um microfone e um IMU de 6 eixos. Graças ao seu formato compacto, design de baixo consumo e capacidades wireless integradas, é uma excelente escolha para projetos em IoT, fusão de sensores e edge AI.

Neste guia, vamos abordar o básico para começar a usar o XIAO MG24 Sense. Começaremos por instalar o core da placa necessário, depois executaremos o clássico exemplo blink para confirmar que tudo está a funcionar. Depois, exploraremos as suas características principais: o microfone integrado e o IMU (Unidade de Medição Inercial).

Peças Necessárias

Vai precisar de uma placa XIAO MG24 Sense da Seeed Studio e de um cabo USB-C para programar a placa e testar os exemplos de código.

Seeed Studio XIAO MG24 Sense

Cabo USB C

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

O XIAO MG24 Sense

O XIAO MG24 Sense é alimentado pelo sistema em chip Silicon Labs EFR32MG24, que usa um microcontrolador ARM Cortex-M33 a até 78 MHz. Isto oferece bastante capacidade de processamento para projetos embebidos gerais, mantendo alta eficiência energética. Uma característica destacada deste chip é o Matrix-Vector Processor (MVP), um pequeno acelerador de hardware que acelera operações matemáticas necessárias em machine learning. Isto torna o MG24 Sense especialmente adequado para aplicações TinyML, como reconhecimento de palavras-chave ou classificação de movimentos, sem esgotar rapidamente a bateria.

Components of XIAO MG24 Sense
Componentes do XIAO MG24 Sense

Em termos de memória, a placa inclui 1,5 MB de flash e 256 kB de RAM integrados no microcontrolador. Além disso, a Seeed Studio adicionou um chip flash SPI externo de 4 MB, útil para armazenar programas maiores, dados de modelos ou até logs. A combinação de memória interna e externa oferece espaço para experimentar aplicações mais complexas, mantendo um formato compacto.

A conectividade wireless é outra força deste dispositivo. O MG24 suporta Matter sobre Thread, bem como Bluetooth Low Energy 5.3, garantindo compatibilidade com ecossistemas IoT modernos e conectividade com smartphones. A placa também inclui recursos de segurança Secure Vault em hardware, que protegem dados sensíveis como chaves de encriptação e permitem boot seguro.

Sensores

O “Sense” no nome da placa vem dos seus sensores integrados. Primeiro, há o IMU LSM6DS3TR-C, um sensor de seis eixos que combina um acelerómetro de três eixos com um giroscópio de três eixos. Este sensor é capaz de medir movimento, orientação, passos e gestos, incluindo modos de baixo consumo para deteção contínua de atividade sem grande gasto energético. Pode encontrar mais detalhes na folha de dados abaixo:

Além do IMU, há o microfone MEMS MSM381ACT001, que permite captar som. Embora seja um microfone analógico, o ADC do microcontrolador facilita a amostragem e processamento de áudio, seja para deteção de som ou interações ativadas por voz. Veja a folha de dados abaixo:

GPIO

Para interfaceamento de hardware, o XIAO MG24 Sense expõe 19 pinos GPIO (entrada/saída de uso geral), organizados no formato familiar do XIAO. Estes pinos podem ser usados para I²C, SPI, UART e outras interfaces padrão.

Pinout of XIAO MG24 Sense
Pinout do XIAO MG24 Sense

Um LED de utilizador e um LED de energia/carga também estão presentes para ajudar na depuração e feedback rápido. O carregamento do código é feito via conector USB-C, que também serve para alimentação e carregamento.

Alimentação

A eficiência energética é um dos pontos fortes do XIAO MG24 Sense. Em modos de sono profundo, o microcontrolador pode reduzir o consumo para apenas alguns microamperes, tornando-o ideal para projetos alimentados por bateria. A placa inclui um circuito de carregamento para baterias Li-Po e pode também medir a tensão da bateria para que os seus projetos possam monitorizar os seus próprios níveis de energia. Com estas características, o MG24 Sense é uma excelente escolha para nós IoT alimentados por bateria a longo prazo.

Battery connector of XIAO MG24 Sense
Conector de bateria do XIAO MG24 Sense

Dimensões

Apesar de incluir todas estas funcionalidades, a placa mantém o formato clássico XIAO com apenas 21 × 17,8 mm, facilitando a integração em projetos compactos ou wearables. Inclui uma antena integrada para comunicação wireless, pelo que não precisa de módulos adicionais para começar.

Para resumir, o XIAO MG24 Sense combina um microcontrolador potente e eficiente, conectividade wireless moderna, hardware seguro, sensores integrados de movimento e áudio, memória generosa e um design amigo da bateria num pacote muito pequeno.

Especificações Técnicas

CaracterísticaEspecificação
ProcessadorSilicon Labs EFR32MG24, ARM Cortex-M33, até 78 MHz
Acelerador de hardwareMatrix-Vector Processor (MVP) para cargas de ML
Memória interna1536 kB flash, 256 kB RAM
Memória externa4 MB SPI flash
WirelessMatter (Thread), Bluetooth Low Energy 5.3
SegurançaMotor de segurança Secure Vault em hardware
IMULSM6DS3TR-C, acelerómetro + giroscópio de 6 eixos
MicrofoneMicrofone MEMS analógico MSM381ACT001
GPIO19 pinos (I²C, SPI, UART, GPIO, etc.)
USBUSB-C para programação, alimentação e carregamento
Características da bateriaCircuito de carregamento integrado, monitorização da tensão da bateria
Eficiência energéticaUltra baixo consumo, corrente de sono até ~1,95 µA
Formato21 × 17,8 mm, antena integrada

XIAO MG24 Sense versus XIAO MG24

A Seeed Studio oferece duas versões muito próximas desta placa: o XIAO MG24 e o XIAO MG24 Sense. Ambos partilham a mesma base, construída em torno do microcontrolador EFR32MG24 com núcleo ARM Cortex-M33, Matrix-Vector Processor para machine learning e suporte para padrões wireless modernos como Matter (Thread) e Bluetooth Low Energy 5.3. Também partilham o mesmo formato compacto XIAO, a mesma flash externa de 4 MB e o mesmo design de baixo consumo com circuito de carregamento integrado para baterias Li-Po.

A principal diferença reside nas capacidades de sensing. O XIAO MG24 Sense integra dois sensores adicionais a bordo: o IMU LSM6DS3TR-C de 6 eixos e o microfone MEMS analógico MSM381ACT001. Estas adições permitem à versão Sense detetar movimento, orientação e som imediatamente, tornando-a uma opção muito mais forte para projetos que envolvam reconhecimento de gestos, entrada de áudio ou fusão de sensores. Em contraste, o XIAO MG24 padrão não inclui estes sensores, o que também o torna ligeiramente mais barato e mais adequado se precisar apenas do microcontrolador, funcionalidades wireless e pinos I/O.

Outra pequena distinção está nos casos de uso pretendidos. O XIAO MG24 é desenhado como uma placa IoT ultra-baixo consumo de uso geral, enquanto o XIAO MG24 Sense é mais direcionado para projetos de edge AI e sensing inteligente onde o movimento e o áudio têm um papel. Se o seu projeto envolve coisas como reconhecimento de palavras-chave TinyML, monitorização de fitness, controlo por gestos ou eventos ativados por som, a versão Sense poupa-lhe o esforço de ligar sensores externos. Se, no entanto, quiser uma placa base simples e económica para nós IoT wireless ou redes de sensores, o MG24 sem Sense pode ser tudo o que precisa.

XIAO MG24 versus ESP32

O ESP32 é bem conhecido na comunidade maker por combinar um processador Xtensa LX6/LX7 dual-core (ou às vezes single-core, dependendo da variante) a até 240 MHz com conectividade Wi-Fi e Bluetooth. Isto torna-o especialmente atraente para projetos que requerem maior poder de processamento bruto ou conectividade à internet via Wi-Fi. O ESP32 também tem quantidades generosas de RAM (normalmente 520 kB SRAM, com PSRAM externo disponível em alguns módulos) e memória flash, tornando-o adequado para aplicações como servidores web, streaming de áudio em tempo real ou interfaces de utilizador complexas. O seu ecossistema é vasto, com excelente suporte comunitário, inúmeros tutoriais e compatibilidade com plataformas como Arduino, ESP-IDF e MicroPython.

Em contraste, o EFR32MG24 usado no XIAO MG24 foca-se no baixo consumo, padrões wireless modernos e segurança. Funciona a uma velocidade de relógio mais baixa (até 78 MHz) e tem menos RAM, mas inclui o Matrix-Vector Processor (MVP) para acelerar tarefas de machine learning. Em vez de Wi-Fi, suporta Matter (Thread) e Bluetooth Low Energy 5.3, ambos altamente relevantes para aplicações de smart home e IoT onde baixo consumo e redes mesh são importantes. O MG24 também integra as funcionalidades Secure Vault da Silicon Labs, oferecendo encriptação a nível de hardware e boot seguro.

Em resumo, o ESP32 é mais adequado para aplicações onde a conectividade Wi-Fi, maior poder de processamento ou grandes quantidades de memória são necessárias, enquanto o MG24 é desenhado para nós IoT alimentados por bateria, dispositivos sensores e aplicações que requerem forte segurança e padrões wireless modernos. Ambos são suportados pelo Arduino, mas o ESP32 beneficia de uma comunidade e ecossistema maiores, enquanto o MG24 é uma escolha forte para desenvolvedores interessados em Matter, BLE 5.3 e operação ultra-baixo consumo.

Tabela Comparativa

CaracterísticaXIAO MG24 (EFR32MG24)ESP32 (variantes típicas)
ProcessadorARM Cortex-M33, até 78 MHzXtensa LX6/LX7, single ou dual-core, até 240 MHz
Acelerador de hardwareMVP (Matrix-Vector Processor para ML)Nenhum (algumas variantes ESP32 incluem co-processadores AI/ML, ex: ESP32-S3 com instruções vetoriais)
Memória interna1536 kB flash, 256 kB RAM~448–520 kB SRAM, PSRAM externo em alguns módulos
Memória externa4 MB SPI flash (na placa XIAO)Normalmente 4–16 MB flash, PSRAM opcional
WirelessMatter (Thread), Bluetooth 5.3Wi-Fi 2.4 GHz, Bluetooth 4.2/5.0 (dependendo da variante)
SegurançaHardware Secure Vault (boot seguro, armazenamento de chaves)Boot seguro, encriptação flash (varia por variante)
EcossistemaSuportado no Arduino, SDKs oficiais Silicon LabsArduino, ESP-IDF, MicroPython, CircuitPython, grande comunidade
Eficiência energéticaUltra baixo consumo, corrente de sono na ordem dos µAModos de baixo consumo disponíveis, mas normalmente com consumo mais elevado
Mais indicado paraNós IoT de baixo consumo, dispositivos Matter/Thread, aplicações BLEProjetos com Wi-Fi, servidores web, streaming em tempo real, projetos maker gerais

Instalar o Core

Antes de começar a programar o XIAO MG24 ou XIAO MG24 Sense com o Arduino IDE, precisa de instalar o core da placa. Mas o que é exatamente um core de placa?

Um core no ecossistema Arduino é essencialmente um conjunto de ficheiros de software que permite ao Arduino IDE entender e comunicar com um tipo específico de microcontrolador. Inclui o compilador, linker, ficheiros de arranque, bibliotecas e definições da placa necessárias para construir e carregar código nesse microcontrolador. Sem um core, o Arduino IDE não saberia como transformar os seus sketches em código máquina que o microcontrolador pode executar.

Adicionar URL às Preferências

O XIAO MG24 usa o microcontrolador Silicon Labs EFR32MG24, que não está incluído na instalação padrão do Arduino. Para adicionar suporte a esta placa, siga estes passos.

Primeiro, Abra o Arduino IDE e vá a File → Preferences:

De seguida, no campo Additional Board Manager URLs, adicione a URL do pacote da Seeed Studio. A URL atual é:

https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json

Pode adicionar a URL como texto no campo de edição. Se já tiver outras URLs listadas, separe-as com uma vírgula.

Ou clique no ícone à direita, que abre um editor separado, onde pode adicionar a URL. Na captura de ecrã abaixo pode ver que já instalei o core ESP8266 e o core ESP32 também:

Instalar Placas

Depois, abra o Boards Manager indo a Tools → Board → Boards Manager… e escreva “MG24” na barra de pesquisa. Vai ver Silicon Labs e um texto listando a placa suportada. Pressione o botão INSTALL. A captura de ecrã abaixo mostra como fica após instalar o core (o botão INSTALL torna-se um botão REMOVE ):

Depois de instalado, selecione uma placa no seletor suspenso sob a barra de menu: No exemplo abaixo mostra um Arduino Uno como placa selecionada, por exemplo:

Bord selector

Clicar no nome da placa atualmente selecionada (Arduino Uno) abre o diálogo de seleção de placa. Na caixa de pesquisa escreva “mg24” e selecione “Seeed Studio XIAO MG24 (Sense)” como mostrado abaixo:

Se a placa estiver ligada ao seu PC via USB, também deverá conseguir selecionar a porta COM. Na captura acima é COM8, mas no seu caso pode ser uma porta COM diferente.

Após a instalação, o Arduino IDE trata o MG24 como qualquer outra placa suportada. Pode aceder a bibliotecas, usar GPIO, I²C, SPI, ADC e até aproveitar exemplos integrados para a placa, como o clássico sketch Blink, que vamos implementar na próxima secção.

Código Blink

Depois de instalado o core para o MG24, vamos testá-lo para ver se funciona mesmo. Usamos o programa comum Blink para o nosso teste. Abaixo está o código:

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  Serial.println("OFF");
  digitalWrite(LED_BUILTIN, HIGH);  
  delay(1000);                      

  Serial.println("ON");
  digitalWrite(LED_BUILTIN, LOW);   
  delay(1000);   

Pisca o LED integrado a cada segundo e também imprime o estado do LED no monitor serial. Note que a lógica é invertida. Escrever um sinal HIGH no pino do LED faz com que o LED fique apagado e vice-versa.

Carregue o código para a sua placa pressionando o ícone de upload no Arduino IDE. Certifique-se de que tem a placa correta selecionada (Seeed Studio XIAO MG24):

Deverá ver o seguinte estado de compilação e programação no terminal Output. Não se deixe enganar pela cor vermelha. Se conseguir ler “** Programming Finished **” está tudo bem.

De seguida, mude para a saída do terminal do Monitor Serial. Deve ver uma sequência de mensagens “ON” e “OFF” a aparecer. Ao mesmo tempo, o LED laranja da placa XIAO MG24 deve estar a piscar.

Se isto tudo funcionar, parabéns, já pode programar o seu XIAO MG24 Sense ; )

Nas próximas secções vamos experimentar a Unidade de Medição Inercial (IMU) e o Microfone do XIAO MG24 Sense.

Código IMU

O sketch seguinte mostra como ler dados de movimento do LSM6DS3, um IMU de 6 eixos que combina um acelerómetro de 3 eixos e um giroscópio de 3 eixos.

Antes de poder executá-lo, vai precisar de instalar a Seeed_Arduino_LSM6DS3 biblioteca. Faça o download da biblioteca em formato .ZIP do repositório Github e instale-a via Sketch → Include Library → Add .ZIP Library …

O programa de exemplo inicializa o sensor, verifica erros e imprime continuamente as leituras do acelerómetro e giroscópio no monitor serial. Vamos analisar o código passo a passo.

#include <LSM6DS3.h>
#include <Wire.h>

LSM6DS3 myIMU(I2C_MODE, 0x6A);  

void setup() {
  Serial.begin(115200);

  pinMode(PD5, OUTPUT);
  digitalWrite(PD5, HIGH);

  if (myIMU.begin() != 0) {
    Serial.println("Device error");
  } 
}

void loop() {
    Serial.print(myIMU.readFloatAccelX(), 3);
    Serial.print(',');
    Serial.print(myIMU.readFloatAccelY(), 3);
    Serial.print(',');
    Serial.print(myIMU.readFloatAccelZ(), 3);
    Serial.print(',');
    Serial.print(myIMU.readFloatGyroX(), 3);
    Serial.print(',');
    Serial.print(myIMU.readFloatGyroY(), 3);
    Serial.print(',');
    Serial.print(myIMU.readFloatGyroZ(), 3);
    Serial.println();
    delay(500);
}

Importações

O sketch começa por incluir duas bibliotecas essenciais. A primeira é <LSM6DS3.h>, que fornece uma interface fácil para o IMU LSM6DS3. A segunda é <Wire.h>, que permite a comunicação I2C entre o Arduino e o sensor. Sem estas, o Arduino não consegue comunicar com o IMU.

#include <LSM6DS3.h>
#include <Wire.h>

Objetos

Após as importações, o sketch cria um objeto chamado myIMU da classe LSM6DS3. O construtor indica ao programa para usar comunicação I2C e define o endereço I2C do sensor para 0x6A. Este endereço depende da forma como os pinos do sensor estão ligados e deve corresponder à configuração de hardware.

LSM6DS3 myIMU(I2C_MODE, 0x6A);

Setup

A função setup() executa uma vez no início. Começa por abrir a porta serial a 115200 baud para podermos ver os dados do sensor no Monitor Serial do Arduino IDE.

Serial.begin(115200);

De seguida, o código configura o pino PD5 como saída e define-o para HIGH. Isto é usado para ativar o IMU.

pinMode(PD5, OUTPUT);
digitalWrite(PD5, HIGH);

Finalmente, o sketch inicializa o IMU chamando myIMU.begin(). Se a função retornar um valor diferente de zero, o programa imprime "Device error" no Monitor Serial, sinalizando que o sensor não foi detetado ou inicializado corretamente.

if (myIMU.begin() != 0) {
  Serial.println("Device error");
}

Loop

A função loop() executa continuamente após o setup. Em cada ciclo, o sketch lê dados de aceleração e giroscópio do IMU e imprime-os no Monitor Serial em formato separado por vírgulas.

As leituras do acelerómetro são feitas nas direções X, Y e Z. Cada chamada a readFloatAccelX(), readFloatAccelY() e readFloatAccelZ() retorna um valor em ponto flutuante em g’s, que mede a aceleração relativa à gravidade. O segundo argumento 3 indica ao Monitor Serial para imprimir três dígitos após o ponto decimal.

Serial.print(myIMU.readFloatAccelX(), 3);
Serial.print(',');
Serial.print(myIMU.readFloatAccelY(), 3);
Serial.print(',');
Serial.print(myIMU.readFloatAccelZ(), 3);

De seguida, os valores do giroscópio são lidos nas direções X, Y e Z. As funções readFloatGyroX(), readFloatGyroY() e readFloatGyroZ() retornam a velocidade angular em graus por segundo. Novamente, o sketch imprime cada valor com três casas decimais, separadas por vírgulas.

Serial.print(',');
Serial.print(myIMU.readFloatGyroX(), 3);
Serial.print(',');
Serial.print(myIMU.readFloatGyroY(), 3);
Serial.print(',');
Serial.print(myIMU.readFloatGyroZ(), 3);

No final de cada loop, o sketch imprime uma nova linha para que cada conjunto completo de leituras apareça numa linha própria. Depois faz uma pausa de 500 milissegundos antes de repetir. Este atraso mantém a saída legível e evita sobrecarregar o Monitor Serial.

Serial.println();
delay(500);

Se carregar e executar este código, deverá ver um fluxo de números a aparecer no seu Monitor Serial que muda se mover o XIAO MG24 Sense:

Nas próximas duas secções vamos experimentar o microfone do XIAO MG24 Sense, usando duas bibliotecas diferentes.

Código do Microfone com a Biblioteca SiliconLabs

O código seguinte mostra como captar amostras de áudio do microfone, calcular o nível médio do sinal e mapear esse nível para o brilho do LED. Usa um sistema de callback para tratar os dados do microfone de forma eficiente. Vamos explorar o código por partes.

#include <SilabsMicrophoneAnalog.h>

#define MIC_DATA_PIN PC9
#define MIC_PWR_PIN PC8
#define NUM_SAMPLES 128
#define MIC_VAL_MIN 735
#define MIC_VAL_MAX 900

uint32_t mic_buffer[NUM_SAMPLES];
uint32_t mic_buffer_local[NUM_SAMPLES];

volatile bool data_ready_flag = false;
MicrophoneAnalog micAnalog(MIC_DATA_PIN, MIC_PWR_PIN);

void mic_samples_ready_cb() {
  memcpy(mic_buffer_local, mic_buffer, NUM_SAMPLES * sizeof(uint32_t));
  data_ready_flag = true;
}

void calculate_and_display_voice_level() {
  static uint32_t avg = 0;

  micAnalog.stopSampling();

  uint32_t level = (uint32_t)micAnalog.getAverage(mic_buffer_local, NUM_SAMPLES);
  level = constrain(level, MIC_VAL_MIN, MIC_VAL_MAX);
  avg = (level + avg) / 2;

  int brightness = map(avg, MIC_VAL_MIN, MIC_VAL_MAX, 0, 255);
  analogWrite(LED_BUILTIN, 255 - brightness);
  Serial.println(avg);

  micAnalog.startSampling(mic_samples_ready_cb);
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  micAnalog.begin(mic_buffer, NUM_SAMPLES);
  Serial.println("Microphone initialized...");

  micAnalog.startSampling(mic_samples_ready_cb);
  Serial.println("Sampling started...");
}

void loop() {
  if (data_ready_flag) {
    data_ready_flag = false;
    calculate_and_display_voice_level();
  }
}

Importações

O sketch começa por incluir a biblioteca SilabsMicrophoneAnalog.h. Esta biblioteca fornece funções para inicializar o microfone, iniciar e parar a amostragem e processar os dados recolhidos.

#include <SilabsMicrophoneAnalog.h>

Constantes

De seguida, o programa define várias constantes. MIC_DATA_PIN e MIC_PWR_PIN especificam os pinos ligados às linhas de dados e alimentação do microfone. NUM_SAMPLES determina quantas amostras de áudio serão recolhidas de cada vez. MIC_VAL_MIN e MIC_VAL_MAX definem o intervalo esperado dos valores do microfone para normalização. Estes limites ajudam a filtrar ruído indesejado e garantem um bom mapeamento do brilho do LED.

#define MIC_DATA_PIN PC9
#define MIC_PWR_PIN PC8
#define NUM_SAMPLES 128
#define MIC_VAL_MIN 735
#define MIC_VAL_MAX 900

Buffers

Dois buffers armazenam as amostras do microfone. mic_buffer guarda amostras brutas do microfone, enquanto mic_buffer_local armazena uma cópia segura dessas amostras para processamento. Esta separação evita erros se novos dados chegarem enquanto os cálculos ainda estão em curso.

uint32_t mic_buffer[NUM_SAMPLES];
uint32_t mic_buffer_local[NUM_SAMPLES];

Flags e Objetos

A variável data_ready_flag indica ao programa quando um novo conjunto de amostras está disponível. Está marcada como volatile porque é atualizada dentro de uma interrupção ou callback. O objeto micAnalog é criado a partir da classe MicrophoneAnalog. Recebe os pinos de dados e alimentação do microfone como parâmetros.

volatile bool data_ready_flag = false;
MicrophoneAnalog micAnalog(MIC_DATA_PIN, MIC_PWR_PIN);

Callback do Microfone

A função mic_samples_ready_cb() executa automaticamente sempre que o microfone termina de recolher um lote de amostras. Copia o conteúdo de mic_buffer para mic_buffer_local e define data_ready_flag como true, sinalizando que os dados estão prontos para processamento.

void mic_samples_ready_cb() {
  memcpy(mic_buffer_local, mic_buffer, NUM_SAMPLES * sizeof(uint32_t));
  data_ready_flag = true;
}

Processamento dos Níveis de Voz

A função calculate_and_display_voice_level() processa os dados de áudio e atualiza o brilho do LED. Primeiro, para a amostragem do microfone para evitar interferências durante os cálculos. Depois calcula o valor médio do sinal usando micAnalog.getAverage(). Este valor é limitado entre MIC_VAL_MIN e MIC_VAL_MAX para suavizar picos extremos.

Para fazer o LED responder de forma mais suave, o valor médio é combinado com a média anterior usando um filtro simples. O resultado é mapeado do intervalo do microfone para o intervalo de brilho do LED de 0 a 255. Finalmente, o brilho do LED é definido usando analogWrite(). Um nível de som mais alto torna o LED mais brilhante.

A função também imprime o valor médio no Monitor Serial e depois reinicia a amostragem do microfone.

void calculate_and_display_voice_level() {
  static uint32_t avg = 0;

  micAnalog.stopSampling();

  uint32_t level = (uint32_t)micAnalog.getAverage(mic_buffer_local, NUM_SAMPLES);
  level = constrain(level, MIC_VAL_MIN, MIC_VAL_MAX);
  avg = (level + avg) / 2;

  int brightness = map(avg, MIC_VAL_MIN, MIC_VAL_MAX, 0, 255);
  analogWrite(LED_BUILTIN, 255 - brightness);
  Serial.println(avg);

  micAnalog.startSampling(mic_samples_ready_cb);
}

Setup

A função setup() prepara o monitor serial e o LED. Também inicializa o microfone com o buffer e o número de amostras. Uma vez inicializado, o sketch começa a amostrar e imprime mensagens de confirmação no Monitor Serial.

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  micAnalog.begin(mic_buffer, NUM_SAMPLES);
  Serial.println("Microphone initialized...");

  micAnalog.startSampling(mic_samples_ready_cb);
  Serial.println("Sampling started...");
}

Loop

A função loop() verifica se há novos dados prontos. Se data_ready_flag for verdadeiro, limpa a flag e chama calculate_and_display_voice_level(). Isto garante que os dados do microfone são processados apenas quando há amostras frescas disponíveis.

void loop() {
  if (data_ready_flag) {
    data_ready_flag = false;
    calculate_and_display_voice_level();
  }
}

Depois de carregar o código, deverá ver o brilho do LED integrado a mudar dependendo dos níveis de volume ambiente. Quanto mais alto, mais brilhante.

Código do Microfone com a Biblioteca Seeed_Arduino_Mic

Este sketch inicializa um microfone usando a biblioteca Seeed_Arduino_Mic, recolhe um número fixo de amostras de áudio e as envia como dados brutos. Demonstra como configurar parâmetros do microfone, tratar callbacks e processar dados de áudio recebidos.

Vai precisar de instalar a biblioteca Seeed_Arduino_Mic antes de poder executar este código. Faça o download da biblioteca em formato .ZIP do repositório Github e instale-a via Sketch → Include Library → Add .ZIP Library …

Dê uma vista rápida ao sketch completo primeiro e depois vamos analisar os detalhes:

#include <mic.h>

#define DEBUG 1  // Enable pin pulse during ISR
#define SAMPLES 800

mic_config_t mic_config{
  .channel_cnt = 1,
  .sampling_rate = 16000,
  .buf_size = 1600,
  .debug_pin = LED_BUILTIN  // Toggles each DAC ISR (if DEBUG is set to 1)
};

MG24_ADC_Class Mic(&mic_config);

int16_t recording_buf[SAMPLES];
volatile uint8_t recording = 0;
volatile static bool record_ready = false;

static void audio_rec_callback(uint16_t *buf, uint32_t buf_len) {
  static uint32_t idx = 0;

  for (uint32_t i = 0; i < buf_len; i++) {
    // Convert 12-bit unsigned ADC value to 16-bit PCM (signed) audio value
    recording_buf[idx++] = buf[i];
    if (idx >= SAMPLES) {
      idx = 0;
      recording = 0;
      record_ready = true;
      break;
    }
  }
}

void setup() {
  Serial.begin(115200);
  Mic.set_callback(audio_rec_callback);

  if (!Mic.begin()) {
    Serial.println("Mic initialization failed");
    while (1)
      ;
  }
  Serial.println("Mic initialization done.");
}

void loop() {
  if (record_ready) {
    Serial.println("Finished sampling");
    for (int i = 0; i < SAMPLES; i++) {
      int16_t sample = recording_buf[i];
      Serial.println(sample);
    }
    record_ready = false;
  }
}

Importações

O programa começa por incluir o ficheiro de cabeçalho mic.h. Esta biblioteca fornece ferramentas para configurar e controlar o hardware do microfone nas plataformas Seeed.

#include <mic.h>

Constantes

Duas constantes são definidas. A primeira, DEBUG, permite ativar o pulso do pino durante interrupções para depuração. Se DEBUG estiver definido como 1, o pino do LED alterna sempre que ocorre uma interrupção, dando uma indicação visual da atividade de amostragem. A segunda constante, SAMPLES, especifica o número de amostras de áudio a gravar antes do processamento.

#define DEBUG 1  // Enable pin pulse during ISR
#define SAMPLES 800

Configuração do Microfone

O microfone é configurado usando uma estrutura mic_config_t. Aqui, o microfone está definido para usar um canal, uma taxa de amostragem de 16 kHz e um buffer de 1600 amostras. O debug_pin está ligado ao LED_BUILTIN, para que o LED integrado alterne durante cada interrupção se a depuração estiver ativada.

mic_config_t mic_config{
  .channel_cnt = 1,
  .sampling_rate = 16000,
  .buf_size = 1600,
  .debug_pin = LED_BUILTIN
};

O programa cria então um objeto microfone chamado Mic usando a MG24_ADC_Class. Este objeto recebe a configuração do microfone como entrada e gere a recolha de dados.

MG24_ADC_Class Mic(&mic_config);

Buffers e Flags

O array recording_buf armazena as amostras gravadas, com um tamanho igual à constante SAMPLES. Duas variáveis gerem o processo de gravação: recording acompanha o estado da gravação, e record_ready sinaliza quando o buffer está cheio e pronto para processamento. Ambas são declaradas volatile porque são modificadas dentro de uma callback de interrupção.

int16_t recording_buf[SAMPLES];
volatile uint8_t recording = 0;
volatile static bool record_ready = false;

Callback

O núcleo do processo de gravação acontece na função audio_rec_callback(). Esta callback executa automaticamente sempre que o buffer do microfone enche. A função copia os dados de áudio do buffer de entrada para o principal recording_buf.

Cada valor bruto ADC de 12 bits do microfone é convertido numa amostra PCM assinada de 16 bits. A função mantém o controlo do índice atual no buffer com uma variável estática idx. Quando o buffer atinge o tamanho máximo (SAMPLES), a função reinicia o índice, limpa a flag de gravação e define record_ready como verdadeiro para que o loop saiba que os dados estão prontos para processamento.

static void audio_rec_callback(uint16_t *buf, uint32_t buf_len) {
  static uint32_t idx = 0;

  for (uint32_t i = 0; i < buf_len; i++) {
    // Convert 12-bit unsigned ADC value to 16-bit PCM (signed) audio value
    recording_buf[idx++] = buf[i];
    if (idx >= SAMPLES) {
      idx = 0;
      recording = 0;
      record_ready = true;
      break;
    }
  }
}

Setup

Dentro de setup(), o Monitor Serial é inicializado a 115200 baud. O programa atribui audio_rec_callback como a função que vai tratar os dados de áudio recebidos sempre que o microfone recolher amostras.

O microfone é então iniciado usando Mic.begin(). Se a inicialização falhar, o programa imprime uma mensagem de erro e entra num ciclo infinito. Caso contrário, confirma a inicialização com sucesso.

void setup() {
  Serial.begin(115200);
  Mic.set_callback(audio_rec_callback);

  if (!Mic.begin()) {
    Serial.println("Mic initialization failed");
    while (1);
  }
  Serial.println("Mic initialization done.");
}

Loop

A função loop() verifica se a gravação foi concluída olhando para record_ready. Se verdadeiro, o programa imprime "Finished sampling" e depois percorre o buffer, imprimindo cada amostra de áudio gravada. Após imprimir, reinicia record_ready para false para que o sistema possa gravar novamente.

void loop() {
  if (record_ready) {
    Serial.println("Finished sampling");
    for (int i = 0; i < SAMPLES; i++) {
      int16_t sample = recording_buf[i];
      Serial.println(sample);
    }
    record_ready = false;
  }
}

Se carregar este sketch e abrir o Serial Plotter verá um sinal de áudio que varia dependendo do som detetado pelo microfone:

E é tudo! Estas instruções e exemplos de código devem ajudar a começar rapidamente com o XIAO MG24 Sense.

Conclusões

Neste tutorial aprendeu como começar a usar o XIAO MG24 Sense da Seeed Studio. Para informações adicionais, consulte o Getting Started Wiki da Seeed Studio. Os exemplos de código neste tutorial são derivados dos exemplos nas bibliotecas Seeed_Arduino_Mic e Seeed_Arduino_LSM6DS3. Vai encontrar mais exemplos de código lá.

Com o microfone integrado e o Matrix-Vector Processor (MVP), o XIAO MG24 Sense é especialmente adequado para aplicações TinyML como reconhecimento de palavras-chave, controlo por voz ou classificação de som.

Um microcontrolador alternativo é o ESP32 baseado no XIAO-ESP32-S3-Sense – também da Seeed Studio. Também vem com microfone e, embora não tenha IMU, tem uma câmara em vez disso. Pode ser usado para aplicações de voz, veja também o nosso Voice control with XIAO-ESP32-S3-Sense and Edge Impulse, mas consome mais energia.

No entanto, se estiver interessado em deteção de objetos, o XIAO ESP32 Sense é a melhor escolha devido à câmara integrada. Veja os nossos tutoriais Face Detection with XIAO ESP32-S3-Sense and SenseCraft AI e Edge AI Room Occupancy Sensor with ESP32 and Person Detection para detalhes.

Se tiver alguma dúvida, sinta-se à vontade para deixar nos comentários.

Boas experiências a criar 😉