Карманное 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. 

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

2.

Все данные по пректу в архиве: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.

 

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

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

01#include <Wire.h>
02 
03#define Pin_DOWN 12//4   // левая кнопка
04#define Pin_UP 13//2     // правая кнопка
05#define Pin_SET 11//3    // центральная кнопка
06const byte channel=5;
07byte Byte0;
08byte val = 0;
09byte volume = 4;
10int freq=1011;
11void setup()
12{
13   pinMode(Pin_DOWN,INPUT_PULLUP);
14   pinMode(Pin_UP,INPUT_PULLUP);
15   pinMode(Pin_SET,INPUT_PULLUP);
16   Wire.begin(); // подключение к шине i2c
17   delay(500);
18   Inicial();
19}
20 
21void loop()
22{
23boolean SET=digitalRead(Pin_SET);
24boolean UP=digitalRead(Pin_UP);
25boolean DOWN=digitalRead(Pin_DOWN);
26if(DOWN==LOW)
27  {
28   volume=volume+1; set_vol();delay(500);
29    //freq=freq+1; set_freq();delay(500);//работает норм
30  }
31if(SET==LOW)
32  {
33    volume=volume-1; set_vol();delay(500);
34    //freq=freq-1;set_freq();delay(500); //работает норм
35  }
36if(UP==LOW)
37  {
38   stby();//выключаем радио ,потребление почти 0
39    
40   delay(1500);//ждем 1,5 сек и вкл
41   set_freq();      // вкл радио
42  }
43}  
44void Inicial()
45{  
46   Wire.beginTransmission(0x10); // передача для устройства
47   //02                            // адрес устройства указывается в документации (datasheet)
48   Wire.write(0B11010000);             // отправка байта
49   Wire.write(0B10000001);
50   //03
51   Byte0 = freq - 870;
52   Wire.write(Byte0);
53   Byte0=0B00010011;
54   Wire.write(Byte0);
55   //04
56   Wire.write(0B00010000);
57   Wire.write(0B00000000);
58   //05
59   Wire.write(0B10001000);
60   Byte0=0B10000000 + volume;
61   Wire.write(Byte0);
62   Wire.endTransmission();     // передача данных
63}
64void set_freq()//установка частоты
65{  
66   if (freq > 1080) freq = 870;
67   if (freq < 880) freq = 1080;
68   Wire.beginTransmission(0x10); // передача для устройства
69   //02                            // адрес устройства указывается в документации (datasheet)
70   Wire.write(0B11010000);             // отправка байта
71   Wire.write(0B10000001);
72   //03
73   Byte0 = freq - 870;
74   Wire.write(Byte0);//частота,старшие 8 бит
75   Byte0=0B00010011;//7,6-мл биты частоты=всегда 00 так как шаг=25, 4-точная установка,3,2-диапазон=87-108,1,0-шаг 25 кгц
76   Wire.write(Byte0);
77   Wire.endTransmission();     // передача данных
78}
79void set_vol()//установка громкости
80{  
81   if (volume > 200) volume = 0;
82   if (volume >15) volume = 15;
83   Wire.beginTransmission(0x11); // передача для устройства
84   //02                            // адрес устройства указывается в документации (datasheet)
85   Wire.write(0B00000101);             // отправка байта val
86  //05
87   Wire.write(0B10001000);
88   Byte0=0B10000000 + volume;
89   Wire.write(Byte0);
90   Wire.endTransmission();     // передача данных
91}
92void stby()
93{
94 Wire.beginTransmission(0x10);      // выкл радио
95  //02                            // адрес устройства указывается в документации (datasheet)
96   Wire.write(0B11010000);             // отправка байта val
97   Wire.write(0B10000000);
98  Wire.endTransmission();     // передача данных
99}

 

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 аватар
Offline
Зарегистрирован: 25.01.2017

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

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

GhostLion пишет:

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

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

Forthomo
Forthomo аватар
Offline
Зарегистрирован: 10.04.2019
01Так правильно?
02void Kanal()
03{
04  switch (s)
05  {
06    case 8750 : k=1;break; //Бизнес ФМ
07    case 8830 : k=2;break; //Ретро ФМ
08    case 8910 : k=3;break; //Радио Джаз
09    case 8950 : k=4;break; //Мегаполис ФМ
10    case 8990 : k=5;break; //Страна ФМ
11    case 9030 : k=6;break; //Авторадио
12    case 9080 : k=7;break; //Релакс ФМ
13    case 9120 : k=8;break; //Эхо Москвы
14    case 9890 : k=9;break; //Радио Культура
15    case 9360 : k=10;break; //Коммерсант ФМ
16    case 9560: k=11;break; //Радио Звезда
17    case 9600: k=12;break; //Дорожное радио
18    case 9720: k=13;break; //Радио КП
19    case 9920: k=14;break; //Радио Романтика
20    case 9960: k=15;break; //Радио Орфей
21    case 10010: k=16;break; //Серебряный дождь
22    case 10170: k=17;break; //Наше радио
23    case 10250: k=18;break; //Камеди Радио
24    case 10300: k=19;break; //Радио Шансон
25    case 10500: k=20;break; //Радио Книга
26    case 10570: k=21;break; //Русское радио
27    case 10740: k=22;break; //Хит ФМ
28    case 10780: k=23;break; //Милицейская волна
29    default: k=0;
30     
31  }
32}
33//==========================================================
34void Frequency()
35{
36 switch(k)
37  {
38    case 1 :{s=8750;break;}
39    case 2 :{s=8830;break;}
40    case 3 :{s=8910;break;}
41    case 4 :{s=8950;break;}
42    case 5 :{s=8990;break;}
43    case 6 :{s=9030;break;}
44    case 7 :{s=9080;break;}
45    case 8 :{s=9120;break;}
46    case 9 :{s=9890;break;}
47    case 10 :{s=9360;break;}
48    case 11 :{s=9560;break;}
49    case 12 :{s=9600;break;}
50    case 13 :{s=9720;break;}
51    case 14 :{s=9920;break;}
52    case 15 :{s=9960;break;}
53    case 16 :{s=10010;break;}
54    case 17 :{s=10170;break;}
55    case 18 :{s=10250;break;}
56    case 19 :{s=10300;break;}
57    case 20 :{s=10500;break;}
58    case 21 :{s=10570;break;}
59    case 22 :{s=10740;break;}
60    case 23 :{s=10780;break;}
61  }
62}

 

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 индикацию  уровня сигнала (антенка вместо наушников). Сам слаб в програмировании, а вот готовый скетч с такой функцией имеется.

 

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

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

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

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

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

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

 

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

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

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

001//FM Radio OLED Copyright by GhostLion v1.6 GOLD
002 
003#include <EEPROM.h>
004#include <radio.h>
005#include <TEA5767.h>
006 
007#include "U8glib.h"
008#include "rus6x10.h"
009#include "MyDigitsHelveticaBold24.h"
010 
011#define Pin_DOWN 4   // левая кнопка
012#define Pin_UP 2     // правая кнопка
013#define Pin_SET 3    // центральная кнопка
014#define FIX_BAND 1
015 
016const 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,
0170xC0, 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,
0180x41,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,
0190xF8, 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,
0200x00, 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,
0210x03, 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};
022 
023const uint8_t Volume[] U8G_PROGMEM = {0x7E, 0x42, 0x81, 0x81, 0x81, 0x81, 0xE7, 0xE7, 0x66, 0x66};
024const 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};
025const 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};
026const 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};
027const 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};
028 
029const 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};
030const 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};
031const 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};
032const 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};
033const 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};
034const 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};
035const 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};
036 
037const 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};
038const 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};
039const 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};
040const 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};
041const 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};
042 
043byte v,k,m,rs, flag1=1,flag2=0,flag3=0;
044int Voltage;
045unsigned int s,s2;
046boolean b,ms,sm,flag=1,MODE=1;
047long TimeOut;
048 
049U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
050TEA5767 radio;
051 
052void setup()
053{
054pinMode(Pin_DOWN,INPUT_PULLUP);
055pinMode(Pin_UP,INPUT_PULLUP);
056pinMode(Pin_SET,INPUT_PULLUP);
057 
058Inicial();
059}
060 
061void loop()
062{
063Parsing();
064Menu();
065Energy(); 
066}
067//==============================================
068void Inicial()
069{
070 u8g.firstPage(); 
071do {
072  u8g.drawBitmapP (5, 16, 5, 40, Radio);
073  u8g.setFont(rus6x10);
074  u8g.setPrintPos(40,11);u8g.print(F("FM РАДИО"));
075  u8g.setPrintPos(55,45);u8g.print(F("v 1.6 GOLD"));
076  u8g.setPrintPos(55,55);u8g.print(F("By GhostLion")); 
077   }
078while( u8g.nextPage() );
079 
080delay(1500);
081if (EEPROM[0]!=1)
082    {
083     EEPROM[0]=1;
084     EEPROM[1]=5;
085     EEPROM[2]=30; // здесь установить номер текущего канала (моя частота 98.90 "Русское радио") (или 0)
086     EEPROM[3]=1;
087     EEPROM[4]=1;
088     EEPROM[5]=0;
089     EEPROM[6]=107;  // частота текущей радиостанции
090     EEPROM[7]=40;  // "Хит FM"
091     EEPROM[8]=1;
092    }
093v  = EEPROM[1];               // громкость
094k  = EEPROM[2];               // текущий канал
095m  = EEPROM[3];               // текущее меню
096b  = EEPROM[4];               // супербасс
097ms = EEPROM[5];               // моно/стерео
098s  = EEPROM[6]*100+EEPROM[7]; // текущая частота
099sm = EEPROM[8];               // softmute
100s2=s;
101radio.init();
102radio.setVolume(v);
103radio.setMono(ms);
104radio.setMute(false);
105radio.setBassBoost(b);
106radio.setSoftMute(sm); 
107radio.setBandFrequency(FIX_BAND, s);
108readVcc();
109}
110//================================================
111void Parsing()
112{
113boolean SET=digitalRead(Pin_SET);
114boolean UP=digitalRead(Pin_UP);
115boolean DOWN=digitalRead(Pin_DOWN);
116 
117if(SET==HIGH && flag1==0)
118  {
119    flag1=1;
120  }
121if(SET==LOW && flag1==1)
122  {
123    flag1=0;
124    TimeOut=millis();
125    if(MODE==1) {m++; flag=1; if(m>7) m=1;}
126  }
127   
128 if(UP==LOW && flag2==1)
129  {
130    flag2=0;
131  }
132   if(UP==HIGH && flag2==0)
133   {
134    if(MODE==1)
135    {
136    switch(m)
137      {
138        case 1:{ (v==15?0:v++); radio.setVolume(v); break; }
139        case 2:{ b = 1; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
140        case 3:{ ms = 0; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
141        case 4:{sm = 1; radio.setSoftMute(true);radio.setBandFrequency(FIX_BAND,s); break;}
142        case 5:{ radio.seekUp(true); delay(3000); s = radio.getFrequency(); Kanal(); break; }
143        case 6:{ s=s+10; if (s > 10800) s = 8700; delay(100); radio.setBandFrequency(FIX_BAND,s);Kanal(); break; }
144        case 7:{ k++; if (k>31) k=1; Frequency(); radio.setBandFrequency(FIX_BAND,s); break;}
145      }
146   flag=1;
147   TimeOut=millis();
148    }
149   else {(v==15?0:v++);radio.setVolume(v);}
150   flag2=1;
151   }
152   if(DOWN==LOW && flag3==1)
153  {
154    flag3=0;
155  }
156   if(DOWN==HIGH && flag3==0)
157   {
158    if(MODE==1)
159    {
160    switch(m)
161      {
162        case 1:{ (v==0?15:v--); radio.setVolume(v); break; }
163        case 2:{ b = 0; radio.setBassBoost(b); radio.setBandFrequency(FIX_BAND,s); break; }
164        case 3:{ ms = 1; radio.setMono(ms); radio.setBandFrequency(FIX_BAND,s); break; }
165        case 4:{sm = 0; radio.setSoftMute(false);radio.setBandFrequency(FIX_BAND,s); break;}
166        case 5:{ radio.seekDown(true); delay(3000); s=radio.getFrequency(); Kanal(); break; }
167        case 6:{ s=s-10; if (s<8700) s=10800; delay(100); radio.setBandFrequency(FIX_BAND,s); Kanal(); break; }
168        case 7:{ k--; if (k<1) k=23; Frequency(); radio.setBandFrequency(FIX_BAND,s); break;}
169      }
170   flag=1;
171   TimeOut=millis();
172   }
173   else {(v==0?15:v--);radio.setVolume(v);}
174   flag3=1;
175  }
176}
177//================================================
178void Menu()
179{
180float ch;
181if(flag==1 && MODE==1)
182{
183//rs = radio.getRSSI();  
184ch=float(s)/100;
185u8g.firstPage(); 
186do {
187u8g.setDefaultForegroundColor();
188if(Voltage>85) u8g.drawBitmapP (110, 0, 2, 10, Bat7);
189  else if(Voltage>70) u8g.drawBitmapP (110, 0, 2, 10, Bat6);
190  else if(Voltage>55) u8g.drawBitmapP (110, 0, 2, 10, Bat5);
191  else if(Voltage>40) u8g.drawBitmapP (110, 0, 2, 10, Bat4);
192  else if(Voltage>25) u8g.drawBitmapP (110, 0, 2, 10, Bat3);
193  else if(Voltage>10) u8g.drawBitmapP (110, 0, 2, 10, Bat2);
194  else u8g.drawBitmapP (110, 0, 2, 10, Bat1);
195u8g.drawBitmapP (0, 0, 1, 10, Volume);
196if(v<3) u8g.drawBitmapP (13, 0, 2, 10, Vol1);
197  else if(v<7) u8g.drawBitmapP (13, 0, 2, 10, Vol2);
198  else if(v<10) u8g.drawBitmapP (13, 0, 2, 10, Vol3);
199  else if(v<13) u8g.drawBitmapP (13, 0, 2, 10, Vol4);
200  else u8g.drawBitmapP (13, 0, 2, 10, Vol5);
201if(ms==0) u8g.drawBitmapP (55, 0, 2, 10, Stereo);
202if(b==1) u8g.drawBitmapP (75, 0, 2, 10, Bass);
203if(sm==1) u8g.drawBitmapP (35, 0, 2, 10, SM);
204 
205u8g.setFont(MyDigitsHelveticaBold24);
206if(ch<100) u8g.setPrintPos(30,43); else u8g.setPrintPos(23,43);
207u8g.print(ch,1);
208u8g.setFont(rus6x10);
209u8g.print(" MHz");
210if (rs>43) u8g.drawBitmapP (0, 16, 2, 10, FM);
211if(k!=0){
212    u8g.drawRFrame (0,32,18,13,2);
213    u8g.setPrintPos(3,42);
214    if(k<10) u8g.print("0");
215    u8g.print(k);
216        }
217u8g.drawRFrame (0,51,127,12,3);
218u8g.setPrintPos(13,61);
219 switch(m)
220 {
221  case 1: {u8g.print(F("- < ГРОМКОСТЬ > +"));break;}
222  case 2: {u8g.print(F(" НЕТ < БАСС > ДА"));break;}
223  case 3: {u8g.print(F("НЕТ < СТЕРЕО > ДА"));break;}
224  case 4: {u8g.print(F("НЕТ < S.MUTE > ДА"));break;}
225  case 5: {u8g.print(F(" <  АВТОПОИСК  >"));break;}
226  case 6: {u8g.print(F("<  РУЧ. ПОИСК  >"));break;}
227  case 7: {u8g.print(F("  <  КАНАЛЫ  >"));break;}
228  
229 }
230 
231 
232}
233while( u8g.nextPage() );    
234  flag=0;   
235}
236}
237//================================================
238void Energy()
239{
240 if(MODE==1 && millis()-TimeOut>2000) flag=1;
241 if(MODE==1 && millis()-TimeOut>8000)
242  {
243    u8g.sleepOn();
244    MODE=0;
245    if(v!= EEPROM[1]) EEPROM[1] = v;
246    if(k!= EEPROM[2]) EEPROM[2] = k;
247    if(m!= EEPROM[3]) EEPROM[3] = m;
248    if(b!= EEPROM[4]) EEPROM[4] = b;
249    if(ms!=EEPROM[5]) EEPROM[5] = ms;
250    if(s2!=s){s2=s;   EEPROM[6] = int(s/100);
251                      EEPROM[7] = s%100;
252             }
253    if(sm!=EEPROM[8]) EEPROM[8] = sm;        
254  }
255  if(MODE==0 && millis()-TimeOut<500)
256  {
257    u8g.sleepOff();
258    readVcc();
259    MODE = 1;
260    flag = 1;
261    m = 7;
262  }
263}
264//===================================================
265void readVcc()
266{
267#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
268  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
269#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
270  ADMUX = _BV(MUX5) | _BV(MUX0);
271#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
272  ADMUX = _BV(MUX3) | _BV(MUX2);
273#else
274  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
275#endif
276  delay(2); // Wait for Vref to settle
277  ADCSRA |= _BV(ADSC); // Start conversion
278  while (bit_is_set(ADCSRA, ADSC)); // measuring
279  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
280  uint8_t high = ADCH; // unlocks both
281  long result = (high << 8) | low;
282 
283  result = 1.080 * 1023 * 1000 / result; // расчёт реального VCC
284  Voltage = int(result);
285  Voltage = map(Voltage, 3200, 4200, 0, 100);
286  Voltage = constrain(Voltage, 0, 100);
287}
288//=======================================================
289void Kanal()
290{
291  switch (s)
292  {
293    case 8750 : k=1;break;
294    case 8790 : k=2;break;
295    case 8830 : k=3;break;
296    case 8870 : k=4;break;
297    case 8910 : k=5;break;
298    case 8950 : k=6;break;
299    case 9030 : k=7;break;
300    case 9080 : k=8;break;
301    case 9120 : k=9;break;
302    case 9240 : k=10;break;
303    case 9560 : k=11;break;
304    case 9600 : k=12;break;
305    case 9640 : k=13;break;
306    case 9760 : k=14;break;
307    case 9880 : k=15;break;
308    case 10010: k=16;break;
309    case 10050: k=17;break;
310    case 10120: k=18;break;
311    case 10170: k=19;break;
312    case 10210: k=20;break;
313    case 10250: k=21;break;
314    case 10370: k=22;break;
315    case 10420: k=23;break;
316    case 10470: k=24;break;
317    case 10520: k=25;break;
318    case 10570: k=26;break;
319    case 10620: k=27;break;
320    case 10660: k=28;break;
321    case 10700: k=29;break;
322    case 10740: k=30;break;
323    case 10780: k=31;break;
324    default: k=0;
325     
326  }
327}
328//==========================================================
329void Frequency()
330{
331 switch(k)
332  {
333    case 1 :{s=8750;break;}
334    case 2 :{s=8790;break;}
335    case 3 :{s=8830;break;}
336    case 4 :{s=8870;break;}
337    case 5 :{s=8910;break;}
338    case 6 :{s=8950;break;}
339    case 7 :{s=9030;break;}
340    case 8 :{s=9080;break;}
341    case 9 :{s=9120;break;}
342    case 10 :{s=9240;break;}
343    case 11 :{s=9560;break;}
344    case 12 :{s=9600;break;}
345    case 13 :{s=9640;break;}
346    case 14 :{s=9760;break;}
347    case 15 :{s=9880;break;}
348    case 16 :{s=10010;break;}
349    case 17 :{s=10050;break;}
350    case 18 :{s=10120;break;}
351    case 19 :{s=10170;break;}
352    case 20 :{s=10210;break;}
353    case 21 :{s=10250;break;}
354    case 22 :{s=10370;break;}
355    case 23 :{s=10420;break;}
356    case 24 :{s=10470;break;}
357    case 25 :{s=10520;break;}
358    case 26 :{s=10570;break;}
359    case 27 :{s=10620;break;}
360    case 28 :{s=10660;break;}
361    case 29 :{s=10700;break;}
362    case 30 :{s=10740;break;}
363    case 31 :{s=10780;break;}
364  }
365}

 

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

otrazhenie пишет:

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

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

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

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

otrazhenie пишет:

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

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

01//FM Radio OLED Copyright by GhostLion v1.6 GOLD
02//=======================================================
03void Kanal()
04{
05  switch (s)
06  {
07    case 8750 : k=1;break;
08    case 8790 : k=2;break;
09    case 8830 : k=3;break;
10    case 8870 : k=4;break;
11    case 8910 : k=5;break;
12    case 8950 : k=6;break;
13    case 9030 : k=7;break;
14    case 9080 : k=8;break;
15    case 9120 : k=9;break;
16    case 9240 : k=10;break;
17    case 9560 : k=11;break;
18    case 9600 : k=12;break;
19    case 9640 : k=13;break;
20    case 9760 : k=14;break;
21    case 9880 : k=15;break;
22    case 10010: k=16;break;
23    case 10050: k=17;break;
24    case 10120: k=18;break;
25    case 10170: k=19;break;
26    case 10210: k=20;break;
27    case 10250: k=21;break;
28    case 10370: k=22;break;
29    case 10420: k=23;break;
30    case 10470: k=24;break;
31    case 10520: k=25;break;
32    case 10570: k=26;break;
33    case 10620: k=27;break;
34    case 10660: k=28;break;
35    case 10700: k=29;break;
36    case 10740: k=30;break;
37    case 10780: k=31;break;
38    default: k=0;
39     
40  }
41}
42//==========================================================
43void Frequency()
44{
45 switch(k)
46  {
47    case 1 :{s=8750;break;}
48    case 2 :{s=8790;break;}
49    case 3 :{s=8830;break;}
50    case 4 :{s=8870;break;}
51    case 5 :{s=8910;break;}
52    case 6 :{s=8950;break;}
53    case 7 :{s=9030;break;}
54    case 8 :{s=9080;break;}
55    case 9 :{s=9120;break;}
56    case 10 :{s=9240;break;}
57    case 11 :{s=9560;break;}
58    case 12 :{s=9600;break;}
59    case 13 :{s=9640;break;}
60    case 14 :{s=9760;break;}
61    case 15 :{s=9880;break;}
62    case 16 :{s=10010;break;}
63    case 17 :{s=10050;break;}
64    case 18 :{s=10120;break;}
65    case 19 :{s=10170;break;}
66    case 20 :{s=10210;break;}
67    case 21 :{s=10250;break;}
68    case 22 :{s=10370;break;}
69    case 23 :{s=10420;break;}
70    case 24 :{s=10470;break;}
71    case 25 :{s=10520;break;}
72    case 26 :{s=10570;break;}
73    case 27 :{s=10620;break;}
74    case 28 :{s=10660;break;}
75    case 29 :{s=10700;break;}
76    case 30 :{s=10740;break;}
77    case 31 :{s=10780;break;}
78  }
79}

 

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

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

b707 пишет:

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

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

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

b707 пишет:

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

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

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

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

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