Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Обнаружение ключевого слова TinyML для управления освещением RGB

Компоненты и расходные материалы

Arduino Nano 33 BLE Sense
× 1

Приложения и онлайн-сервисы

Edge Impulse Studio

Об этом проекте

Предпосылка

Машинное обучение на периферии чрезвычайно полезно для создания устройств, которые могут выполнять «интеллектуальные» задачи с гораздо меньшим объемом программирования и логических блок-схем по сравнению с традиционным кодом. Вот почему я хотел включить передовое определение ключевых слов, которое может распознавать определенные слова, а затем выполнять задачу на основе того, что было сказано.

Аппаратное обеспечение

В этом проекте всего один компонент:Arduino Nano 33 BLE Sense. Настоящее волшебство происходит в модели машинного обучения. Arduino Nano 33 BLE Sense полон датчиков, включая микрофон, 9-осевой IMU, датчик окружающей среды и датчик жестов / приближения / цвета / внешней освещенности (APDS-9960). Микроконтроллер на нем - nRF52840, который работает на частоте 64 МГц и содержит 1 МБ флэш-памяти и 256 КБ ОЗУ. В этом проекте также используется встроенный светодиод RGB для отображения текущего цвета.

Настройка Edge Impulse

Я начал с создания нового проекта на Edge Impulse, а затем установил инструмент Edge Impulse CLI. Для получения дополнительных инструкций о том, как это сделать, посетите страницу с инструкциями по установке. Это позволяет Arduino Nano взаимодействовать с облачным сервисом для автоматического получения команд и отправки данных датчиков. Я загрузил самую последнюю версию прошивки Edge Impulse и прошил ее на плату, дважды щелкнув кнопку сброса, чтобы она перешла в режим загрузчика. Затем я запустил flash_windows.bat передать это.

В командной строке я запустил edge-impulse-daemon и, следуя указаниям мастера, настроил его. Теперь Nano отображается в списке устройств проекта, что позволяет брать образцы и выгружать их как часть набора данных для обучения / тестирования.

Сбор образцов

Для обучения модели машинного обучения требуются данные, и их довольно много. Я хотел иметь следующие режимы для светодиодной ленты RGB:

  • Вкл.
  • Выкл.
  • Красный
  • Зеленый
  • Синий

У меня было около 1 минуты звука для каждого режима, где я несколько раз повторял слово с интервалом 1-2 секунды и разбивал их.

Но просто иметь эти образцы недостаточно, поскольку фоновый шум и другие слова дадут ложные показания. К счастью, Edge Impulse уже предоставляет готовый набор данных для шума и «неизвестных» слов, поэтому я использовал их инструмент «Загрузить существующие данные», чтобы загрузить эти аудиофайлы в обучающие данные.

Наконец, я перебалансировал набор данных, чтобы получить рекомендованное разделение 80-20 для данных обучения и тестирования соответственно.

Обучение модели

Теперь, когда вы вооружились часом данных для обучения и множеством этикеток, пришло время обучить модель. Разработанный мной импульс воспринимает звук как данные временного ряда с размером окна в 1 секунду и увеличением окна на 500 мс. Затем он проходит через блок MFCC в блок нейронной сети Keras.

Блок MFCC позволяет вам настроить способ обработки звука, а также спектрограмму, отображающую частоты в визуальном виде.

Я оставил настройки нейронной сети в основном по умолчанию, но также внес несколько изменений. Во-первых, я изменил минимальный порог достоверности с 0,80 на 0,70 и добавил немного увеличения данных в виде дополнительного шума и временных диапазонов маскировки. Это помогает NN избежать чрезмерной подгонки модели, поскольку у нее есть более разнообразные данные для работы.

Развертывание на Arduino Nano 33 BLE Sense

Arduino Nano 33 BLE Sense действует как постоянно включенный микрофон, который непрерывно дискретизирует звук и определяет, было ли произнесено одно из ключевых слов. Как только он будет найден, ключевое слово преобразуется в индекс, который используется для декодирования желаемого цвета. Для ключевого слова on или off индикатор устанавливается на черный или светло-серый цвет.

Я загрузил модель в виде библиотеки и добавил ее в IDE Arduino, затем скомпилировал и прошил код в Nano.

Код

  • RGBLEDKeywordDetection
RGBLEDKeywordDetection C / C ++
 / * Примеры Edge Impulse Arduino * Copyright (c) 2020 EdgeImpulse Inc. * * Настоящим предоставляется бесплатное разрешение любому лицу, получившему копию * этого программного обеспечения и связанных файлов документации («Программное обеспечение»), иметь дело * с Программным обеспечением без ограничений, включая, помимо прочего, права * использовать, копировать, изменять, объединять, публиковать, распространять, сублицензировать и / или продавать * копии Программного обеспечения, а также разрешать лицам, которым принадлежит Программное обеспечение * предоставлено для этого при соблюдении следующих условий:* * Приведенное выше уведомление об авторских правах и это уведомление о разрешении должны быть включены * во все копии или существенные части Программного обеспечения. * * ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ * ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ​​ГАРАНТИЯМИ КОММЕРЧЕСКОЙ ЦЕННОСТИ, * ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НЕЗАЩИТЫ ОТ ИСПОЛЬЗОВАНИЯ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ * АВТОРЫ ИЛИ ВЛАДЕЛЬЦЫ АВТОРСКИХ ПРАВ НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УБЫТКИ ИЛИ ДРУГИЕ * ОТВЕТСТВЕННОСТЬ, ВЫЯВЛЯЮЩИЕСЯ В РЕЗУЛЬТАТЕ ДОГОВОРА, ИЛИ ИНОСТРАННЫМИ ПРАВИЛАМИ, ВЫЗЫВАЮЩИМИСЯ, * В СВЯЗИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМ ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ. ДЕЙСТВИЯ В ПРОГРАММНОМ ОБЕСПЕЧЕНИИ. * /// Если ваша цель ограничена в памяти, удалите этот макрос, чтобы сэкономить 10 КБ ОЗУ # define EIDSP_QUANTIZE_FILTERBANK 0 / ** * Определите количество срезов на окно модели. Например. окно модели 1000 мс * со срезами на окно модели, установленным на 4. В результате получается размер среза 250 мс. * Для получения дополнительной информации:https://docs.edgeimpulse.com/docs/continuous-audio-sampling * / # define EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW 3 / * Включает ------------------- --------------------------------------------- * / # include  #include  #include 
 #define CONFIDENCE_THRESHOLD 0.7static const uint32_t colors [] ={0x00ff0000, 0x0000ff00, 0x000000ff}; // красный, зеленый, синий действия enum {LED_ON =1, LED_OFF =0, LED_RED =2, LED_GREEN =3, LED_BLUE =4, NONE =5}; перечисление функций {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 <Действия, Функции> actionToFunctionMap ={{LED_ON, CHANGE_LED_ON_OFF}, {LED_OFF, CHANGE_LED_ON_OFF}, {LED_RED, CHANGE_LED_LED_COLGE_LED_COLGE_LED_COLGE_LED_COLED_COL }, {LED_BLUE, CHANGE_LED_COLOR}, {NONE, CHANGE_LED_NONE}}; const std ::map  labelToActionMap ={{"on", LED_ON}, {"off", LED_OFF}, {"red" , LED_RED}, {"зеленый", LED_GREEN}, {"синий", LED_BLUE}, {"unknown", NONE}, {"noise", NONE}}; / ** Аудио буферы, указатели и селекторы * / typedef struct {короткие подписанные * буферы [2]; беззнаковый символ buf_select; беззнаковый символ buf_ready; беззнаковый int buf_count; беззнаковый int n_samples;} вывод_t; статический вывод_выводки; статический логический вывод record_ready =false; статический знаковый короткий * sampleBuffer; статический логический вывод debug_nn =false; // Установите значение true, чтобы увидеть, например, функции, сгенерированные из необработанного signalstatic int print_results =- (EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW); / ** * @brief функция настройки Arduino * / void setup () {// поместите здесь свой код настройки, чтобы запустить его один раз:Serial.begin (115200); Serial.println («Выявление граничных импульсов»); setPixelColor (0xaeae00); // сводка параметров вывода (из model_metadata.h) ei_printf ("Параметры вывода:\ n"); ei_printf ("\ tInterval:% .2f ms. \ n", (float) EI_CLASSIFIER_INTERVAL_MS); ei_printf ("\ tРазмер кадра:% d \ n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE); ei_printf ("\ tДлина выборки:% d мс. \ n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16); ei_printf ("\ tКоличество классов:% d \ n", sizeof (ei_classifier_inferencing_categories) / sizeof (ei_classifier_inferencing_categories [0])); run_classifier_init (); if (mic_inference_start (EI_CLASSIFIER_SLICE_SIZE) ==false) {ei_printf ("ОШИБКА:не удалось настроить выборку звука \ r \ n"); возвращение; }} / ** * @brief основная функция Arduino. Запускает цикл вывода. * / void loop () {bool m =mic_inference_record (); if (! m) {ei_printf ("ОШИБКА:не удалось записать звук ... \ n"); возвращение; } signal_t ​​signal; signal.total_length =EI_CLASSIFIER_SLICE_SIZE; signal.get_data =&микрофон_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:Не удалось запустить классификатор (% d) \ n", r); возвращение; } if (++ print_results> =(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW)) {// распечатать прогнозы ei_printf ("Predictions"); ei_printf ("(DSP:% d мс., Классификация:% d мс., Аномалия:% d мс.)", result.timing.dsp, result.timing.classification, result.timing.anomaly); ei_printf (":\ п"); for (size_t ix =0; ix  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 ("оценка аномалии:% .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 * classLabel) {auto itr =labelToActionMap.find (classesLabel); если (itr ==labelToActionMap.end ()) return; auto itr2 =actionToFunctionMap.find (itr-> second); если (itr2 ==actionToFunctionMap.end ()) return; переключатель (itr2-> second) {case CHANGE_LED_ON_OFF:setPixelColor ((itr-> second)? 0x5c5c5c:0x00); ломать; case CHANGE_LED_COLOR:{uint32_t pixelColor =colors [itr-> second - 2]; setPixelColor (pixelColor); } ломать; case CHANGE_LED_NONE:перерыв; }} / ** * @brief Функция Printf использует vsnprintf и выводит с использованием Arduino Serial * * @param [in] формат Список переменных аргументов * / void ei_printf (const char * format, ...) {static char print_buf [1024] ={0}; va_list args; va_start (аргументы, формат); int r =vsnprintf (print_buf, sizeof (print_buf), формат, аргументы); va_end (аргументы); если (г> 0) {Serial.write (print_buf); }} / ** * @brief PDM-буфер полного обратного вызова * Получить данные и вызвать обратный вызов аудиопотока * / static void pdm_data_ready_inference_callback (void) {int bytesAvailable =PDM.available (); // считываем в буфер выборки int bytesRead =PDM.read ((char *) &sampleBuffer [0], bytesAvailable); if (record_ready ==true) {for (int i =0; i > 1; i ++) {inference.buffers [inference.buf_select] [inference.buf_count ++] =sampleBuffer [i]; если (вывод.buf_count> =вывод.n_samples) {вывод.buf_select ^ =1; inference.buf_count =0; inference.buf_ready =1; }}}} / ** * @brief Init вывести структуру и настроить / запустить PDM * * @param [in] n_samples n образцов * * @return {description_of_the_return_value} * / static bool mic_inference_start (uint32_t n_samples) {inference.buffers [ 0] =(короткое со знаком *) malloc (n_samples * sizeof (короткое со знаком)); если (inference.buffers [0] ==NULL) {вернуть ложь; } inference.buffers [1] =(короткое со знаком *) malloc (n_samples * sizeof (короткое со знаком)); если (inference.buffers [0] ==NULL) {бесплатно (inference.buffers [0]); вернуть ложь; } sampleBuffer =(короткое со знаком *) malloc ((n_samples>> 1) * sizeof (короткое со знаком)); если (sampleBuffer ==NULL) {бесплатно (inference.buffers [0]); бесплатно (inference.buffers [1]); вернуть ложь; } inference.buf_select =0; inference.buf_count =0; inference.n_samples =n_samples; inference.buf_ready =0; // настраиваем обратный вызов приема данных PDM.onReceive (&pdm_data_ready_inference_callback); // необязательно установить усиление, по умолчанию 20 PDM.setGain (80); PDM.setBufferSize ((n_samples>> 1) * sizeof (int16_t)); // инициализируем PDM с:// - одним каналом (моно режим) // - частотой дискретизации 16 кГц if (! PDM.begin (1, EI_CLASSIFIER_FREQUENCY)) {ei_printf ("Не удалось запустить PDM!"); } record_ready =true; return true;} / ** * @brief Ожидание новых данных * * @return Истина по завершении * / static bool mic_inference_record (void) {bool ret =true; if (inference.buf_ready ==1) {ei_printf ("Ошибка переполнения буфера выборки. Уменьшите количество срезов в окне модели" "(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW) \ n"); ret =false; } пока (inference.buf_ready ==0) {задержка (1); } inference.buf_ready =0; return ret;} / ** * Получение необработанных данных аудиосигнала * / static int mic_audio_signal_get_data (смещение size_t, длина size_t, float * out_ptr) {numpy ::int16_to_float (&inference.buffers [inference.buf_select ^ 1] [смещение], out_ptr , длина); return 0;} / ** * @brief Остановить PDM и освободить буферы * / static void mic_inference_end (void) {PDM.end (); бесплатно (inference.buffers [0]); бесплатно (inference.buffers [1]); free (sampleBuffer);} # if! defined (EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR! =EI_CLASSIFIER_SENSOR_MICROPHONE # error «Неверная модель для текущего датчика.» # Endif 

Производственный процесс

  1. Советы и тенденции безопасности IIoT на 2020 год
  2. Облачные и периферийные вычисления для Интернета вещей:краткая история
  3. Почему периферийные вычисления для Интернета вещей?
  4. Kontrons KBox A-150-WKL для пограничных приложений IoT, интенсивно использующих данные
  5. Преимущества граничных вычислений для ИИ Кристаллизация
  6. Четыре шага для обеспечения успеха в пограничных вычислениях
  7. Microsoft запускает Azure Edge Zones для приложений 5G
  8. Необходимость открытого исходного кода на периферии (электронная книга)
  9. Система обнаружения химических веществ для низких уровней концентрации
  10. 3 причины для технического обслуживания устройств обнаружения газа