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

Небольшая предыстория


Больше года назад я нашел в своих закромах одноплатный компьютер Raspberry Pi 4 Model B 8 ГБ. Устройство было куплено за небольшую цену в то время, когда человечество ещё не сошло с ума. Без долгих размышлений, я принял решение создать голосового ассистента на базе этого одноплатного компьютера, чтобы управлять своей системой домашней автоматизации. Бонусом к этой идее шли приватность и автономность. В итоге у меня «родилось» устройство под кодовым именем «Мария».

Демонстрация голосового ассистента #Мария


Видео отладки


Но в этой статье не пойдет речь об использовании Raspberry Pi 4 Model B, так как в современных реалиях использование данного одноплатного компьютера стоимостью более $190, трудно назвать бюджетным решением.

Давайте изобретать


Недавно компания Xunlong Software, которая занимается выпуском одноплатных компьютеров под маркой Orange Pi, представила интересное решение — плату Orange Pi Zero 2W с 4 ГБ оперативной памяти, стоимостью $27.


Технические характеристики:
Процессор: Allwinner H618 Четырехъядерный процессор Cortex-A53 с тактовой частотой 1,5 ГГц
Графический процессор: Mali G31 MP2
- — Поддержка OpenGL ES 1.0/2.0/3.2, OpenCL 2.0, Vulkan 1.1
Оперативная память LPDDR4: 4 ГБ
Объем памяти SPI Flash: 16 МБ
Wi-Fi + BT: Wi-Fi 5.0+BT 5.0, BLE
Видеовыход: 1 * Порт Mini HDMI TX 2.0 с поддержкой 4K @ 60 кадров
USB: Type-C USB2.0*2
Интерфейс SD-карты: 1 * Интерфейс карты microSD
Интерфейс расширения: USB2.0 * 2, интерфейс Ethernet 100 м, интерфейс ИК-приемника, аудиовыход, ТВ-выход, кнопка включения, пользовательские кнопки *2
40Pin интерфейс:
- GPIO, UART, I2C, SPI, PWM
Источник питания: Type-C 5V2A
Поддерживаемые ОС: Android 12 TV, Debian 11, Debian 12, Ubuntu22.04, Ubuntu20.04, Orange Pi OS (Arch)
Размер печатной платы: 30 мм x 65 мм x 1,2 мм
Вес: 12,5 г

Данное решение вполне подходит для нашего проекта, как в техническом, так и в экономическом плане.

Итак, определимся с конструкцией устройства. Изучив спецификацию Orange Pi Zero 2W, у нас формируется следующий список дополнительных компонентов:

  1. Динамик 52мм (просто он у меня уже был $1,3)
  2. Усилитель низкой частоты (буду использовать PAM8403 $0,9 за 10 шт)
  3. USB микрофон (xingzhaotong $1,5)
  4. Шлейф FFC FPC 24pin тип B ($1)
  5. RGB светодиод

Разработка звуковой платы


Согласно документации, аудиовыходы реализованы на боковом разъеме FPC, а интерфейс I2S отсутствует. По крайней мере, мне не удалось его реализовать на этой плате. Таким образом, в качестве аудиовхода мы будем использовать USB-микрофон. В версии «Мария» я использовал I2S-микрофон, который продемонстрировал отличные результаты. Ниже предоставлена распиновка бокового разъёма.



Исходя из вышесказанного, в процессе разработки у нас получается следующая схема «звуковой платы»:



Так могла бы выглядеть плата при производстве на китайской фабрике:





Изготовление звуковой платы


На тот момент, я разрабатывал прототип, и не было известно, как поведет себя схема звуковой платы. Поэтому пришлось выполнять изготовление прототипа платы в домашних условиях, для меня это дело привычное. Плата изготавливалась с помощью фоторезиста и вытравливалась в растворе перекиси водорода, лимонной кислоты и соли.



Немного были переживания относительно качества вытравливания мелких дорожек, но фоторезист не подвёл, всё получилось хорошо.

Ниже показано тестовое подключение звуковой платы к одноплатному компьютеру с помощью шлейфа FFC FPC:



Настало время творчества! Проектируем корпус


Обычно в своих разработках я использую естественный интеллект. Поэтому пришлось придумывать дизайн корпуса самостоятельно, учитывая особенности печати 3D принтера. Разработку модели корпуса выполнял с помощью FreeCAD, результат моделирования вы можете видеть ниже.


Корпус в собранном виде


Вид снизу



Элементы корпуса были спроектированы с учетом оптимизации процесса печати, при этом качество не пострадало. В процессе печати не используются структуры поддержки. Ножки корпуса выполнены из TPU-пластика, использование флекс пластика предотвращает скольжение умной колонки по поверхности стола.

Сборка умной колонки


Подключение элементов устройства выполняется по следующей схеме:



Как видно из схемы, для управления усилителем используется выход 28 (wPi 18) RPI разъёма, данный выход подключается к контакту звуковой платы с обозначением «SOUND EN». К выходам 26, 24, 22 подключается управление RGB светодиода, который выполняет функцию индикатора при выполнения запросов.

Как я упоминал ранее, в качестве микрофона используется USB микрофон марки xingzhaotong, который выглядит так:



Для установки в корпус колонки, нам необходимо его полностью разобрать и оставить только плату. Данная плата подключается согласно распиновки к соответствующим контактам на звуковой плате GND, DP, DM, VCC:



Давайте приступим к сборке устройства. Предварительная примерка платы Orange Pi Zero 2W:


Примерка динамика


Установка динамика и резонатора. Резонатор одновременно выполняет функцию фиксатора


Вид снизу



Вид сверху без верхней крышки, на верхней поверхности резонатора виден прикрепленный USB микрофон в центре будет размещен RGB светодиод.


Распечатанная на 3D принтере часть корпуса


Устройство в собранном виде в компании старшей модели


Вид снизу собранной умной колонки. Также снизу располагаются вентиляционные отверстия для охлаждения платы


Для питания устройства используется модуль с разъёмом USB Type C, который фиксируется в специальном адаптере



Немного программной части


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

Операционная система:

В качестве операционной системы я использовал Debian Bullseye c версией ядра 6.1.31, скачать можно на официальном сайте Orange Pi.

Управление GPIO:

Для управления GPIO используется официальная библиотека Orange Pi wiringPi.

Установка wiringPi:

apt-get update
apt-get install -y git
git clone https://github.com/orangepi-xunlong/wiringOP.git
cd wiringOP
sudo ./build clean
sudo ./build

После успешной установки Orange Pi wiringPi, мы можем вывести таблицу GPIO:

gpio readall

В итоге мы увидим следующее:



Обратите внимание, что в колонке «V» указано текущее состояние пина RPI.
Чтобы изменить состояние, мы можем воспользоваться следующими командами:

gpio mode 18 out # Изменение типа пина вход/выход (in/out)
gpio write  18 0    # Изменение уровня пина низкий/высокий (0/1)
gpio read   18       # Чтение состояние пина

Пример одного из вариантов управления GPIO из Python скрипта:

import os

os.system("gpio mode 18 out")  # Изменение типа пина вход/выход (in/out)
os.system("gpio write  18 0")  # Изменение уровня пина низкий уровень
os.system("gpio write  18 1")  # Изменение уровня пина высокий уровень
os.system("gpio read   18")    # Чтение состояние пина

Проверка наличия микрофона в системе:

Чтобы убедиться в правильности подключения микрофона, в консоли необходимо выполнить следующую команду:

arecord -l

Вывод команды должен быть следующим:

**** List of CAPTURE Hardware Devices ****
card 2: ahubhdmi [ahubhdmi], device 0: ahub_plat-i2s-hifi i2s-hifi-0 [ahub_plat-i2s-hifi i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 3: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

Как видим из вывода, устройство USB PnP Sound Device успешно определилось в системе, если устройство отсутствует, то необходимо убедиться в его корректном подключении.

Настройка аудиовыхода:

Чтобы сконфигурировать аудиовыход под наши задачи, в терминале необходимо выполнить следующую команду:

alsamixer

В консоли появится окно с аудио устройствами, нажав F6 необходимо выбрать наше устройство с именем audiocodec и выполнить настройку как отображено ниже на картинке:



После этого можно выполнить алгоритм теста аудиосистемы.

Вывод списка доступных устройств воспроизведения звука:

aplay -l

Вывод команды:

**** List of PLAYBACK Hardware Devices ****
card 0: audiocodec [audiocodec], device 0: CDC PCM Codec-0 [CDC PCM Codec-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: ahubhdmi [ahubhdmi], device 0: ahub_plat-i2s-hifi i2s-hifi-0 [ahub_plat-i2s-hifi i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Мы используем линейный выход, поэтому наше устройство имеет имя CDC PCM Codec-0 [CDC PCM Codec-0]. Давайте протестируем вывод звука через наше устройство.

Первое что нужно сделать — это включить наш усилитель с помощью команд:

gpio mode 18 out
gpio write  18 1

Далее нам необходимо запустить тест с помощью генератора шума, командой в терминале:

speaker-test -c2 -Dplughw:0,0 # plughw:0,0 - это адрес нашего звукового устройства

Вывод команды:

speaker-test 1.2.4

Playback device is plughw:0,0
Stream parameters are 48000Hz, S16_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 32 to 131072
Period size range from 16 to 16384
Using max buffer size 131072
Periods = 4
was set period_size = 16384
was set buffer_size = 131072
 0 - Front Left
 1 - Front Right
Time per period = 2.742858
 0 - Front Left
 1 - Front Right
Time per period = 5.461073
 0 - Front Left
 1 - Front Right
Time per period = 0.580064

Во время теста должен наблюдаться «белый» шум из динамика, если это произошло, то подключение и настройка аудиосистемы была выполнена корректно.

Итог


В этой статье я попытался описать реализацию аппаратной части своего DIY проекта голосового ассистента для умного дома. Написание статьи отнимает большое количество времени, поэтому программную часть проекта постараюсь описать в следующем материале, если вам будет интересно.

Предугадывая ваш вопрос — «Почему бы не использовать Yandex Алису и подобные коммерческие решения?», сразу же изложу свою мысль:

Я сторонник автономных решений в плане их использования в критической инфраструктуре. А системы умного дома я отношу к этим категориям, поэтому, с моей точки зрения, использование устройств, зависящих от внешних систем, недопустимо. Описанное в статье решение не использует внешних сервисов для распознавания речи, векторизации запросов, синтеза речи и управления устройствами. И, конечно, я имею полный контроль над алгоритмами моего устройства, включая приватность.

Спасибо за ваше внимание! Ниже под спойлером несколько видео работы собранного устройства.

Видео работы устройства





Файлы проекта:




Возможно, захочется почитать и это:


Комментарии (27)


  1. REPISOT
    12.11.2023 08:59
    +1

    Разводка звуковой платы похожа на образец из статьи "типичные ошибки разводки печатных плат". Прямые углы, длинные линии до конденсаторов и т.п. При этом исправление этих ошибок не усложнило бы изготовление платы DIY-методом.


    1. Dark_Purple
      12.11.2023 08:59
      +11

      А что не так с прямыми углами? Электроны не успеют повернуть на 90 градусов?


      1. Dancho67
        12.11.2023 08:59
        +2

        Искажения и помехи, если кратко. Можете вскрыть любое фабричное устройство и увидите, что прямых углов на дорожках нету.


        1. HiTechSpoon
          12.11.2023 08:59
          +5

          На этих линия не такие высокие частоты чтобы образовавшаяся паразитные ёмкость и индуктивность повлияли на что-то, и они не слаботочные, чтобы был какой-то crosstalking. С таким же успехом можно требовать залитый полигон общего провода с обратной стороны текстолита и крыжку от наводок сверху. Это ни на что не повлияет.


  1. Weron2
    12.11.2023 08:59

    А управляет умными устройствами сама колонка, или это только интерфейс взаимодействия с home assistant?


    1. CyberexTech Автор
      12.11.2023 08:59

      Может и сама колонка управлять, у меня она напрямую управляет устройствами.


  1. WondeRu
    12.11.2023 08:59
    +2

    А как у вас распознавание голоса происходит при работающем динамике? Как-то компенсируете?


    1. CyberexTech Автор
      12.11.2023 08:59
      +3

      Во время воспроизведения, она не "слушает"


  1. Rasidel
    12.11.2023 08:59
    +3

    Спасибо за статью. Очень интересно будет почитать про программную часть проекта. По поводу I2C интерфейса - то он на этой плате присутствует.


    1. CyberexTech Автор
      12.11.2023 08:59
      +3

      Спасибо за отзыв. Возможно вы перепутали с I2C, мне был нужен I2S интерфейс для подключения цифрового микрофона.


  1. ErshoffPeter
    12.11.2023 08:59
    +3

    Круто!

    Завидую белой завистью, как обладатель двух Алис, одной Google-станции и Сбер-стика (он тоже с голосовым интерфейсом).


    1. CyberexTech Автор
      12.11.2023 08:59

      Спасибо )


  1. smart_alex
    12.11.2023 08:59
    +7

    Ё! Если я всё правильно понял, то это как раз то, что мне (всем нам) нужно — свободный, автономный и отвязанный от всех (хитрожопых) корпораций голосовой помощник.

    Дайте два!


    1. janvarev
      12.11.2023 08:59
      +6

      Опенсорс голосовой помощник Ирина вам в помощь: https://github.com/janvarev/Irene-Voice-Assistant (там же ссылки на 3 статьи на Хабре о нём )))


    1. vikarti
      12.11.2023 08:59
      +1

      Вот тоже.. и мне кажется более важно что это платформа.

      Хочу себе такую штуку именно в собранном красивом работающем виде а с софтом уровня "вот ssh, софт полноценный ставьте сами, вот исходники ядра, вот документация на плату".

      Вот сколько такое может стоить?

      Готовая ж платформа для Ирины той же.


      1. CyberexTech Автор
        12.11.2023 08:59

        Сейчас занимаюсь коробочным решением, в плане ПО для данной умной колонки, с нормальным пользовательским интерфейсом, чтобы человек далёкий от программирования смог использовать данную систему.


  1. supersmeh
    12.11.2023 08:59
    +2

    Класс! Буду следить. Тоже нужен такой девайс. Точнее несколько, в разных комнатах, как-то прикрутить все в один HA, хочу чтобы команда "выключи свет" работала в той комнате, где её произнес


  1. Jury_78
    12.11.2023 08:59
    +1

    Интересно... Особенно на код посмотреть :)


    1. Alex_Jet
      12.11.2023 08:59
      -1

      В коде ничего особенно нет - определяем от какой железки пришло STT, соответственно, в ее зоне управляем оборудованием. А вот что автор использует в качестве оператора STT и TTS, особенно не используя облачные сервисы, - вот это очень интересно)


  1. Levin7
    12.11.2023 08:59

    Сеточка декоративная под динамик будет не лишней


    1. CyberexTech Автор
      12.11.2023 08:59

      В обычном режиме эксплуатации динамик не доступен


  1. slavius
    12.11.2023 08:59
    +2

    Я сторонник автономных решений в плане их использования в критической инфраструктуре. А системы умного дома я отношу к этим категориям, поэтому, с моей точки зрения, использование устройств, зависящих от внешних систем, недопустимо. Описанное в статье решение не использует внешних сервисов для распознавания речи, векторизации запросов, синтеза речи и управления устройствами. И, конечно, я имею полный контроль над алгоритмами моего устройства, включая приватность.
    Спасибо за каждое слово:)


    1. CyberexTech Автор
      12.11.2023 08:59
      +1

      Пожалуйста). Хотя моя фраза:

      И, конечно, я имею полный контроль над алгоритмами моего устройства, включая приватность.

      Звучит двояко и немного зловеще )


  1. Alex_Jet
    12.11.2023 08:59

    @CyberexTechхорошая реализация! Поздравляю. У меня есть реализация mdmTerminal2 на Orange Pi Zero - всё работает почти замечательно. Но есть вопросы:

    1. Что за продукт используется для голосового ассистента?

    2. Что с нагревом процессора у этой платы?

    3. На сколько стабилен wi-fi в этой реализации?

    4. Не пробовали использовать массивы микрофонов со всеми фишками типа DOA, BMF и прочие?


    1. CyberexTech Автор
      12.11.2023 08:59

      Спасибо за отзыв.

      Что за продукт используется для голосового ассистента?

      В своих проектах я использую собственные решения. Распознавание и синтез речи выполняется на устройстве, без использования внешних API. Используются внешние API только для второстепенных функций, таких как ChatGPT и курсы валют.

      Что с нагревом процессора у этой платы?

      С нагревом нет проблем, радиатора, что можно видеть на фото, вполне хватает. Температура SoC не поднимается выше 65 ℃, что в эксплуатационных рамках.

      На сколько стабилен wi-fi в этой реализации?

      Проблем с подключением к сети по Wi-Fi ни разу не наблюдал.

      Не пробовали использовать массивы микрофонов со всеми фишками типа DOA, BMF и прочие?

      Определение направления источника звука и бимформинг, конечно интересные штуки, но в данном устройстве я считаю их лишними, так как расположение микрофона позволяет без проблем улавливать звук со всех сторон, а нейросеть, которая отвечает за распознавание речи, справляется с шумом.


      1. Alex_Jet
        12.11.2023 08:59

        В своих проектах я использую собственные решения. Распознавание и синтез речи выполняется на устройстве, без использования внешних API

        Ну не с нуля же писали? Наверное, это что-то типа Azure/RHvoice/Vosk/Kaldi с локальными словарями?

        Определение направления источника звука и бимформинг, конечно интересные штуки, но в данном устройстве я считаю их лишними, так как расположение микрофона позволяет без проблем улавливать звук со всех сторон, а нейросеть, которая отвечает за распознавание речи, справляется с шумом.

        Вот это очень интересно! Мне одного микрофона явно недостаточно. У меня кейс следующий - железка в виде "светодиодного" светильника установлена в потолок посередине помещения. Алиса и Маруся явно лучше "слышат" своими 4-6 микрофонами.

        Тем более то что мой голосовой ассистент помимо того, что подключен к локальному серверу УД, еще завязан на LMS. Соответственно, музыка играет (акустика разнесена от самой железки) и ассистент должен слушать. Поэтому было бы очень круто звук с микрофона с помощью нейронной сети обрабатывать.


  1. vvzvlad
    12.11.2023 08:59
    +1

    Очень интересна программная часть.