Радио на RDA5807m + OLED 1.3″ (Arduino)

Модуль RRD_102v 2.0 FM радиоприёмника на ИМС RDA5807M отлично работает совместно с ARDUINO или любым микроконтроллером. К плате подключается антенна (или кусок проволоки длиной 20 см), звуковой сигнал через разделительные конденсаторы подается на наушники или усилитель. В данном варианте питание 3,3 В подается непосредственно с платы Arduino Nano.

Управление чипом цифровое, по I2C интерфейсу.

Характеристики FM-тюнера RDA5807m:
* Все в одном корпусе, практически не требуется внешних компонентов
* КМОП технология
* Максимальная полоса частот от 50 МГц до 115 МГц
* Настраиваемый шаг между каналами – 200 кГц, 100 кГц, 50 кГц, 25 кГц
* Поддерживает RDS/RBDS
* Высококачественный АЦП
* Синтезатор частот полностью встроен в микросхему
* Автоматическая регулировка усиления
* Цифровое адаптивное подавление шума
* Поддержка выхода звука как в моно, так и в стерео
* Индикатор уровня сигнала (Receive signal strength indicator — RSSI) и SNR
* Усилитель низких частот
* Регулировка звука и функция mute
* Цифровой интерфейс I2C
* Нагрузка на выходе звукового канала 32 Ом
* Встроенный LDO регулятор
* Корпус MSOP (10 выводов)

Электрические параметры FM тюнера RDA5807m:
* Напряжение питания — 3 вольта (от 1,8 до 3,6 вольт)
* Температура окружающей среды — от -20 до +75 градусов Цельсия
* Ток потребления в рабочем режиме — до 21 мА
* Ток потребления в спящем режиме – 5 мкА
* Коэффициент нелинейных искажений – 0,15 – 0,2 %
* Максимальная частота I2C – 400 кГц

Радиоприемник работает в частотном диапазоне от 87 до 108 МГц, управление приемником осуществляется при помощи двух кнопок и энкодера KY-040 (модуль), информация выводится на OLED дисплей с разрешением 128 на 64 точки, диагональ дисплея 1,3 дюйма, чип драйвера — SH1106  I2C.

Параметры дисплея SH1106:

  • Технология дисплея: OLED
  • Разрешение дисплея: 128 на 64 точки
  • Диагональ дисплея: 1,3 дюйма
  • Угол обзора > 170°
  • Напряжение питания: 3,3 В ~ 5.0 В
  • Мощность: 0,08 Вт
  • Габариты: 35.7 х 30.9 х 4.0 мм
  • Вес: 7 грамм

Радиоприемник поддерживает следующие режимы работы:

  • Частотный диапазон 87 до 108 МГц
  • Автоматический поиск станций и запоминание частот в EEPROM
  • Подстройка (ручная настройка) частоты станции
  • Регулировка громкости 0-15 шагов
  • Кол-во каналов 10

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

Меню настроек содержит меню авто поиска станций и меню ручной подстройки частоты канала. Переход и выход из меню настроек осуществляется при помощи кнопки SET.

Дополнительно имеется POWER, активируется кнопкой POWER, позволяет перевести радиомодуль в беззвучный режим, отключает экран и подает команду STANDBY для отключения усилителя.

Меню громкости

Меню выбора канала

Меню авто поиска

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

Авто поиск

Меню подстройки частоты выбранной станции

Скетч

#define FIX_BAND    RADIO_BAND_FM  
#define RSS 25
#define DELAY_CH 500

#include <Wire.h>
#include <radio.h>             // http://rcl-radio.ru/wp-content/uploads/2023/08/radio.zip
#include <RDA5807M.h>          // http://rcl-radio.ru/wp-content/uploads/2023/08/RDA5807-master.zip
#include <RDSParser.h>         // >> radio.h
#include <MsTimer2.h>          // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip 
#include <Encoder.h>           // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip 
#include <U8glib.h>            // https://github.com/olikraus/u8glib/
#include <EEPROM.h>

RDA5807M radio; 
RADIO_INFO info;
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST);  // Dev 0, Fast I2C / TWI
Encoder myEnc(9, 8);// DT, CLK

int v_pos,menu,vol,f0,f_scan[10],k,i1=8700,i;
float f;
long oldPosition  = -999,newPosition, times, times1;
bool w,w2,t, power;
byte start1,start;
int z;


void setup(){
  delay(300);
  Wire.begin();
  if(EEPROM.read(300)!=0){for(int i=0;i<301;i++){EEPROM.update(i,0);}}
  vol=EEPROM.read(0);
  for(int c=0;c<10;c++){f_scan[c]=EEPROM.read(10+c)*100+EEPROM.read(100+c);}
  k=EEPROM.read(3);
  f=EEPROM.read(1)*100+EEPROM.read(2);start=0;
  pinMode(10,INPUT);        // encoder SW
  pinMode(2,INPUT_PULLUP); // КНОПКА SET 
  pinMode(3,INPUT_PULLUP); // КНОПКА POWER  
  pinMode(4,OUTPUT);       // OUT STANDBY
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  Serial.begin(9600);
  radio.init();
  radio.debugEnable();
  radio.setBandFrequency(FIX_BAND, f);
  radio.setVolume(vol);
  radio.setMono(false);
  radio.setMute(false);
  u8g.firstPage();do {u8g.setFont(u8g_font_profont12r);
  u8g.drawStr(40,20,"RDA5807M");
  u8g.drawStr(40,50,"RADIO FM");
  } 
  while( u8g.nextPage() );
  delay(1000);
  }

void loop(){
  if(start==0){radio.setBandFrequency(FIX_BAND, f);delay(100);radio.getRadioInfo(&info);start=1;}
//////////////////////////////////////////////////////////////////////////////////////////////////  
if(power==0){
  if(digitalRead(10)==LOW && menu<2){menu++;if(menu>1){menu=0;}w=1;w2=1;delay(200);}
  if(digitalRead(2)==LOW && menu<2){menu=2;times=millis();w=1;w2=1;delay(200);}
  if(digitalRead(2)==LOW && menu==2){menu=3;times=millis();times1=millis()-10000;w=1;w2=1;delay(200);}
  if(digitalRead(2)==LOW && menu==3){menu=0;times=millis();w=1;w2=1;delay(200);}
}
  if(digitalRead(3)==LOW && power==0){power=1;radio.setMute(true);digitalWrite(4,LOW);
    u8g.firstPage();do {u8g.setFont(u8g_font_profont12r);u8g.drawStr(40,30,"POWER OFF");}
    while( u8g.nextPage() );menu=100;delay(1000);u8g.firstPage();do {} while( u8g.nextPage() );}
  if(digitalRead(3)==LOW && power==1){power=0;radio.setMute(false);menu=0;digitalWrite(4,HIGH);delay(200);}
  
//////////////////////////////////////////////////////////////////////////////////////////////////   
  if(menu==0){ // ГРОМКОСТЬ
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
    vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;if(vol>15){vol=15;}if(vol<0){vol=0;}radio.setVolume(vol);Serial.println(vol);}
 
    u8g.firstPage();do {
    u8g.setFont(u8g_font_profont29r);u8g.setPrintPos(5, 20);u8g.print(f/100);  
    u8g.setFont(u8g_font_profont12r);u8g.drawStr(110,20,"MHz"); 
    u8g.drawLine(0, 25, 128, 25);  
    u8g.drawStr(0,40,"VOLUME");for(int v_pos=0; v_pos<vol*4+1;v_pos+=4){u8g.drawBox(v_pos+53,32, 2, 8);}
    u8g.drawLine(0, 46, 128, 46); 
    radio.getRadioInfo(&info);
    u8g.setPrintPos(0, 60);u8g.print(info.rssi);u8g.drawStr(15,60,"dBm |");
    u8g.drawStr(50,60,info.tuned  ? "TUNED"  : "-----");
    u8g.drawStr(80,60,info.stereo ? " STEREO  " : "  MONO   ");
    }
  while( u8g.nextPage() );
    }
////////////////////////////////////////////////////////////////////////////////////////
   if(menu==1){ // КАНАЛЫ 
    if(start1==0){f=f_scan[k];start=0;start1=1;radio.setBandFrequency(FIX_BAND, f);}
    if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
      k=k+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;if(k>9){k=9;}if(k<0){k=0;}times=millis();start=0;f=f_scan[k];}
    
    u8g.firstPage();do { 
    if(f_scan[k]!=0){u8g.setFont(u8g_font_profont29r);u8g.setPrintPos(5, 20);u8g.print((float)f_scan[k]/100); 
      u8g.setFont(u8g_font_profont12r);u8g.drawStr(110,20,"MHz");}
        else{u8g.setFont(u8g_font_profont17r);u8g.drawStr(45, 18,"N/A");}
    u8g.drawLine(0, 25, 128, 25);  u8g.setFont(u8g_font_profont12r);
    u8g.drawStr(0,40,"CHANNEL");u8g.setPrintPos(80, 40);u8g.print(k+1); 
    u8g.drawLine(0, 46, 128, 46); 
    radio.getRadioInfo(&info);
    u8g.setPrintPos(0, 60);u8g.print(info.rssi);u8g.drawStr(15,60,"dBm |");
    u8g.drawStr(50,60,info.tuned  ? "TUNED"  : "-----");
    u8g.drawStr(80,60,info.stereo ? " STEREO  " : "  MONO   ");
    }
  while( u8g.nextPage() );
   }   
/////////////////////////////////////////////////////////////////////////////////////////
    if(menu==2){// АВТО ПОИСК КАНАЛОВ
     if(digitalRead(10)==LOW){
     for(int i=10;i<301;i++){EEPROM.update(i,0);}
     for(int c=0;c<10;c++){f_scan[c]=EEPROM.read(10+c)*100+EEPROM.read(100+c);}
     for(i=0;i<10;i++){
     for(i1;i1<=10800;i1=i1+10){
      radio.setBandFrequency(FIX_BAND, i1);delay(DELAY_CH);
      radio.getRadioInfo(&info);
    if(info.tuned==1 and info.rssi>RSS){f_scan[i]=i1;f0=f_scan[i];i1=f_scan[i]+10;
    EEPROM.update(10+i,f_scan[i]/100);EEPROM.update(100+i,f_scan[i]-(f_scan[i]/100)*100);
    if(i1>=10800){f_scan[i]=0;}break;}  
    u8g.firstPage();do {  
    u8g.setFont(u8g_font_profont29r);u8g.setPrintPos(5, 20);u8g.print((float)i1/100);  
    u8g.setFont(u8g_font_profont12r);u8g.drawStr(110,20,"MHz");
    u8g.drawLine(0, 25, 128, 25);
    u8g.drawStr(5,40,"CH");u8g.setPrintPos(20, 40);u8g.print(i); 
    u8g.setFont(u8g_font_profont12r);u8g.setPrintPos(50, 40);u8g.print((float)f0/100);u8g.drawStr(110,40,"MHz");
    u8g.drawLine(0, 46, 128, 46); 
    u8g.setPrintPos(0, 60);u8g.print(info.rssi);u8g.drawStr(15,60,"dBm |");
    u8g.drawStr(50,60,info.tuned  ? "TUNED"  : "-----");
    u8g.drawStr(80,60,info.stereo ? " STEREO  " : "  MONO   ");
      }
 while( u8g.nextPage() );
  }}
 delay(1000);times=millis();i1=8700;k=0;start1=0;menu=1;}
    u8g.firstPage();do {  
    u8g.setFont(u8g_font_profont12r);
    u8g.drawStr(40,20,"AUTOSCAN");
    u8g.drawStr(30,40,"PRESS BUTTON");
    }while( u8g.nextPage() );
}     
////////////////////////////////////////////////////////////////////////////////////////// 
 if(menu==3){// ПОДСТРОЙКА ЧАСТОТЫ КАНАЛА
    if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
      f=f+newPosition*10;myEnc.write(0);newPosition=0;times=millis();t=1;w=1;w2=1;if(f<8700){f=8700;}if(f>10800){f=10800;}times1=millis();start=0;}
    u8g.firstPage();do {  
    u8g.setFont(u8g_font_profont29r);u8g.setPrintPos(5, 20);u8g.print(f/100);  
    u8g.setFont(u8g_font_profont12r);u8g.drawStr(110,20,"MHz"); 
    u8g.drawLine(0, 25, 128, 25);  
    if(millis()-times1<1000){u8g.drawStr(50,40,"SAVE");}
      else{u8g.drawStr(15,40,"FREQUENCY TUNING");}
    u8g.drawLine(0, 46, 128, 46); 
    u8g.setPrintPos(0, 60);u8g.print(info.rssi);u8g.drawStr(15,60,"dBm |");
    u8g.drawStr(50,60,info.tuned  ? "TUNED"  : "-----");
    u8g.drawStr(80,60,info.stereo ? " STEREO  " : "  MONO   ");
    if(t==1){f_scan[k]=f;t=0;EEPROM.update(10+k,f_scan[k]/100);EEPROM.update(100+k,f_scan[k]-(f_scan[k]/100)*100);}
      }
 while( u8g.nextPage() );
  }
  
 delay(10);
 if(millis()-times>5000 && w==1){EEPROM.update(0,vol);EEPROM.update(3,k);EEPROM.update(1,f_scan[k]/100);EEPROM.update(2,f_scan[k]-(f_scan[k]/100)*100);w=0;}
 }  
 
void to_Timer(){newPosition = myEnc.read()/4;} 

Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=8190#p8190

Comments

            1. Попробуйте заменить строку
              U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST); // Dev 0, Fast I2C / TWI
              на
              U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI

  1. Здравствуйте, а можно как то программно переключать моно — стерео? в моей местности 10 станций из них в качестве только 3 из за постоянного шипения слушать остальные 7 проблематично.

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

Войти с помощью: