Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Control de Luces RGB con Detección de Palabras Clave TinyML

Componentes y suministros

Arduino Nano 33 BLE Sense × 1

Aplicaciones y servicios en línea

Sobre el proyecto

La premisa

El machine learning en el borde (edge) es extremadamente útil para crear dispositivos que pueden realizar tareas "inteligentes" con mucha menos programación y diagramas de flujo lógico comparado con código tradicional. Por eso quise incorporar detección de palabras clave en el borde que reconozca ciertas palabras y realice una tarea basada en lo dicho.

Hardware

Este proyecto tiene un solo componente: un Arduino Nano 33 BLE Sense. La magia ocurre en el modelo de machine learning. El Nano 33 BLE Sense está lleno de sensores: micrófono, IMU de 9 ejes, sensor ambiental y sensor de gestos/proximidad/color/luz ambiente (APDS-9960). El microcontrolador es un nRF52840 a 64MHz con 1MB flash y 256KB RAM. Este proyecto también usa su LED RGB integrado para mostrar el color actual.

Configuración de Edge Impulse

Comencé creando un nuevo proyecto en Edge Impulse e instalé la CLI de Edge Impulse. Esto permite que el Arduino Nano se comunique con el servicio en la nube para recibir comandos y enviar datos de sensores automáticamente. Descargué el firmware más reciente de Edge Impulse y lo flasheé a la placa pulsando dos veces el botón de reset para entrar en modo bootloader. Luego ejecuté flash_windows.bat para transferirlo.

En la línea de comandos ejecuté edge-impulse-daemon y seguí el asistente. Ahora el Nano aparece en la lista de dispositivos del proyecto, permitiendo tomar muestras y subirlas como parte del conjunto de datos de entrenamiento/prueba.

Recopilación de muestras

Entrenar un modelo ML requiere datos, y bastantes. Quería los siguientes modos para la tira LED RGB:

Obtuve aproximadamente 1 minuto de audio para cada modo repitiendo la palabra a intervalos de 1-2 segundos y las dividí. Pero solo tener estas muestras no basta, ya que el ruido de fondo y otras palabras darían falsos positivos. Afortunadamente, Edge Impulse proporciona un dataset pre-construido para ruido y palabras "desconocidas", así que usé su herramienta "Upload Existing Data" para subir estos archivos de audio a los datos de entrenamiento. Finalmente, rebalanceé el dataset para tener la división recomendada 80-20 entre entrenamiento y prueba.

Entrenamiento del modelo

Con una hora de datos de entrenamiento y muchas etiquetas, era hora de entrenar. El impulso diseñado toma audio como datos de series temporales con ventana de 1 segundo e incremento de 500ms. Pasa por un bloque MFCC a una red neuronal Keras.

El bloque MFCC permite configurar cómo se procesa el audio, con un espectrograma visual. Dejé la red neuronal mayormente por defecto, pero bajé el umbral de confianza mínima de 0.80 a 0.70 y añadí aumento de datos (ruido adicional y enmascaramiento de bandas temporales) para evitar sobreajuste.

Despliegue en Arduino Nano 33 BLE Sense

El Nano 33 BLE Sense actúa como micrófono siempre activo que muestrea continuamente audio y detecta si se ha pronunciado una palabra clave. Al detectar una, la convierte en un índice para decodificar el color deseado. Para "on"/"off", el LED se pone gris claro o negro (apagado).

Descargué el modelo como biblioteca, la añadí al Arduino IDE, compilé y flasheé el código al Nano.

Código

RGBLEDKeywordDetection (C/C++)

/* Edge Impulse Arduino examples
 * Copyright (c) 2020 EdgeImpulse Inc. */
#define EIDSP_QUANTIZE_FILTERBANK 0
#define EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW 3

#include <PDM.h>
#include <keyword_detection_inference.h>
#include <map>

#define CONFIDENCE_THRESHOLD 0.7

static const uint32_t colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff}; // rojo, verde, azul

enum Actions { LED_ON = 1, LED_OFF = 0, LED_RED = 2, LED_GREEN = 3, LED_BLUE = 4, NONE = 5 };
enum Functions { CHANGE_LED_ON_OFF = 0, CHANGE_LED_COLOR = 1, CHANGE_LED_NONE = 2 };

static const uint8_t redPin = 22, greenPin = 23, bluePin = 24;

const std::map<Actions, Functions> actionToFunctionMap = {
  {LED_ON, CHANGE_LED_ON_OFF}, {LED_OFF, CHANGE_LED_ON_OFF},
  {LED_RED, CHANGE_LED_COLOR}, {LED_GREEN, CHANGE_LED_COLOR},
  {LED_BLUE, CHANGE_LED_COLOR}, {NONE, CHANGE_LED_NONE}
};

const std::map<const char*, Actions> labelToActionMap = {
  {"on", LED_ON}, {"off", LED_OFF}, {"red", LED_RED},
  {"green", LED_GREEN}, {"blue", LED_BLUE},
  {"unknown", NONE}, {"noise", NONE}
};

// Buffers de audio, punteros y selectores
typedef struct {
  signed short *buffers[2];
  unsigned char buf_select, buf_ready;
  unsigned int buf_count, n_samples;
} inference_t;

static inference_t inference;
static bool record_ready = false;
static signed short *sampleBuffer;
static bool debug_nn = false;
static int print_results = -(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW);

void setup() {
  Serial.begin(115200);
  Serial.println("Edge Impulse Inferencing");
  setPixelColor(0xaeae00); // Amarillo inicial
  
  ei_printf("Inferencing settings:\n");
  ei_printf("\tInterval: %.2f ms.\n", (float)EI_CLASSIFIER_INTERVAL_MS);
  ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
  ei_printf("\tSample length: %d ms.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16);
  ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0]));
  
  run_classifier_init();
  if (microphone_inference_start(EI_CLASSIFIER_SLICE_SIZE) == false) {
    ei_printf("ERR: Failed to setup audio sampling\r\n");
    return;
  }
}

void loop() {
  bool m = microphone_inference_record();
  if (!m) { ei_printf("ERR: Failed to record audio...\n"); return; }
  
  signal_t signal;
  signal.total_length = EI_CLASSIFIER_SLICE_SIZE;
  signal.get_data = µphone_audio_signal_get_data;
  ei_impulse_result_t result = {0};
  EI_IMPULSE_ERROR r = run_classifier_continuous(&signal, &result, debug_nn);
  if (r != EI_IMPULSE_OK) { ei_printf("ERR: Failed to run classifier (%d)\n", r); return; }
  
  if (++print_results >= (EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW)) {
    ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.):\n",
              result.timing.dsp, result.timing.classification, result.timing.anomaly);
    for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
      if(result.classification[ix].value > CONFIDENCE_THRESHOLD) {
        performAction(result.classification[ix].label);
      }
      ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
    }
    #if EI_CLASSIFIER_HAS_ANOMALY == 1
    ei_printf(" anomaly score: %.3f\n", result.anomaly);
    #endif
    print_results = 0;
  }
}

void setPixelColor(uint32_t c) {
  analogWrite(redPin, 255 - (c >> 16));
  analogWrite(greenPin, 255 - ((c >> 8) & 0xff));
  analogWrite(bluePin, 255 - (c & 0xff));
}

void performAction(const char* classificationLabel) {
  auto itr = labelToActionMap.find(classificationLabel);
  if(itr == labelToActionMap.end()) return;
  auto itr2 = actionToFunctionMap.find(itr->second);
  if(itr2 == actionToFunctionMap.end()) return;
  
  switch(itr2->second) {
    case CHANGE_LED_ON_OFF:
      setPixelColor((itr->second) ? 0x5c5c5c : 0x00);
      break;
    case CHANGE_LED_COLOR: {
      uint32_t pixelColor = colors[itr->second - 2];
      setPixelColor(pixelColor);
    } break;
    case CHANGE_LED_NONE: break;
  }
}

void ei_printf(const char *format, ...) {
  static char print_buf[1024] = { 0 };
  va_list args;
  va_start(args, format);
  int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
  va_end(args);
  if (r > 0) Serial.write(print_buf);
}

// Callbacks PDM e inferencia (microphone_inference_start, record, end, signal_get_data)
// Ver código completo en el original

Proceso de manufactura

  1. Cuatro pasos probados para maximizar el éxito del edge computing en fábricas inteligentes
  2. Por qué debe mantener los detectores de gases en óptimas condiciones: 3 razones esenciales
  3. Arm presenta Cortex-M55 y Ethos-U55: nuevos núcleos IP para TinyML en endpoints de bajo consumo
  4. Sistema ultra-sensible de detección de armas químicas para amenazas de bajo nivel
  5. Seguridad Industrial IoT: Tendencias clave y mejores prácticas para 2020
  6. Edge y Cloud Computing en IoT: Una visión evolutiva concisa
  7. Por qué el Edge Computing es esencial para el éxito del IoT
  8. Kontron KBox A-150-WKL: PC Edge IoT de Alto Rendimiento y Bajo Consumo para Automatización Industrial
  9. Edge Computing: Acelerando el despliegue de IA en el perímetro de la red
  10. Microsoft presenta Azure Edge Zones para impulsar cargas de trabajo IoT e IA con 5G
  11. Por Qué el Open Source Impulsa la Innovación en el Edge: eBook Esencial