<xml><w><w>Normal<w>false<w>false<w>false<w>RU<w>X-NONE<w>X-NONE</w></w></w></w></w></w></w></w></xml> Хочу познакомить русскоязычных пользователей интернета с очень интересным проектом под названием Karadio. Данное устройство позволяет проигрывать потоки интернет-радиостанций, которых огромное множество на сегодня. Устройство полностью автономно и способно воспроизводить потоки без участия компьютера. Устройству необходим только выход в интернет посредством Wifi (например, с помощью роутера). Для самого минимума постройки этого проекта необходимо две платы ESP8266 и VS1053. Можно добавить дополнительно усилитель для вывода звука на динамики и различного рода дисплеи для отображения информации о потоке. Понадобится еще блок питания на 5В и 3,3В или преобразователи напряжения DC—DC. При подключении дисплея необходима плата Arduino mini или nano. На данный момент этот проект является самым прогрессивным на территории интернета (как мне кажется). С руссификацией дисплея уже разобрался, нашел в интернете шрифт кириллический на ЭТОЙ странице и просто скопировал его числовой массив в один из ненужных шрифтов. Править нужно файл u8g_font_data.c по пути «C:UsersAndrewDocumentsArduinolibrariesU8glib_Arduino-mastersrcclib» у вас может быть чуть иной путь. Теперь все нормально отображается, стало удобнее пользоваться радио, потому что я слушаю преимущественно русскоязычные радиостанции. Более подробно об этом проекте можно узнать на страницах сайтов:https://hackaday.io/project/11570-wifi-webradio-with-esp8266-and-vs1053http://www.instructables.com/id/Wifi-Webradio-With-ESP8266-and-VS1053/ По этим ссылкам вы можете найти схему устройства, прошивку для ESP8266 и Arduino Pro mini, а также связаться с автором проекта, написать ему сообщение. Если вам понравится эта разработка, то есть возможность поддержать автора материально. А пока можно посмотреть на то, как получилось повторить эту конструкцию мне. Онлайн-радио сделано на базе готовой mp3 колонки (кубика) Atlanfa, которую можно найти сейчас почти везде. Отсеком для дополнительных аккумуляторов я пожертвовал и разместил в нем дисплей и Arduino nano. Слева ручка потенциометра усилителя (громкость). Справа гнездо блока питания 5В. Позже я добавил гнездо для наушников. Динамики при подключении наушников не отключаются, просто убавляю громкость усилителя на ноль. Дисплей очень маленький, но его хватает для отображения минимальной информации, тем более практика показала, что и она не нужна. В будущем автор планирует добавить управление воспроизведением с помощью IR пульта. А пока есть возможность переключать каналы через Web-интерфейс в браузере смартфона или компьютера. Правда, есть еще возможность подключить несколько обыкновенных кнопок к радио, но я не стал этого делать, потому что они тоже требуют свободного места. После включения радио начинает играть спустя несколько секунд. Web-интерфейс немного подтормаживает и долго не появляется в браузере. А в остальном все очень здорово. Качество звука хорошее, на уровне колонки Atlanfa примерно. Слышны тихие щелчки, видимо, их дает ESP8266 своей деятельностью. Возможно, кое-где стоит проложить экранированные провода (до усилителя). При воспроизведении потребление тока около 500мА, а в момент запуска больше одного ампера. Без усилителя потребление было меньше. А сейчас со слабым блоком питания будут циклические перезапуски. Блок питания на 5В 3А позволяет без проблем пользоваться устройством, но это с запасом (другого не было у меня).
Микросхема RDA5807M — это FM радиоприемник нового поколения с поддержкой RDS/RBDS и цифровым управлением по I2C. Микросхема выполнена по CMOS технологии, что определяет ее минимальное энергопотребление. RDA5807M уже содержит все необходимые узлы и требует лишь небольшого числа внешних компонентов. А мощный аудиопроцессор обеспечивает оптимальное качество звука при различных условиях приема. Все это делает RDA5807M удачным выбором для носимых, портативных устройств. В интернет магазинах распространен модуль RRD-102v2, на котором распаяны RDA5807M, кварцевый резонатор и пара компонентов обвязки. В данной статье я опишу как подключить этот модуль к Ардуино и что нужно знать для создания радиоприемника на его основе.Характеристики RDA5807M
Сразу даю ссылку на даташит: RDA5807M_datasheet_v1.1, наиболее полную информацию о характеристиках RDA5807M вы можете найти в нем. Я перечислю некоторые из них:
- Напряжение питания 2.7 — 3.3В
- Потребляемый ток (при напряжении питания 3В):
- в рабочем режиме — не более 20мА
- в режиме сна — не более 15мкА
- Диапазон принимаемых частот 50 — 115МГц
- Выбираемый шаг изменения частоты: 200кГц, 100кГц, 50кГц, 25кГц
- Выбираемый источник тактового сигнала: внешний или внутренний генератор (для внутреннего генератора требуется резонатор 32.768кГц)
- Поддержка RDS/RBDS
- Управление по шине I2C
- Возможность прямого подключения нагрузки от 32Ом
Диапазон напряжения питания не самый удобный, например, от лития без стабилизации запитать не получится. Зато наушники можно подключать прямо к выводам микросхемы, дополнительное усиление не требуется. Также можно отметить небольшой потребляемый ток микросхемы, что позволяет запитывать ее от цифрового вывода микроконтроллера (по крайней мере AVR) в тех случаях, когда требуется отключение питания радио в целях энергосбережения.
Распиновка и подключение к Ардуино
Распиновка RRD-102v2 |
Подключение RRD-102v2 (RDA5807M) к Ардуино |
Выводы SDA и SCL модуля подключаются к одноименным выводам Ардуино. Для платы Uno это пины A4 и A5 соответственно. Их уровни превышают напряжение питания RDA5807M, но это не критично, микросхема отлично работает без преобразователя уровней. Питание берем с вывода 3v3.
Интерфейс управления
Здесь я хочу обратить внимание на имеющуюся в технической документации неточность (даташит на эту микросхему вообще очень мутный): в ней говорится, что I2C адрес микросхемы 0x10h, что внутренние адреса ее регистров не видны и что чтение и запись выполняются последовательно, начиная с фиксированного стартового адреса (0x0Ah для чтения, 0x02h для записи). После каждой операции чтения/записи происходит инкремент внутреннего счетчика и очередная операция будет выполняться уже для следующего регистра. Так до тех пор, пока внутренний счетчик не дойдет до верхней границы 0x3Ah, после этого он вернется к своему начальному значению. На самом деле RDA5807M отзывается на три I2C адреса, в чем легко убедиться, воспользовавшись I2C сканером:
I2C адреса RDA5807M |
Адрес 0x10h используется для последовательного обращения к регистрам, как было описано выше.Адрес 0x11h позволяет обращаться к произвольным регистрам.Адрес 0x60h позволяет работать с RDA5807M в режиме совместимости с TEA5767. Упоминание адреса 0x11h можно найти в документе RDA5807P_ProgManual_1.0. Хоть он и предназначен для другой микросхемы, но практически всё применимо и для RDA5807M. Ниже приведен фрагмент из данного документа, описывающий формат I2C обмена при использовании адреса 0x11h:
Формат обмена с RDA5807M по I2C адресу 0x11h |
Как можно видеть, при записи в режиме произвольного доступа первым передается адрес интересующего регистра (REGISTER ADDRESS), затем старший и младший байты данных. Для чтения содержимого регистра из RDA5807M микроконтроллер сначала передает его адрес, затем считывает старший и младший байты. Чуть позже я приведу пример чтения/записи регистров, а пока разберемся с их назначением.
Регистры RDA5807M
Управление работой RDA5807M заключается в обращении к его регистрам: изменяя одни регистры, мы производим необходимые нам настройки; из других можно читать различную информацию (флаги, данные RDS и т.д.). Регистры 16-разрядные, их адреса и назначение приведены в даташите. Описание весьма скудное, поэтому я решил сам «пощупать» каждый регистр, чтобы понять какой бит за что отвечает. Для этого была написана следующая программа:
Управление работой RDA5807M с компьютера |
Данная программа читает значения регистров RDA5807M, отображает в удобном виде и позволяет изменять их, щелкая мышью по элементам управления. Ардуино при этом выступает в роли посредника между программой на компьютере и RDA5807M, для этого в нее должен быть загружен соответствующий скетч (вы найдёте его в программе по кнопке «Скетч для Ардуино»). Очень рекомендую попробовать данную программу, чтобы разобраться с назначением регистров. Скачать ее можно здесь. И, чтобы совсем не осталось вопросов по управлению RDA5807M, привожу описание регистров на понятном языке.
Регистр | Биты | Имя | Назначение | |
00h | 15:0 | CHIP_ID | Chip ID — Идентификатор микросхемы. Есть у меня основания полагать, что значение ChipID состоит именно из двух байт, а не одного, как это указано в даташите. | 0x5804 |
02h | 15 | DHIZ | Audio Output High-Z Disable. Управляет состоянием аудио выводов: 0 — выводы находятся в высокоимпедансном состоянии; 1 — переводит выводы в рабочий режим. | 0 |
14 | DMUTE | Mute Disable — отключение режима mute, который по умолчанию включен (значение 0). Для отключения mute в этот бит следует записать 1. | 0 | |
13 | MONO | Принудительное моно, включается записью в данный бит значения 1 | 0 | |
12 | BASS | Bass Boost — усиление басов. Для включения данной опции необходимо записать 1 | 0 | |
11 | Если я правильно понял, этот бит отключает температурную компенсацию тактового генератора, в результате чего RDA5807M не сможет работать в заявленном температурном диапазоне (-20..70C) и сможет поддерживать колебания температуры только на +/- 20C от точки настройки. | 0 | ||
10 | Бит RCLK Direct Input Mode следует установить в 1, если используется внешний тактовый сигнал | 0 | ||
9 | SEEKUP | Seek Up — направление поиска радиостанций: 0 — к нижней границе диапазона; 1 — вверх. | 0 | |
8 | SEEK | Запись 1 в этот бит запускает процесс поиска радиостанции. Поиск ведется в направлении, заданном битом SEEKUP, до нахождения радиостанции или до прохождения всего диапазона частот, после чего данный бит сбрасывается и устанавливается бит STC. | 0 | |
7 | SKMODE | Seek Mode. Определяет поведение при достижении границы диапазона во время поиска радиостанций: 0 — продолжить поиск с другой границы; 1 — прекратить поиск | ||
6:4 | CLK_MODE | 000 | ||
3 | RDS_EN | RDS/RBDS Enable. Запись 1 в этот бит включает прием RDS/RBDS сообщений. | ||
2 | NEW_METHOD | New Demodulation Method Enable — установка этого бита задействует новый метод демодуляции, способный улучшить чувствительность приемника | ||
1 | SOFT_RESET | Программный сброс RDA5807M. Установка бита в 1 приведет к сбросу всех внутренних регистров к значениям по умолчанию. Сброс выполняется автоматически при включении питания микросхемы, нет необходимости сбрасывать устройство дополнительно. | ||
ENABLE | Power Up Enable — разрешение работы. Установка в 1 переводит приемник в рабочий режим; 0 — спящий режим — отключает питание внутренних узлов, состояние регистров при этом сохраняется, после возвращения в рабочий режим необходимо выполнить TUNE для настройки на радиостанцию. | |||
03h | 15:6 | CHAN | Channel Select — выбор канала. Частота радиостанции устанавливается не явно, а путем изменения значения CHAN, которое при умножении на SPACE и прибавления нижней границы диапазона дает итоговую частоту. Для записи CHAN необходимо также установить бит TUNE, в противном случае CHAN не изменится. | 0x00 |
5 | DIRECT_MODE | Режим прямого управления, который используется только при тестировании — это описание из даташита, не уверен, что данный бит имеет отношение к RDA5807M. | 0 | |
4 | TUNE | Запись в этот бит значения 1 запускает процесс настройки. По окончании настройки устанавливается бит STC, бит TUNE при этом сбрасывается. | 0 | |
3:2 | BAND | 00 | ||
1-0 | SPACE | 00 | ||
04h | 15:12 | RSVD | Биты зарезервированы | 0000 |
11 | DE | 0 | ||
10 | RSVD | Зарезервирован | 1 | |
9 | SOFTMUTE_EN | Soft Mute Enable — приглушение звука, может быть использовано для минимизации шумов в условиях слабого приема. Функция включается установкой бита в 1. | ||
8 | AFCD | 0 | ||
05h | 15 | INT_MODE | Режим генерации прерывания при завершении поиска/настройки. Данный бит определен в даташите, но не имеет отношения к RDA5807M. Актуален для микросхем с дополнительными выводами GPIO, например, RDA5807P. | 1 |
14:12 | RSVD | Биты зарезервированы | 000 | |
11:8 | SEEKTH | Seek Threshold. Данные биты задают порог отношения сигнал/шум при выполнении поиска радиостанций. | 1000 | |
7:6 | LNA_PORT_SEL | 10 | ||
5:4 | RSVD | Биты зарезервированы | 00 | |
3:0 | VOLUME | Регулировка громкости | 1011 | |
06h | 15 | RSVD | Зарезервирован | |
14:13 | OPEN_MODE | Данные биты указаны в даташите, но они неактуальны для RDA5807M. В других микросхемах серии установка этих битов в 11 разрешает изменение остальных битов регистра, отвечающих за настройку I2S (Audio Data Interface). | 00 | |
07h | 15 | RSVD | Зарезервирован | |
14:10 | TH_SOFTBLEND | Soft Blend Thershold — настройка уровня шумоподавления. | 10000 | |
9 | 65M_50M MODE | 1 | ||
8 | RSVD | Зарезервирован | ||
7:2 | SEEK_TH_OLD | Seek Threshold Old — по аналогии с SEEKTH данные биты определяют порог при поиске радиостанций, но актуальны только при SEEK_MODE (биты 14:12 регистра 0x20h) = 001 — «старый» метод поиска. | 000000 | |
1 | SOFTBLEND_EN | Soft Blend Enable. Данный бит разрешает шумоподавление, уровень которого задан битами TH_SOFTBLEND. Помогает здорово очистить сигнал от помех. | 1 | |
FREQ_MODE | Режим задания частоты. Когда данный бит сброшен в 0, результирующая частота определяется как BAND + CHAN * STEP. При FREQ_MODE = 1 частота определяется как BAND + содержимое регистра 08h. | |||
08h | 15:0 | FREQ_DIRECT | 0x0h | |
0Ah | 15 | RDSR | RDS Ready — флаг готовности данных RDS/RBDS (1 — данные готовы) | |
14 | STC | Seek/Tune Complete — флаг завершения поиска/настройки на заданную частоту (1 — операция завершена). | ||
13 | SF | Seek Fail — флаг, сигнализирующий о неуспешном выполнении поиска, когда не удалось найти сигнал с RSSI большим порога SEEKTH | ||
12 | RDSS | |||
11 | BLK_E | Данный флаг сообщает о получении E блока. | ||
10 | ST | 1 | ||
9:0 | READCHAN | Read Channel. Эти биты содержат значение CHAN, доступны только для чтения. В режиме последовательного доступа к регистрам RDA5807M стартовый адрес для чтения — 0Ah, таким образом нет возможности прочитать значение CHAN регистра 03h. Этим и обусловлено наличие битов READCHAN. | 0x0h | |
0Bh | 15:9 | RSSI | Received Signal Strength Indicator — показатель уровня принимаемого сигнала. | |
8 | FM_TRUE | Данный флаг сигнализирует о наличии передачи на текущей частоте. То есть приемник настроен на радиостанцию. | ||
7 | FM_READY | Насколько я могу судить, данный флаг идентичен флагу STC | ||
6:5 | RSVD | Биты зарезервированы | 00 | |
4 | ABCD_E | |||
3:2 | BLERA | |||
1:0 | BLERB | Block Errors Level Of B — уровень ошибок в блоке B (RDS) или E (RBDS, когда ABCD_E флаг установлен в 1). Значения битов аналогичны BLERA. | ||
0Ch | 15:0 | RDSA | Блок A (в режиме RDS) или E (в режиме RBDS при ABCD_E = 1). | 0x5803h |
0Dh | 15:0 | RDSB | Блок B (в режиме RDS) или E (в режиме RBDS при ABCD_E = 1). | 0x5804h |
0Eh | 15:0 | RDSC | Блок C (в режиме RDS) или E (в режиме RBDS при ABCD_E = 1). | 0x5808h |
0Fh | 15:0 | RDSD | Блок D (в режиме RDS) или E (в режиме RBDS при ABCD_E = 1). | 0x5804h |
10h | 15:14 | BLERC | Block Errors Level Of C — уровень ошибок в блоке C (RDS) или E (RBDS, когда ABCD_E флаг установлен в 1). Значения битов аналогичны BLERA. | |
13:12 | BLERD | Block Errors Level Of D — уровень ошибок в блоке D (RDS) или E (RBDS, когда ABCD_E флаг установлен в 1). Значения битов аналогичны BLERA. |
Это не все регистры RDA5807M, по старшим адресам доступны другие. Возможно, среди них есть еще что-то интересное. И если вам о них известно, пишите, добавлю их в список.
Программирование RDA5807M
Давайте начнем с простенького скетча. Если вы попробуете управлять RDA5807M из моей программы, то обнаружите, что для того чтобы заставить его работать достаточно установить несколько битов: ENABLE, DHIZ, DMUTE, SEEK. Установка последнего запустит поиск радиостанции. Эти же действия можно выполнить программно при помощи следующего скетча:
voidsetup() { Wire.begin(); setRegister(0x02, 0xC101); } voidloop() { } void setRegister(uint8_t reg, const uint16_t value) { Wire.beginTransmission(0x11); Wire.write(reg); Wire.write(highByte(value)); Wire.write(lowByte(value)); Wire.endTransmission(true); }
Подключите RDA5807M к Ардуино по приведенной ранее схеме и залейте в нее скетч. Приемник выполнит поиск и настроится на первую найденную радиостанцию. Бит Tune при этом сбрасывается. Нажатие кнопки Reset на Ардуино и повторное выполнение функции setup будут снова устанавливать этот бит, инициируя поиск следующей станции. Работает? Двигаемся дальше. В примере скетча выше мы записали в регистр 02h заранее определенное значение. На деле такое требуется редко, разве что для инициализации некоторых регистров. В основном же значения регистров формируются в процессе работы программы при изменении отдельных битов. В таких случаях удобно использовать константы, содержащие номера этих битов или маски для их установки. Ниже приведен пример такого скетча. Он позволяет настроиться на конкретную радиостанцию, установить громкость и получить RSSI.
uint8_t volume = 1; uint16_t freq = 1073; uint16_t reg02h, reg03h, reg05h, reg0Bh; voidsetup() { Serial.begin(9600); Wire.begin(); reg02h = RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE; setRegister(RDA5807M_REG_CONFIG, reg02h); reg02h |= RDA5807M_FLG_BASS; setRegister(RDA5807M_REG_CONFIG, reg02h); reg03h = (freq - 870) << RDA5807M_CHAN_SHIFT; setRegister(RDA5807M_REG_TUNING, reg03h | RDA5807M_FLG_TUNE); reg05h = getRegister(RDA5807M_REG_VOLUME); reg05h &= ~RDA5807M_VOLUME_MASK; reg05h |= volume << RDA5807M_VOLUME_SHIFT; setRegister(RDA5807M_REG_VOLUME, reg05h); } voidloop() { reg0Bh = getRegister(RDA5807M_REG_RSSI); uint8_t RSSI = (reg0Bh & RDA5807M_RSSI_MASK) >> RDA5807M_RSSI_SHIFT; Serial.print("RSSI = "); Serial.print(RSSI); Serial.println(" (0-min, 127-max)"); delay(500); } void setRegister(uint8_t reg, const uint16_t value) { Wire.beginTransmission(0x11); Wire.write(reg); Wire.write(highByte(value)); Wire.write(lowByte(value)); Wire.endTransmission(true); } uint16_t getRegister(uint8_t reg) { uint16_t result; Wire.beginTransmission(RDA5807M_RANDOM_ACCESS_ADDRESS); Wire.write(reg); Wire.endTransmission(false); Wire.requestFrom(0x11, 2, true); result = (uint16_t)Wire.read() << 8; result |= Wire.read(); return result; }
В этом примере значения регистров получаются установкой отдельных разрядов. Для этого используются определенные в начале скетча флаги и маски. Я описал несколько из них для примера, остальные добавляются по аналогии. Чтобы настроить RDA5807M на интересующую частоту необходимо установить значения BAND и SPACE и затем изменять только значение CHAN. Итоговая частота определяется по формуле:F = BAND + CHAN * SPACE. В скетче используются определенные по умолчанию BAND и SPACE (87..108МГц и 100кГц соответственно). По ним можно определить значение, которое должно быть записано в биты CHAN для получения интересующей частоты. Не забывайте при записи CHAN устанавливать также бит TUNE. Для изменения громкости значение регистра 05h считывается из RDA5807M в переменную. Затем осуществляется сброс битов VOLUME. И уже после этого можно устанавливать новое значение громкости и записывать результат в регистр. Для получения RSSI выполняются обратные действия: в считанном из регистра 0Bh значении сбрасываются все биты, кроме содержащих RSSI. Затем результат сдвигается вправо, чтобы младший бит RSSI оказался в младшем разряде переменной. Так мы получим нужное нам значение. Теперь, когда описаны основные приемы управления RDA5807M, можно приступить к программированию. Нужно лишь определиться с функционалом и интерфейсом.
Добавим LCD дисплей и энкодер
Да, я люблю использовать в своих проектах LCD2004 с I2C интерфейсом и энкодер вращения. Это уже привычные для меня элементы создания пользовательского интерфейса. Используя их, я могу сосредоточиться на текущей задаче, а не заморачиваться с изобретением велосипеда. Поэтому сейчас я добавил их в схему:
Схема радио с дисплеем и энкодером |
Макет радио с дисплеем и энкодером |
Итак, моя текущая задача — это создание радио с базовым функционалом и индикацией. О законченном проекте речь пока не идет. Для меня это скорее знакомство с данным модулем. Поэтому в предлагаемом ниже скетче нет фишек вроде сохранения списка радиостанций в EEPROM. Нет и работы с RDS — использованию этой технологии в RDA5807M я посвящу следующую публикацию. В последствии я планирую сделать радио в оригинальном корпусе с OLED дисплеем. А пока можете оценить результат данного этапа, скетч доступен по ссылке. Для работы требуется библиотека LiquidCrystal_I2C_Menu, скачайте и установите ее. В скетче реализовано:
- Поиск радиостанции вверх/вниз и отображение частоты
- Регулировка громкости
- Ввод значения частоты энкодером
- Выбор поведения при повороте энкодера: регулировка громкости или поиск радиостанции
- Установка ряда параметров, отвечающих за звук и шумоподавление
- Сохранение настроек в EEPROM и чтение их при включении радио
На этом пока всё. Продолжение будет в следующей публикации с обзором RDS.Используемые источники:
- http://andrew25kir.blogspot.com/2017/01/karadio-esp8266-vs1053.html
- https://tsibrov.blogspot.com/2019/11/rda5807m-part1.html