Простой AVR-управляемый FM-приемник

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

Добрый день. Наткнулся на проект простого управляемого ардуиной приемника. Проект по адресу https://alexkaltsas.wordprecc.com/2018/05/01/a-simple-avr-controlled-fm-receiver Там же есть ссылка на видеоролик в ютубе. Тюнер в приемнике использован фирменный собран на LC7213V с синтезатором частоты  PLL c LA1837M. Я не являюсь специалистом по этим вопросам поэтому при попытке собрать это устройство возникли трудности, а именно:

1. Выложенный проект не дает понимания на какой платформе он разрабатывался . AVR Studio 7 обругала выдала кучу ошибок и не нашла ссылки на библиотеки проекта.

2. В файлах любезно представленных разработчиком я нашел HEX файлы. Но не понял какой из них является прошивкой для Ардуино.

3. Не ясно чем же шился Ардуино.

4. И не был ли при прошивке снесен родной загрузчик ардуино.

Буду признателен за Ваши коментарии и разьяснения по этому проекту.

С уважением !

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

[quote=metrologsastem12]

Исправлен адрес  Проекта https://alexkaltsas.wordpress.com/2018/05/01/a-simple-avr-controlled-fm-receiver

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

У проекта есть автор.  Тебе туда. 

strarbit
Offline
Зарегистрирован: 12.06.2016

1. компилятор AVR-GCC
2. AVR_Radio.hex находится в AVR_Radio-master\Firmware\bin\Release
3. программатор USBASP интерфейс SPI или вы можете применить arduino в режиме SPI
4. загрузчик uart стирается (затирается)
софт компиляция хорошо, персонально проверка

 

 

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

Доброго дня Уважаемые участники форума!

Благодарю !

Низкий поклон  "strarbit" за   компетентный и быстрый ответ!

Без Вашей помощи  реализация  этот проекта была бы невозможна!!

Постараюсь в ближайшее время сообщить на этой ветке форума о результатах его реализации.

С уважением!

strarbit
Offline
Зарегистрирован: 12.06.2016

господин metrologsaste, эти слова нет нет ненужно никогда! Уважением!

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

Доброго дня участники форума! В реализацию проекта вклинился тайм-Аут, связанный с тем, что присланная посылка с заказом платформы Arduino UNO, на самом деле оказалась Arduino Duemilanove.

Сейчас нахожусь в легком охренении поскольку:

1. Идея состояла в том, чтобы из сокета платформы Arduino UNO, которую использовал автор проекта alexkaltsas , изьять оригинальную Atmega 238P-PU и поставить прошитую Atmega 238P-PU дампом AVR_Radio.hex , автора проекта с адреса https://github.com/firew4lker/AVR_Radio/blob/master/Firmware/bin/Release/AVR_Radio.hex.

2. Прошивку с дампом AVR_Radio.hex предполагалось вливать в чистую Atmega 238P-PU с помощью программатора MiniPro TL866A (штатным ПО программатора) и затем установить в посадочное место взамен оригинальной.

3. Учитывая различия платформ Arduino UNO и Arduino Duemilanove возникает опасение в самой возможности такой замены.

Я побаиваюсь, что таким образом можно вывести из строя Arduino Duemilanove. Заранее благодарен за Ваши советы и комментарии.

С уважением!

sadman41
Offline
Зарегистрирован: 19.10.2016

Какие различия в плптформах вы видите?

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

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

Но фото этих плат представлены на вкладке Сайта Контроллеры Ардуино.

С уважением!

 

 

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

metrologsastem12 пишет:

Доброго дня участники форума! В реализацию проекта вклинился тайм-Аут, связанный с тем, что присланная посылка с заказом платформы Arduino UNO, на самом деле оказалась Arduino Duemilanove.

Сейчас нахожусь в легком охренении поскольку:

1. Идея состояла в том, чтобы из сокета платформы Arduino UNO, которую использовал автор проекта alexkaltsas , изьять оригинальную Atmega 238P-PU и поставить прошитую Atmega 238P-PU дампом AVR_Radio.hex , автора проекта с адреса https://github.com/firew4lker/AVR_Radio/blob/master/Firmware/bin/Release/AVR_Radio.hex.

2. Прошивку с дампом AVR_Radio.hex предполагалось вливать в чистую Atmega 238P-PU с помощью программатора MiniPro TL866A (штатным ПО программатора) и затем установить в посадочное место взамен оригинальной.

3. Учитывая различия платформ Arduino UNO и Arduino Duemilanove возникает опасение в самой возможности такой замены.

Я побаиваюсь, что таким образом можно вывести из строя Arduino Duemilanove. Заранее благодарен за Ваши советы и комментарии.

С уважением!

sadman41
Offline
Зарегистрирован: 19.10.2016

metrologsastem12 пишет:

Увы, я не являюсь специалистом, и ориентируюсь по внешнему виду платы. (Что находится на борту каждой из них) О прошивках рассуждать я тоже не могу, - нет знаний. 

Я из своего Duemilanove вытащил ATMega168 и засунул ATMega328 с алиэкспресса, предварительно залив бутлоадер. Она уже года четыре работает и не чихает. Так что ничего страшного произойти от вашей замены не должно.

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

Благодарю за совет sadman41!

Однако, в сути своей задача обратная той, - о которой говорите Вы! Постараюсь подробней пояснить это:

1. Есть проект собраный на плате Arduino UNO, с примочками на борту и своим ПО (бутлодер,+ фьюзы). Шился проект как сказано выше более компетентным участником форума на платформе Arduino UNO . При этом бутлодер затираеться, что с фьюзами, - одному богу известно, поскольку в представленной информации по проекту об этом ни гу-гу. Ссылки на проект выше.

2. У меня плата другая, а именно, - Arduino Duemilanove, с другими примочками на борту и т.д.

Вот из-за этого и возник вопрос о взаимозаменяемости. И звучит он другими словами так:

Можно ли использовать Arduino Duemilanove в этом проекте вместо Arduino UNO?

Естественно, не повредив плату Arduino  Duemianove.

С уважением!

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Так я и пишу, что явных проблем не вижу. МК один и тот же. Duemilanove - это предок Uno. Различия между ними в USB-UART мосте, но он наврядли будет препятствовать нормальной работе, так как является самостоятельной частью схемы и соединен с МК однотипно в обоих случаях - к RX/TX (D0/D1).

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

Благодарю за уточнение! Попробую воспользоваться Вашим советом.

Еще один вопрос связанный с реализацией проекта:

Поскольку оригинал буду извлекать и на его место ставить прошитую дампом проекта ( Atmega 328P-PU) то наверное при прошивке все настройки регистров нужно устанавливать как в исходнике, - Arduino UNO или это не принципиально?

С уважением!

sadman41
Offline
Зарегистрирован: 19.10.2016

Покак кто-то из нас этого не попробует сделать - ответа получить не выйдет. Сжечь МК вы наврядли сумеете.

metrologsastem12
Offline
Зарегистрирован: 06.11.2018

Благодарю!

Пойду пробовать. Страшно!!! Отпишусь о результатах на ветке.

С уважением!

DIVGENY
Offline
Зарегистрирован: 23.08.2016

 делал приемник на синтезаторе LC72131, управлял Pro Mini ATmega328P 5V / 16MHz - аналог UNO

http://arduino.ru/forum/apparatnye-voprosy/muzykalnyi-tsentr-lg-cd-962-c...

В теме есть ссылки на используемые библиотеки.

нарыл у себя скетч чисто для приемника.


/*


The module is based on a Sanyo LC72131 PLL and a tuner IC. 

The PLL can communicate with a microcontroller via the Sanyo CCB bus, and have
5 I/O pins which controls the tuner:

PLL pin    Direction       Function
BO0        PLL -> Tuner    Not used
BO1        PLL -> Tuner    Band selector (0 = FM; 1 = AM)
BO2        PLL -> Tuner    Mute / IF output (0 = Mute / IF counter mode
                                             1 = Normal tuner mode)
BO3        PLL -> Tuner    Audio mode (0 = Stereo; 1 = Mono)
BO4        PLL -> Tuner    Not used
IO0        Tuner -> PLL    Not used (pulled high.  Reads "1")
IO1        Tuner -> PLL    Stereo indicator (0 = Stereo; 1 = Mono)

Note: BO0 must be set to "0" for the tuner to output the IF signal to the PLL.
This means the tuner will have to be muted every time one want the PLL to count
the IF frequency.



Note:   This example uses an analog keypad with the following schematics:

                 A0
                 |
          2k2    |   330R        620R         1k          3k3        
VCC -----\/\/\---+---\/\/\---+---\/\/\---+---\/\/\---+---\/\/\-----+----- GND
                 |           |           |           |             |
                 X SCAN_UP   X UP        X DOWN      X SCAN_DOWN   X BAND
                 |           |           |           |             |
                GND         GND         GND         GND           GND

X = keys (N.O.)

*/

#include <inttypes.h>
#include <LiquidCrystal.h>
#include <SanyoCCB.h>

// This example uses an analog 5-key keypad tied to A0
#define KEYPAD_PIN A0

// Keypad keys
#define KEY_BAND      5
#define KEY_SCAN_DOWN 4
#define KEY_DOWN      3
#define KEY_UP        2
#define KEY_SCAN_UP   1
#define KEY_NONE      0

// LC72131 IN1, byte 0
#define IN10_R3     7
#define IN10_R2     6
#define IN10_R1     5
#define IN10_R0     4
#define IN10_XS     3
#define IN10_CTE    2
#define IN10_DVS    1
#define IN10_SNS    0

// LC72131 IN2, byte 0
#define IN20_TEST2  7
#define IN20_TEST1  6
#define IN20_TEST0  5
#define IN20_IFS    4
#define IN20_DLC    3
#define IN20_TBC    2
#define IN20_GT1    1
#define IN20_GT0    0

// LC72131 IN2, byte 1
#define IN21_DZ1    7
#define IN21_DZ0    6
#define IN21_UL1    5
#define IN21_UL0    4
#define IN21_DOC2   3
#define IN21_DOC1   2
#define IN21_DOC0   1
#define IN21_DNC    0

// LC72131 IN2, byte 2
#define IN22_BO4    7
#define IN22_BO3    6
#define IN22_BO2    5
#define IN22_BO1    4
#define IN22_IO2    3
#define IN22_IO1    2
#define IN22_IOC2   1
#define IN22_IOC1   0

// LC72131 DO0, byte 0
#define DO0_IN2     7
#define DO0_IN1     6
#define DO0_UL      4

// For function YST93xSetMode
#define YST93x_MONO    1
#define YST93x_STEREO  2
#define YST93x_MUTE    3
#define YST93x_UNMUTE  4
#define YST93x_BAND_FM 5
#define YST93x_BAND_AM 6

// Acceptable IF frequency deviation window (for the PLL) when searching for radio stations
// You may need to tweek these values to have a reliable "scan" mode
#define FM_TUNED_WINDOW 180
#define AM_TUNED_WINDOW 20

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // назначение пинов для дисплея
               // RS E  D4  D5 D6 D7

SanyoCCB ccb(12, 13, 11, 10); // назначение пинов для синтезатора
    // Pins: DI> CL  DO<  CE

byte pll_in1[3]; // глобальная переменная 3x8 бит или 3 байта
byte pll_in2[3];

// Initial frequencies
uint16_t FMFrequency = 1044;   // MHz / 10 начальная частота FM
uint16_t AMFrequency = 53;    // KHZ * 10

uint8_t band = YST93x_BAND_FM;
uint8_t tuned = 0;


/************************************************\
 *               YST93xInit()                   *
 * Initialize the PLL settings vectors with     *
 * parameters common to booth AM and FM modes   *
\************************************************/ 
void YST93xInit() {
  memset(pll_in1, 0, 3); //    1 - Указатель на блок памяти для заполнения.
                         //    2 - Установка значения. Передается как int
                         //          без знака этого значения.  
                         //    3 -  количество байт, которое должно быть установлено.
                         
  memset(pll_in2, 0, 3);                      
  bitSet(pll_in2[0], IN20_IFS);   // IF counter in normal mode
  bitSet(pll_in2[1], IN21_UL0);   // Phase error detection width = 0us
  bitSet(pll_in2[2], IN22_BO2);   // Mute off / normal tuner mode
  //bitSet(pll_in1[0], IN10_XS);    // Кварц 7.2 МГц СМ. НИЖЕ ....!
  bitClear(pll_in1[0], IN10_XS); // Кварц 4.5 МГц 
}


/************************************************\
 *              YST93xSetMode()                 *
 * Some predefined setups for the YST93x module *
\************************************************/
void YST93xSetMode(uint8_t mode) {
  switch(mode) {
    case YST93x_STEREO:
      bitClear(pll_in2[2], IN22_BO3);
      break;

    case YST93x_MONO:
      bitSet(pll_in2[2], IN22_BO3);
      break;

    case YST93x_MUTE:
      bitClear(pll_in2[2], IN22_BO2);
      break;

    case YST93x_UNMUTE:
      bitSet(pll_in2[2], IN22_BO2);
      break;

    case YST93x_BAND_FM:
      band = YST93x_BAND_FM;
      bitWrite(pll_in1[0], IN10_R0,  1); // Reference frequency = 50kHz / 10 кГц R0->0
      bitWrite(pll_in1[0], IN10_R3,  0); //                                      R3->1
      bitWrite(pll_in1[0], IN10_DVS, 1); // Programmable Divider divisor = 2
      bitWrite(pll_in2[0], IN20_GT0, 0); // IF counter mesurement period = 32ms
      bitWrite(pll_in2[0], IN20_GT1, 1); //
      bitWrite(pll_in2[1], IN21_DZ0, 1); // Dead zone = DZB
      bitWrite(pll_in2[1], IN21_DZ1, 0); //
      bitWrite(pll_in2[2], IN22_BO1, 0); // FM mode
      break;
    
    case YST93x_BAND_AM:
      band = YST93x_BAND_AM;
      bitWrite(pll_in1[0], IN10_R0,  0); // Reference frequency = 10kHz
      bitWrite(pll_in1[0], IN10_R3,  1); //
      bitWrite(pll_in1[0], IN10_DVS, 0); // Programmable Divider divisor = 1
      bitWrite(pll_in2[0], IN20_GT0, 1); // IF counter mesurement period = 8ms
      bitWrite(pll_in2[0], IN20_GT1, 0); //
      bitWrite(pll_in2[1], IN21_DZ0, 0); // Dead zone = DZC
      bitWrite(pll_in2[1], IN21_DZ1, 1); //
      bitWrite(pll_in2[2], IN22_BO1, 1); // AM mode
      break;
  }
  ccb.write(0x82, pll_in1, 3); 
  ccb.write(0x92, pll_in2, 3); 
}



/************************************************************\
 *                       YST93xTune()                       *
 * Set the tuner frequency and return 1 if it is tuned      *
 * or 0 otherwise.                                          *
 *                                                          *
 * The frequency divisors was chosen in a way the frequency *
 * representation can be directly sent to the PLL and is    *
 * easy to represent:                                       *
 * - FM mode (divisor = 100): frequency (MHz) * 10          *
 * - AM mode (divisor = 10):  frequency (kHZ) / 10          *
\************************************************************/
uint8_t YST93xTune(uint16_t frequency) {
  uint16_t fpd = 0;
  uint8_t i = 0;
  uint8_t r[3];
  unsigned long IFCounter = 0;
  
  switch(band) {
    case YST93x_BAND_FM:
    //fpd = (frequency + FI)/(50 * 2);//частота и так уже задана в кГц/100, поэтому ниже правильно
    
    fpd = (frequency + 107); // частота перестройки 50 Кгц R3 R2 R1 R0
                               // __________________________ 0  0  0  1
                               
      //fpd = (frequency + 107) * 5 ; //     10 Кгц            1  0  0  0  
      
      break;
      
    case YST93x_BAND_AM:
      // AM: fpd = ((frequency + FI) / 10) << 4
      fpd = (frequency + 45) << 4;
      break;
      
    default: return 1;
  }

  YST93xSetMode(YST93x_MUTE);   // YST93x only injects FI signal into the PLL when in MUTE mode

  // Reset the IF counter and program the Frequency Programmable Divider (fpd)
  bitClear(pll_in1[0], IN10_CTE);
  pll_in1[1] = byte(fpd >> 8);       // старший байт настройки частоты, сдвигаем побитово значения на 8 байт влево
  pll_in1[2] = byte(fpd & 0x00ff);   // младший ший байт, операцией Побитовое И (&) обнуляем значения ст. разрядов
  
  ccb.write(0x82, pll_in1, 3);       // 0x82, pll_in1[0] -> pll_in1[2]
                                     // буфер вывернут в библиотеке, поетому выводится наоборот
                                     // pll_in1[2], pll_in1[1], pll_in1[0]
  
    // выводим показания частоты в Serial порт  
      Serial.println((FMFrequency < 1000) ? 4 : 3, 0); 
      Serial.print((float)FMFrequency / 10, 2);

  // Start the IF counter
  bitSet(pll_in1[0], IN10_CTE);
  ccb.write(0x82, pll_in1, 3);

  // Wait for PLL to be locked (DO0_UL == 1)
  while(i < 20) {
    delay(50);
    ccb.read(0xa2, r, 3);  // Discard the 1st result: it is latched from the last count (as said on the datasheet)
    ccb.read(0xa2, r, 3);  // The 20 rightmost bits from r[0..2] are the IF counter result
    i = (bitRead(r[0], DO0_UL)) ? 100 : i + 1;
  }
  
  YST93xSetMode(YST93x_UNMUTE);   // Mute off / normal tuner mode

  if(i == 100) {
    // PLL is locked.  If the IF deviation is within the defined (window) interval,
    // the radio is likely to be tuned.
    // Note: this "tuned" detection method is not recommended on the LC72131 datasheet as 
    // it can give false positive results.  A better approach would be to get the "tuned"
    // flag from a RDS decoder with signal quality detection (e.g.: PT2579 or Philips SAA6588)
    // connected to the YST93x tuner module "RDS Output" pin. SAA6588 is more powerful/popular, 
    // but PT2579 looks a lot easier to use as it is not programmable and has a dedicated
    // signal quality output pin.
    IFCounter = (r[0] & 0x0f);
    IFCounter = (IFCounter << 16) | (unsigned long)(r[1] << 8) | (r[2]);
    //Serial.println(IFCounter);
    switch(band) {
      case YST93x_BAND_FM:
        // Expected value: IF (10.7MHz) * Mesurement period (32ms, as set via GT[1..0]) = 342400
        if((IFCounter > 342400) && ((IFCounter - 342400) < FM_TUNED_WINDOW)) return 1;
        if((IFCounter < 342400) && ((342400 - IFCounter) < FM_TUNED_WINDOW)) return 1;
        break;
      case YST93x_BAND_AM:
        // Expected value: IF (450kHz) * Mesurement period (8ms, as set via GT[1..0]) = 3600
        // Note: scan mode in AM is really poor.  I have done my best in tweaking it, but it barely works
        if((IFCounter > 3600) && ((IFCounter - 3600) < AM_TUNED_WINDOW)) return 1;
        if((IFCounter < 3600) && ((3600 - IFCounter) < AM_TUNED_WINDOW)) return 1;
        break;
    }
  }
  return 0; 
}


/**************************************************\
 *                   YST93xIsStereo()             *
 * Returns 1 if the tuned radio station is stereo *
\**************************************************/
uint8_t YST93xIsStereo() {
  uint8_t r[3];
  
  ccb.read(0xa2, r, 3);
  return(bitRead(r[0], DO0_IN2) ? 0 : 1);
}


/*******************************************************\
 *                       getKey()                      *
 * Read the (analog) keypad.                           *
 * If you are using an digital (one key per input pin) *
 * keypad, just this function to return the correct    *
 * values                                              *
\*******************************************************/
uint8_t getKey(uint8_t keypadPin) {
  uint16_t keypad;
  uint8_t key = KEY_NONE;
  
  keypad = analogRead(keypadPin);
    
  if(keypad < 800) key = KEY_BAND;  
  if(keypad < 650) key = KEY_SCAN_DOWN;  
  if(keypad < 500) key = KEY_DOWN;  
  if(keypad < 300) key = KEY_UP;  
  if(keypad < 60)  key = KEY_SCAN_UP;
   // if(keypad < 1000) Serial.println(keypad); // проверка кнопок
  
  return key;
}


/*******************\
 * Arduino setup() *
\*******************/ 
void setup() {
  lcd.begin(16, 2);
  Serial.begin(19200);
  ccb.init();
  delay(1000);
  YST93xInit();
  YST93xSetMode(YST93x_BAND_FM);
  tuned = YST93xTune(FMFrequency);
}


/******************\
 * Arduino loop() *
\******************/ 
void loop() {
  uint8_t scan = 0;
  int8_t delta = 0;
  uint8_t key = getKey(KEYPAD_PIN);

  lcd.setCursor(0, 0);
  switch(band) {
    case YST93x_BAND_FM:
      lcd.print("FM ");
      lcd.setCursor((FMFrequency < 1000) ? 4 : 3, 0); lcd.print((float)FMFrequency / 10, 1);
      lcd.print("MHz ");
      

      break;
    case YST93x_BAND_AM:
      lcd.print("AM ");
      lcd.setCursor((AMFrequency < 100) ? 4 : 3, 0); lcd.print(AMFrequency * 10);
      lcd.print("KHz ");
      break;
  }
  
  // Updates the Stereo indicator
  lcd.setCursor(12, 0);
  if(YST93xIsStereo())
    lcd.print("[ST]");
  else
    lcd.print("[  ]");

  // The "Tuned" indicator is updated only when the station changes
  lcd.setCursor(2, 1);
  if(tuned)    
    lcd.print("   Tuned   ");
  else
    lcd.print("           ");

  // Processo keypad inputs
  if(key != KEY_NONE) {  
   
    switch(key) {
      case KEY_UP:        scan = 0; delta = +1; break;
      case KEY_DOWN:      scan = 0; delta = -1; break;
      case KEY_SCAN_UP:   scan = 1; delta = +1; break;
      case KEY_SCAN_DOWN: scan = 1; delta = -1; break;
      case KEY_BAND:
        switch(band) {
          case YST93x_BAND_FM:
            YST93xSetMode(YST93x_BAND_AM);
            tuned = YST93xTune(AMFrequency);
            break;

          case YST93x_BAND_AM:
            YST93xSetMode(YST93x_BAND_FM);
            tuned = YST93xTune(FMFrequency);
            break;
        }
    }

    if(scan) {
      lcd.setCursor(2, 1);
      lcd.print("Scanning...");
    }

    // Change the station  
    switch(band) {
      case YST93x_BAND_FM:
        do{
          FMFrequency += delta;
          if(FMFrequency > 1080) FMFrequency = 880;
          if(FMFrequency < 880)  FMFrequency = 1080;
          tuned = YST93xTune(FMFrequency);

          lcd.setCursor(3, 0);
          if(FMFrequency < 1000) lcd.print(' ');
          lcd.print((float)FMFrequency / 10, 1);
        } while(scan && (! tuned));
        break;
        
      case YST93x_BAND_AM:
        do{
          AMFrequency += delta;
          if(AMFrequency > 170) AMFrequency = 53;
          if(AMFrequency < 53)  AMFrequency = 170;
          tuned = YST93xTune(AMFrequency);

          lcd.setCursor(3, 0);
          if(AMFrequency < 100) lcd.print(' ');
          lcd.print(AMFrequency * 10);
        } while(scan && (! tuned));
        break;
        
    } // switch
    
  } // if(key)
  
}
metrologsastem12
Offline
Зарегистрирован: 06.11.2018

Благодарю DIVGENY!

Я видел Ваш проект под тюнер в котором используеться приемник на 24 ножках LA1831. Это высший пилотаж!!!

Для меня любителя, (из-за отсутствия знаний) такой проект пока недоступен для понимания. (Постараюсь изучить и на это уйдет время).  Его то (времени) как правило и не хватает, поскольку придется погружаться в "тонкости".

В более широком смысле  это направление, - использование платформы Arduino (и не только)  для "стандартных тюнеров" радиоприемных устройств весьма интересно и познавательно. Многие подбные устройства, - FM/AM и TV тюнерa (от спутниковых до эфирных) уже давно лежат в мусорных ведрах на разборке (стоимость копейки,- возможности широченные). И представляют "академический" интерес, реализованный на практике. К сожалению ни один ВУЗ таких знаний не дает. Страницы форума, это бесценные знания.  Низкий поклон Вам!!!

Соображения по использованию других платформ, в некоторых старых CD, DVD используются контроллеры с еще более могучими возможностями, например H8/3000.

С уважением!