Радио-будильник (Arduino)

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

В состав радио-будильника входят следующие компоненты:

  • Arduino Nano (Uno)
  • Цветной TFT-дисплей SPI 320×240 (Контроллер: ILI9340C)
  • PT2257 2-х канальный I2C цифровой контроллер громкости
  • Радио на ИМС TEA5767 (модуль)
  • Часы реального времени DS3231SN (ZS-042) (модуль)
  • Стерео аудио усилитель 2х3Вт D-класса на базе PAM8403 (модуль)

 

Технические характеристики компонентов схемы радио-будильника:

 

Технические параметры радио модуля TEA5767 (описание):

  • Напряжение питания от 2,5 до  5 В
  • Потребляемый ток при Uпит = 5 В 12,8 мА
  • Чувствительность 2 мкВ
  • Отношение сигнал/шум  54 дБ
  • Разделение между стереоканалами 24 дБ
  • Коэффициент гармоник 0,4 %
  • Диапазон принимаемых частот от 76 МГц до 108 МГц
  • Шины управления: I2C или 3-х проводная
  • Функция автоматической настройки на принимаемые радиостанции
  • Автоматическое стереодекодирование принятого сигнала

Основные характеристики регулятора громкости на ИМС PT2257 (описание):

  • Напряжение питания от 3 до 9 В
  • Регулировка громкости от -79 до 0 дБ
  • Раздельная для каждого канала регулировка громкости
  • Режим MUTE
  • КНИ при выходном напряжении 200 мВ не превышает 0,003% при входном напряжении 2 В КНИ не более 0,07%

Основные характеристики TFT-дисплей SPI 320×240 (описание):

  • Наименование: TFT01-22SP
  • Контроллер: ILI9340C
  • Диагональ: 2,2 дюйма
  • Напряжение питание: 5 В
  • Напряжение сигналов: 3,3 В
  • Разрешение: 240 x 320 (RGB)

Основные характеристики усилителя (описание):

  • Напряжение питания: 2,5…5,5 В
  • Ток потребления при отсутствии сигнала: 10 мА
  • Выходная мощность при нагрузке 8 Ом: 1,5 Вт x2 канала
  • Выходная мощность при нагрузке 4 Ом: 3,0 Вт x2 канала
  • Разделение каналов: 60 дБ и более (при мощности 1 Вт и нагрузке 4 Ом)

Основные характеристики DS3231 (описание):

  • Точность ±2 ppm в диапазоне температур от 0°C до +40°C
  • Точность ±3.5 ppm в диапазоне температур от-40°C до +85°C
  • Вход для подключения автономного источника питания, позволяющего обеспечить непрерывную работу
  • Рабочий температурный диапазон
    коммерческий: от 0°C до +70°C
    индустриальный: -от 40°C до +85°C
  • Низкое потребление
  • Часы реального времени, отсчитывающие секунды, минуты, часы, дни недели, дни месяца, месяц и год с коррекцией високосного года вплоть до 2100
  • Два ежедневных будильника
  • Выход прямоугольного сигнала с программируемой частотой
  • Быстродействующие (400 кГц) I2C интерфейс
  • 3.3 В питание
  • Цифровой температурный датчик с точностью измерения ±3°C
  • Регистр, содержащий данные о необходимой подстройке
  • Вход/выход сброса nonRST

Управление радио-будильником осуществляется при помощи 4-х кнопок:

  • Кнопка поиска станции +
  • Кнопка поиска станции —
  • Кнопка громкость +
  • Кнопка громкость —

При длительном нажатии на одну из кнопок поиска станций происходит поиск ближайшей станции с хорошим уровнем сигнала, при единичном нажатии происходит перестройка частоты на 100 кГц.

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

В режиме установки времени будильника звук радиоприемника отключается, при срабатывании будильника включается звук радиоприемника и происходит выход из режима коррекции времени будильника.

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

Библиотеки

PT2257.zip

DS3231.zip

UTFT.zip

TEA5767.zip

#include <UTFT.h>
#include <Wire.h>
#include <DS3231.h> 
#include <PT2257.h>
#include <TEA5767.h>
#include <EEPROM.h>
  PT2257 rt;
  TEA5767 Radio;
  UTFT tft(TFT01_22SP, 8, 9, 12, 11, 10); // SDI (MOSI), SCK, CS, RESET, DC
  DS3231 clock;RTCDateTime DateTime;RTCAlarmTime Alarm;
  extern uint8_t SmallFont[];extern uint8_t BigFont[];//extern uint8_t SevenSegNumFont[];
 
  unsigned long time;
  unsigned char buf[5];
  int stereo,signal_level,i,w,stat,up,vol,start=1,w1,alarm,s,vol_a,day,hi,low,f;
  float f_new;
 
 
 
void setup(){
     tft.InitLCD(0);tft.clrScr();
     Wire.begin();//Serial.begin(9600);
     clock.begin();
//   clock.setDateTime(__DATE__, __TIME__);
     pinMode(7,INPUT);pinMode(6,INPUT);pinMode(5,INPUT);pinMode(4,INPUT);
     vol=EEPROM.read(0);Alarm.minute=EEPROM.read(1);Alarm.hour=EEPROM.read(2);alarm=EEPROM.read(3);day=EEPROM.read(4);f=EEPROM.read(5)*256+EEPROM.read(6);
     f_new=(float)f;
     Radio.init();Radio.set_frequency(f_new/10); 
     audio();
}
 
void loop(){ 
////////////////////////////////// TIME /////////////////////////////////////////////////////////////
    DateTime=clock.getDateTime();
    tft.setFont(BigFont);tft.setColor(255,255,255);tft.print(clock.dateFormat("H:i:s",DateTime), CENTER, 10);
    tft.setFont(SmallFont);tft.setColor(200,200,200);tft.print(clock.dateFormat("D d M Y", DateTime), CENTER,30);
    tft.drawLine(5,55,235,55);  
//////////////////////////////// RADIO ///////////////////////////////////////////////////////////////    
    stat = Radio.read_status(buf);
    stereo = Radio.stereo(buf);
    signal_level = Radio.signal_level(buf);
    tft.setFont(BigFont);
  if(start==1){tft.print("FM RADIO",CENTER,65);}
    tft.setColor(255,255,255);  tft.printNumF(f_new/10,2,50,85);tft.print(" MHz ",145,85);
    tft.setColor(200,200,200); 
  if(start==1){tft.drawLine(5,110,235,110);}
    tft.setFont(SmallFont);   if (stereo) {tft.print("STEREO",30,115);} else {tft.print(" MONO ",30,115);}
    tft.print("SIGNAL ",100,115);if(signal_level<15){tft.print("LOW ",170,115);}else{tft.print("HIGH",170,115);}
  if (digitalRead(6)==HIGH&&alarm==0){f_new=f_new+1;w=1;up=1;Radio.set_frequency(f_new/10);delay(50);}
  if (digitalRead(7)==HIGH&&alarm==0){f_new=f_new-1;w=1;up=2;Radio.set_frequency(f_new/10);delay(50);} 
  if(signal_level<14&&up==1){f_new=f_new+1;Radio.set_frequency(f_new/10);delay(50);}
  if(signal_level<14&&up==2){f_new=f_new-1;Radio.set_frequency(f_new/10);delay(50);}
  if(f_new/10>108){up=2;f_new=1080;}if(f_new/10<87.5){up=1;f_new=875;}
 
//////////////////////////// VOLUME ////////////////////////////////////////////////////////////////////    
  if (digitalRead(4)==HIGH&&alarm==0){vol=vol+4;if(vol>=76){vol=76;}audio();time=millis();w=1;w1=1;}
  if (digitalRead(5)==HIGH&&alarm==0){vol=vol-4;if(vol<=2){vol=2;}audio();time=millis();w=1;w1=1;}   
  tft.setColor(255,255,255); tft.setFont(BigFont);
  if(start==1){tft.print("VOLUME",CENTER,140);}
  if(start==1){tft.setColor(220,220,220);tft.fillRect(0,165,240,185);}  
  if(w1==1||start==1){for(i=4;i<vol;i=i+4){ tft.setColor(100,148,255);
    tft.fillRect(i*3,170,(i+2)*3,180);tft.setColor(220,220,220);tft.fillRect((i+4)*3,170,(i+6)*3,180);}}w1=0;
///////////////////////////////////////// alarm /////////////////////////////////////////////////////
    if(alarm==1){tft.setColor(255,0,0);vol_a=0;audio();}else{tft.setColor(200,200,200);vol_a=vol;audio();}tft.print("ALARM",CENTER,200);
 
     if (digitalRead(4)==HIGH&&digitalRead(5)==HIGH){alarm=1;s=0;time=millis();w=1;}
     if(alarm==1){ 
     if (digitalRead(6)==HIGH&&digitalRead(7)==LOW){Alarm.minute++;if(Alarm.minute>=60){Alarm.minute=0;}time=millis();w=1;}
     if (digitalRead(7)==HIGH&&digitalRead(6)==LOW){Alarm.hour++;if(Alarm.hour>=24){Alarm.hour=0;}time=millis();w=1;}
     if (s==1&&(digitalRead(4)==HIGH||digitalRead(5)==HIGH)){alarm=0;}s=1;time=millis();w=1;
 
     if (digitalRead(7)==HIGH&&digitalRead(6)==HIGH){day++;if(day>2){day=0;}time=millis();w=1;}
     if(day==0){
     if((DateTime.hour*10000+DateTime.minute*100+DateTime.second)==(Alarm.hour*10000+Alarm.minute*100+Alarm.second)){alarm=0;}}
     if(day==1){
     if(((DateTime.hour*10000+DateTime.minute*100+DateTime.second)==(Alarm.hour*10000+Alarm.minute*100+Alarm.second))&&DateTime.dayOfWeek<6){alarm=0;}}
     }
     if(day==2){}
 
     tft.setColor(255,255,255);tft.print(clock.dateFormat("H:i",Alarm), CENTER, 235);
     if(day==0){tft.print("EVERY DAY", CENTER, 260);}
     if(day==1){tft.print(" WEEKDAY ", CENTER, 260);}
     if(day==2){tft.print("   OFF   ", CENTER, 260);}
     tft.setColor(200,200,200);  tft.printNumF(clock.readTemperature(),1,70,290);tft.print("C  ",150,290);
/////////////////////////// EEPROM ////////////////////////////////////////////////////////////////////
  if(w==1&&millis()-time>10000){
    f=f_new;
  EEPROM.update(0,vol);
  EEPROM.update(1,Alarm.minute);
  EEPROM.update(2,Alarm.hour);
  EEPROM.update(3,alarm);
  EEPROM.update(4,day);
  EEPROM.update(5,highByte(f));
  EEPROM.update(6,lowByte(f));
  w=0;
  }
  start=0;
}// loop
 
void audio(){  
  rt.setLeft(vol_a); // int 0...79 
  rt.setRight(vol_a);// int 0...79
  rt.setMute(0);  // int 0...1
}

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

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