Как передать звук через esp32 bluetooth
Перейти к содержимому

Как передать звук через esp32 bluetooth

  • автор:

Ряд способов для передачи голоса на расстояние с помощью ESP32/Arduino

Источник картинки: silenthollywood.com

Использование микроконтроллеров ESP32/Arduino позволяет создавать достаточно любопытные проекты, среди которых особняком стоят проекты для передачи голоса. Например, создать собственную рацию, которая может быть весьма тонко настроена на программном уровне. В этой статье мы обзорно рассмотрим несколько известных способов для реализации подобной задумки.

В одном из проектов был продемонстрирован достаточно любопытный подход: возможность выбора одного из двух способов передачи данных:

Использование широковещательной рассылки UDP

Широковещательная рассылка UDP — очень простой механизм. Вы отправляете UDP-пакет на специальный IP-адрес, и ваш маршрутизатор передаёт этот пакет всем другим устройствам в вашей сети.

Мы можем безопасно отправлять до 1436 байт в пакете UDP, поэтому, если мы семплируем на частоте 16 кГц и используем 8-битные сэмплы, это около 90 мс аудиоданных. Таким образом, нам нужно отправить около 11 пакетов в секунду. Это вполне соответствует возможностям ESP32.

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

Однако у UDP есть и некоторые недостатки:

  • Доставка UDP-пакетов — это только максимальные усилия — нет никакой гарантии, что кто-то получит отправленный вами пакет.
  • Также нет гарантии порядка пакетов — кто-то может получить отправленные вами пакеты в совершенно случайном порядке.

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

Использование ESP-NOW

ESP-NOW — это протокол, разработанный Esppresif, который позволяет нескольким устройствам ESP взаимодействовать друг с другом без необходимости использования Wi-Fi.

Это даёт нам большое преимущество перед опцией UDP, заключающееся в том, что нам не нужна сеть Wi-Fi, чтобы наша рация работала.

Недостатком ESP-NOW является гораздо меньший размер пакета — 250 байт. Это означает, что нам нужно отправлять пакеты 64 раза в секунду.

У нас также есть все те же недостатки, что и у UDP — доставка пакетов осуществляется с максимальной эффективностью и нет гарантий, в каком порядке будут приходить пакеты.
Выбор одного из двух режимов осуществляется с помощью комментирования / раскомментирования строки 45 в файле Config:

// Which transport do you want to use? ESP_NOW or UDP? // comment out this line to use UDP // #define USE_ESP_NOW

Единственным минусом использования решения на базе радиомодуля ESP32 является некоторая ограниченность радиуса действия устройства, так как wi-fi модуль ESP32 не предназначен изначально до передачи на большие расстояния. Да, я понимаю, вы можете сказать, что с использованием отражателя или тарелки — расстояние можно существенно увеличить: мне известны подобные эксперименты, где радиус действия увеличили вплоть до 10 км. Однако подобное решение всё-таки существенно выбивается за рамки и требует достаточно точной настройки друг на друга как приёмника, так и передатчика.

Альтернативным способом передачи голосового потока является использование известных дальнобойных плат радиосвязи NRF24L01+PA+LNA, которые позволяют (при соответствующем падении скорости передачи с ростом дальности) увеличить радиус, вплоть до более чем 1 километра.

Для этого нам надо будет использовать библиотеку RF24Audio — это поистине библиотека «для ленивых людей», так как сам скетч полноценной рации не содержит даже и 10 строк:

#include #include #include RF24 radio(7,8); // Set radio up using pins 7 (CE) 8 (CS) RF24Audio rfAudio(radio,1); // Set up the audio using the radio, and set to radio number 0. // Setting the radio number is only important if one-to-one communication is desired // in a multi-node radio group. See the privateBroadcast() function. void setup() < rfAudio.begin(); // The only thing to do is initialize the library. >void loop() < // Audio playback and button handling is all managed internally. // In this example, the radio is controlled by external buttons, so there is nothing to do here >

Чтобы работать с ним, нам необходимо:

  • микрофон подключить к пину А0;
  • кнопку переключателя, которая переключает режимы, для осуществления передачи следует соединить с пином А1;
  • кнопка прибавления громкости должна быть подключена к пину A2;
  • убавление громкости к пину А3;
  • кстати сказать, библиотека предоставляет достаточно интересную функцию, которая позволяет включать удалённо передающее устройство! То есть не совсем включать, а переводить его в режим «прослушки, что вокруг происходит» ;). Для этого следует использовать кнопку, присоединённую к пину A4.

Следует отметить, что если кто-то соберётся экспериментировать с этим передатчиком, то стоит понимать, радиомодуль nrf является весьма чувствительным к качеству питания (напряжение и сила тока), поэтому питать его от стандартного пина Arduino совершенно недостаточно.

В идеале следует использовать специальные модули для питания:

Если же это недоступно, то тебе следует использовать любой другой модуль, например, регулятор/стабилизатор напряжения (так называемый DC-DC модуль). Например, MT3608:

Аппаратная часть проекта на основе этой идеи хорошо разобрана здесь, если кому интересно.

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

Говоря о способах передачи голоса на расстояние, я совершенно не могу пройти мимо одного из проектов, поскольку он «реализует мои потаённые желания» и одну нереализованную задумку из далёкой молодости — передача голоса с помощью лазерного луча.

В своё время мне очень хотелось создать нечто подобное, так как в те времена, когда динозавры были зеленее, а сотовой связи не было, мы с одним товарищем жили в прямой видимости друг от друга, на расстоянии порядка 100 метров, и подобный проект был бы как нельзя кстати. Единственная проблема, что в те времена не существовало ещё Arduino 🙂

Приведённую ниже затею можно взять в качестве основы, так как основная задумка, положенная в основу проекта, заключается в использовании ШИМ-модуляции на 11 пине, для воспроизведения аудио (ссылка на скетч):

Код передатчика

/* * speaker_pcm * * Plays 8-bit PCM audio on pin 11 using pulse-width modulation (PWM). * For Arduino with Atmega168 at 16 MHz. * * Uses two timers. The first changes the sample value 8000 times a second. * The second holds pin 11 high for 0-255 ticks out of a 256-tick cycle, * depending on sample value. The second timer repeats 62500 times per second * (16000000 / 256), much faster than the playback rate (8000 Hz), so * it almost sounds halfway decent, just really quiet on a PC speaker. * * Takes over Timer 1 (16-bit) for the 8000 Hz timer. This breaks PWM * (analogWrite()) for Arduino pins 9 and 10. Takes Timer 2 (8-bit) * for the pulse width modulation, breaking PWM for pins 11 & 3. * * References: * https://www.uchobby.com/index.php/2007/11/11/arduino-sound-part-1/ * https://www.atmel.com/dyn/resources/prod_documents/doc2542.pdf * https://www.evilmadscientist.com/article.php/avrdac * https://gonium.net/md/2006/12/27/i-will-think-before-i-code/ * https://fly.cc.fer.hr/GDM/articles/sndmus/speaker2.html * https://www.gamedev.net/reference/articles/article442.asp * * Michael Smith */ #include #include #include #include #define SAMPLE_RATE 8000 /* * The audio data needs to be unsigned, 8-bit, 8000 Hz, and small enough * to fit in flash. 10000-13000 samples is about the limit. * * sounddata.h should look like this: * const int sounddata_length=10000; * const unsigned char sounddata_data[] PROGMEM = < . >; * * You can use wav2c from GBA CSS: * https://thieumsweb.free.fr/english/gbacss.html * Then add "PROGMEM" in the right place. I hacked it up to dump the samples * as unsigned rather than signed, but it shouldn't matter. * * https://musicthing.blogspot.com/2005/05/tiny-music-makers-pt-4-mac-startup.html * mplayer -ao pcm macstartup.mp3 * sox audiodump.wav -v 1.32 -c 1 -r 8000 -u -1 macstartup-8000.wav * sox macstartup-8000.wav macstartup-cut.wav trim 0 10000s * wav2c macstartup-cut.wav sounddata.h sounddata * * (starfox) nb. under sox 12.18 (distributed in CentOS 5), i needed to run * the following command to convert my wav file to the appropriate format: * sox audiodump.wav -c 1 -r 8000 -u -b macstartup-8000.wav */ #include "sounddata.h" int ledPin = 13; int speakerPin = 11; // Can be either 3 or 11, two PWM outputs connected to Timer 2 volatile uint16_t sample; byte lastSample; void stopPlayback() < // Disable playback per-sample interrupt. TIMSK1 &= ~_BV(OCIE1A); // Disable the per-sample timer completely. TCCR1B &= ~_BV(CS10); // Disable the PWM timer. TCCR2B &= ~_BV(CS10); digitalWrite(speakerPin, LOW); >// This is called at 8000 Hz to load the next sample. ISR(TIMER1_COMPA_vect) < if (sample >= sounddata_length) < if (sample == sounddata_length + lastSample) < stopPlayback(); >else < if(speakerPin==11)< // Ramp down to zero to reduce the click at the end of playback. OCR2A = sounddata_length + lastSample - sample; >else < OCR2B = sounddata_length + lastSample - sample; >> > else < if(speakerPin==11)< OCR2A = pgm_read_byte(&sounddata_data[sample]); >else < OCR2B = pgm_read_byte(&sounddata_data[sample]); >> ++sample; > void startPlayback() < pinMode(speakerPin, OUTPUT); // Set up Timer 2 to do pulse width modulation on the speaker // pin. // Use internal clock (datasheet p.160) ASSR &= ~(_BV(EXCLK) | _BV(AS2)); // Set fast PWM mode (p.157) TCCR2A |= _BV(WGM21) | _BV(WGM20); TCCR2B &= ~_BV(WGM22); if(speakerPin==11)< // Do non-inverting PWM on pin OC2A (p.155) // On the Arduino this is pin 11. TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0); TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0)); // No prescaler (p.158) TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // Set initial pulse width to the first sample. OCR2A = pgm_read_byte(&sounddata_data[0]); >else < // Do non-inverting PWM on pin OC2B (p.155) // On the Arduino this is pin 3. TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0); TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0)); // No prescaler (p.158) TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // Set initial pulse width to the first sample. OCR2B = pgm_read_byte(&sounddata_data[0]); >// Set up Timer 1 to send a sample every interrupt. cli(); // Set CTC mode (Clear Timer on Compare Match) (p.133) // Have to set OCR1A *after*, otherwise it gets reset to 0! TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12); TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10)); // No prescaler (p.134) TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // Set the compare register (OCR1A). // OCR1A is a 16-bit register, so we have to do this with // interrupts disabled to be safe. OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000 // Enable interrupt when TCNT1 == OCR1A (p.136) TIMSK1 |= _BV(OCIE1A); lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]); sample = 0; sei(); > void setup() < pinMode(ledPin, OUTPUT); digitalWrite(ledPin, HIGH); startPlayback(); >void loop()

То есть, другими словами, он берёт заранее заготовленный массив данных (подключаемый как библиотека sounddata.h) и воспроизводит его. Выглядит конечно «зело эффектно»:

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

Хотя, честно говоря, требуется для этого не так уж много – обеспечить модуляцию лазерного луча. Другими словами, мерцать его в такт голосу. Например, захватывать сигнал с аналогового пина ардуино с подключенным к нему микрофоном и выводить на другом аналоговом пине, к которому подключен лазер (это на стороне передатчика). На стороне приёмника – обратное преобразование: снимать сигнал с аналогового пина и выводить на другом аналоговом пине, к которому подключено устройство воспроизведения – колонка, динамик и т. д. Понятно, что качество звучания будет оставлять желать лучшего – но для коммуникации сгодится 😉

Нечто примерно подобное было продемонстрировано вот в этой самоделке, только без участия ардуино (просто как принцип действия, который можно взять за основу):

Рассмотренные способы не охватывают все вероятные аппаратно-программные комбинации для передачи голоса, однако их вполне можно использовать в своих проектах, а вариант передачи с помощью радиомодуля nrf — вообще с минимальным вмешательством в код.

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

LoRa (Long Range) — запатентованная проприетарная технология модуляции маломощной глобальной сети. Среди её особенностей в рамках нашей задачи можно выделить:

  • Дальность передачи существенно выше, чем у других способов (10-15 км. Есть даже прецеденты передачи на 200! км).
  • Высокая проникающая способность в городских условиях.
  • Низкая пропускная способность (сотни бит/с – десятки кбит/сек). Да, «фоточки» уже не покачаешь. Если только текстовые сообщения.

Если экспериментировать с LoRa, то имеет смысл это делать с модулями TTGO LoRa32 SX1276 OLED, которые построены на основе ESP32 и имеют кроме модуля LoRa в своём составе — ещё и OLED дисплей, что может быть достаточно полезно в целом. Например, вот тут есть подробная инструкция по соединению двух таких модулей и исходный код для этого.

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

А какой способ предпочитаете вы?

НЛО прилетело и оставило здесь промокод для читателей нашего блога:

— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS .

Осуществление разных способов связи между модулями esp32

Микроконтроллер esp32 примечателен многим, однако его наиболее известной характеристикой (которая, кстати, вполне себе «перевернула» рынок в своё время) является встроенная возможность осуществления связи по bluetooth и wi-fi. Эти способы коммуникации позволяют микроконтроллеру осуществлять как скоростную связь с устройствами, так и энергосберегающую. Именно об этих способах мы и поговорим в этой статье.

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

Что такое Bluetooth? Это беспроводной стандарт связи для обмена данными на коротком расстоянии. Как и WiFi, Bluetooth работает на частоте 2.4 ГГц.

image

Источник картинки: wikihandbk.com

Bluetooth применяется во множестве разных ситуаций, где требуется беспроводное управление и передача данных. Например:

  • Передача аудиоданных в наушники или аудиосистему автомобиля
  • Коммуникация между периферийными устройствами и ПК
  • Передача данных между Bluetooth-устройствами

Что такое Bluetooth Low Energy (BLE)? – это энергосберегающий вариант Bluetooth, и его главная область применения – это передача маленьких порций данных на короткие расстояния. Этот стандарт предназначен для очень маломощных проектов, питаемых от батареек-таблеток.

image

Источник картинки: wikihandbk.com

В отличие от Bluetooth, который включён постоянно, BLE-устройство постоянно находится в спящем режиме, кроме ситуаций, когда оно подключено к другим устройствам. Благодаря этому BLE-устройства потребляют очень мало питания. Эта функция крайне полезна для коммуникации типа M2M (англ. «machine-to-machine», т.е. «между машинами»), т.к. позволяет делать проекты из маленьких устройств, питаемых от батареек и работающих очень долгое время.

Из-за этого стандарт BLE идеален для проектов, где требуется периодический обмен небольшими порциями данных – например, в медицине, фитнесе, отслеживании объектов, навигации, безопасности и домашней автоматизации.

О других различиях между Bluetooth и BLE можно посмотреть в таблице ниже:

Bluetooh Low Energy (BLE) Bluetooh:
Базовый режим (Base Rate, BR) /
Дополнительный режим (Enhanced Date Rate, EDR)
Оптимизирован для: Передача данных “короткими очередями” Постоянный поток данных
Диапазон частот ISM-диапазон 2.4 ГГц
(2.402 — 2.480 ГГц)
ISM-диапазон 2.4 ГГц
(2.402 — 2.480 ГГц)
Каналы 40 каналов с диапазоном 2 МГц
(3 канала для оповещений, 37 каналов для
данных)
79 каналов с диапазоном 1 МГц
Использование
каналов
Псевдослучайная перестройка
рабочей частоты (FHSS)
Псевдослучайная перестройка
рабочей частоты (FHSS)
Модуляция GFSK GFSK, π/4 DQPSK, 8DPSK
Энергопотребление Примерно от 0.01х до 0.5х
относительно опорной величины
(зависит от способа применения)
1 (опорная величина)
Скорость передачи данных * LE2М РНУ: 2 Мбит/с
* LE1М РНУ: 1 Мбит/с
* LE Coded РНУ (S=2): 500 Кбит/с
* LE Coded РНУ (s=8): 125 Кбит/с
* EDR РНУ (8DPSK): 3 Мбит/с
* EDR РНУ (п/4 DQPSK): 2 Мбит/с
* BR PHY (GFSK): 1 Мбит/с
Макс. мощность * Класс 1: 100 мВТ (+20 дБм)
* Класс 1.5: 10 мВт (+10 дБм)
* Класс 2: 2.5 мВт (+4 дБм)
* Класс 3: 1 мВт (0 дБм)
* Класс 1: 100 мВт (+20 дБм)
* Класс 2: 2.5 мВт (+4 дм)
* Класс 3: 1 мВт (0 дБм)
Сетевая топология * “Точка-точка” (включая “пикосеть”)
* Вещание
* Ячеистая сеть
“Точка-точка” (включая “пикосеть”)

В стандарте Bluetooth Low Energy предусмотрено два типа устройств: сервер и клиент.
Сервер оповещает о своём существовании, чтобы его могли найти другие устройства, а также содержит данные для считывания клиентом. Клиент сканирует близлежащие устройства и, найдя искомый сервер, подключается к нему и начинает прослушивать входящие данные. Этот тип коммуникации называют «сквозным» или «точка-точка».

Стандарт BLE предусматривает и другие типы подключения:

  • Режим вещания. Сервер передаёт данные нескольким клиентам, подключённым к нему.
  • Ячеистая сеть. Все устройства подключены друг к другу. Это тип соединения, когда в сети несколько устройств и у каждого из них по несколько подключений.

GATT — расшифровывается как «generic attributes» («общие атрибуты»). Эта спецификация определяет иерархию данных, которую BLE-устройство демонстрирует другим BLE-устройствам, подключённым к нему. Другими словами, GATT определяет то, как два BLE-устройства отправляют и получают стандартные сообщения.

image

Источник картинки: wikihandbk.com

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

Характеристики всегда находятся внутри сервисов, и это то место, где, собственно, хранятся данные во всей этой GATT-иерархии. Характеристика имеет уникальный идентификатор (UID), значение и свойства.

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

Каждый сервис, характеристика и дескриптор имеют собственный UUID (англ. «universally unique identifier», что переводится как «универсальный уникальный идентификатор»). UUID – это уникальное 128-битное (16-байтное) число вроде такого:

Сокращённые UUID для всех сервисов, характеристик, профилей и т.д. можно найти на сайте Bluetooth SIG.

Но если вашему приложению нужен собственный UUID, его можно сгенерировать при помощи этого UUID-генератора.

Итак, теперь, когда мы немного ознакомились с теоретической стороной вопроса, посмотрим, как это можно было бы реализовать на базе esp32.

Так как мы осуществляем связь двух модулей esp32 между собой — нам понадобится серверный и клиентский код.

Посмотрим общий случай такой реализации и начнём с серверной части:

Сначала мы подключаем необходимые библиотеки:

#include #include #include

Генерируем с помощью сервиса, указанного выше, уникальные UUID:

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
 BLEDevice::init("Eto moye imya");
 BLEServer *pServer = BLEDevice::createServer();

Создаём сервис и характеристику с указанными UUID:

 BLEService *pService = pServer->createService(SERVICE_UUID); BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE );

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

 pCharacteristic->setValue("Всем привет!"); pService->start(); BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pAdvertising->setScanResponse(true); pAdvertising->setMinPreferred(0x06); pAdvertising->setMinPreferred(0x12); BLEDevice::startAdvertising(); Serial.println("Характеристика установлена! Теперь вы можете прочитать её на телефоне!");

После прошивки программы в микроконтроллер в мониторе COM-порта появляются приветственные сообщения:

Теперь посмотрим на клиентскую часть.

Также подключаем необходимую библиотеку:

#include "BLEDevice.h"

Далее указываем UUID сервиса и характеристики (должны совпадать с таковыми на сервере):

static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b"); static BLEUUID charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");

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

if (connected) < String newValue = "Time since boot: " + String(millis()/1000); Serial.println("Setting new characteristic value to \"" + newValue + "\""); pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length()); >else if(doScan)< BLEDevice::getScan()->start(0); > 

И в мониторе COM-порта клиента эта картина выглядит следующим образом:

Таким образом, используя энергоэффективный метод связи с использованием BLE, вы можете реализовывать свои интересные применения этого типа связи.

Поговорим теперь и о связи с использованием Wi-Fi

Здесь одно устройство также будет играть роль сервера, а другое — клиента.
Структура вкладок сервер выглядит следующим образом:

Структура вкладок клиента:

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

То есть: 1) запущена wi-fi сеть; 2) запущен сервер и на клиенте, и на точке доступа;

Подробнее рассмотрим код сервера на точке доступа

Для работы нам понадобятся следующие библиотеки:

#include "WiFi.h" #include "ESPAsyncWebServer.h" #include

Конфигурируем точку доступа, а также определяем адрес сервера на клиенте, куда будем обращаться с точки доступа:

const char* ssid = "ESP32-Access-Point"; const char* password = "123456789"; const char* SlaveServerName = "http://192.168.4.2/post"; 

Запускаем сервер на 80 порту:

AsyncWebServer server(80); void setup() < Serial.begin(115200); Serial.println(); Serial.print("Setting AP (Access Point)…"); WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); Server ();//запустили сервер для входящих POST-запросов >

Функция Server () , вызывающаяся в последней строке (выше), служит для прослушивания входящих POST-запросов и реализована во вкладке server :

void Server () < server.on( "/post", HTTP_POST, [](AsyncWebServerRequest * request)<>, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) < // IsReadyForRead = false; for (size_t i = 0; i < len; i++) < Serial.write(data[i]); >Serial.println(); request->send(200); >); server.begin(); >

Ну и в методе loop () — мы вызываем тестовую функцию TestSender , которая отсылает сообщение клиенту:

void loop() void TestSender () < WiFiClient client; HTTPClient http; // Your Domain name with URL path or IP address with path http.begin(client, SlaveServerName); // отсылаем то, что получили // If you need an HTTP request with a content type: text/plain http.addHeader("Content-Type", "text/plain"); int httpResponseCode = http.POST("Привет!"); Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); // Освобождаем ресурсы http.end(); >

Теперь рассмотрим код клиента точки доступа

Подключаем необходимые библиотеки:

#include #include #include #include "ESPAsyncWebServer.h"

Задаём логин и пароль точки доступа, к которой будем подключаться:

const char* ssid = "ESP32-Access-Point"; const char* password = "123456789";

Определяем адрес для обращений на сервере (у точки доступа):

const char* MainServerName = "http://192.168.4.1/post";

Подключаемся к точке доступа и запускаем сервер для прослушки входящих POST-запросов:

AsyncWebServer server(80); void setup() < Serial.begin(115200); WiFi.begin(ssid, password); Serial.println("Connecting"); while(WiFi.status() != WL_CONNECTED) < delay(500); Serial.print("."); >Serial.println(""); Serial.print("Connected to WiFi network with IP Address: "); Serial.println(WiFi.localIP()); Server ();//запустили сервер для входящих POST-запросов >

Функция Server () — в последней строке (выше) полностью аналогична таковой у точки доступа и служит для прослушивания POST-запросов:

void Server () < server.on( "/post", HTTP_POST, [](AsyncWebServerRequest * request)<>, NULL, [](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) < // IsReadyForRead = false; for (size_t i = 0; i < len; i++) < Serial.write(data[i]); >Serial.println(); request->send(200); >); server.begin(); >

Ну и в методе loop () — мы вызываем тестовую функцию TestSender () , которая отсылает сообщение на POST-сервер, запущенный на точке доступа:

 void loop() void TestSender () < WiFiClient client; HTTPClient http; http.begin(client, MainServerName); // отсылаем то, что получили // If you need an HTTP request with a content type: text/plain http.addHeader("Content-Type", "text/plain"); int httpResponseCode = http.POST("И тебе привет!"); Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); // Освобождаем ресурсы http.end(); >

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

Библиотеку для работы wi-fi варианта можно скачать здесь: ESPAsyncWebServer
Все необходимые библиотеки для работы BLE-варианта устанавливаются автоматически при инсталляции поддержки esp32 в Arduino IDE.

Код сервера и клиента для BLE можно скачать здесь, для wi-fi варианта — тут.

Код для обоих вариантов полностью рабочий и протестирован. «Бери и используй!» 🙂

Вот такими интересными способами вы можете наладить связь между 2-мя и более устройствами esp32. Успехов в проектировании!

НЛО прилетело и оставило здесь промокод для читателей нашего блога:

— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS .

  • Блог компании FirstVDS
  • Беспроводные технологии
  • Программирование микроконтроллеров
  • Интернет вещей
  • DIY или Сделай сам

Передатчик аудиоданных на базе esp32 // нужна помощь!

Добрый день. Есть идея передатчика аудиоданных на базе esp32 посредством bluetooth на стандартную гарнитуру (наушники, например).
ключевые вопросы:
1. как произвести сопряжение esp32 и гарнитуры через bluetooth?
2. возможно ли программно сгенерировать аудиосигнал с помощью esp32?
3. какие библиотеки необходимы в решении задачи?

буду рад любым дельным комментариям по данной теме, спасибо!

enjoynering
Well-known member

Подсказка I2S не путать с I2C.

pvvx
Активный участник сообщества

GitHub — schreibfaul1/ESP32_A2DP_Source: Arduino version

Arduino version. Contribute to schreibfaul1/ESP32_A2DP_Source development by creating an account on GitHub.

github.com

github.com

pvvx
Активный участник сообщества

GitHub — pschatzmann/ESP32-A2DP: A Simple ESP32 Bluetooth A2DP Library (to implement a Music Receiver or Sender) that supports Arduino, PlatformIO and Espressif IDF

A Simple ESP32 Bluetooth A2DP Library (to implement a Music Receiver or Sender) that supports Arduino, PlatformIO and Espressif IDF — pschatzmann/ESP32-A2DP

github.com

github.com

mihanick
New member

GitHub — schreibfaul1/ESP32_A2DP_Source: Arduino version

Arduino version. Contribute to schreibfaul1/ESP32_A2DP_Source development by creating an account on GitHub.

github.com

github.com

Благодарю Вас, очень помогли. Получилось осуществить сопряжение!

mihanick
New member

@pvvx возможно вы снова сможете мне помочь. Хочу реализовать поиск и вывод на серийный порт имен устройств, расположенных в зоне видимости bluetooth esp32. Перерыл уже кучу страниц, пока ничего полезного не встретил. Если есть информация на этот счет или методы, которые пригодятся для этого, сообщите пожалуйста! Спасибо!

pvvx
Активный участник сообщества

Там-же в примерах это всё есть.

ESP32-A2DP/examples/bt_music_sender_ssid_callback/bt_music_sender_ssid_callback.ino at main · pschatzmann/ESP32-A2DP

A Simple ESP32 Bluetooth A2DP Library (to implement a Music Receiver or Sender) that supports Arduino, PlatformIO and Espressif IDF — pschatzmann/ESP32-A2DP

github.com

github.com

Но всё связанное с BT очень нестабильно работает на ESP32.

vrd
Member

Думаю приколхозить esp32 к повербанку и записывать звук с блютуз гарнитуры.
Это конечно хуже чем запись на камеру, но лучше чем ничего. Да и не так заметно.
Поэтому у меня обратная ситуация. Необходимо принять звук с микрофона и записать на SD карту. И дабы не доставать каждый раз карту памяти, поднимать ФТП-шку при нахождении родной вифи сети.
Эххх. Столько хотелок. А времени не хватает.
Пните плиззз в нужном направлении.

Как передать звук через esp32 bluetooth

ARDUINO esp32 bluetooth audio

  • Автор темы gunship
  • Дата начала 2 Авг 2022

Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно.
Вам необходимо обновить браузер или попробовать использовать другой.

gunship

2 Авг 2022 1 0

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

Геннадий П

14 Апр 2021 1,749 564 44
Поделиться:

О сайте

  • Официальное сообщество YouTube-канала AlexGyver. Здесь обсуждаются проекты автора и остальных участников форума, а также рождаются новые крутые идеи. У нас можно получить ответы на вопросы по техническим темам в разделе помощи, найти себе исполнителя или заказчика на разработку электроники и совместно заказать плату для проекта. Приятного общения!

Новые темы

  • Автор: uriy1000
  • Вчера в 18:06
  • Ответы: 1
  • Автор: Att
  • Вчера в 14:55
  • Ответы: 3

Статистика форума

Темы 5,852 Сообщения 110,319 Пользователи 60,385 Новый пользователь daimdmtr

  • Обратная связь
  • Условия и правила
  • Политика конфиденциальности
  • Помощь
  • RSS

Локализация от XenForo.Info
XenPorta 2 PRO © Jason Axelrod of 8WAYRUN

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *