Карманное FM Радио на RDA5807m, IIC Oled 1.3" и Arduino Nano

grandfox
grandfox аватар
Offline
Зарегистрирован: 25.11.2019
Здравствуйте, форумчане. Немного предыстории. Попал  в руки старенький FM-приемник "Вестник РП-301", в
состоянии хорошем, но... естественно требуется перестройка на другой диапазон частот, что и было сделано.
Результатом остался недоволен, стал искать замену "начинке" преёмника и в процессе поиска наткнулся на
схемы с использованием модуля RDA5807m. Наибольший интерес представила схема, опубликованная на этом сайте
пользователем GhostLion 19/11/2018, отдельное ему спасибо в виде плюсика ))). Но... имеющийся корпус с
отсеком под "Крону" не позволял разместить все необходимые компоненты. Выход нашел в применении модуля
Arduino NANO, с встроенным мини usb разъемом, стабилизаторами +5 В, +3,3 В и возможностью питания от
внешнего источника 9 В. Это позволило отказаться от печатной платы и просто соединить два используемых
модуля проводами в фторопластовой изоляции. В данном приемнике применена фиксированная настройка на все
местные радиостанции, что значительно упростило схему, у меня таких станций 10 и позволило отказаться
от OLED дисплея (не достаточно места). Естественно в скетче необходимо заменить список на станции своего
региона, желающие могут применить и дисплей. Встроенный в корпус динамик 0,25ГДШ-2 сопротивлением 50 Ом
подключен напрямую, громкость звучания приемлемая. Ток, потребляемый от батареи типа 6F22 ~ 40 мА.
Библиотеки: - "U8glib.h" https://www.arduinolibraries.info/libraries/u8glib
            - <radio.h>, <RDA5807M.h> https://github.com/mathertel/Radio
 
/*
file MyRadioPubl.ino 
*/
#include "U8glib.h" // Библиотека шрифтов OLED
#include "rusUnifont.h" // Русифицированные шрифты для U8glib
#include <Wire.h> // Библиотека интерфейса I2C
#include <radio.h> // Библиотека
#include <RDA5807M.h> // Библиотека

U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // Строка настроек OLED-SH1106 не ошибка!

#define BTN_1  12 // Кнопка 1
#define BTN_2  11 // Кнопка 2

RADIO_FREQ preset[] = { // Устанавливаем фиксированные яастоты настройки местных FM станций
  8890,  // Дорожное
  10130, // Радио 7
  10170, // Европа +
  10220, // Авторадио
  10270, // Energy
  10320, // Дача
  10370, // Русское
  10410, // Юмор FM
  10470, // Шансон
  10510, // Ретро FM
  10790, // Хит FM
};

RDA5807M radio;
int i_sidx = 2; // выбор станции при включении, в данном случае Европа+
unsigned long currentTime; // переменная контроля времени для гашения OLED
unsigned long loopTime; // переменная контроля времени для гашения OLED
String nameFM; // переменная для вывода на OLED названия станции
String freqFM; // переменная для вывода на OLED частоты станции

void draw(void) { // процедура вывода на дисплей информации о станциях
  u8g.setFont(rusUnifont);
  u8g.setPrintPos(1,22);
  u8g.print(nameFM);
  u8g.setPrintPos(1,54);
  u8g.print(freqFM);
}

void clearOLED(){ // процедура гашения (очистки) дисплея
u8g. firstPage (); 
do { 
} while( u8g.nextPage ());
} 


void setup() {
  radio.init(); // инициализация радио
  radio.setBandFrequency(RADIO_BAND_FM, preset[i_sidx]); // настройка на станция с индексом 2
  radio.setMono(false); // режим стерео
  radio.setMute(false); // звук включен 
  radio.setVolume(15);  // максимальная громкость  
  pinMode(BTN_1, INPUT);
  pinMode(BTN_2, INPUT);
  currentTime = millis();       // считываем время, прошедшее с момента запуска программы
  loopTime = currentTime;  

} // setup

void loop() {
// обработка нажатия кнопок
  int  val = digitalRead(BTN_1);
  delay(50);
  if(val==HIGH)
     if (i_sidx < (sizeof(preset) / sizeof(RADIO_FREQ)) - 1) {
        i_sidx++; radio.setFrequency(preset[i_sidx]);
        loopTime = currentTime;
  }
  val = digitalRead(BTN_2);
  delay(50);
  if(val==HIGH)
    if (i_sidx > 0) {
      i_sidx--; radio.setFrequency(preset[i_sidx]);
      loopTime = currentTime;
  }
switch (i_sidx) {
  case 0:
    nameFM = "Дорожное радио";
    freqFM = "88,9 FM";
    break;
  case 1:
    nameFM = "Радио 7";
    freqFM = "101,3 FM";
    break;
  case 2:
    nameFM = "Европа+";
    freqFM = "101,7 FM";
    break;
  case 3:
    nameFM = "Авторадио";
    freqFM = "102,2 FM";
    break;
   case 4:
    nameFM = "Energy";
    freqFM = "102,7 FM";
    break;
   case 5:
    nameFM = "Радио Дача";
    freqFM = "103,2 FM";
    break;
  case 6:
    nameFM = "Русское радио";
    freqFM = "103,7 FM";
    break;
  case 7:
    nameFM = "Юмор FM";
    freqFM = "104,1 FM";
    break;
  case 8:
    nameFM = "Шансон";
    freqFM = "104,7 FM";
    break;
  case 9:
    nameFM = "Ретро FM";
    freqFM = "105,1 FM";
    break;
  case 10:
    nameFM = "Хит FM";
    freqFM = "107,9 FM";
    break;
  }
  currentTime = millis();                // считываем время, прошедшее с момента запуска программы
  if(currentTime <= (loopTime + 5000)){  // сравниваем текущий таймер с переменной loopTime+5 секунд
    u8g.firstPage();  
  do {
    draw();                              // выводим информацию на дисплей
  } while( u8g.nextPage() );}
  else {
    clearOLED();                         // гасим (очищаем) дисплей
  }
} // loop
//Конец скетча

 

 

grandfox
grandfox аватар
Offline
Зарегистрирован: 25.11.2019

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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

Банку лития на пин "+5V", и вопрос решен.

grandfox
grandfox аватар
Offline
Зарегистрирован: 25.11.2019

dimax, да, питание от +5 В хорошее решение, но... ну никак не вписывается в имеющийся корпус с отсеком под "крону". А остальным на заметку. Плюсик.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

grandfox, Никто ж не заставляет брать банку 18650.  В габариты посадочного места  кроны запросто влезет компактный аккум и зарядка.  Сейчас выпускаются аккумуляторы любых габаритов.

PS: вы тестировали, сколько он проработает от обычной кроны? Кушает то вся эта конструкция поди в разы больше, чем родной приёмник.

grandfox
grandfox аватар
Offline
Зарегистрирован: 25.11.2019

Родной приемник ток покоя 23 мА, при приеме сигнала потребление скорее всего сопоставимо. Часов на 10-15, в зависимости от конкретной "кроны", думаю хватит.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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

grandfox
grandfox аватар
Offline
Зарегистрирован: 25.11.2019

Замер косвенным способом (резистор 10 Ом+конденсатор 1000 мкФ) дал тот же результат ~ 40 мА.

Repz
Offline
Зарегистрирован: 27.11.2019

Что не так с настройкой среды Ардуино? Arduino: 1.8.10 (Windows XP), Плата:"Arduino Nano, ATmega328P"

 
panic: Failed to find GetFileInformationByHandleEx procedure in kernel32.dll: Не найдена указанная процедура.
 
goroutine 1 [running]:
syscall.(*LazyProc).mustFind(0x11c439e0)
/home/jenkins/go1.12.5/src/syscall/dll_windows.go:311 +0x42
syscall.(*LazyProc).Addr(0x11c439e0, 0xdda500)
/home/jenkins/go1.12.5/src/syscall/dll_windows.go:318 +0x21
internal/syscall/windows.GetFileInformationByHandleEx(0x774, 0x9, 0x11c71a04, 0x8, 0x3, 0x11c1b348)
/home/jenkins/go1.12.5/src/internal/syscall/windows/zsyscall_windows.go:353 +0x27
os.newFileStatFromGetFileInformationByHandle(0x11d0d340, 0x3c, 0x774, 0x0, 0x11d0d340, 0x3c)
/home/jenkins/go1.12.5/src/os/types_windows.go:52 +0x135
os.(*File).Stat(0x11c40ee8, 0x984490, 0x11c40ee8, 0x0, 0x11c40ee8)
/home/jenkins/go1.12.5/src/os/stat_windows.go:55 +0x133
io/ioutil.ReadFile(0x11d0d340, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0)
/home/jenkins/go1.12.5/src/io/ioutil/ioutil.go:62 +0xac
github.com/arduino/go-paths-helper.(*Path).ReadFile(...)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/go-paths-helper/paths.go:407
github.com/arduino/arduino-cli/arduino/cores/packageindex.LoadIndex(0x11c40ee0, 0xa29e60, 0x11c4fda0, 0x0)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/arduino/cores/packageindex/index.go:205 +0x2f
github.com/arduino/arduino-cli/arduino/cores/packagemanager.(*PackageManager).LoadPackageIndexFromFile(0x11cfac60, 0x11c40ee0, 0x0, 0x0, 0x11c40ee0)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/arduino/cores/packagemanager/package_manager.go:202 +0x25
github.com/arduino/arduino-cli/arduino/cores/packagemanager.(*PackageManager).loadPlatforms(0x11cfac60, 0x11c8b650, 0x11c40e20, 0x7, 0x11c4ab38)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/arduino/cores/packagemanager/loader.go:186 +0xf4d
github.com/arduino/arduino-cli/arduino/cores/packagemanager.(*PackageManager).LoadHardwareFromDirectory(0x11cfac60, 0x11c40bf8, 0xdda500, 0x703815)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/arduino/cores/packagemanager/loader.go:116 +0x43f
github.com/arduino/arduino-cli/arduino/cores/packagemanager.(*PackageManager).LoadHardwareFromDirectories(0x11cfac60, 0x11c40c00, 0x2, 0x2, 0x1, 0x1)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/arduino/cores/packagemanager/loader.go:52 +0x4f
github.com/arduino/arduino-cli/legacy/builder.(*HardwareLoader).Run(0xdebc68, 0x11cda5a0, 0xdebc68, 0x0)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/hardware_loader.go:43 +0xe4
github.com/arduino/arduino-cli/legacy/builder.(*ContainerSetupHardwareToolsLibsSketchAndProps).Run(0xdebc68, 0x11cda5a0, 0xdebc68, 0xdda500)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/container_setup.go:60 +0x266
github.com/arduino/arduino-cli/legacy/builder.runCommands(0x11cda5a0, 0x11c71f0c, 0x2, 0x2, 0xffffff01, 0x0, 0x4)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/builder.go:210 +0xbd
github.com/arduino/arduino-cli/legacy/builder.(*ParseHardwareAndDumpBuildProperties).Run(0x11c71f40, 0x11cda5a0, 0xdebbb4, 0x11c40c98)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/builder.go:198 +0xbc
github.com/arduino/arduino-cli/legacy/builder.RunParseHardwareAndDumpBuildProperties(...)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/builder.go:231
main.main()
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-builder/main.go:388 +0x772
C:\Program Files\Arduino\arduino-builder возвратил 2
 
Ошибка компиляции для платы Arduino Nano.
 
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
 

 

grandfox
grandfox аватар
Offline
Зарегистрирован: 25.11.2019

Попробуйте установить Arduino IDE 1.6.5. Взять здесь https://all-arduino.ru/arduino-ide/

Repz
Offline
Зарегистрирован: 27.11.2019

Спасибо! Буду пробовать.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Repz пишет:

Что не так с настройкой среды Ардуино? Arduino: 1.8.10 (Windows XP), Плата:"Arduino Nano, ATmega328P"

 
Это потому, что последние версии IDE c XP  не работают
Chudo-Judo
Offline
Зарегистрирован: 07.03.2022
Уважаемый автор! При повторении вашего радио столкнулся с такой проблемой - при отключении дисплея станции принимаются чисто. Как только я подключаю дисплей начинаются помехи - жж жж жж жж ...
Ардуино 2.1.0, плата Нано 3, TEA5767.
С RDA5807M на одной станции стоит.
Как бороться с помехами ?

В чем может быть проблема ?

Chudo-Judo
Offline
Зарегистрирован: 07.03.2022

Разобрался сам. Все работает !