Андрей Смирнов
Время чтения: ~27 мин.
Просмотров: 145

Еще одно FM радио на RDA5807 под управлением Ардуино

RRD102v2.jpg Микросхема 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) в тех случаях, когда требуется отключение питания радио в целях энергосбережения.

Распиновка и подключение к Ардуино

RRD102v2%2BRDA5807M%2Bpinout.png
Распиновка RRD-102v2
RDA5807M%2BArduino.png
Подключение 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.
4 TUNE Запись в этот бит значения 1 запускает процесс настройки. По окончании настройки устанавливается бит STC, бит TUNE при этом сбрасывается.
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.Схема радиоприемника</figcaption>

На рисунке 1 представлена основная схема радиоприемника, взятая и адаптированная из технического описания Silicon Labs Si4844 и рекомендаций по применению. Для приема в диапазоне КВ я использовал ферритовую антенну от старого портативного приемника. Q1 – усилитель для СВ/УКВ, здесь я так же использовал телескопическую антенну от старого приемника. Стоит заметить, что руководство по проектированию, приведенное выше, дает несколько альтернатив и различные подходы к антеннам.

Переменный резистор (VR1) является критичным элементом схемы, поскольку он будет использоваться для настройки частоты приемника (ручка настройки). Рекомендуется использовать линейный потенциометр. Для аудиовыхода я решил использовать пару «экономичных» аудиоколонок со встроенным усилителем, которые у меня остались от старого компьютера. Разумеется, можно использовать простой стереоусилитель.

Возможно, наиболее сложная часть сборки – это работа с микросхемой в корпусе SSOP-24. Если у вас нет опыта работы с SMD микросхемами, возможно, самым простым способом будет использование переходной платы. У меня была переходная плата SSOP-28; немного пайки, и с микросхемой стало можно работать, как с микросхемой в DIP корпусе. Другими потенциально трудными компонентами для работы является пара из ферритового фильтра (бусинки) и конденсатора. Эти компоненты также можно припаять на переходную плату, чтобы работать с ними как с DIL элементом.

SMD компоненты, припаянные на переходные платы
Список компонентов основной схемы
Компонент Описание
B1 Ферритовый фильтр (бусинка) 2,5 кОм (100 МГц)
C1,C2,C5 Неполярный конденсатор 4,7 мкФ
C3,C4 Конденсатор 22 пФ
C6,C7,C9 Конденсатор 0,1 мкФ
C8 Неполярный конденсатор 47 мкФ
C10,C11 Конденсатор 0,47 мкФ
C12,C14 Конденсатор 33 нФ
C13 Конденсатор 33 пФ
C15 Конденсатор 10 пФ
IC1 Радиоприемник Si4844-A10
Q1 NPN транзистор SS9018
R1, R2 Резистор 2,2 кОм
R3 Резистор 1 кОм
R4,R7 Резистор 100 кОм
R5 Резистор 10 Ом
R6 Резистор 120 кОм
R8 Резистор 100 Ом
L1 Индуктивность 270 нГн
VR1 Линейный потенциометр 100кОм
Y1 Кварцевый резонатор 32,768 кГц
ANT1 Ферритовая антенна
ANT2 Телескопическая/штыревая антенна

Подключение Arduino

Еще одна вещь, которую надо решить до включения схемы для тестирования, – это взаимодействие с Arduino. Здесь я решил использовать плату Arduino Pro Mini 3В/8МГц. Это небольшая плата Arduino, полностью работающая на напряжении 3,3 В и совместимая с Si4448-A10, что является главным преимуществом. Небольшой размер платы – второе преимущество. Подключение к Si4448-A10 осуществляется по четырем линиям, как описано ниже:

Подключение Arduino к Si4844-A10
Arduino (3.3 В) Si4844-A10
A5/SCL SCLK
A4/SDA SDIO
D2 INT
D12 RST

Кроме того, используется стандартный преобразователь USB/TTL для подключения Arduino к компьютеру для программирования. Таким образом, у Arduino также будут задействованы выводы TX, RX и GND. Так вы сможете программировать и тестировать Si4844-A10 «внутрисхемно», что облегчает разработку и экспериментирование. Когда всё будет завершено, это подключение может быть убрано для автономной работы нового радиоприемника. Питание платы радио и платы Arduino должно осуществляться внешним стабилизированным источником питания на 3,3 В. Не пытайтесь запитывать их от преобразователя USB/TTL, даже если у него есть выходной вывод 3,3 В – нельзя полагаться, что он обеспечит необходимый ток для питания и Arduino, и Si4844-A10.

Тестирование основной схемы

Когда у вас будет собранная на макетной плате схема, подключенные к ней Arduino и аудиоколонки со встроенным усилителем, вы сможете запустить тестовую программу, которая приведена в архиве в конце статьи (Si4844_Quick_Test.ino). Эта программа выполняет простой тест, который включает питание устройства, устанавливает диапазон FM (УКВ) и предоставляет информацию о версии микросхемы. Если всё пройдет хорошо, вы сможете настроить частоту радиоприемника, повернув ручку VR1, увидите частоту, динамически отображаемую на экране и, конечно, услышите то, что выдает радиоприемник.

Скриншот экрана с результатами вывода тестовой программы

Если основная схема и ее подключение к Arduino работают, то можно собирать полноценный радиоприемник.

Программирование Arduino

Микросхема Si в этом проекте является ведомым устройство I2C, имеющим фиксированный адрес 0x11; при этом ведущим устройством (мастером) является плата Arduino. Однако скорость обмена информацией по I2C у этой микросхемы относительно медленная: максимальная поддерживаемая скорость 50 кГц. Кроме того, во время процедуры включения питания скорость не должна превышать 10 кГц. Чтобы удовлетворить эти требования, мы должны явно установить у Arduino скорость I2C, которая, как правило, слишком велика для Si4844-A10. К счастью, благодаря большому количеству документации по функциям I2C Arduino, мы можем легко выполнить необходимые изменения.

В принципе, скорость I2C для наших целей определяется в программном обеспечении Arduino двумя переменными. Эти переменные – это TWBR и TWSR. Биты 0 и 1 TWSR управляют предделителем, который работает со значением TWBR для установки скорости I2C. Скорость (тактовая частота) передачи по I2C рассчитывается по формуле:

Частота = Тактовая частота процессора / (16 + (2 * (TWBR) * (предделитель))

Arduino Pro mini 3,3В работает на частоте 8 МГц. Чтобы установить скорость I2C на 10 кГц, мы используем значение TWBR 98 и установим предделитель в значение 4 (путем установки в 1 только бита 0 TWSR). Таким образом,

8 000 000 / (16 + (2 * 98 * 4 )) = 10 000 или 10 кГц

Чтобы установить скорость I2C на 50 кГц, мы используем значение TWBR 18 и установим предделитель в значение 4 (путем установки в 1 только бита 0 TWSR). Таким образом,

8 000 000 / (16 + (2 * 18 * 4)) = 50 000 или 50 кГц

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

Еще один важный момент, связанный с программирование, заключается в том, что нам в коде нужно использовать подпрограмму внешнего прерывания. Мы используем INT0 на Arduino, и, когда Si4844-A10 установит уровень на этом выводе в 1, выполнится простая функция, которая «привязана» к этому прерыванию. Всё, что делает эта функция, это изменяет значение переменной флага, которая может быть проверена и изменена в других частях программы. Si4844-A10 будет запускать прерывания (т.е. подавать уровень логической единицы на вывод INT) при определенных условиях, в основном в случае изменения сопротивления потенциометра настройки. Так Si4844-A10 сообщает Arduino, что вы повернули ручку настройки, и что необходимо обновить данные на дисплее.

Программирование Si4844-A10

По сути, Arduino посылает команды микросхеме радиоприемника по шине I2C, затем микросхема выполняет запрошенные действия и возвращает информацию о состоянии. Микросхема Si может работать в нескольких режимах, что позволяет настроить в ней точную частоту и нужные параметры. В этом проекте мы используем чип Si4844-A10 в режиме, который принимает предварительно определенные (или стандартные) диапазоны радиочастот с параметрами по умолчанию. Этот режим был выбран потому, что он легко дает доступ к базовому функционалу и при этом предлагает определенную степень настройки.

Вместо того, чтобы просто устанавливать значение «регистра» СВ/КВ/УКВ, в радиочипе может быть выбран один из 41 различных частотных диапазонов. Диапазоны 0–19 – ультракороткие волны (FM) 87–109 МГц; диапазоны 20–24 – средние волны (AM) 504–1750 кГц; диапазоны 25–40 – короткие волны 5,6–22,0 МГц (SW). Эти дипазоны различаются шириной, что может усложнить настройку. Более того, частотные диапазоны нескольких запрограммированных диапазонов равны или отличаются незначительно, но имеют различные параметры, например, предыскажения (УКВ/FM), ширина канала (СВ/AM), пороги разделения стереосигналов (УКВ/FM) и уровня принимаемого сигнала. Для полного понимания этого необходимо обратиться к техническому описанию и примечаниям к применению, где вы сможете увидеть таблицы диапазонов, а также все режимы, команды программирования и форматы ответов и статуса.

В данном проекте программное обеспечение будет обеспечивать доступ ко всем стандартным диапазонам, а также к управлению основными параметрами, включая изменение режима (AM/FM/SW), громкость, тон и отключение звука.

Добавление клавиатуры

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

Простая мембранная клавиатура
Подключение клавиатуры к Arduino
Клавиатура Arduino
Строка 1 D8
Строка 2 D9
Строка 3 D10
Строка 4 D11
Столбец 1 D13
Столбец 2 D14
Столбец 3 D15

В программном обеспечении я использовал библиотеку от Марка Стэнли и Александра Бревига, которая выпущена под лицензией GNU General Public License. Для проекта мы сопоставим функции с кнопками, как показано ниже.

Назначение кнопок для управления радиоприемником

Назначение кнопок клавиатуры:

  • AM: переключить в режим AM (средние волны), диапазон 22;
  • FM: переключить в режим FM (ультракороткие волны), диапазон 8;
  • SW: переключить в режим SW (короткие волны), диапазон 31.

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

  • Vol+ / Vol- : Увеличить или уменьшить громкость на один шаг. Есть 64 уровня громкости. Поскольку в проекте используются колонки со встроенным усилителем, эти кнопки не сильно важны, но их наличие всё равно радует;
  • Band+/Band- : Изменение диапазона на один шаг, но из числа доступных в текущем режиме;
  • B/T+ / B/T- : Увеличить или уменьшить тон на один шаг. Я признаю, что несколько вольно использую термин «тон». Для режима FM это увеличит или уменьшит уровень низких частот от 0 (макс. бас) до 8 (макс. высокий). Для режимов AM/SW это установит канальный фильтр от 1 до 7. Фильтры составляют 1.0 кГц, 1.8 кГц, 2.0 кГц, 2.5 кГц, 2.83 кГц, 4.0 кГц и 6.0 кГц соответственно. Также обратите внимание, что для простоты и удобства программирования (т.е. лени) в режимы AM/SW могут быть добавлены уровни 0 и 8, но они не будут отличаться от уровней 1 и 7 соответственно;
  • Mute: Включить или выключить звук на выходе.

Добавление дисплея

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

Дисплей Nokia 5110/3310

При работе с этим дисплеем необходимо учитывать два важных момента. Во-первых, существует несколько разновидностей этих дисплеев, и у них могут быть разные распиновки. Вы должны проверить распиновку на своем дисплее, убедиться, что он на самом деле работает от 3,3 В, и проверить правильность подключения к Arduino Pro Mini. Во-вторых, поскольку все входы/выходы Arduino используют напряжение 3,3 В, мне не пришлось использовать понижающие резисторы, которые вы обычно видите, когда эти дисплеи используются 5-вольтовыми платами Arduino, например, Uno.

Подключение дисплея Nokia 5110/3310 к Arduino
Вывод дисплея / Назначение Вывод Arduino или точка на схеме
1-RST D3
2-CE D4
3-DC D5
4-DIN D6
5-CLK D7
6-VCC Vcc (3.3v)
7-LIGHT GND
8-GND GND

В программе я решил использовать библиотеку LCD5110_Basic, которая быстра и очень проста в использовании.

На рисунке ниже показан заполненный данными дисплей радиоприемника.

Дисплей Nokia 5110/3310 при использовании в радиоприемнике (на скриншоте некорректно показаны единицы измерения частоты mHz, в прошивке это исправлено MHz)

Начиная с левого верхнего угла, мы показываем:

  • строка 1 – режим (AM/FM/SW) и номер диапазона;
  • строка 2 – частотный диапазон;
  • строка 3 – уровни громкости и баса/тембра;
  • строка 4 – текущая частота (МГц или кГц);
  • строка 1 – индикаторы стерео (только для FM) и выключения звука (если активно).

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

Собранный радиоприемник

Ниже представлен собранный на макетной плате проект радиоприемника – возможно, не такой аккуратный, каким мог бы быть (хорошо, здесь полный бардак), но полностью рабочий. Конечно, качество его работы можно улучшить только с помощью окончательной сборки.

Макет радиоприемника на Arduino

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

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

Заключение

Это был сложный и приятный проект. Я определенно поражен микросхемой Si4844-A10 и ее возможностями. Этот проект только слегка затронул её функционал и может послужить основой чего-то для более сложного.

Код программ

Скачать код прошивки

Теги

ArduinoFM радиоприемникLCD дисплей Nokia 5110/3310Графический LCD дисплейКлавиатураРадиоприемникНа эту тему было много толковых публикаций, однако я сделал все по-своему, вдобавок создал трехмерную модель корпуса с практичным и оригинальным дизайном. В результате получился вполне законченный проект, достаточно простой для повторения начинающим любителем электроники. Счастливый владелец 3D принтера сможет похвастаться красивой самоделкой, способной конкурировать с фабричной продукцией. Хочешь разорить друга — подари ему фотоаппарат. Хочешь заставить раскошелиться радиолюбителя — подкинь ему ссылку на китайский модуль RDA5807.xxdwusrb0ztq96uddtivaxgwppe.jpeg Крохотный квадратик размером около сантиметра и ценой около двадцати рублей. На удивление, внутри вполне приличный цифровой радиоприемник с автопоиском радиостанций и умеющий читать RDS. Скажу честно: обольщаться на дешевизну модуля RDA5807 не стоит, чтоб запустить эту прелесть, нужно все остальное: ардуинка, усилитель с динамиками, и маленький дисплейчик для большой красоты. Вместо батареек просится аккумулятор, значит добавляем в проект контроллер заряда от USB. Скетч можно отладить на макетной плате, но для готового устройства нужен приличный корпус. Внешнее оформление — вопрос очень творческий, но к нам на помощь приходит технология 3D печати. Стараемся сделать все максимально просто и дешево. Ардуинку берем такую:yhey_lwfrbvbrwiv3hebnoqohlc.jpeg дисплей — вот такой:m1wdrmmtam0qsbzjtlblv-p9-bi.jpeg питание от аккумулятора 18650, а для него такой вот контроллер заряда. 97ku3eiw7oiqf8nglsm3zdowx_4.jpeg Усилитель низкой частоты — стандартный элемент для очень многих проектов, а потому имеем в запасе вот такие самодельные модули. v57glpqrvj58tfxix9q7b1rp59u.jpeg Полная электрическая схема получается вот такой.rvt2czbgwjmpnqelvmeeojs761a.jpeg Вместо дефицитной советской микросхемы К174УН14 применяем доступную TDA2003. Диод D1 нужен, чтобы при максимальном заряде аккумулятора напряжение на модуле приемника оставалось ниже четырех вольт. Надо заметить, RDA5807 не перегорает даже от пяти вольт, но на повышенном напряжении либо вообще не работает, либо ловит всякий шум вместо радиостанций. Для него четыре вольта — уже многовато, по очень хорошему надо бы питать через кренку на 3.3 вольта. При напряжении ниже трех вольт устройство перестает реагировать на кнопки, поскольку затыкается ардуинка. Но даже при 2.5 вольт RDA5807 стойко держит прежнюю частоту и качество приема не ухудшается. Если подключить аккумулятор к контроллеру заряда напрямую, то при выключенном USB зарядник превращается в нагрузку, вытягивая из аккумулятора ток примерно в 2 микроампера. Много это или мало — не знаю, но сам факт просто возмутительный. В качестве решения ставим герконовое реле K1, которое при подключении USB замыкает контакты K1.1. Релюшка самодельная, изготавливается путем намотки в навал эмалированного провода диаметром не более 0,1 мм непосредственно на корпус геркона. Чем больше провода удастся намотать, и чем тоньше он будет — тем меньше будет потребляемый ток. Намотать слишком много, так, чтобы не хватало пяти вольт для срабатывания, адекватный человек не сможет, здравый смысл заставит вовремя остановиться. Как китайцы крепят контроллер заряда, — не знаю. Могу предложить припереть винтиками с боков. fo5fdggy8pa0qw1ndmy0-loaz4a.jpeg Чтоб было видно индикацию, пришлось заменить планарный светодиод на обыкновенный. Можно было бы сделать световод из толстой рыболовной лески или прозрачного прутка для 3D принтера, но ничего, сойдет и так. Теперь пишем скетч, библиотеки берем стандартные SSD1306Ascii для дисплея и RDA5807M для радио. Оказалось, в строке RDS есть хитрости. Там три блока: текущее время, имя радиостанции и собственно сама информационная строка. Я так и не понял, то ли в библиотеке кривой парсер, то ли радиостанция как то не так транслирует текущее время. Вразумительные цифры там появляются далеко не всегда. В результате первый блок был отброшен. А если читать саму строку, выясняется, что там ничего нет, кроме телефонов рекламной службы. Пришлось оставить только имя радиостанции, никакой другой пользы из строки RDS извлечь не удалось. Кроме названия радио, дисплей показывает силу сигнала, заряд аккумулятора и рабочую частоту. Планировал делать память для рабочих частот, но лень матушка меня остановила. Не захотел я делать много кнопок, оставил всего две: одну для запуска автопоиска, другую для регулировки громкости. С одной кнопки поиск идет по кругу, потому иногда для выбора нужной станции приходится пробегать весь диапазон. К счастью, у нас не слишком много передатчиков, чтобы такой серфинг сильно напрягал. Регулировка громкости происходит так: при первом нажатии уровень сбрасывается на самый минимум, и далее при каждом последующем нажатии увеличивается на одну ступень. Если возникает пауза более двух секунд — очередное нажатие считается первым. Таким образом, за все про все две кнопки. Два динамика, смотрящие в противоположные стороны и включенные противофазно, орут как надо: на самом первом уровне громкости вполне нормально слушать. Если немного добавить — услышат даже соседи. Как люди жили без 3D принтера я помню, но это была не жизнь, а кошмарный сон. В наши дни корпус можно просто распечатать. Разве что, его надо сперва нарисовать. Но это намного проще, чем разворачивать полномасштабные слесарные работы. Могу поделиться своими моделями, замечу только, что они рассчитаны для динамиков 3-ГДШ-8. Все материалы проекта выложены на GitHub. Я не маркетолог, но не мог не заметить, насколько мощно модуль RDA5807 стимулирует продажи. Все происходит за счет цепочки расходов, каждый из которых кажется сущей мелочью. Ардуинка за 120 руб, но только если доставка Super Economy. Иными словами, посылка не отслеживаемая и срок может растянуться на три месяца Хочешь получить трек номер и получить быстрее — заплати побольше. Дисплейчик — тоже 120 рублей — и снова Super Economy. Контроллер заряда совсем дешевый, но продается только пачками, еще сто рублей. Самое дорогое — аккумулятор, разброс цен широкий, но неизбежно более двухсот рублей. Усилитель можно купить готовым модулем, а можно собирать из компонентов самому. В любом случае меньше сотни не получается. Не забываем про динамики — их два, значит дважды по сто рублей. В моем случае корпус получился очень дешевым. На печать ушло около 40 метров прутка ABS, это на самом деле не так много. Трудно рассчитать, сколько это в деньгах, но явно пустяки. А если решать проблему корпуса как-то иначе, он превратится в самую дорогую деталь, в смысле расходов, и в смысле головной боли. У радиолюбителя многие компоненты давно лежат в запасе, а потому кажется, будто достались даром. Но если непреклонно складывать все подряд, общая стоимость проекта приближается к тысяче. Готовый китайский приемник, вполне симпатичный, можно купить за пятьсот рублей, другое дело, что информационный повод с этого никакой. Вот почему мы чертим схемы и пишем скетчи. Иначе неинтересно.Используемые источники:

  • https://tsibrov.blogspot.com/2019/11/rda5807m-part1.html
  • https://radioprog.ru/post/232
  • https://habr.com/post/485448/

Рейтинг автора
5
Подборку подготовил
Максим Уваров
Наш эксперт
Написано статей
171
Ссылка на основную публикацию
Похожие публикации