Tinypocketradio — чм стерео радиоприемник на основе attiny13a и rda5807mp

Подбор диодов для детекторного приемника.

От типа и качества выбранного детекторного диода напрямую зависит громкость звука детекторного приемника. Даже диоды одного наименования могут выдавать разную громкость. По этому, необходимо подобрать диод на слух, на работающем детекторном приемнике. С помощью переключателя два диода вручную быстро переключаются, и таким образом определяется диод «победитель» по громкости. Далее победитель ставится против следующего «претендента» и опять определяется диод «победитель». И так до определения самого громкого диода «чемпиона» .

Отличные результаты по громкости в детекторном радиоприемнике показывают диоды Д311 и Д18. И как оказалось, классический Д9 не лучший вариант по сравнению с Д311 и Д18.

RDA5807M documentation

Poor documentation might be main issue of RDA5807M. There are two datasheet version on the Internet, 1.0 and 1.1, both from 2011 and they are (surprisingly)
written in close to correct English, but it seems that either chip was updated or documentation was incomplete and this cost me few solid hours. In «TEA5767 mode»
chip had decent reception, but once I switched to native mode it was practically unusable, barely receiving any stations through the noise when placed near the window.
Comparing initialization procedure with few other project initially gave no clues. Then small arduino test code
got interesting as reception was good with it. Upon closer inspection that code works because it actually doesn’t do anything — it sets software reset bit in R2
and apparently this causes all changes to base configuration to be ignored. With try and error R5 writing was proven to cause problem and this is register that also controls volume,
so skipping writing to it was not a good option. Reading this register to get default value does not seem to be possible. Accidentally I’ve looked
into code — there is 0x0080 bit set in R5 (in datasheet described
as «Resvered» with default value = 0) and this works. This bit deserves to be named «R5_UNDOCUMENTED_SHIT» in source code below.

As I’ve ordered and received my RDA5807M modules in 2018 and this undocumented bit is not set in most existing projects, my theory is that RDA5807M
received some update while related datasheet version is still not available.

Прошивка

Отдельно стоит остановиться на прошивке. Она написана на C++ и мы распространяем её по лицензии GPLv3: https://github.com/xtremespb/fm_receiver.Я практически не разрабатывал на C/C++, поэтому (вероятно) код далёк от идеала и может содержать ошибки, но GPL на то и GPL, чтобы можно было его дорабатывать сообществом Текущие возможности прошивки включат в себя: — Ручную и автоматическую настройку станций — RDS — Управление громкостью — Включение режима усиленных басов — Включение и отключение подсветки дисплея — Отображение и динамическая визуализация уровня сигнала В следующей, четвёртой по счёту ревизии, мы сделаем ещё несколько полезных «фишек»: подключим левый и правый каналы к аналоговым входам на МК, что позволить «визуализировать» поступающий аудиосигнал. Кстати, возможности устройства не ограничиваются радио! Никто не мешает, например, написать какую-нибудь игру (интереса ради я сделал старый добрый Arkanoid) или другую программу, использующую возможности платы.

Основы радиоприема

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

Существует два вида сигналов, которые излучает любая радиостанция при работе в диапазоне АМ:

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

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

Интерфейс управления

Здесь я хочу обратить внимание на имеющуюся в технической документации неточность (даташит на эту микросхему вообще очень мутный): в ней говорится, что 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 микроконтроллер сначала передает его адрес, затем считывает старший и младший байты. Чуть позже я приведу пример чтения/записи регистров, а пока разберемся с их назначением.

Приемник RDA5807

RDA5807 представляет собой однокристальный модуль (микросхему) FM стерео радиоприёмника с интегрированным в него синтезатором частоты. Модуль способен работать в диапазоне частот 50 – 115 МГц, обеспечивать управление уровнем громкости и владеть информацией об уровне принимаемого сигнала. Модуль содержит кварцевый генератор на 32.768 КГц, цифровой усилитель и другие компоненты. Структурная схема модуля RDA5807M представлена на следующем рисунке.

Модуль построен на цифровой архитектуре и включает малошумящий усилитель, работающий в диапазоне от 50 до 115 МГц. Также модуль содержит программируемый усилитель на ПЛИСах (PGA), АЦП (аналого-цифровой преобразователь) высокого разрешения и высокоточный ЦАП (цифро-аналоговый преобразователь). Амплитудный ограничитель на входе модуля предотвращает его перегрузку (по уровню) и ограничивает число интермодуляционных составляющих, создаваемых соседними каналами. Усилитель на ПЛИСах усиливает входной сигнал, который затем преобразуется в цифровую форму с помощью АЦП. Ядро цифровой обработки сигналов модуля управляет выбором каналов, демодуляцией FM сигналов и разуплотнением стерео сигнала. Назначение контактов (распиновка) микросхемы RDA5807 представлено на следующем рисунке.

Питающее напряжение для модуля составляет от 1.8 до 3.3V. Подключить модуль RDA5807 к микроконтроллеру можно по интерфейсу I2C. Модуль имеет 13 16-битных регистров, каждый из которых выполняет свою определенную функцию. Адреса регистров начинаются с 00H и заканчиваются 0FH. Во всех 13 регистрах некоторые биты зарезервированы. Регистры выполняют такие функции как изменение уровня, смена канала и т.д.

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

Регистры RDA5807M

Управление работой RDA5807M заключается в обращении к его регистрам: изменяя одни регистры, мы производим необходимые нам настройки; из других можно читать различную информацию (флаги, данные RDS и т.д.). Регистры 16-разрядные, их адреса и назначение приведены в даташите. Описание весьма скудное, поэтому я решил сам «пощупать» каждый регистр, чтобы понять какой бит за что отвечает. Для этого была написана следующая программа:

Управление работой RDA5807M с компьютера

Данная программа читает значения регистров RDA5807M, отображает в удобном виде и позволяет изменять их, щелкая мышью по элементам управления. Ардуино при этом выступает в роли посредника между программой на компьютере и RDA5807M, для этого в нее должен быть загружен соответствующий скетч (вы найдёте его в программе по кнопке «Скетч для Ардуино»). Очень рекомендую попробовать данную программу, чтобы разобраться с назначением регистров. Скачать ее можно здесь. И, чтобы совсем не осталось вопросов по управлению 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, можно приступить к программированию. Нужно лишь определиться с функционалом и интерфейсом.

IR kit

Main addition to previous (ATmega8) version is infrared remote control. For this purpose
I’ve bought cheapest «arduino» IR kit: tiny remote controller, VS1838B IR receiver
and (unnecessary) board for this receiver. Remote controller seems to be really low quality — it was only $1.27 including shipping
and I’m not even sure if it is worth it, so only plus is it is easily replaceable and manufactured in millions. Mine is almost unused,
just laying around few months but front is already delaminated.

Controller is intented to be powered with CR2025 cell but popular and cheap CR2032 fits also.
I’ve accidentally discovered that this kit can work with depleted cell (2.90V with no load, 1.25V on 1k load) but range is limited to ~30 cm then.
With fresh cell this remote + receiver set works across the room (few meters) with no problems, although it requires aiming.

This remote sends signals following NEC protocol (basic variant with 8 bit address)

For precise time readings: NEC.json for miniscope v4

For decoding NEC protocol I’ve used slightly modified nec-decoder library
by Malte Pцggel. Timings generated by my $1 remote were little different than nominal (e.g. 10 ms burst) and original code was not accepting this.

NEC standard codes sent by remote have address = 0x00 and following command values (hexadecimal):

I’ve received very similar remote controller with popular USB DVB-T RTL2832U tuner:

It has identical size to «Car mp3» controller, NEC address code is identical (0x00) but command codes assigned to buttons are different.
You can change mapping from NEC command code to function (ON/OFF, VOLUME UP/DOWN, SEEK UP/DOWN, …) in ir_remote_s1_car_mp3.c file.

Another popular remote controllers that are using NEC codes are ones from DVB-T tuners based on MSTAR chip:

Schematic and Kicad files

Schematic — pdfmega328_FM_Kicad.zip

  • radio is powered from mini-USB port on arduino nano clone module and is not very picky — small USB charger/power supply, PC USB port or small powerbank work fine;
    in my setup I’m using currently «parasite» power with 5V/1A power supply shared by always on «web thermometer» and this radio
  • maximum audio volume is rather moderate, this is intended to be «kitchen»/small room audio device, full theoretical 2x3W from PAM8403 would be overkill
    and I care more about minimal audio volume (there are 15 volume levels from RDA5807M and lowest level is intended to be used at night time)
  • J4 is alternative to soldering TSOP17xx directly — if you need to mount IR sensor to front panel
  • AUX IN is — you guessed — auxiliary audio input; in my case it is connected to PC audio output thus radio works also as PC speakers
  • audio signal from FM module and AUX IN is mixed together
  • there is no volume control for AUX IN signal (volume control is only «inside» RDA5807M); depending on your preferences you might change R8 and R9 to lower values
    as with 4k7 used PC volume might need to be set to rather high values and it might be not comfortable when switching to e.g. internal laptop speakers
  • device is «always on» (this also means that AUX IN always works), consuming about 50mA (or 250mW)
  • there is place for two electrolytic capacitors near PAM8403 module; I’ve soldered only one of them to limit inrush current which might be a problem if powering from PC USB port (I believe chargers or similar power supplies do not care)
  • I’ve used toner transfer when making PCB and I had to use «Print as image» option, otherwise some pads were missing from printout — this might be some compatibility issue with PDF generator / PDF reader / particular postscript printer

Детали детекторного приемника.

Этот детекторный приемник – классика школьного приборостроения. Собран он на деревянном сосновом бруске и канцелярских кнопках. При пайке приемника на такой доске ощущается ностальгический сосново – канифольный «ламповый» аромат – весьма немаловажная составляющая. Как в детстве.

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

Конденсатор С1* — как уже говорилось выше – 180 пф. Хотя может быть и другого номинала . Или можно вовсе без него, если получится принять какую-нибудь радиостанцию.

Конденсатор С2 может быть 1000 – 2200 пф. Не критично.

Диод D1 – лучший диод для детекторного приемника это Д18 или Д311. Но можно использовать и любой другой высокочастотный германиевый детекторный диод. Например Д9. Хотя звук будет немного тише. Вообще, диоды для детекторного приемника нужно подбирать – смотри ниже.

Заказ печатных плат

В Китае можно заказать печатные платы, выполненные промышленным способом. Стоимость выходит относительно небольшой даже при малых тиражах, а время ожидания (включая доставку) как правило не превышает 2-3 недель. Первую «партию» плат заказали на PCBWay. Так она выглядела: Одна из проблем, с которой мы по неопытности столкнулись: металлизация «съедает» значительную часть размера самого отверстия, поэтому некоторые компоненты с трудом «влезали» в нужные отверстия. При проектировании схемы необходимо учитывать этот момент. По результатам тестирования мы ещё немного доработали конструкцию, добавив несколько конденсаторов для более стабильной работы устройства. Собрали ещё один прототип: Разъём USB используется для питания приёмника. Питание также подаётся при подключении программатора. Всё работает!

Production

Разработка устройства от идеи до реализации заняла около 6 месяцев, что, с практически полным отсутствием опыта в данной области, не так уж и плохо. На данный момент у нас есть около 10 полностью собранных комплектов, которые включают в себя всё необходимое для сборки своего собственного устройства: — МК Atmega328P-PU — Преобразователь уровня CD4050BE — Дисплей Nokia 5110 — Приемник RDA5807M — Программатор USBasp — Операционный усилитель LM386N — Разъемы под МК и программатор — USB B, Audio Jack 3.5, три кнопки, провода, однорядные коннекторы — 11 резисторов и 12 конденсаторов, 4 индуктивности, кварц, стабилитрон и светодиод — Динамик — Печатная плата Для сборки понадобится припой, флюс и паяльник, больше ничего не нужно. Все комплектующие упакованы в небольшую коробку из «крафтового» картона: Исходники прошивки уже выложены на Github; Gerber-файл, принципиальная схема и инструкция по сборке будут также опубликованы позднее. Микросхема RDA5807M — это FM радиоприемник нового поколения с поддержкой RDS/RBDS и цифровым управлением по I2C. Микросхема выполнена по CMOS технологии, что определяет ее минимальное энергопотребление. RDA5807M уже содержит все необходимые узлы и требует лишь небольшого числа внешних компонентов. А мощный аудиопроцессор обеспечивает оптимальное качество звука при различных условиях приема. Все это делает RDA5807M удачным выбором для носимых, портативных устройств. В интернет магазинах распространен модуль RRD-102v2, на котором распаяны RDA5807M, кварцевый резонатор и пара компонентов обвязки. В данной статье я опишу как подключить этот модуль к Ардуино и что нужно знать для создания радиоприемника на его основе.

MIT License

Copyright (c) 2019 Ricardo Lima Caratti

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the «Software»), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

ЛУТ, фоторезист и отладка

После успешных испытаний на монтажной плате мы решили создать ещё несколько прототипов методом ЛУТ (а в дальнейшем — фоторезистом). Также мы решили усовершенствовать приемник, добавив туда ещё один усилитель звука для подключения не только наушников, но и внешнего динамика. Выбор пал на PAM8403, это простой и недорогой усилитель, который требует питания 5В. Первый прототип, изготовленный методом ЛУТ, выглядел следующим образом:

ЛУТ — хорошая штука для относительно быстрого прототипирования в домашних условиях, но когда дело доходит до двухсторонних плат, начинаются сложности. Количество компонентов на плате увеличивалось — например, мы решили разместить на плате разъем для программатора, чтобы не было необходимости каждый раз извлекать МК для перепрошивки. Так, последующий прототип стал двухсторонним, был изготовлен методом фоторезиста и стал выглядеть намного приятнее:

В сборке:

Следующим шагом был отказ от «навесных» компонентов, которые мы размещали на плате при помощи однорядных PINов. Так, было принято заменить усилитель на LM386N, установить преобразователь уровней CD4050BE. Всё это усложнило конструкцию, но устройство стало выглядеть намного лучше.

Итоговый прототип, изготовленный нами в домашних условиях, выглядел так:

Library Installation

The easiest method to install this library is via your Arduino IDE. All you have to do is:

  1. Select Tools menu;
  2. Select Manage Libraries option;
  3. In the text box (top windows), type PU2CLR or RDA5807;
  4. Select the PU2CLR RDA5807.

The images below show how you can install this library via your Arduino IDE from Manage Libraries tool.

Installing via the repository

With this approach, you will have the most current version of the library. However, it may not be the most stable version. This is because the current version is always in development. Prefer releases. Do you need some old version (release) of this library? If yes, check here.

First, you have to download this library in zip format.
After, unzip the RDA5807-master.zip file in your Arduino Library folder.

  • On Windows: «My Documents\Arduino\libraries»
  • On MAC OS: ˜/Documents/Arduino/libraries
  • On Linux: ˜/Documents/Arduino/libraries

Тестирование работы FM приёмника

Когда на схему нашего проекта подается питание происходит сброс модуля RDA5807M и установка в нем канала по выбору пользователя. При вращения ручки потенциометра, отвечающего за настройку приемника на требуемую частоту, подключенного к контакту A0, значения, считываемые платой Arduino Nano с этого контакта, изменяются. Если разница между старым и новым значениями больше 10, мы считаем это изменение истинным (то есть произошедшим не вследствие действия шума) и изменяем в соответствии с ним канал, на который будет настроен радиоприемник. Уровень громкости звука мы изменяем с помощью потенциометра, подключенного между контактом 3 и GND.

Более подробно работа нашего FM приёмника представлена в видео, приведенном в конце статьи.

RDA5807M documentation

Poor documentation might be main issue of RDA5807M. There are two datasheet version on the Internet, 1.0 and 1.1, both from 2011 and they are (surprisingly)
written in close to correct English, but it seems that either chip was updated or documentation was incomplete and this cost me few solid hours. In «TEA5767 mode»
chip had decent reception, but once I switched to native mode it was practically unusable, barely receiving any stations through the noise when placed near the window.
Comparing initialization procedure with few other project initially gave no clues. Then small arduino test code
got interesting as reception was good with it. Upon closer inspection that code works because it actually doesn’t do anything — it sets software reset bit in R2
and apparently this causes all changes to base configuration to be ignored. With try and error R5 writing was proven to cause problem and this is register that also controls volume,
so skipping writing to it was not a good option. Reading this register to get default value does not seem to be possible. Accidentally I’ve looked
into code — there is 0x0080 bit set in R5 (in datasheet described
as «Resvered» with default value = 0) and this works. This bit deserves to be named «R5_UNDOCUMENTED_SHIT» in source code below.

As I’ve ordered and received my RDA5807M modules in 2018 and this undocumented bit is not set in most existing projects, my theory is that RDA5807M
received some update while related datasheet version is still not available.

Предыстория

Я думаю, многие из вас не только слышали, но и непосредственно сталкивались с такой платформой, как Arduino. И как показывает моя личная статистика, очень немногие заходят дальше, чем поморгать светодиодами. Когда я познакомился с Arduino в первый раз, меня останавливало то, что не было идей, как именно я бы мог использовать все возможности того же UNO на «полную катушку». Хватило только на сборку простенького робота на двух колёсах и сигнализации. Вместе с тем, хотелось сделать что-то более основательное. Тогда я вспомнил о своем детстве, в котором были так называемые «радиоконструкторы». Суровый советский DIY Kit, который при правильной сборке и грамотной пайке даже начинал работать, и ловил радиостанции в различных диапазонах: Юность, Электрон-М и другие.

Ни один из таких Kit’ов мне не достался, зато достался ЭКОН-1:

Основной «фишкой» этого конструктора было то, что с его помощью можно было быстро и просто собрать большое количество различных устройств, от простых «пищалок» до вполне полноценного радиоприемника. ЭКОН-1 — одна из многих причин, по которой я вообще оказался в сфере IT. И мне пришло в голову, что было бы неплохо создать современную версию подобного конструктора, чтобы все желающие могли получить удовольствие от только что собранного своими руками девайса.

Few notes on arduino / AVR bootloader

Arduino nano clone I bought (popular <$2 board with mini-USB socket) had bootloader already programmed.

ATmega328P has special Flash area designated for bootloaders — located at the end of the Flash area. Flash programming can be initiated
only if code is running from this area. Size of the bootloader
area is determined by two fuse bits: BOOTSZ1 and BOOTSZ0 — can be set to either 256 words (512B or 4 Flash pages), 512 words, 1024 words or 2048 words (4kB).
Entering the bootloader could be done either from application (jump) or by programming BOOTRST fuse (setting value = 0) that would change reset vector from
application (0x0000) to bootloader making bootloader running by default. This is what arduino is using. Including code that jumps to bootloader in user application
would result in problems as user application might just hung, disable interrupts or serial port. Instead each time programming is requested PC application
sets DTR line low for a short time. This line is connected with AVR RESET input with 100nF capacitor and since BOOTRST fuse is programmed microcontroller
starts executing bootloader code on reset. Bootloader waits few seconds for communication, jumps to application on timeout. As same PC application is
controlling DTR state and initiates communication bootloader timeout can be short and all works smoothly. Note that while bootloader
is very convenient it adds few seconds to cold startup (i.e. when turning power on) which might be annoying.

As user application Flash area starts from 0x0000 regardless whether bootloader is used or not no changes to the application
are required if working with or without bootloader. Application can be developed with help of the bootloader but does not depend on it.

Here is arduino configuration (excerpt from boards.txt) for arduino nano:

nano.name=Arduino Nano

nano.upload.tool=avrdude
nano.upload.protocol=arduino

nano.bootloader.tool=avrdude
nano.bootloader.unlock_bits=0x3F
nano.bootloader.lock_bits=0x0F

nano.build.f_cpu=16000000L
nano.build.board=AVR_NANO
nano.build.core=arduino
nano.build.variant=eightanaloginputs

## Arduino Nano w/ ATmega328
nano.menu.cpu.atmega328=ATmega328
nano.menu.cpu.atmega328.upload.maximum_size=30720
nano.menu.cpu.atmega328.upload.maximum_data_size=2048
nano.menu.cpu.atmega328.upload.speed=57600
nano.menu.cpu.atmega328.bootloader.low_fuses=0xFF
nano.menu.cpu.atmega328.bootloader.high_fuses=0xDA
nano.menu.cpu.atmega328.bootloader.extended_fuses=0x05
nano.menu.cpu.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
nano.menu.cpu.atmega328.build.mcu=atmega328p

This bootloader (atmega/ATmegaBOOT) is GPL-licensed. Optiboot has same license yet arduino FAQ mentions only LGPL licensing.
In bird culture, this is considered a dick move.

For firmware loading arduino is using avrdude version 6.0.1. As WinAVR
is not maintained anymore and contains version 5.10 from 2010 you might need to update these files.
Avrdude command line for writing Flash (replace COM16 with own port number):

avrdude -p atmega328p -c arduino -P COM16 -b 57600 -D -U flash:w:main.hex:i

These parameters are also included in project makefile (make program).

Arduino bootloader is not able to read fuses (returning 0) but fuses can be verified from avr-gcc application itself:

static void dump_fuses(void)
{
	uint8_t lfuse, hfuse, efuse, lock;

	cli();
	lfuse = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS);
	hfuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
	efuse = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS);
	lock = boot_lock_fuse_bits_get(GET_LOCK_BITS);
	sei();
	printf("LFUSE = %02X, HFUSE = %02X, EFUSE = %02X, LOCK = %02X\n", lfuse, hfuse, efuse, lock);
}

Fuses on my board are little weird (LFUSE = FF, HFUSE = DA, EFUSE = F8, LOCK = CF) as BOD level in EFUSE was programmed to restricted value.

Что такое детекторный приемник – для тех, кто не знает.

Для тех, кто впервые слышит про детекторный приемник, сразу скажу – это не то радио, которое будет наполнять вашу комнату музыкой круглые сутки. Вот его некоторые особенности:

  1. — Да, это радио работает без батареек. :- ). Но…
  2. — На простой детекторный приемник не удастся услышать станции FM диапазона. Детекторный приемник принимает лишь станции AM диапазона – Средние, Длинные, и если повезет Короткие волны (СВ, ДВ, КВ ).
  3. — Детекторный приемник – это ночное радио. Из-за особенностей ДВ-СВ-КВ, нормальный прием чаще всего возможен с наступлением темного времени суток. Не пытайтесь собирать детекторный приемник днем, если вы не живете возле радиостанции.
  4. — Громкость звука детекторного приемника. Это будет еле слышное «шуршание» или в лучшем случае негромкий звук, сравнимый с шёпотом.
  5. — Количество принимаемых станций. Детекторный приемник может принимать лишь мощные или близко расположенные АМ радиостанции. По этому, скорее всего, на первых порах удастся поймать лишь одну — две радиостанции, «тонущие» в шуме помех.
  6. — Для детекторного приемника нужны специальные высокоомные наушники (наушники родом из СССР с сопротивлением 1600 Ом и более). Хотя можно использовать и обычные наушники от плеера, если подключить их через согласующий трансформатор (см. схему ниже). Без такого трансформатора на простые наушники ничего услышать не удастся. Можно еще использовать пьезо наушники.
  7. — Детекторному радиоприемнику нужна хорошая наружная антенна и заземление. Возможно, к этим благам не получится иметь доступ в вашей квартире.
  8. — Если все вышесказанное не пугает – тогда хорошая новость: детекторный радиоприемник теоретически может работать вечно :- ).