Карманное FM Радио на RDA5807, IIC Oled 0.96" и Arduino Pro Mini

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

  Здравствуйте Форумчане. Как-то на глаза попался маленький фм модуль RDA5807 и решил я замутить проект, так как радио слушаю практически постоянно, да и руки "набивать" в программировании и фоторезисте нужно.      Облазил весь форум в поиске подобных проектов, но кроме пары тем в "аппаратных вопросах" ничего не нашел. На других форумах таких проектов много. Непорядок, нужно заполнить пробел. Динамики с усилком решил не прикручивать - миниджек универсальнее. Ну и устройство должно быть более-менее компактным.

Плату развел в SprintLayout 6.0.

Oled дисплей выбрал в связи с его компактностью да и их у меня уже несколько штук из Китая. Компоненты для компактности использовал SMD. Дисплей запитал от DC-ВС преобразователя для удобства разводки на плате.

Плату зарядки тупо приклеил сверху платы под дисплеем (заизолировал скотчем от дисплея).

1.Выключатель: https://belchip.by/product/?selected_product=04189

2. DC-DC преобразователь такой:https://belchip.by/product/?selected_product=30792

3. Миниджек: https://belchip.by/product/?selected_product=09201

4. Конденсаторы что-то типа таких: https://belchip.by/product/?selected_product=05329

5. Индуктивности: https://belchip.by/product/?selected_product=17151

    Звучание в наушниках очень понравилось - в разы лучше, чем в телефоне. Да и ловит сигнал он гораздо лучше телефона и плеера.

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

 1. 

//FM Radio OLED Copyright by GhostLion v1.3
#include <EEPROM.h>
#include <radio.h>
#include <RDA5807M.h>
#include "U8glib.h"
#include "rus6x10.h"
#include "rus10x20.h"

#define Pin_DOWN 4   // левая кнопка 
#define Pin_UP 2     // правая кнопка 
#define Pin_SET 3    // центральная кнопка 
#define FIX_BAND 1

const unsigned char Bat1 [] = {
0x7F, 0xFC, 0x80, 0x02, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat2 [] = {
0x7F, 0xFC, 0x80, 0x02, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat3 [] = {
0x7F, 0xFC, 0x80, 0x02, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat4 [] = {
0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat5 [] = {
0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat6 [] = {
0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat7 [] = {
0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA9, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xA9, 0x80, 0x02, 0x7F, 0xFC};

byte v,v2,k,k2,m,m2,flag1=1,flag2=0,flag3=0;
int Voltage,s,s2;
boolean b,b2,ms,ms2,flag=1,MODE=1;
long TimeOut;

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
RDA5807M radio; 

void setup()
{
pinMode(Pin_DOWN,INPUT_PULLUP);
pinMode(Pin_UP,INPUT_PULLUP);
pinMode(Pin_SET,INPUT_PULLUP); 

Inicial();
}

void loop()
{
Parsing();
Menu();
Energy();  
}
//==============================================
void Inicial()
{
 u8g.firstPage();  
do {
  u8g.setFont(rus10x20);
  u8g.setPrintPos(25,14);
  u8g.print(F("ФМ РАДИО"));
  u8g.setFont(rus6x10);
  u8g.setPrintPos(36,28);u8g.print(F("v 1.3 Rus"));
  u8g.setPrintPos(40,40);u8g.print(F("03.11.18"));
  u8g.setPrintPos(25,52);u8g.print(F("By GhostLion"));
  u8g.setPrintPos(40,62);u8g.print(F("STANDART"));  
   }
while( u8g.nextPage() );
delay(3000);
v  = EEPROM[1];
k  = EEPROM[2];
m  = EEPROM[3];
b  = EEPROM[4];
ms = EEPROM[5];
s  = EEPROM[6]*100+EEPROM[7];
v2=v; k2=k; m2=m; b2=b; ms2=ms; s2=s;
radio.init();
radio.setBandFrequency(FIX_BAND, s);
radio.setVolume(v);
radio.setMono(ms);
radio.setMute(false);
radio.setBassBoost(b);  
readVcc();
}
//================================================
void Parsing()
{
boolean SET=digitalRead(Pin_SET);
boolean UP=digitalRead(Pin_UP);
boolean DOWN=digitalRead(Pin_DOWN);

if(SET==HIGH && flag1==0)
  {
    flag1=1;
  }
if(SET==LOW && flag1==1)
  {
    flag1=0;
    TimeOut=millis();
    if(MODE==1) {m++; if(m>5) m=1; flag=1;}
  }
  
 if(UP==LOW && flag2==1)
  {
    flag2=0;
  }
   if(UP==HIGH && flag2==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==15?0:v++); radio.setVolume(v); break; }
        case 2:{ b = !b; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ radio.seekUp(true); delay(4000); s = radio.getFrequency(); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{ s=s+10; if (s > 10800) s = 8700; radio.setBandFrequency(FIX_BAND,s); break; }
        case 5:{ k++; if (k>23) k=1; Frequency(); radio.setBandFrequency(FIX_BAND,s);break;}
      }
   flag=1;
   TimeOut=millis();
    }
   else {(v==15?0:v++);radio.setVolume(v);}
   flag2=1;
   }
   if(DOWN==LOW && flag3==1)
  {
    flag3=0;
  }
   if(DOWN==HIGH && flag3==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==0?15:v--); radio.setVolume(v); break; }
        case 2:{ ms = !ms; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ radio.seekDown(true); delay(4000); s=radio.getFrequency(); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{ s=s-10; if (s<8700) s=10800; radio.setBandFrequency(FIX_BAND,s); break; }
        case 5:{ k--; if (k<1) k=23; Frequency(); radio.setBandFrequency(FIX_BAND,s);break;}
      }
   flag=1;
   TimeOut=millis();
   }
   else {(v==0?15:v--);radio.setVolume(v);}
   flag3=1;
  }
}
//================================================
void Menu()
{
float ch;
if(flag==1 && MODE==1)
{
ch=float(s)/100; 
u8g.firstPage();  
do {
u8g.setFont(rus6x10);
u8g.setDefaultForegroundColor();
u8g.setPrintPos(40,10);u8g.print(F("ФМ РАДИО"));
u8g.setPrintPos(8,23);u8g.print(F("Громкость:"));u8g.setPrintPos(85,23);u8g.print(v);
u8g.setPrintPos(8,33);u8g.print(F("Стерео/Басс:"));u8g.setPrintPos(85,33);
if(b==1){if(ms==0)u8g.print(F("ДА/ДА")); else u8g.print(F("НЕТ/ДА"));}
if(b==0){if(ms==0)u8g.print(F("ДА/НЕТ")); else u8g.print(F("НЕТ/НЕТ"));}
u8g.setPrintPos(8,43);u8g.print(F("Автопоиск:"));u8g.setPrintPos(85,43);u8g.print(F("<.>"));
u8g.setPrintPos(8,53);u8g.print(F("Частота:"));u8g.setPrintPos(85,53);u8g.print(ch,1);
u8g.setPrintPos(8,63);Kanal();
int x = 10*m;
u8g.drawTriangle(0,13+x,0,5+x,4,9+x);

if(Voltage>85) u8g.drawBitmap (0, 0, 2, 8, Bat7);
  else if(Voltage>70) u8g.drawBitmap (0, 0, 2, 8, Bat6);
  else if(Voltage>55) u8g.drawBitmap (0, 0, 2, 8, Bat5);
  else if(Voltage>40) u8g.drawBitmap (0, 0, 2, 8, Bat4);
  else if(Voltage>25) u8g.drawBitmap (0, 0, 2, 8, Bat3);
  else if(Voltage>10) u8g.drawBitmap (0, 0, 2, 8, Bat2);
  else u8g.drawBitmap (0, 0, 2, 8, Bat1);
}
while( u8g.nextPage() );     
flag=0;    
}
}
//================================================
void Kanal()
{
  switch (s)
  {
    case 8750 : k=1;break;
    case 9240 : k=2;break;
    case 9370 : k=3;break;
    case 9410 : k=4;break;
    case 9620 : k=5;break;
    case 9740 : k=6;break;
    case 9800 : k=7;break;
    case 9840 : k=8;break;
    case 9890 : k=9;break;
    case 9950 : k=10;break;
    case 10040: k=11;break;
    case 10120: k=12;break;
    case 10170: k=13;break;
    case 10210: k=14;break;
    case 10250: k=15;break;
    case 10290: k=16;break;
    case 10370: k=17;break;
    case 10460: k=18;break;
    case 10510: k=19;break;
    case 10570: k=20;break;
    case 10620: k=21;break;
    case 10710: k=22;break;
    case 10790: k=23;break;
    default: k=0;
    
  }
  switch(k)
  {
    case 0 :{u8g.print(F("Нет Данных..."));break;}
    case 1 :{u8g.print(F("Релакс ФМ"));break;}
    case 2 :{u8g.print(F("Радио Минск"));break;}
    case 3 :{u8g.print(F("Юмор ФМ"));break;}
    case 4 :{u8g.print(F("Легенды ФМ"));break;}
    case 5 :{u8g.print(F("Мелодии Века"));break;}
    case 6 :{u8g.print(F("Минская Волна"));break;}
    case 7 :{u8g.print(F("АвтоРадио"));break;}
    case 8 :{u8g.print(F("Новое Радио"));break;}
    case 9 :{u8g.print(F("Русское Радио"));break;}
    case 10 :{u8g.print(F("Радио Юнистар"));break;}
    case 11 :{u8g.print(F("Радио Хит"));break;}
    case 12 :{u8g.print(F("Пилот ФМ"));break;}
    case 13 :{u8g.print(F("Радио ОНТ"));break;}
    case 14 :{u8g.print(F("Радио Рокс"));break;}
    case 15 :{u8g.print(F("Народное Радио"));break;}
    case 16 :{u8g.print(F("Радио Культура"));break;}
    case 17 :{u8g.print(F("Радиус ФМ"));break;}
    case 18 :{u8g.print(F("Радио Би-Эй"));break;}
    case 19 :{u8g.print(F("Радио Столица"));break;}
    case 20 :{u8g.print(F("Душевное Радио"));break;}
    case 21 :{u8g.print(F("Первый Канал"));break;}
    case 22 :{u8g.print(F("Радио Мир"));break;}
    case 23 :{u8g.print(F("Альфа Радио"));break;}
   }
}
//========================================================
void Frequency()
{
 switch(k)
  {
    case 1 :{s=8750;break;}
    case 2 :{s=9370;break;}
    case 3 :{s=8750;break;}
    case 4 :{s=9410;break;}
    case 5 :{s=9620;break;}
    case 6 :{s=9740;break;}
    case 7 :{s=9800;break;}
    case 8 :{s=9840;break;}
    case 9 :{s=9890;break;}
    case 10 :{s=9950;break;}
    case 11 :{s=10040;break;}
    case 12 :{s=10120;break;}
    case 13 :{s=10170;break;}
    case 14 :{s=10210;break;}
    case 15 :{s=10250;break;}
    case 16 :{s=10290;break;}
    case 17 :{s=10370;break;}
    case 18 :{s=10460;break;}
    case 19 :{s=10510;break;}
    case 20 :{s=10570;break;}
    case 21 :{s=10620;break;}
    case 22 :{s=10710;break;}
    case 23 :{s=10790;break;}
  } 
}
//=======================================================
void Energy()
{
 if(MODE==1 && millis()-TimeOut>8000)
  {
    u8g.sleepOn(); 
    MODE=0;
    if(v2!=v){v2=v; EEPROM[1] = v;}
    if(k2!=k){k2=k; EEPROM[2] = k;}
    if(m2!=m){m2=m; EEPROM[3] = m;}
    if(b2!=b){b2=b; EEPROM[4] = b;}
    if(ms2!=ms){ms2=ms; EEPROM[5] = ms;}
    if(s2!=s){s2=s; EEPROM[6] = int(s/100); EEPROM[7] = s%100;}
  }
  if(MODE==0 && millis()-TimeOut<500)
  {
    u8g.sleepOff(); 
    readVcc();
    MODE=1;flag=1; 
  }
}
//===================================================
void readVcc() 
{
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring
  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both
  long result = (high << 8) | low;

  result = 1.080 * 1023 * 1000 / result; // расчёт реального VCC
  Voltage = int(result);
  Voltage = map(Voltage, 3200, 4200, 0, 100);
  Voltage = constrain(Voltage, 0, 100);
}

Дисплей для сохранения отключается через 8 секунд. Когда дисплей выключен кнопками регулируется громкость. Когда дисплей выключается измененные настройки сохраняются в EEPROM.

2.

//FM Radio OLED Copyright by GhostLion v1.4

#include <EEPROM.h>
#include <radio.h>
#include <RDA5807M.h>

#include "U8glib.h"
#include "rus6x10.h"
#include "rus10x20.h"

#define Pin_DOWN 4   // левая кнопка 
#define Pin_UP 2     // правая кнопка 
#define Pin_SET 3    // центральная кнопка
#define FIX_BAND 1

const unsigned char Volume [] = {0x7E, 0x42, 0x81, 0x81, 0x81, 0x81, 0xE7, 0xE7, 0x66, 0x66};
const unsigned char Bass [] = {0x7F, 0xFE, 0x80, 0x01, 0x9B, 0x8D, 0xA2, 0x51, 0xA3, 0x91, 0x9A, 0x4D, 0x8A, 0x45, 0xB3, 0x99,0x80, 0x01, 0x7F, 0xFE};
const unsigned char FM [] = {0x7F, 0xFE, 0x80, 0x01, 0x8C, 0x51, 0x90, 0xA9, 0x90, 0xA9, 0x98, 0xA9, 0x90, 0xA9, 0x90, 0x89,0x80, 0x01, 0x7F, 0xFE};
const unsigned char Stereo [] = {0x7F, 0xFE, 0x80, 0x01, 0x9B, 0xB9, 0xA1, 0x25, 0xA1, 0x39, 0x99, 0x31, 0x89, 0x29, 0xB1, 0x25,0x80, 0x01, 0x7F, 0xFE};

const unsigned char Bat1 [] = {0x7F, 0xFC, 0x80, 0x02, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat2 [] = {0x7F, 0xFC, 0x80, 0x02, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat3 [] = {0x7F, 0xFC, 0x80, 0x02, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat4 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat5 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat6 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat7 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA9, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xA9,0x80, 0x02, 0x7F, 0xFC};

const unsigned char Vol1 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x60, 0x00, 0x60, 0x00};
const unsigned char Vol2 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00,0x6C, 0x00, 0x6C, 0x00};
const unsigned char Vol3 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x0D, 0x80, 0x0D, 0x80,0x6D, 0x80, 0x6D, 0x80};
const unsigned char Vol4 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x01, 0xB0, 0x01, 0xB0, 0x0D, 0xB0, 0x0D, 0xB0,0x6D, 0xB0, 0x6D, 0xB0};
const unsigned char Vol5 [] = {0x00, 0x06, 0x00, 0x06, 0x00, 0x36, 0x00, 0x36, 0x01, 0xB6, 0x01, 0xB6, 0x0D, 0xB6, 0x0D, 0xB6,0x6D, 0xB6, 0x6D, 0xB6};

byte v,v2,k,k2,m,m2,rs, flag1=1,flag2=0,flag3=0;
int Voltage,s,s2;
boolean b,b2,ms,ms2,flag=1,MODE=1;
long TimeOut;

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
RDA5807M radio; 

void setup()
{
pinMode(Pin_DOWN,INPUT_PULLUP);
pinMode(Pin_UP,INPUT_PULLUP);
pinMode(Pin_SET,INPUT_PULLUP); 

Inicial();
}

void loop()
{
Parsing();
Menu();
Energy();  
}
//==============================================
void Inicial()
{
 u8g.firstPage();  
do {
  u8g.setFont(rus10x20);
  u8g.setPrintPos(25,14);
  u8g.print(F("ФМ РАДИО"));
  u8g.setFont(rus6x10);
  u8g.setPrintPos(36,28);u8g.print(F("v 1.4 Rus"));
  u8g.setPrintPos(40,40);u8g.print(F("18.11.18"));
  u8g.setPrintPos(25,52);u8g.print(F("By GhostLion"));
  u8g.setPrintPos(40,62);u8g.print(F("EXTENDED"));  
   }
while( u8g.nextPage() );
delay(2000);
v  = EEPROM[1];
k  = EEPROM[2];
m  = EEPROM[3];
b  = EEPROM[4];
ms = EEPROM[5];
s  = EEPROM[6]*100+EEPROM[7];
v2=v; k2=k; m2=m; b2=b; ms2=ms; s2=s;
radio.init();
radio.setBandFrequency(FIX_BAND, s);
radio.setVolume(v);
radio.setMono(ms);
radio.setMute(false);
radio.setBassBoost(b);  
readVcc();
}
//================================================
void Parsing()
{
boolean SET=digitalRead(Pin_SET);
boolean UP=digitalRead(Pin_UP);
boolean DOWN=digitalRead(Pin_DOWN);

if(SET==HIGH && flag1==0)
  {
    flag1=1;
  }
if(SET==LOW && flag1==1)
  {
    flag1=0;
    TimeOut=millis();
    if(MODE==1) {m++; if(m>6) m=1; flag=1;}
  }
  
 if(UP==LOW && flag2==1)
  {
    flag2=0;
  }
   if(UP==HIGH && flag2==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==15?0:v++); radio.setVolume(v); break; }
        case 2:{ b = 1; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ ms = 0; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{ radio.seekUp(true); delay(3000); s = radio.getFrequency(); Kanal(); break; }
        case 5:{ s=s+10; if (s > 10800) s = 8700; delay(100); radio.setBandFrequency(FIX_BAND,s);Kanal(); break; }
        case 6:{ k++; if (k>23) k=1; Frequency(); radio.setBandFrequency(FIX_BAND,s);break;}
      }
   flag=1;
   TimeOut=millis();
    }
   else {(v==15?0:v++);radio.setVolume(v);}
   flag2=1;
   }
   if(DOWN==LOW && flag3==1)
  {
    flag3=0;
  }
   if(DOWN==HIGH && flag3==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==0?15:v--); radio.setVolume(v); break; }
        case 2:{ b = 0; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ ms = 1; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{ radio.seekDown(true); delay(3000); s=radio.getFrequency(); Kanal(); break; }
        case 5:{ s=s-10; if (s<8700) s=10800; delay(100); radio.setBandFrequency(FIX_BAND,s); Kanal(); break; }
        case 6:{ k--; if (k<1) k=23; Frequency(); radio.setBandFrequency(FIX_BAND,s); break;}
      }
   flag=1;
   TimeOut=millis();
   }
   else {(v==0?15:v--);radio.setVolume(v);}
   flag3=1;
  }
}
//================================================
void Menu()
{
float ch;
if(flag==1 && MODE==1)
{
rs = radio.getRSSI();   
ch=float(s)/100; 
u8g.firstPage();  
do {
u8g.setDefaultForegroundColor();
if(Voltage>85) u8g.drawBitmap (110, 0, 2, 10, Bat7);
  else if(Voltage>70) u8g.drawBitmap (110, 0, 2, 10, Bat6);
  else if(Voltage>55) u8g.drawBitmap (110, 0, 2, 10, Bat5);
  else if(Voltage>40) u8g.drawBitmap (110, 0, 2, 10, Bat4);
  else if(Voltage>25) u8g.drawBitmap (110, 0, 2, 10, Bat3);
  else if(Voltage>10) u8g.drawBitmap (110, 0, 2, 10, Bat2);
  else u8g.drawBitmap (110, 0, 2, 10, Bat1);
u8g.drawBitmap (0, 0, 1, 10, Volume);
if(v<3) u8g.drawBitmap (13, 0, 2, 10, Vol1);
  else if(v<7) u8g.drawBitmap (13, 0, 2, 10, Vol2);
  else if(v<10) u8g.drawBitmap (13, 0, 2, 10, Vol3);
  else if(v<13) u8g.drawBitmap (13, 0, 2, 10, Vol4);
  else u8g.drawBitmap (13, 0, 2, 10, Vol5);
if(ms==0) u8g.drawBitmap (68, 0, 2, 10, Stereo);
if(b==1) u8g.drawBitmap (88, 0, 2, 10, Bass);
if (rs>40) u8g.drawBitmap (32, 0, 2, 10, FM);

u8g.setFont(rus10x20);
if(ch<100) u8g.setPrintPos(40,35); else u8g.setPrintPos(36,35);
u8g.print(ch,1);
u8g.setFont(rus6x10);
u8g.print(" MHz");
if(k!=0){
    u8g.drawRFrame (0,22,18,13,2);
    u8g.setPrintPos(3,32);
    if(k<10) u8g.print("0");
    u8g.print(k);
        }
u8g.drawRFrame (0,51,127,12,3);
u8g.setPrintPos(13,61);
 switch(m)
 {
  case 1: {u8g.print(F("- < ГРОМКОСТЬ > +"));break;}
  case 2: {u8g.print(F(" НЕТ < БАСС > ДА"));break;}
  case 3: {u8g.print(F("НЕТ < СТЕРЕО > ДА"));break;}
  case 4: {u8g.print(F(" <  АВТОПОИСК  >"));break;}
  case 5: {u8g.print(F("<  РУЧ. ПОИСК  >"));break;}
  case 6: {u8g.print(F("  <  КАНАЛЫ  >"));break;}
 
 }


}
while( u8g.nextPage() );     
  flag=0;    
}
}
//================================================
void Energy()
{
 if(MODE==1 && millis()-TimeOut>2000) flag=1;
 if(MODE==1 && millis()-TimeOut>8000)
  {
    u8g.sleepOn(); 
    MODE=0;
    if(v2!=v){v2=v; EEPROM[1] = v;}
    if(k2!=k){k2=k; EEPROM[2] = k;}
    if(m2!=m){m2=m; EEPROM[3] = m;}
    if(b2!=b){b2=b; EEPROM[4] = b;}
    if(ms2!=ms){ms2=ms; EEPROM[5] = ms;}
    if(s2!=s){s2=s; EEPROM[6] = int(s/100); EEPROM[7] = s%100;}
  }
  if(MODE==0 && millis()-TimeOut<500)
  {
    u8g.sleepOff(); 
    readVcc();
    MODE=1;flag=1; 
  }
}
//===================================================
void readVcc() 
{
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring
  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both
  long result = (high << 8) | low;

  result = 1.080 * 1023 * 1000 / result; // расчёт реального VCC
  Voltage = int(result);
  Voltage = map(Voltage, 3200, 4200, 0, 100);
  Voltage = constrain(Voltage, 0, 100);
}
//=======================================================
void Kanal()
{
  switch (s)
  {
    case 8750 : k=1;break;
    case 9240 : k=2;break;
    case 9370 : k=3;break;
    case 9410 : k=4;break;
    case 9620 : k=5;break;
    case 9740 : k=6;break;
    case 9800 : k=7;break;
    case 9840 : k=8;break;
    case 9890 : k=9;break;
    case 9950 : k=10;break;
    case 10040: k=11;break;
    case 10120: k=12;break;
    case 10170: k=13;break;
    case 10210: k=14;break;
    case 10250: k=15;break;
    case 10290: k=16;break;
    case 10370: k=17;break;
    case 10460: k=18;break;
    case 10510: k=19;break;
    case 10570: k=20;break;
    case 10620: k=21;break;
    case 10710: k=22;break;
    case 10790: k=23;break;
    default: k=0;
    
  }
}
//==========================================================
void Frequency()
{
 switch(k)
  {
    case 1 :{s=8750;break;}
    case 2 :{s=9370;break;}
    case 3 :{s=8750;break;}
    case 4 :{s=9410;break;}
    case 5 :{s=9620;break;}
    case 6 :{s=9740;break;}
    case 7 :{s=9800;break;}
    case 8 :{s=9840;break;}
    case 9 :{s=9890;break;}
    case 10 :{s=9950;break;}
    case 11 :{s=10040;break;}
    case 12 :{s=10120;break;}
    case 13 :{s=10170;break;}
    case 14 :{s=10210;break;}
    case 15 :{s=10250;break;}
    case 16 :{s=10290;break;}
    case 17 :{s=10370;break;}
    case 18 :{s=10460;break;}
    case 19 :{s=10510;break;}
    case 20 :{s=10570;break;}
    case 21 :{s=10620;break;}
    case 22 :{s=10710;break;}
    case 23 :{s=10790;break;}
  } 
}

Все данные по пректу в архиве:https://yadi.sk/d/S678nWJY8EChPw

Novice User
Offline
Зарегистрирован: 25.09.2017

А от дисплея помехи есть?я делал подобное,дисплей мешал приему...

И можно ли частоту чуть крупнее шрифт?

 

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Помех не замечал. Шрифта, крупнее 10х20 для библиотеки u8glib у меня нет. Была идея нарисовать квадратик и из него как из "кирпичиков" сделать свои цифры. Может потом займусь...

Novice User
Offline
Зарегистрирован: 25.09.2017

Понятно,на будущее ничего не планируете добавить? 

У меня есть почти такой,попробую переделать под свою схему (у меня только кнопки к другим портам и все)

http://img.radiokot.ru/files/111886/medium/1k9jhfm54j.jpg

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

GhostLion пишет:

Помех не замечал. Шрифта, крупнее 10х20 для библиотеки u8glib у меня нет. Была идея нарисовать квадратик и из него как из "кирпичиков" сделать свои цифры. Может потом займусь...


Может интересно будет? http://arduino.ru/forum/programmirovanie/krivye-beze?page=1#comment-403069
Ну и видео обзор не помешает.

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Нашел на просторах интернета чисто цифровой большой шрифт. https://yadi.sk/d/7zwsvuiwqzFbZA Закинуть в папку со скетчем, подключить в начале скетча и заменить строки 182-183:

u8g.setFont(MyDigitsHelveticaBold24);
if(ch<100) u8g.setPrintPos(30,43); else u8g.setPrintPos(23,43);
 
Шрифт 10х20 можно для экономии места из скетча выкинуть - он будет только в начале скетча использоваться. Надпись"ФМ Радио" можно и обычным написать...
Вот как получилось:
GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Версия 1.5 - выбросил шрифт 10х20, добавил функцию SoftMute.

//FM Radio OLED Copyright by GhostLion v1.5

#include <EEPROM.h>
#include <radio.h>
#include <RDA5807M.h>

#include "U8glib.h"
#include "rus6x10.h"
#include "MyDigitsHelveticaBold24.h"

#define Pin_DOWN 4   // левая кнопка 
#define Pin_UP 2     // правая кнопка 
#define Pin_SET 3    // центральная кнопка
#define FIX_BAND 1

const unsigned char Volume [] = {0x7E, 0x42, 0x81, 0x81, 0x81, 0x81, 0xE7, 0xE7, 0x66, 0x66};
const unsigned char Bass [] = {0x7F, 0xFE, 0x80, 0x01, 0x9B, 0x8D, 0xA2, 0x51, 0xA3, 0x91, 0x9A, 0x4D, 0x8A, 0x45, 0xB3, 0x99,0x80, 0x01, 0x7F, 0xFE};
const unsigned char FM [] = {0x7F, 0xFE, 0x80, 0x01, 0x8C, 0x51, 0x90, 0xA9, 0x90, 0xA9, 0x98, 0xA9, 0x90, 0xA9, 0x90, 0x89,0x80, 0x01, 0x7F, 0xFE};
const unsigned char Stereo [] = {0x7F, 0xFE, 0x80, 0x01, 0x9B, 0xB9, 0xA1, 0x25, 0xA1, 0x39, 0x99, 0x31, 0x89, 0x29, 0xB1, 0x25,0x80, 0x01, 0x7F, 0xFE};

const unsigned char Bat1 [] = {0x7F, 0xFC, 0x80, 0x02, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat2 [] = {0x7F, 0xFC, 0x80, 0x02, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat3 [] = {0x7F, 0xFC, 0x80, 0x02, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat4 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat5 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat6 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1,0x80, 0x02, 0x7F, 0xFC};
const unsigned char Bat7 [] = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA9, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xA9,0x80, 0x02, 0x7F, 0xFC};

const unsigned char Vol1 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x60, 0x00, 0x60, 0x00};
const unsigned char Vol2 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00,0x6C, 0x00, 0x6C, 0x00};
const unsigned char Vol3 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x0D, 0x80, 0x0D, 0x80,0x6D, 0x80, 0x6D, 0x80};
const unsigned char Vol4 [] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x01, 0xB0, 0x01, 0xB0, 0x0D, 0xB0, 0x0D, 0xB0,0x6D, 0xB0, 0x6D, 0xB0};
const unsigned char Vol5 [] = {0x00, 0x06, 0x00, 0x06, 0x00, 0x36, 0x00, 0x36, 0x01, 0xB6, 0x01, 0xB6, 0x0D, 0xB6, 0x0D, 0xB6,0x6D, 0xB6, 0x6D, 0xB6};

byte v,v2,k,k2,m,m2,rs, flag1=1,flag2=0,flag3=0;
int Voltage,s,s2;
boolean b,b2,ms,ms2,sm,sm2,flag=1,MODE=1;
long TimeOut;

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
RDA5807M radio; 

void setup()
{
pinMode(Pin_DOWN,INPUT_PULLUP);
pinMode(Pin_UP,INPUT_PULLUP);
pinMode(Pin_SET,INPUT_PULLUP); 

Inicial();
}

void loop()
{
Parsing();
Menu();
Energy();  
}
//==============================================
void Inicial()
{
 u8g.firstPage();  
do {
  u8g.setFont(rus6x10);
  u8g.setPrintPos(38,12);u8g.print(F("ФМ РАДИО"));
  u8g.setPrintPos(36,32);u8g.print(F("v 1.5 Rus"));
  u8g.setPrintPos(40,42);u8g.print(F("20.11.18"));
  u8g.setPrintPos(25,52);u8g.print(F("By GhostLion"));
  u8g.setPrintPos(40,62);u8g.print(F("EXTENDED"));  
   }
while( u8g.nextPage() );

delay(1500);
sm = EEPROM[0];
v  = EEPROM[1];
k  = EEPROM[2];
m  = EEPROM[3];
b  = EEPROM[4];
ms = EEPROM[5];
s  = EEPROM[6]*100+EEPROM[7];
v2=v; k2=k; m2=m; b2=b; ms2=ms; s2=s;sm2=sm;
radio.init();
radio.setVolume(v);
radio.setMono(ms);
radio.setMute(false);
radio.setBassBoost(b);
radio.setSoftMute(sm);  
radio.setBandFrequency(FIX_BAND, s);
readVcc();
}
//================================================
void Parsing()
{
boolean SET=digitalRead(Pin_SET);
boolean UP=digitalRead(Pin_UP);
boolean DOWN=digitalRead(Pin_DOWN);

if(SET==HIGH && flag1==0)
  {
    flag1=1;
  }
if(SET==LOW && flag1==1)
  {
    flag1=0;
    TimeOut=millis();
    if(MODE==1) {m++; flag=1; if(m>7) m=1;}
  }
  
 if(UP==LOW && flag2==1)
  {
    flag2=0;
  }
   if(UP==HIGH && flag2==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==15?0:v++); radio.setVolume(v); break; }
        case 2:{ b = 1; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ ms = 0; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{sm = 1; radio.setSoftMute(true);radio.setBandFrequency(FIX_BAND,s); break;}
        case 5:{ radio.seekUp(true); delay(3000); s = radio.getFrequency(); Kanal(); break; }
        case 6:{ s=s+10; if (s > 10800) s = 8700; delay(100); radio.setBandFrequency(FIX_BAND,s);Kanal(); break; }
        case 7:{ k++; if (k>23) k=1; Frequency(); radio.setBandFrequency(FIX_BAND,s); break;}
      }
   flag=1;
   TimeOut=millis();
    }
   else {(v==15?0:v++);radio.setVolume(v);}
   flag2=1;
   }
   if(DOWN==LOW && flag3==1)
  {
    flag3=0;
  }
   if(DOWN==HIGH && flag3==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==0?15:v--); radio.setVolume(v); break; }
        case 2:{ b = 0; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ ms = 1; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{sm = 0; radio.setSoftMute(false);radio.setBandFrequency(FIX_BAND,s); break;}
        case 5:{ radio.seekDown(true); delay(3000); s=radio.getFrequency(); Kanal(); break; }
        case 6:{ s=s-10; if (s<8700) s=10800; delay(100); radio.setBandFrequency(FIX_BAND,s); Kanal(); break; }
        case 7:{ k--; if (k<1) k=23; Frequency(); radio.setBandFrequency(FIX_BAND,s); break;}
      }
   flag=1;
   TimeOut=millis();
   }
   else {(v==0?15:v--);radio.setVolume(v);}
   flag3=1;
  }
}
//================================================
void Menu()
{
float ch;
if(flag==1 && MODE==1)
{
rs = radio.getRSSI();   
ch=float(s)/100; 
u8g.firstPage();  
do {
u8g.setDefaultForegroundColor();
if(Voltage>85) u8g.drawBitmap (110, 0, 2, 10, Bat7);
  else if(Voltage>70) u8g.drawBitmap (110, 0, 2, 10, Bat6);
  else if(Voltage>55) u8g.drawBitmap (110, 0, 2, 10, Bat5);
  else if(Voltage>40) u8g.drawBitmap (110, 0, 2, 10, Bat4);
  else if(Voltage>25) u8g.drawBitmap (110, 0, 2, 10, Bat3);
  else if(Voltage>10) u8g.drawBitmap (110, 0, 2, 10, Bat2);
  else u8g.drawBitmap (110, 0, 2, 10, Bat1);
u8g.drawBitmap (0, 0, 1, 10, Volume);
if(v<3) u8g.drawBitmap (13, 0, 2, 10, Vol1);
  else if(v<7) u8g.drawBitmap (13, 0, 2, 10, Vol2);
  else if(v<10) u8g.drawBitmap (13, 0, 2, 10, Vol3);
  else if(v<13) u8g.drawBitmap (13, 0, 2, 10, Vol4);
  else u8g.drawBitmap (13, 0, 2, 10, Vol5);
if(ms==0) u8g.drawBitmap (68, 0, 2, 10, Stereo);
if(b==1) u8g.drawBitmap (88, 0, 2, 10, Bass);
if (rs>43) u8g.drawBitmap (32, 0, 2, 10, FM);

u8g.setFont(MyDigitsHelveticaBold24);
if(ch<100) u8g.setPrintPos(30,43); else u8g.setPrintPos(23,43);
u8g.print(ch,1);
u8g.setFont(rus6x10);
u8g.print(" MHz");
if(sm==1){ 
  u8g.drawRFrame (0,16,18,13,2);
  u8g.setPrintPos(3,26);
  u8g.print("SM");
      }
if(k!=0){
    u8g.drawRFrame (0,32,18,13,2);
    u8g.setPrintPos(3,42);
    if(k<10) u8g.print("0");
    u8g.print(k);
        }
u8g.drawRFrame (0,51,127,12,3);
u8g.setPrintPos(13,61);
 switch(m)
 {
  case 1: {u8g.print(F("- < ГРОМКОСТЬ > +"));break;}
  case 2: {u8g.print(F(" НЕТ < БАСС > ДА"));break;}
  case 3: {u8g.print(F("НЕТ < СТЕРЕО > ДА"));break;}
  case 4: {u8g.print(F("НЕТ < S.MUTE > ДА"));break;}
  case 5: {u8g.print(F(" <  АВТОПОИСК  >"));break;}
  case 6: {u8g.print(F("<  РУЧ. ПОИСК  >"));break;}
  case 7: {u8g.print(F("  <  КАНАЛЫ  >"));break;}
 
 }


}
while( u8g.nextPage() );     
  flag=0;    
}
}
//================================================
void Energy()
{
 if(MODE==1 && millis()-TimeOut>2000) flag=1;
 if(MODE==1 && millis()-TimeOut>8000)
  {
    u8g.sleepOn(); 
    MODE=0;
    if(sm2!=sm){sm2=sm;EEPROM[0] = sm;}
    if(v2!=v){v2=v; EEPROM[1] = v;}
    if(k2!=k){k2=k; EEPROM[2] = k;}
    if(m2!=m){m2=m; EEPROM[3] = m;}
    if(b2!=b){b2=b; EEPROM[4] = b;}
    if(ms2!=ms){ms2=ms; EEPROM[5] = ms;}
    if(s2!=s){s2=s; EEPROM[6] = int(s/100); EEPROM[7] = s%100;}
  }
  if(MODE==0 && millis()-TimeOut<500)
  {
    u8g.sleepOff(); 
    readVcc();
    MODE=1;flag=1; 
  }
}
//===================================================
void readVcc() 
{
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring
  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both
  long result = (high << 8) | low;

  result = 1.080 * 1023 * 1000 / result; // расчёт реального VCC
  Voltage = int(result);
  Voltage = map(Voltage, 3200, 4200, 0, 100);
  Voltage = constrain(Voltage, 0, 100);
}
//=======================================================
void Kanal()
{
  switch (s)
  {
    case 8750 : k=1;break;
    case 9240 : k=2;break;
    case 9370 : k=3;break;
    case 9410 : k=4;break;
    case 9620 : k=5;break;
    case 9740 : k=6;break;
    case 9800 : k=7;break;
    case 9840 : k=8;break;
    case 9890 : k=9;break;
    case 9950 : k=10;break;
    case 10040: k=11;break;
    case 10120: k=12;break;
    case 10170: k=13;break;
    case 10210: k=14;break;
    case 10250: k=15;break;
    case 10290: k=16;break;
    case 10370: k=17;break;
    case 10460: k=18;break;
    case 10510: k=19;break;
    case 10570: k=20;break;
    case 10620: k=21;break;
    case 10710: k=22;break;
    case 10790: k=23;break;
    default: k=0;
    
  }
}
//==========================================================
void Frequency()
{
 switch(k)
  {
    case 1 :{s=8750;break;}
    case 2 :{s=9370;break;}
    case 3 :{s=8750;break;}
    case 4 :{s=9410;break;}
    case 5 :{s=9620;break;}
    case 6 :{s=9740;break;}
    case 7 :{s=9800;break;}
    case 8 :{s=9840;break;}
    case 9 :{s=9890;break;}
    case 10 :{s=9950;break;}
    case 11 :{s=10040;break;}
    case 12 :{s=10120;break;}
    case 13 :{s=10170;break;}
    case 14 :{s=10210;break;}
    case 15 :{s=10250;break;}
    case 16 :{s=10290;break;}
    case 17 :{s=10370;break;}
    case 18 :{s=10460;break;}
    case 19 :{s=10510;break;}
    case 20 :{s=10570;break;}
    case 21 :{s=10620;break;}
    case 22 :{s=10710;break;}
    case 23 :{s=10790;break;}
  } 
}

 

Novice User
Offline
Зарегистрирован: 25.09.2017

Зря травил/паял,не получается скомпилировать,ошибка компиляции

Arduino: 1.6.5 (Windows 7), Плата"Arduino Pro or Pro Mini, ATmega328 (3.3V, 8 MHz)"
 
In file included from RadioFM_v1.4_Extended.ino:5:0:
C:\Program Files (x86)\arduino-1.6.5-r5\libraries\Radio\src/RDA5807M.h:32:18: fatal error: Wire.h: No such file or directory
 #include <Wire.h>
                  ^
compilation terminated.
Ошибка компиляции.
 
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки
 
GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

У меня версия Arduino IDE 1.8.5. У вас проблема с бибилотекой Wire.h - попробуйте скачать последнюю версию.

  p.s. Скоро сделаю ручное сохранение каналов, уже освободил кучу памяти - перекинул иконки в PROGMEM

Novice User
Offline
Зарегистрирован: 25.09.2017

Спасибо!получилось

Прошивка 1.4

Вручном ежима непонятно-одна станция у нас  98,3,ставлю 98,0 и нажимаю плюс-станция принимается на 98,5,нажимаю дальше-станция пропадает,частота 98,6,теперь нажимаю минус и станция принимается на правильной частоте 98,3

Тоже самое радио "Шансон",частота 99,6-при переключении вверх принимается на 99,8,при переключении вниз принимается правильно-99,6

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Это в режиме автопоиска или ручном? В ручном должно по 0.1 Мгц добавляться.

Novice User
Offline
Зарегистрирован: 25.09.2017

 В ручном,до по 0,1 МГц,настраиваюсь на дорожное радио 98,3 начиная с 98,0-нажимаю-частота 98,1,еще нажимаю-98,2,еще нажимаю частота 98,3 (станция еле пробивается),потом 98,4 (станцияс шумом но сильнее),нажимаю-98,5-станция принимается замечательно,и так со всеми станциями (99,6,  100,2  ,100,6, 1011 и т д)-все принимаются на 0,2 МГц выше

Если вручную уменьшать частоты то все станции на своих частотах

Перепрошивал-то же самое

Программа ваша у меня только кнопки на другие порты и частоты свои

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Возможно у вас какая-то проблема с модулем RDA5807 - так как это по всей видимости не программная ошибка. У меня все работает идеально, все станции на своих частотах.

Novice User
Offline
Зарегистрирован: 25.09.2017

С модулем все замечательно-стоял в другом радио,при переключении по каналам все отлично,автопоиск тоже отлично,только при ручной перестройке вверх такая байда,так то ручная не очень нужна-забил в память и слушай!

Программа занимает 20 кб памяти-непозволительная роскошь...

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Память не бензин -  в ведро не сольешь. А если честно: библиотека модуля и дисплея в основном и "кушают" её.

Novice User
Offline
Зарегистрирован: 25.09.2017

Ну это понятно,знал бы как передавать по и2с в ардуино переписал бы обращение к 5807,там ничего сложного,там наверно полно всякой ненужности,поищу инфу по и2с...

автопоиск странноватый-правильнее наверно включать автопоиск и ждать пока не установится флаг STC

 

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Можно покопаться в файлах библиотеки и посмотреть что как работает...В даташите модуля копался, но у меня пока не тот уровень, чтобы все понимать.

Novice User
Offline
Зарегистрирован: 25.09.2017

Там ничего сложного нет,вот http://cxem.net/tuner/files/tuner84_RDA5807M_datasheet_v1.pdf даташит хороший,есть на русском на каткаткат

например регулировка громкости на баском авр-

                   I2cstart
                   I2cwbyte &h22  -адрес 5807 при общении с конкретными регистрами управления
                   I2cwbyte &h05       'H05 регистр где ставим громкость 
                   I2cwbyte &B10001000       'старший байт,оставляем по умолчанию,старший бит=1=это включение антенного входа
                   Byte0 = &B10000000 + volume  'младшие 4 байта и есть уровень громкости
                   I2cwbyte Byte0
                   I2cstop
как это переписать в ардуино?я вас не напрягаю?
GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Вот здесь посмотрите листинг программы:http://full-chip.net/arduino-proekty/97-cifrovoy-fm-priemnik-na-arduino-i-module-rda5807-s-graficheskim-displeem-i-funkciey-rds.html Там все сделано без библиотек модуля и дисплея (Nokia 5110). Только библиотека Wire.h

Novice User
Offline
Зарегистрирован: 25.09.2017

Там вообще все мудрено,вот начал-все работает

#include <Wire.h>

#define Pin_DOWN 12//4   // левая кнопка 
#define Pin_UP 13//2     // правая кнопка 
#define Pin_SET 11//3    // центральная кнопка
const byte channel=5;
byte Byte0;
byte val = 0;
byte volume = 4;
int freq=1011;
void setup()
{
   pinMode(Pin_DOWN,INPUT_PULLUP);
   pinMode(Pin_UP,INPUT_PULLUP);
   pinMode(Pin_SET,INPUT_PULLUP);
   Wire.begin(); // подключение к шине i2c
   delay(500);
   Inicial();
}

void loop()
{
boolean SET=digitalRead(Pin_SET);
boolean UP=digitalRead(Pin_UP);
boolean DOWN=digitalRead(Pin_DOWN);
if(DOWN==LOW)
  {
   volume=volume+1; set_vol();delay(500);
    //freq=freq+1; set_freq();delay(500);//работает норм
  }
if(SET==LOW)
  {
    volume=volume-1; set_vol();delay(500);
    //freq=freq-1;set_freq();delay(500); //работает норм
  }
if(UP==LOW)
  {
   stby();//выключаем радио ,потребление почти 0
   
   delay(1500);//ждем 1,5 сек и вкл
   set_freq();      // вкл радио
  }
}   
void Inicial()
{   
   Wire.beginTransmission(0x10); // передача для устройства 
   //02                            // адрес устройства указывается в документации (datasheet)
   Wire.write(0B11010000);             // отправка байта 
   Wire.write(0B10000001);
   //03
   Byte0 = freq - 870;
   Wire.write(Byte0);
   Byte0=0B00010011;
   Wire.write(Byte0);
   //04
   Wire.write(0B00010000);
   Wire.write(0B00000000);
   //05
   Wire.write(0B10001000);
   Byte0=0B10000000 + volume;
   Wire.write(Byte0);
   Wire.endTransmission();     // передача данных
}
void set_freq()//установка частоты
{   
   if (freq > 1080) freq = 870;
   if (freq < 880) freq = 1080;
   Wire.beginTransmission(0x10); // передача для устройства 
   //02                            // адрес устройства указывается в документации (datasheet)
   Wire.write(0B11010000);             // отправка байта 
   Wire.write(0B10000001);
   //03
   Byte0 = freq - 870;
   Wire.write(Byte0);//частота,старшие 8 бит
   Byte0=0B00010011;//7,6-мл биты частоты=всегда 00 так как шаг=25, 4-точная установка,3,2-диапазон=87-108,1,0-шаг 25 кгц
   Wire.write(Byte0);
   Wire.endTransmission();     // передача данных
}
void set_vol()//установка громкости
{   
   if (volume > 200) volume = 0;
   if (volume >15) volume = 15; 
   Wire.beginTransmission(0x11); // передача для устройства
   //02                            // адрес устройства указывается в документации (datasheet)
   Wire.write(0B00000101);             // отправка байта val
  //05
   Wire.write(0B10001000);
   Byte0=0B10000000 + volume;
   Wire.write(Byte0);
   Wire.endTransmission();     // передача данных
}
void stby()
{
 Wire.beginTransmission(0x10);      // выкл радио
  //02                            // адрес устройства указывается в документации (datasheet)
   Wire.write(0B11010000);             // отправка байта val
   Wire.write(0B10000000);
  Wire.endTransmission();     // передача данных 
}



 

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Финальная версия радио. С каналами не стал морочиться - сделал, поигрался, но через программу забивать удобнее. Короче, оставил все как было, только внёс некоторые правки.

. 

https://yadi.sk/d/_8VCmTGt4vO5vw

bulat943
Offline
Зарегистрирован: 19.09.2016

У меня небольшая проблемка ))) дисплей развел вверх-тормашкой,реально перевернуть картинку?

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

 

Попробуйте вот это:

setRot90
setRot180
setRot270

    C++ Prototype void U8GLIB::setRot90() void U8GLIB::setRot180() void U8GLIB::setRot270()

  C Prototype void u8g_SetRot90(u8g_t *u8g) void u8g_SetRot180(u8g_t *u8g) void u8g_SetRot270(u8g_t *u8g



Описание

По часовой стрелке поворачивается экран дисплея на 90, 180 или 270 градусов. Для большинства устройств отображения пейзаж - режим по умолчанию. Вращение на 90 или 270 градусов приведет к отображению дисплея в портретном режиме. Обратите внимание, что эта функция уменьшит производительность U8glib.

Аргументы:

u8g: Указатель на структуру u8g (только для интерфейса C).

Использование:

Внешний контур изображения. Окружающая среда Arduino. Рекомендуется использовать эту процедуру в процедуре setup ().

bulat943
Offline
Зарегистрирован: 19.09.2016

Все,решил,извините...

 

Одновременно писали-я и поставил u8g.setRot180();,просто сначала ставил lcd.setRot180();

 
ronixx
ronixx аватар
Offline
Зарегистрирован: 20.12.2018

GhostLion пишет:

Финальная версия радио. С каналами не стал морочиться - сделал, поигрался, но через программу забивать удобнее. Короче, оставил все как было, только внёс некоторые правки.

. 

https://yadi.sk/d/_8VCmTGt4vO5vw

Вы из Беларуси ?

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Да.

 

ronixx
ronixx аватар
Offline
Зарегистрирован: 20.12.2018

GhostLion пишет:

Да.

 


Я из Могилева, делаю проект по вашей схеме. Можно ваш мейл или вк ?

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

ronixx пишет:
GhostLion пишет:

Да.

 

Я из Могилева, делаю проект по вашей схеме. Можно ваш мейл или вк ?
########

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

ronixx, пришлите фотки проблемы и куски кода, который меняли.

p.s. Письмо на ваш mail.ru не хочет доставлять.

ronixx
ronixx аватар
Offline
Зарегистрирован: 20.12.2018

GhostLion пишет:

ronixx, пришлите фотки проблемы и куски кода, который меняли.

p.s. Письмо на ваш mail.ru не хочет доставлять.

На днях отправлю, artur.gromyko@yandex.ru

Ванька79
Offline
Зарегистрирован: 15.04.2019

Заинтересовал данный приемник,вопрос по унч-есть модули PAM8403,стоит ли их использовать? а то в инете пишут что он сильно забивает эфир 

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

GhostLion, здравствуйте! Как я понял в скетче (прошивка Голд) перед заливкой надо свои радиостанции прописывать?

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Да.

 

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

Спасибо. Плюсанул. Ручная подстройка частоты предусмотрена? Катаюсь много, поволжье,  урал.

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

GhostLion, править строки 321-343 и 289-311?

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Да, и в строках 144,168 изменить количество каналов (23)

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

а чо б в EEPROM не засунуть любимые радиастанцыи?

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

GhostLion пишет:

Да, и в строках 144,168 изменить количество каналов (23)

Сколько максимально?

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019
Так правильно?
void Kanal()
{
  switch (s)
  {
    case 8750 : k=1;break; //Бизнес ФМ
    case 8830 : k=2;break; //Ретро ФМ
    case 8910 : k=3;break; //Радио Джаз
    case 8950 : k=4;break; //Мегаполис ФМ
    case 8990 : k=5;break; //Страна ФМ
    case 9030 : k=6;break; //Авторадио
    case 9080 : k=7;break; //Релакс ФМ
    case 9120 : k=8;break; //Эхо Москвы
    case 9890 : k=9;break; //Радио Культура
    case 9360 : k=10;break; //Коммерсант ФМ
    case 9560: k=11;break; //Радио Звезда
    case 9600: k=12;break; //Дорожное радио
    case 9720: k=13;break; //Радио КП
    case 9920: k=14;break; //Радио Романтика
    case 9960: k=15;break; //Радио Орфей
    case 10010: k=16;break; //Серебряный дождь
    case 10170: k=17;break; //Наше радио
    case 10250: k=18;break; //Камеди Радио
    case 10300: k=19;break; //Радио Шансон
    case 10500: k=20;break; //Радио Книга
    case 10570: k=21;break; //Русское радио
    case 10740: k=22;break; //Хит ФМ
    case 10780: k=23;break; //Милицейская волна
    default: k=0;
    
  }
}
//==========================================================
void Frequency()
{
 switch(k)
  {
    case 1 :{s=8750;break;}
    case 2 :{s=8830;break;}
    case 3 :{s=8910;break;}
    case 4 :{s=8950;break;}
    case 5 :{s=8990;break;}
    case 6 :{s=9030;break;}
    case 7 :{s=9080;break;}
    case 8 :{s=9120;break;}
    case 9 :{s=9890;break;}
    case 10 :{s=9360;break;}
    case 11 :{s=9560;break;}
    case 12 :{s=9600;break;}
    case 13 :{s=9720;break;}
    case 14 :{s=9920;break;}
    case 15 :{s=9960;break;}
    case 16 :{s=10010;break;}
    case 17 :{s=10170;break;}
    case 18 :{s=10250;break;}
    case 19 :{s=10300;break;}
    case 20 :{s=10500;break;}
    case 21 :{s=10570;break;}
    case 22 :{s=10740;break;}
    case 23 :{s=10780;break;}
  } 
}

 

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

255 (переменная k типа byte)  

GhostLion
GhostLion аватар
Offline
Зарегистрирован: 30.07.2018

Да, правильно.

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019

GhostLion, доброго дня! Собрал на макетке, 51 радиостанцию внес в скетч, залил, все работает. Теперь буду засовывать все в корпус сгоревшей БТ колонки Оклик ОК-10 (аудио вход джек умудрился попасть в фазу пилота на столе).

Предела совершенству не существует, и я попросил бы Вас создать скетч PLATINUM 1.7, внесением в v1.6 индикацию  уровня сигнала (антенка вместо наушников). Сам слаб в програмировании, а вот готовый скетч с такой функцией имеется.

// Nicu Florica (aka niq_ro) from http://www.tehnic.go.ro made a small change for nice display for low frequence (bellow 100MHz)
// it use info from http://full-chip.net/arduino-proekty/97-cifrovoy-fm-priemnik-na-arduino-...
// original look like is from http://seta43.hol.es/radiofm.html
// version 1 - store frequency and volume step in EEPROM memory

#include <EEPROM.h> // info -> http://tronixstuff.com/2011/03/16/tutorial-your-arduinos-inbuilt-eeprom/

#include <Wire.h>
#define DEBUG 0

const int entrada = A0; 
int entradaV = 0; 

int menu;
#define MAXmenu  4
int menux;
#define MAXmenux  4
static char* menuS[]= {" ","MANUAL TUNE","VOLUME     ","AUTO TUNE","INFO        "};

//int volumen=2,volumenOld=7;
int volumen, volumenOld=7;
int frecuencia,frecuenciaOld;


unsigned int z,z1;
byte xfrecu,xfrecuOld;
unsigned int estado[6];

unsigned long time,time1,time2,time3;

// int    RDA5807_adrs=0x10;       // I2C-Address RDA Chip for sequential  Access
// int    RDA5807_adrr=0x11;       // I2C-Address RDA Chip for random      Access
// int    RDA5807_adrt=0x60;       // I2C-Address RDA Chip for TEA5767like Access

char buffer[30];
unsigned int RDS[4];
char seg_RDS[8];
char seg_RDS1[64];
char indexRDS1;

char hora,minuto,grupo,versio;
unsigned long julian;

 int mezcla;

void setup() 
{
  Wire.begin();   
  Serial.begin(9600); 

/* 
// write data in eeprom memory
EEPROM.write(201,175);    // frequency  = frecvencia * 0.1 + 87 
                          //   frecuencia=175; //104.5
EEPROM.write(202,7);      // volume 0 to 15
*/

// read value of last frequency
frecuencia = EEPROM.read(201);
volumen = EEPROM.read(202);

if (volumen < 0) volumen = 0;
if (volumen >15) volumen = 15;
if (frecuencia <0) frecuencia = 0;
if (frecuencia >210) frecuencia = 210;
  
  LcdInitialise();
  LcdClear();
//  drawBox();

//   WriteReg(0x02,0xC001); // write 0xC002 into Reg.2 (soft reset, enable,RDS, )
   WriteReg(0x02,0xC00d); // write 0xC00d into Reg.2 ( soft reset, enable,RDS, )
   WriteReg(0x05,0x84d8);  // write ,0x84d8 into Reg.3 
   
// frecuencia inicial = frecvencia * 0.1 + 87 
//   frecuencia=175; //104.5
//frecuencia=130; //100.0 ==> 
//  frecuencia=26; //89.6
  time3=time2=time1=time = millis();
  menu=3;
  
  canal(frecuencia);
  clearRDS;
}

void loop() {
 
  entradaV = analogRead(entrada);
  
   #if DEBUG  
      Serial.print("sensor = " );  Serial.println(entradaV);delay(50);
   #endif
   
// Boton menu   
 if(entradaV>500 && entradaV<524)
   {
    menu++;
    if(menu>MAXmenu)menu=1;
    Visualizar();
//    sprintf(buffer,"Menu->%s",menuS[menu]); gotoXY(2,2);  LcdString(buffer); 
    #if DEBUG 
      Serial.print("menu = " );  Serial.println(menu); 
    #endif   
    while(1020>analogRead(entrada))delay(5);
   }
            
// Boton derecho
 if( entradaV<50)
   {
    menux++;
    if(menux>MAXmenux)menux=MAXmenux;
    #if DEBUG 
      Serial.print("menux = " );  Serial.println(menux);
    #endif
    switch(menu)
      {
        case 1:
          frecuencia++;
          if(frecuencia>210)frecuencia=210; // верхняя граница частот
          delay(130);
        break;  
        case 2:
           volumen++;
           if(volumen>15)volumen=15;
           while(1020>analogRead(entrada))delay(5);
        break; 
        case 3:
           busqueda(0);
           while(1020>analogRead(entrada))delay(5);
        break; 
        case 4:
            LcdClear();
            visualPI();
            delay(3000);
            LcdClear();
            frecuenciaOld=-1;
        break; 
      }              
   }
   
// Boton izquierdo
 if( entradaV<700 && entradaV>660)
   {
    menux--;
    if(menux<1)menux=1; 
    #if DEBUG 
      Serial.print("menux = " );  Serial.println(menux);
    #endif   
    switch(menu)
      {
        case 1:
            frecuencia--;
            if(frecuencia<0)frecuencia=0;    
            delay(130);
        break;  
        case 2:
            volumen--;
            if(volumen<0)volumen=0;
            while(1020>analogRead(entrada))delay(5);
        break; 
        case 3:
            busqueda(1);
            while(1020>analogRead(entrada))delay(5);
        break; 
        case 4:
            LcdClear();
            visualPTY();
            delay(3000);
            LcdClear();
            frecuenciaOld=-1;
        break; 
      }
    
   }
      
      if( millis()-time2>50)
          {
           ReadEstado();
           time1 = millis(); 
            //RDS   
           if ((estado[0] & 0x8000)!=0) {get_RDS();}
          }
     if( millis()-time3>500)
          {
            time3 = millis();
            Visualizar(); 

          }

    if( frecuencia!=frecuenciaOld)
          {  
            frecuenciaOld=frecuencia;                        
            z=870+frecuencia;
            EEPROM.write(201,frecuencia);
         #if DEBUG  
            Serial.print("Frecuencia = " );  Serial.println(frecuencia);
         #endif 
            sprintf(buffer,"%04d ",z);
             gotoXY(1,3);     
             
          for(z=0;z<5;z++)
               {
          if (z==0) {
          if (frecuencia < 130) LcdStringX(" ");
          else LcdCharacterX(buffer[0]);
   //       else LcdStringX("1");
          }
                     
             if(z==3)  LcdStringX(".");
             //   if((z==0) and (buffer[0]==0)) LcdStringX("."); else LcdCharacterX(buffer[z]);
           if (z>0) LcdCharacterX(buffer[z]);
               }
               
               
       //   LcdString("MHz"); 
          gotoXY(62,3); 
          LcdString("MHz");
        
          canal(frecuencia);
          clearRDS();
       }     

    //Cambio de volumen        
    if(volumen!=volumenOld)
        { 
          volumenOld=volumen;
          sprintf(buffer,"Vol %02d",volumen); gotoXY(38,1);  LcdString(buffer);      
          WriteReg(5, 0x84D0 | volumen);
          EEPROM.write(202,volumen);
        }       
}

void visualPI(void)
{
    #if DEBUG       
     Serial.print("PAIS:  "); Serial.println(RDS[0]>>12 & 0X000F);
     Serial.print("Cobertura:"); Serial.println(RDS[0]>>8 & 0X000F);
     Serial.print("CODIGO:"); Serial.println(RDS[0] & 0X00FF); 
    #endif
/*    
     gotoXY(1,3);sprintf(buffer,"PAIS  -%02d",RDS[0]>>12 & 0X000F); LcdString(buffer);
     gotoXY(1,4);sprintf(buffer,"COBERT-%02d",RDS[0]>>8 & 0X000F); LcdString(buffer);
     gotoXY(1,5);sprintf(buffer,"CODIGO-%02d",RDS[0] & 0X00FF); LcdString(buffer);     
*/ 
     gotoXY(1,3);sprintf(buffer,"COUNTRY -%02d",RDS[0]>>12 & 0X000F); LcdString(buffer);
     gotoXY(1,4);sprintf(buffer,"COVERAGE-%02d",RDS[0]>>8 & 0X000F); LcdString(buffer);
     gotoXY(1,5);sprintf(buffer,"CODE    -%02d",RDS[0] & 0X00FF); LcdString(buffer);     

}
void visualPTY(void)
{
    #if DEBUG       
     Serial.print("PTY:  "); Serial.println(RDS[1]>>5 & 0X001F);     
    #endif
 
 /*   
     gotoXY(1,3);     LcdString("TIPO");
     gotoXY(1,4);     LcdString("PROGRAMA");
     gotoXY(1,5);sprintf(buffer,"%02d",RDS[1]>>5 & 0X001F); LcdString(buffer);
*/
     gotoXY(1,3);     LcdString("TYPE");
     gotoXY(1,4);     LcdString("PROGRAMS");
     gotoXY(1,5);sprintf(buffer,"%02d",RDS[1]>>5 & 0X001F); LcdString(buffer);

}

void busqueda(byte direc)
{
  byte i;
  if(!direc) WriteReg(0x02,0xC30d); else  WriteReg(0x02,0xC10d);
  
  for(i=0;i<10;i++)
    {
      delay(200);      
      ReadEstado();      
      if(estado[0]&0x4000)
        {
          //Serial.println("Emisora encontrada");
          frecuencia=estado[0] & 0x03ff;  
          break;
        }       
    }
}

void clearRDS(void)
{       
         gotoXY(10,4); for (z=0;z<8;z++) {seg_RDS[z]=32; LcdCharacter(32);}  //borrar Name LCD Emisora
         gotoXY(38,2); for (z=0;z<6;z++) { LcdCharacter(32);}  //borrar linea Hora
         for (z=0;z<64;z++) seg_RDS1[z]=32;   
}

void Visualizar(void)
{ 
      //Serial.print("READ_Frecuencia= " );  Serial.println(estado[0] & 0x03ff);
      gotoXY(2,0); LcdStringX("FM"); 
      sprintf(buffer,"%s",menuS[menu]); gotoXY(2,2);  LcdString(buffer); 
       //Detectar se&#241;al stereo
       gotoXY(72,0);
       if((estado[0] & 0x0400)==0)  LcdCharacter(32);   else     LcdCharacter(127);        
       //Se&#241;al 
       z=estado[1]>>10; sprintf(buffer,"S-%02d",z); gotoXY(38,0);  LcdString(buffer);
       sprintf(buffer,"Vol %02d",volumen); gotoXY(38,1);  LcdString(buffer);
       //ver RADIO_TXT
       gotoXY(0,5);
       z1=indexRDS1;
       for (z=0;z<12;z++)
       {           
         LcdCharacter(seg_RDS1[z1]);
         z1++;
         if(z1>35)z1=0;           
       }
       indexRDS1++; if(indexRDS1>35) indexRDS1=0;
       
      frecuencia=estado[0] & 0x03ff;  
  }

void canal( int canal)
     {
       byte numeroH,numeroL;
       
       numeroH=  canal>>2;
       numeroL = ((canal&3)<<6 | 0x10); 
       Wire.beginTransmission(0x11);
       Wire.write(0x03);
         Wire.write(numeroH);                     // write frequency into bits 15:6, set tune bit         
         Wire.write(numeroL);
         Wire.endTransmission();
       }

//________________________ 
//RDA5807_adrr=0x11;       
// I2C-Address RDA Chip for random      Access
void WriteReg(byte reg,unsigned int valor)
{
  Wire.beginTransmission(0x11);
  Wire.write(reg); Wire.write(valor >> 8); Wire.write(valor & 0xFF);
  Wire.endTransmission();
  //delay(50);
}

//RDA5807_adrs=0x10;
// I2C-Address RDA Chip for sequential  Access
int ReadEstado()
{
 Wire.requestFrom(0x10, 12); 
 for (int i=0; i<6; i++) { estado[i] = 256*Wire.read ()+Wire.read(); }
 Wire.endTransmission();

}

//READ RDS  Direccion 0x11 for random access
void ReadW()
{
   Wire.beginTransmission(0x11);            // Device 0x11 for random access
   Wire.write(0x0C);                                // Start at Register 0x0C
   Wire.endTransmission(0);                         // restart condition
   Wire.requestFrom(0x11,8, 1);       // Retransmit device address with READ, followed by 8 bytes
   for (int i=0; i<4; i++) {RDS[i]=256*Wire.read()+Wire.read();}        // Read Data into Array of Unsigned Ints
   Wire.endTransmission();                  
 } 

 void get_RDS()
 {    
  int i;
  ReadW();      
  grupo=(RDS[1]>>12)&0xf;
      if(RDS[1]&0x0800) versio=1; else versio=0;  //Version A=0  Version B=1   
      if(versio==0)
      {
       #if DEBUG             
       sprintf(buffer,"Version=%d  Grupo=%02d ",versio,grupo); Serial.print(buffer);
    //    Serial.print(" 0->");Serial.print(RDS[0],HEX);Serial.print(" 1->");Serial.print(RDS[1],HEX);Serial.print(" 2->");Serial.print(RDS[2],HEX);Serial.print(" 3->");Serial.println(RDS[03],HEX);
    //    Serial.print(" 0->");Serial.print(RDS[0],BIN);Serial.print(" 1->");Serial.print(RDS[1],BIN);Serial.print(" 2->");Serial.print(RDS[2],BIN);Serial.print(" 3->");Serial.println(RDS[03],BIN);
    #endif 
    switch(grupo)
    {
     case 0:              
      #if DEBUG 
      Serial.print("_RDS0__");     
      #endif
      i=(RDS[1] & 3) <<1;
      seg_RDS[i]=(RDS[3]>>8);       
      seg_RDS[i+1]=(RDS[3]&0xFF);
      gotoXY(10,4);
      for (i=0;i<8;i++)
      {
        #if DEBUG 
        Serial.write(seg_RDS[i]);   
        #endif
        
        if(seg_RDS[i]>31 && seg_RDS[i]<128)
        LcdCharacter(seg_RDS[i]);
        else
        LcdCharacter(32);
      }  
      //Serial.print("FrecuAlt1-");Serial.println((RDS[2]>>8)+875);
      //Serial.print("FrecuAlt2-"); Serial.println(RDS[2]&0xFF+875);      
      
      #if DEBUG                 
      Serial.println("---");
      #endif
      break;
     case 2:
      i=(RDS[1] & 15) <<2;              
      seg_RDS1[i]=(RDS[2]>>8);       
      seg_RDS1[i+1]=(RDS[2]&0xFF);
      seg_RDS1[i+2]=(RDS[3]>>8);       
      seg_RDS1[i+3]=(RDS[3]&0xFF);
      #if DEBUG 
      Serial.println("_RADIOTEXTO_");
              //Serial.print(i);Serial.print("   ");Serial.println(RDS[1] & 15);
              //Serial.write(RDS[2]>>8); Serial.write (RDS[2]&0xFF);Serial.write(RDS[3]>>8);Serial.write(RDS[3]&0xFF);Serial.write("_");
              for (i=0;i<32;i++)  Serial.write(seg_RDS1[i]);                                    
              Serial.println("-TXT-");
              #endif      
              break;
              case 4:             
              i=RDS[3]& 0x003f;
              minuto=(RDS[3]>>6)& 0x003f;
              hora=(RDS[3]>>12)& 0x000f;
              if(RDS[2]&1) hora+=16;
              hora+=i;        
              z=RDS[2]>>1;
              julian=z;
              
              if(RDS[1]&1) julian+=32768;
              if(RDS[1]&2) julian+=65536;
              #if DEBUG 
              Serial.print("_DATE_");
              Serial.print(" Juliano=");Serial.print(julian);
              sprintf(buffer," %02d:%02d ",hora,minuto); gotoXY(38,2);  LcdString(buffer); 
              Serial.println(buffer); 
              #endif            
              break;
              default:
              #if DEBUG 
              Serial.println("__"); 
              #endif    
              ;        
            }                        
          }                   
        } 
        
// The pins to use on the arduino
#define PIN_SCE   7
#define PIN_RESET 6
#define PIN_DC    5
#define PIN_SDIN  4
#define PIN_SCLK  3 

// COnfiguration for the LCD
#define LCD_C     LOW
#define LCD_D     HIGH
#define LCD_CMD   0

// Size of the LCD
#define LCD_X     84
#define LCD_Y     48

int scrollPosition = -10;

static const byte ASCII[][5] =
{
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c &#194;&#165;
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e &#195;&#162;&#194;&#134;&#194;&#144; 
//,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f &#195;&#162;&#194;&#134;&#194;&#146;
,{B11111111, B01111110, B00011000, B01111110, B11111111} //Stereo 127
};

void LcdCharacter(char character)
{
  unsigned char z,z1;
  
  z1=character - 0x20;
  LcdWrite(LCD_D, 0x00);
  for (int index = 0; index < 5; index++)
  {
    //para que funciona en proteus
    
    z=ASCII[z1][index];
    LcdWrite(LCD_D, z);
   // LcdWrite(LCD_D, ASCII[character - 0x20][index]);    
 }
 LcdWrite(LCD_D, 0x00);
}

void LcdCharacterX(char character)
{
  unsigned char z,z1;
  z1=character - 0x20;       
  LcdWrite(LCD_D, 0x00);
  for (int index = 0; index < 5; index++)
  {
     //para que funciona en proteus
     z=ASCII[z1][index];
     LcdWrite(LCD_D, z);
     LcdWrite(LCD_D, z);
    //LcdWrite(LCD_D, ASCII[character - 0x20][index]);
    //LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  }
  LcdWrite(LCD_D, 0x00);
}  

void LcdClear(void)
{
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    LcdWrite(LCD_D, 0x00);
  }
}

void LcdInitialise(void)
{
  pinMode(PIN_SCE,   OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC,    OUTPUT);
  pinMode(PIN_SDIN,  OUTPUT);
  pinMode(PIN_SCLK,  OUTPUT);
  
  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);
  
  LcdWrite(LCD_CMD, 0x21);  // LCD Extended Commands.
  LcdWrite(LCD_CMD, 0xB5);  // Set LCD Vop (Contrast). //B1
  LcdWrite(LCD_CMD, 0x04);  // Set Temp coefficent. //0x04
  LcdWrite(LCD_CMD, 0x14);  // LCD bias mode 1:48. //0x13
  LcdWrite(LCD_CMD, 0x0C);  // LCD in normal mode. 0x0d for inverse
  LcdWrite(LCD_C, 0x20);
  LcdWrite(LCD_C, 0x0C);
}

void LcdString(char *characters)
{
  while (*characters)
  {
    LcdCharacter(*characters++);
  }
}
void LcdStringX(char *characters)
{
  while (*characters)
  {
    LcdCharacterX(*characters++);
  }
} 

void LcdWrite(byte dc, byte data)
{
  digitalWrite(PIN_DC, dc);
  digitalWrite(PIN_SCE, LOW);
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
  digitalWrite(PIN_SCE, HIGH);
}

/**
 * gotoXY routine to position cursor
 * x - range: 0 to 84
 * y - range: 0 to 5
 */
 void gotoXY(int x, int y)
 {
  LcdWrite( 0, 0x80 | x);  // Column.
  LcdWrite( 0, 0x40 | y);  // Row.
}

void drawBox(void)
{
  int j;
  for(j = 0; j <= 84; j++) // top
  {
    gotoXY(j, 0);
    LcdWrite(1, 0x01);
  }     
  
  for(j = 0; j < 84; j++) //Bottom
  {
    gotoXY(j, 5);
    LcdWrite(1, 0x80);
  }     
  
  for(j = 0; j < 6; j++) // Right
  {
    gotoXY(83, j);
    LcdWrite(1, 0xff);
  }     
  
  for(j = 0; j < 6; j++) // Left
  {
    gotoXY(0, j);
    LcdWrite(1, 0xff);
  }
}

void Scroll(String message)
{
  for (int i = scrollPosition; i < scrollPosition + 11; i++)
  {
    if ((i >= message.length()) || (i < 0))
    {
      LcdCharacter(' ');
    }
    else	
    {
      LcdCharacter(message.charAt(i));
    }
  }
  scrollPosition++;
  if ((scrollPosition >= message.length()) && (scrollPosition > 0))
  {
    scrollPosition = -10;
  }
}

 

Aduard
Offline
Зарегистрирован: 18.09.2018

Сделал индикацию уровня сигнала , правда не антенка , а цифры.

otrazhenie
Offline
Зарегистрирован: 19.11.2019

как переделать код под TEA5767

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

Заинтересовал приемник,есть ли обновления?

 

otrazhenie
Offline
Зарегистрирован: 19.11.2019

заработал скетч под tea5767. вот моя версия с московскими радиостанциями.

хочется запилить туда RDS......

//FM Radio OLED Copyright by GhostLion v1.6 GOLD

#include <EEPROM.h>
#include <radio.h>
#include <TEA5767.h>

#include "U8glib.h"
#include "rus6x10.h"
#include "MyDigitsHelveticaBold24.h"

#define Pin_DOWN 4   // левая кнопка 
#define Pin_UP 2     // правая кнопка 
#define Pin_SET 3    // центральная кнопка
#define FIX_BAND 1

const uint8_t Radio [] U8G_PROGMEM = {0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0x40, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0xC0, 0x01, 0x80,0x00, 0x00, 0xC0, 0x01, 0x8E, 0x88, 0x00, 0xC0, 0x01, 0x88, 0xD8, 0x00, 
0xC0, 0x01, 0x88, 0xA8,0x00, 0xC0, 0x01, 0x8C, 0xA8, 0x00, 0xC0, 0x01, 0x88, 0xA8, 0x00, 0xC0, 0x01, 0x80, 0x00, 0x00,0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x81, 0x04, 0x10, 0x41, 0x05, 0x81, 0x04, 0x10, 
0x41,0x05, 0x95, 0x55, 0x55, 0x55, 0x55, 0x95, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80,0x00, 0x00, 
0xF8, 0x01, 0x80, 0x00, 0x03, 0xFE, 0x01, 0x80, 0x00, 0x07, 0x03, 0x01, 0x80, 0x00,0x0C, 0x01, 0x81, 0x80, 0x60, 0x18, 0x00, 0xC1, 0x81, 0xF8, 0x18, 0x00, 0x41, 0x83, 0x9C, 0x10,0x00, 0x61, 0x83, 0x0C, 0x30, 
0x00, 0x61, 0x83, 0x0C, 0x30, 0x00, 0x61, 0x83, 0x0C, 0x30, 0x00,0x61, 0x83, 0x9C, 0x10, 0x00, 0x61, 0x81, 0xF8, 0x18, 0x00, 0x41, 0x80, 0x60, 0x18, 0x00, 0xC1,0x80, 0x00, 0x0C, 0x01, 0x81, 0x80, 0x00, 0x07, 
0x03, 0x01, 0x80, 0x00, 0x03, 0xFE, 0x01, 0x80,0x00, 0x00, 0xF8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00,0x00, 0x00, 0x02, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC};

const uint8_t Volume[] U8G_PROGMEM = {0x7E, 0x42, 0x81, 0x81, 0x81, 0x81, 0xE7, 0xE7, 0x66, 0x66};
const uint8_t Bass[] U8G_PROGMEM = {0x7F, 0xFE, 0x80, 0x01, 0x9B, 0x8D, 0xA2, 0x51, 0xA3, 0x91, 0x9A, 0x4D, 0x8A, 0x45, 0xB3, 0x99,0x80, 0x01, 0x7F, 0xFE};
const uint8_t FM[] U8G_PROGMEM = {0x7F, 0xFE, 0x80, 0x01, 0x8C, 0x51, 0x90, 0xA9, 0x90, 0xA9, 0x98, 0xA9, 0x90, 0xA9, 0x90, 0x89,0x80, 0x01, 0x7F, 0xFE};
const uint8_t Stereo[] U8G_PROGMEM = {0x7F, 0xFE, 0x80, 0x01, 0x9B, 0xB9, 0xA1, 0x25, 0xA1, 0x39, 0x99, 0x31, 0x89, 0x29, 0xB1, 0x25,0x80, 0x01, 0x7F, 0xFE};
const uint8_t SM[] U8G_PROGMEM = {0x7F, 0xFE, 0x80, 0x01, 0x8C, 0x51, 0x90, 0xA9, 0x90, 0xA9, 0x8C, 0xA9, 0x84, 0xA9, 0x98, 0x89,0x80, 0x01, 0x7F, 0xFE};

const uint8_t Bat1[] U8G_PROGMEM = {0x7F, 0xFC, 0x80, 0x02, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,0x80, 0x02, 0x7F, 0xFC};
const uint8_t Bat2[] U8G_PROGMEM = {0x7F, 0xFC, 0x80, 0x02, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01, 0xA0, 0x01,0x80, 0x02, 0x7F, 0xFC};
const uint8_t Bat3[] U8G_PROGMEM = {0x7F, 0xFC, 0x80, 0x02, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01, 0xA8, 0x01,0x80, 0x02, 0x7F, 0xFC};
const uint8_t Bat4[] U8G_PROGMEM = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01, 0xAA, 0x01,0x80, 0x02, 0x7F, 0xFC};
const uint8_t Bat5[] U8G_PROGMEM = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81, 0xAA, 0x81,0x80, 0x02, 0x7F, 0xFC};
const uint8_t Bat6[] U8G_PROGMEM = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1, 0xAA, 0xA1,0x80, 0x02, 0x7F, 0xFC};
const uint8_t Bat7[] U8G_PROGMEM = {0x7F, 0xFC, 0x80, 0x02, 0xAA, 0xA9, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xAD, 0xAA, 0xA9,0x80, 0x02, 0x7F, 0xFC};

const uint8_t Vol1[] U8G_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x60, 0x00, 0x60, 0x00};
const uint8_t Vol2[] U8G_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00,0x6C, 0x00, 0x6C, 0x00};
const uint8_t Vol3[] U8G_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x0D, 0x80, 0x0D, 0x80,0x6D, 0x80, 0x6D, 0x80};
const uint8_t Vol4[] U8G_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x01, 0xB0, 0x01, 0xB0, 0x0D, 0xB0, 0x0D, 0xB0,0x6D, 0xB0, 0x6D, 0xB0};
const uint8_t Vol5[] U8G_PROGMEM = {0x00, 0x06, 0x00, 0x06, 0x00, 0x36, 0x00, 0x36, 0x01, 0xB6, 0x01, 0xB6, 0x0D, 0xB6, 0x0D, 0xB6,0x6D, 0xB6, 0x6D, 0xB6};

byte v,k,m,rs, flag1=1,flag2=0,flag3=0;
int Voltage;
unsigned int s,s2;
boolean b,ms,sm,flag=1,MODE=1;
long TimeOut;

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
TEA5767 radio; 

void setup()
{
pinMode(Pin_DOWN,INPUT_PULLUP);
pinMode(Pin_UP,INPUT_PULLUP);
pinMode(Pin_SET,INPUT_PULLUP); 

Inicial();
}

void loop()
{
Parsing();
Menu();
Energy();  
}
//==============================================
void Inicial()
{
 u8g.firstPage();  
do {
  u8g.drawBitmapP (5, 16, 5, 40, Radio);
  u8g.setFont(rus6x10);
  u8g.setPrintPos(40,11);u8g.print(F("FM РАДИО"));
  u8g.setPrintPos(55,45);u8g.print(F("v 1.6 GOLD"));
  u8g.setPrintPos(55,55);u8g.print(F("By GhostLion"));  
   }
while( u8g.nextPage() );

delay(1500);
if (EEPROM[0]!=1)
    {
     EEPROM[0]=1;
     EEPROM[1]=5;
     EEPROM[2]=30; // здесь установить номер текущего канала (моя частота 98.90 "Русское радио") (или 0)
     EEPROM[3]=1;
     EEPROM[4]=1;
     EEPROM[5]=0;
     EEPROM[6]=107;  // частота текущей радиостанции
     EEPROM[7]=40;  // "Хит FM"
     EEPROM[8]=1;
    }
v  = EEPROM[1];               // громкость
k  = EEPROM[2];               // текущий канал
m  = EEPROM[3];               // текущее меню
b  = EEPROM[4];               // супербасс
ms = EEPROM[5];               // моно/стерео
s  = EEPROM[6]*100+EEPROM[7]; // текущая частота
sm = EEPROM[8];               // softmute
s2=s;
radio.init();
radio.setVolume(v);
radio.setMono(ms);
radio.setMute(false);
radio.setBassBoost(b);
radio.setSoftMute(sm);  
radio.setBandFrequency(FIX_BAND, s);
readVcc();
}
//================================================
void Parsing()
{
boolean SET=digitalRead(Pin_SET);
boolean UP=digitalRead(Pin_UP);
boolean DOWN=digitalRead(Pin_DOWN);

if(SET==HIGH && flag1==0)
  {
    flag1=1;
  }
if(SET==LOW && flag1==1)
  {
    flag1=0;
    TimeOut=millis();
    if(MODE==1) {m++; flag=1; if(m>7) m=1;}
  }
  
 if(UP==LOW && flag2==1)
  {
    flag2=0;
  }
   if(UP==HIGH && flag2==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==15?0:v++); radio.setVolume(v); break; }
        case 2:{ b = 1; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ ms = 0; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{sm = 1; radio.setSoftMute(true);radio.setBandFrequency(FIX_BAND,s); break;}
        case 5:{ radio.seekUp(true); delay(3000); s = radio.getFrequency(); Kanal(); break; }
        case 6:{ s=s+10; if (s > 10800) s = 8700; delay(100); radio.setBandFrequency(FIX_BAND,s);Kanal(); break; }
        case 7:{ k++; if (k>31) k=1; Frequency(); radio.setBandFrequency(FIX_BAND,s); break;}
      }
   flag=1;
   TimeOut=millis();
    }
   else {(v==15?0:v++);radio.setVolume(v);}
   flag2=1;
   }
   if(DOWN==LOW && flag3==1)
  {
    flag3=0;
  }
   if(DOWN==HIGH && flag3==0)
   {
    if(MODE==1)
    {
    switch(m)
      {
        case 1:{ (v==0?15:v--); radio.setVolume(v); break; }
        case 2:{ b = 0; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
        case 3:{ ms = 1; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
        case 4:{sm = 0; radio.setSoftMute(false);radio.setBandFrequency(FIX_BAND,s); break;}
        case 5:{ radio.seekDown(true); delay(3000); s=radio.getFrequency(); Kanal(); break; }
        case 6:{ s=s-10; if (s<8700) s=10800; delay(100); radio.setBandFrequency(FIX_BAND,s); Kanal(); break; }
        case 7:{ k--; if (k<1) k=23; Frequency(); radio.setBandFrequency(FIX_BAND,s); break;}
      }
   flag=1;
   TimeOut=millis();
   }
   else {(v==0?15:v--);radio.setVolume(v);}
   flag3=1;
  }
}
//================================================
void Menu()
{
float ch;
if(flag==1 && MODE==1)
{
//rs = radio.getRSSI();   
ch=float(s)/100; 
u8g.firstPage();  
do {
u8g.setDefaultForegroundColor();
if(Voltage>85) u8g.drawBitmapP (110, 0, 2, 10, Bat7);
  else if(Voltage>70) u8g.drawBitmapP (110, 0, 2, 10, Bat6);
  else if(Voltage>55) u8g.drawBitmapP (110, 0, 2, 10, Bat5);
  else if(Voltage>40) u8g.drawBitmapP (110, 0, 2, 10, Bat4);
  else if(Voltage>25) u8g.drawBitmapP (110, 0, 2, 10, Bat3);
  else if(Voltage>10) u8g.drawBitmapP (110, 0, 2, 10, Bat2);
  else u8g.drawBitmapP (110, 0, 2, 10, Bat1);
u8g.drawBitmapP (0, 0, 1, 10, Volume);
if(v<3) u8g.drawBitmapP (13, 0, 2, 10, Vol1);
  else if(v<7) u8g.drawBitmapP (13, 0, 2, 10, Vol2);
  else if(v<10) u8g.drawBitmapP (13, 0, 2, 10, Vol3);
  else if(v<13) u8g.drawBitmapP (13, 0, 2, 10, Vol4);
  else u8g.drawBitmapP (13, 0, 2, 10, Vol5);
if(ms==0) u8g.drawBitmapP (55, 0, 2, 10, Stereo);
if(b==1) u8g.drawBitmapP (75, 0, 2, 10, Bass);
if(sm==1) u8g.drawBitmapP (35, 0, 2, 10, SM);

u8g.setFont(MyDigitsHelveticaBold24);
if(ch<100) u8g.setPrintPos(30,43); else u8g.setPrintPos(23,43);
u8g.print(ch,1);
u8g.setFont(rus6x10);
u8g.print(" MHz");
if (rs>43) u8g.drawBitmapP (0, 16, 2, 10, FM); 
if(k!=0){
    u8g.drawRFrame (0,32,18,13,2);
    u8g.setPrintPos(3,42);
    if(k<10) u8g.print("0");
    u8g.print(k);
        }
u8g.drawRFrame (0,51,127,12,3);
u8g.setPrintPos(13,61);
 switch(m)
 {
  case 1: {u8g.print(F("- < ГРОМКОСТЬ > +"));break;}
  case 2: {u8g.print(F(" НЕТ < БАСС > ДА"));break;}
  case 3: {u8g.print(F("НЕТ < СТЕРЕО > ДА"));break;}
  case 4: {u8g.print(F("НЕТ < S.MUTE > ДА"));break;}
  case 5: {u8g.print(F(" <  АВТОПОИСК  >"));break;}
  case 6: {u8g.print(F("<  РУЧ. ПОИСК  >"));break;}
  case 7: {u8g.print(F("  <  КАНАЛЫ  >"));break;}
 
 }


}
while( u8g.nextPage() );     
  flag=0;    
}
}
//================================================
void Energy()
{
 if(MODE==1 && millis()-TimeOut>2000) flag=1;
 if(MODE==1 && millis()-TimeOut>8000)
  {
    u8g.sleepOn(); 
    MODE=0;
    if(v!= EEPROM[1]) EEPROM[1] = v;
    if(k!= EEPROM[2]) EEPROM[2] = k;
    if(m!= EEPROM[3]) EEPROM[3] = m;
    if(b!= EEPROM[4]) EEPROM[4] = b;
    if(ms!=EEPROM[5]) EEPROM[5] = ms;
    if(s2!=s){s2=s;   EEPROM[6] = int(s/100); 
                      EEPROM[7] = s%100;
             }
    if(sm!=EEPROM[8]) EEPROM[8] = sm;         
  }
  if(MODE==0 && millis()-TimeOut<500)
  {
    u8g.sleepOff(); 
    readVcc();
    MODE = 1; 
    flag = 1; 
    m = 7;
  }
}
//===================================================
void readVcc() 
{
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring
  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both
  long result = (high << 8) | low;

  result = 1.080 * 1023 * 1000 / result; // расчёт реального VCC
  Voltage = int(result);
  Voltage = map(Voltage, 3200, 4200, 0, 100);
  Voltage = constrain(Voltage, 0, 100);
}
//=======================================================
void Kanal()
{
  switch (s)
  {
    case 8750 : k=1;break;
    case 8790 : k=2;break;
    case 8830 : k=3;break;
    case 8870 : k=4;break;
    case 8910 : k=5;break;
    case 8950 : k=6;break;
    case 9030 : k=7;break;
    case 9080 : k=8;break;
    case 9120 : k=9;break;
    case 9240 : k=10;break;
    case 9560 : k=11;break;
    case 9600 : k=12;break;
    case 9640 : k=13;break;
    case 9760 : k=14;break;
    case 9880 : k=15;break;
    case 10010: k=16;break;
    case 10050: k=17;break;
    case 10120: k=18;break;
    case 10170: k=19;break;
    case 10210: k=20;break;
    case 10250: k=21;break;
    case 10370: k=22;break;
    case 10420: k=23;break;
    case 10470: k=24;break;
    case 10520: k=25;break;
    case 10570: k=26;break;
    case 10620: k=27;break;
    case 10660: k=28;break;
    case 10700: k=29;break;
    case 10740: k=30;break;
    case 10780: k=31;break;
    default: k=0;
    
  }
}
//==========================================================
void Frequency()
{
 switch(k)
  {
    case 1 :{s=8750;break;}
    case 2 :{s=8790;break;}
    case 3 :{s=8830;break;}
    case 4 :{s=8870;break;}
    case 5 :{s=8910;break;}
    case 6 :{s=8950;break;}
    case 7 :{s=9030;break;}
    case 8 :{s=9080;break;}
    case 9 :{s=9120;break;}
    case 10 :{s=9240;break;}
    case 11 :{s=9560;break;}
    case 12 :{s=9600;break;}
    case 13 :{s=9640;break;}
    case 14 :{s=9760;break;}
    case 15 :{s=9880;break;}
    case 16 :{s=10010;break;}
    case 17 :{s=10050;break;}
    case 18 :{s=10120;break;}
    case 19 :{s=10170;break;}
    case 20 :{s=10210;break;}
    case 21 :{s=10250;break;}
    case 22 :{s=10370;break;}
    case 23 :{s=10420;break;}
    case 24 :{s=10470;break;}
    case 25 :{s=10520;break;}
    case 26 :{s=10570;break;}
    case 27 :{s=10620;break;}
    case 28 :{s=10660;break;}
    case 29 :{s=10700;break;}
    case 30 :{s=10740;break;}
    case 31 :{s=10780;break;}
  } 
}

 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

otrazhenie пишет:

заработал скетч под tea5767. 

хочется запилить туда RDS.....

Забуть, у 5767 нет RDS, тока у 5807 есть

b707
Offline
Зарегистрирован: 26.05.2017

otrazhenie пишет:

заработал скетч под tea5767. вот моя версия с московскими радиостанциями.

хочется запилить туда RDS......

//FM Radio OLED Copyright by GhostLion v1.6 GOLD
//=======================================================
void Kanal()
{
  switch (s)
  {
    case 8750 : k=1;break;
    case 8790 : k=2;break;
    case 8830 : k=3;break;
    case 8870 : k=4;break;
    case 8910 : k=5;break;
    case 8950 : k=6;break;
    case 9030 : k=7;break;
    case 9080 : k=8;break;
    case 9120 : k=9;break;
    case 9240 : k=10;break;
    case 9560 : k=11;break;
    case 9600 : k=12;break;
    case 9640 : k=13;break;
    case 9760 : k=14;break;
    case 9880 : k=15;break;
    case 10010: k=16;break;
    case 10050: k=17;break;
    case 10120: k=18;break;
    case 10170: k=19;break;
    case 10210: k=20;break;
    case 10250: k=21;break;
    case 10370: k=22;break;
    case 10420: k=23;break;
    case 10470: k=24;break;
    case 10520: k=25;break;
    case 10570: k=26;break;
    case 10620: k=27;break;
    case 10660: k=28;break;
    case 10700: k=29;break;
    case 10740: k=30;break;
    case 10780: k=31;break;
    default: k=0;
    
  }
}
//==========================================================
void Frequency()
{
 switch(k)
  {
    case 1 :{s=8750;break;}
    case 2 :{s=8790;break;}
    case 3 :{s=8830;break;}
    case 4 :{s=8870;break;}
    case 5 :{s=8910;break;}
    case 6 :{s=8950;break;}
    case 7 :{s=9030;break;}
    case 8 :{s=9080;break;}
    case 9 :{s=9120;break;}
    case 10 :{s=9240;break;}
    case 11 :{s=9560;break;}
    case 12 :{s=9600;break;}
    case 13 :{s=9640;break;}
    case 14 :{s=9760;break;}
    case 15 :{s=9880;break;}
    case 16 :{s=10010;break;}
    case 17 :{s=10050;break;}
    case 18 :{s=10120;break;}
    case 19 :{s=10170;break;}
    case 20 :{s=10210;break;}
    case 21 :{s=10250;break;}
    case 22 :{s=10370;break;}
    case 23 :{s=10420;break;}
    case 24 :{s=10470;break;}
    case 25 :{s=10520;break;}
    case 26 :{s=10570;break;}
    case 27 :{s=10620;break;}
    case 28 :{s=10660;break;}
    case 29 :{s=10700;break;}
    case 30 :{s=10740;break;}
    case 31 :{s=10780;break;}
  } 
}

 

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

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

b707 пишет:

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

если код по строкам продавать, как индусы, то так дороже выходит. :) 

otrazhenie
Offline
Зарегистрирован: 19.11.2019

b707 пишет:

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

не нравится код? а покажи свой " правильный"

тогда и посмотрим чей код лучше....авторский  код работает...а вот Ваш....под вопросом пока

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

просто аффтар - махровый непрофессионал или индус.