Модуль Si4703 представляет собой FM-радиоприёмник (УКВ от 76 МГц до 108 МГц) с цифровым управлением и функцией RDS. Так же модуль содержит маломощный усилитель мощности звуковой частоты TPA6111A2, позволяющий подключать наушники к модулю используя разъем 3,5 мм, при этом подключенные наушники используются в качестве антенны.
Radio Data System ( RDS) — многоцелевой стандарт, предназначенный для передачи информационных сообщений по каналам ЧМ-радиовещания в диапазоне УКВ.
Основные параметры SI4703:
- Диапазон принимаемых частот: 76–108 МГц
- Интерфейс: 2-Wire, 3-Wire
- Напряжение питания: от 2,7 В до 5,5 В
- Потребляемый ток: до 17 мА
- Управление громкостью: цифровое
- Автоматическая регулировка усиления (AGC)
- Измерение уровня сигнала
- Адаптивное подавление шума
- Регулятор громкости (16 уровней)
- Аналоговый выход линейного уровня
- RDS/RBDS
- Авто поиск станций с шагом 50, 100 и 200 кГц
Для тестового запуска модуля Si4703 на базе Arduino необходимо собрать следующую схему:
Управление модулем на Si4703 осуществляется при помощи шины 3-Wire (SDIO, SCLK, SEN), для перевода микросхемы для работы с шиной 3-Wire выход GPIO1 должен замкнут на землю. Выход RST используется для сброса настроек модуля после подачи питания.
Для управления Si4703 используется библиотека — si4703.zip
Библиотека поддерживает следующие функции:
- radio.fm_start( int f ) — функция установки частоты радиостанции, применяется один раз при включении приемника
- int f = F x 10 — 760
- где F — частота станции в МГц
- int f = F x 10 — 760
- radio.init() — функция содержит все необходимые настройки для запуска приемника
- si4703 radio( 3,2,4,5 ) — функция подключения, необходимо указать номера пинов Arduino (SDIO, SCLK, SEN, RST)
- radio.si_volume( int vol ) — установка громкости, 16 шагов
- int vol от 0 до 15
- radio.seek_up() — авто поиск станции, увеличение частоты (шаг 0,1 МГц)
- radio.seek_down() — авто поиск станции, уменьшение частоты (шаг 0,1 МГц)
- radio.nom_ch() — чтение текущей установленной частоты int f
- F = ( int f + 760 ) / 10
- F — частота станции в МГц
- F = ( int f + 760 ) / 10
- radio.seach() — чтение флага установки частоты станции в режиме поиска, 1 — частота станции установлена, 0 — поиск станции
- radio.rss() — чтение уровня сигнала
- radio.st_mn() — чтение установки режимов моно\стерео
- radio.readRDS() — чтение данных RDS (название станции — 8 символов)
Тестовый скетч:
#include <si4703.h> si4703 radio(3,2,4,5); // SDIO, SCLK, SEN, RST int f_cannel = 1019; void setup() { radio.init(); Serial.begin(9600); radio.fm_start(f_cannel-760);// 101.9 МГц (1019-760 = 259) radio.si_volume(10);// 0...15 } void loop() { if(Serial.available()){ char serial = Serial.read(); if(serial == 'u'){radio.seek_up();} if(serial == 'd'){radio.seek_down();} } Serial.print(" F = "); Serial.print(float((radio.nom_ch()+760.00)/10),2); Serial.print(" RDS ="); Serial.print(radio.readRDS()); Serial.print(" STC ="); Serial.print(radio.seach()); Serial.print(" RSSI ="); Serial.print(radio.rss()); Serial.print(" ST ="); Serial.println(radio.st_mn()); }
После загрузки скетча в мониторе порта можно увидеть данные о текущей частоте, RDS, флаг поиска станции, уровень сигнала и значение флага моно\стерео. Если в стоке ввода монитора порта указать и отправить символы u или d, то можно начать поиск станции при повышении или понижении частоты поиска.
Используя дисплей LCD2004 с модулем I2C (I2C модуль на базе микросхем PCF8574 позволяют подключить символьный дисплей 1602 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея) и 4-е кнопки, можно собрать простой радиоприёмник.
Радиоприемник имеет следующие функциональные возможности:
- Поиск станции — увеличение и уменьшение частоты
- Запуск станции при включении
- Регулировка громкости
- Запоминание уровня громкости (0…15) и последней выбранной станции (была включена не менее одной минуты) перед выключением.
- RDS — название станции
- Индикатор уровня сигнала
- Индикатор моно/стерео
#include <EEPROM.h> #include <LiquidCrystal_I2C.h> #include <Wire.h> #include <si4703.h> si4703 radio(3,2,4,5); // SDIO, SCLK, SEN, RST LiquidCrystal_I2C lcd(0x27,20,4); byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}; byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00}; byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C}; byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C}; byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07}; byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}; byte d1,d2,d3,d4,d5,d6,e1,e2,e3; int a[6],x; bool w=1,save_ch,w1; int canel,vol; unsigned long times,times1; byte t; char old[8]; char * print_rds; void setup() { Wire.begin();lcd.init();lcd.backlight(); lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4); lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8); //Serial.begin(9600); radio.init(); pinMode(7,INPUT_PULLUP);// button up pinMode(8,INPUT_PULLUP);// button down pinMode(9,INPUT_PULLUP);// button volume UP pinMode(10,INPUT_PULLUP);// button volume DOWN canel = ((EEPROM.read(400)<<8))|EEPROM.read(401);vol=EEPROM.read(402); if(canel>320){canel=0;}if(vol>15){vol=10;} Serial.print("Device ID: ");Serial.println(radio.read_device_id(),HEX); Serial.print("Chip ID: ");Serial.println(radio.read_chip_id(),HEX); radio.si_volume(vol); } void loop() { //////// BUTTON ///////////////////////////////////////////////// if(digitalRead(7)==LOW){radio.seek_up();save_ch=1;times=millis();delay(100);} if(digitalRead(8)==LOW){radio.seek_down();save_ch=1;times=millis();delay(100);} if(digitalRead(9)==LOW){vol++;save_ch=1;times=millis();if(vol>15){vol=15;}radio.si_volume(vol);delay(100);} if(digitalRead(10)==LOW){vol--;save_ch=1;times=millis();if(vol<0){vol=0;}radio.si_volume(vol);delay(100);} ///////////////////////////////////////////////////////////////// /////// EEPROM ////////////////////////////////////////////////// if(millis()-times>60000&&save_ch==1){save_ch=0;canel = radio.nom_ch(); EEPROM.update(400,(canel>>8) & 0b11);EEPROM.update(401,canel & 0xFF);EEPROM.update(402,vol);} /////// LCD STEREO/MONO SIGNAL VOLUME ///////////////////////////////////////////////// if(w==1){w=0;radio.fm_start(canel);} if(millis()-times1>1000){times1=millis();lcd.setCursor(13,2);lcd.print("SIG ");lcd.print(radio.rss());lcd.print(" "); if(radio.st_mn()==0){lcd.setCursor(13,1);lcd.print("MONO ");} else{lcd.setCursor(13,1);lcd.print("STEREO");}} lcd.setCursor(13,0);lcd.print("VOL ");lcd.print(vol);lcd.print(" "); lcd.setCursor(2,2);lcd.print("FM RADIO"); ////// LCD PRINT RDS ST_NAME /////////////////////////////////////////////// if(radio.seach()==1 && radio.rss()>30){print_rds = radio.readRDS();} if(t==0){for(int i=0;i<8;i++){old[i]=print_rds[i];}}t++; if(radio.seach()==0){ for(int i=0;i<8;i++){print_rds[i]=61;}t=0;lcd.setCursor(6,3);lcd.print(" No RDS ");} byte d=0;for(int i=0;i<8;i++){if(old[i]==print_rds[i]){}else{d++;}} if(d==0 && t==5){t=0; for(int i=0;i<8;i++){lcd.setCursor(6+i,3);lcd.print(print_rds[i]);}} if(t>8){t=0;} lcd.setCursor(0,3);lcd.print("======"); lcd.setCursor(14,3);lcd.print("======"); ///////// LCD BIG /////////////////////////////////////////////// int f_ch = radio.nom_ch() + 760; a[0]=f_ch/1000; a[1]=f_ch/100%10; a[2]=f_ch/10%10; a[3]=f_ch%10; if(f_ch<1000){a[0]=10;} for(x=0;x<4;x++){ switch(x){ case 0: e1=0;e2=0,e3=1;break; case 1: e1=2,e2=3,e3=4;break; case 2: e1=5,e2=6,e3=7;break; case 3: e1=9,e2=10,e3=11;break; }digit();} lcd.setCursor(8,1);lcd.print("."); ////////////////////////////////////////////////////////////////// delay(1); }// loop void digit(){switch(a[x]){ case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break; case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break; case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break; case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break; case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break; case 10:d1=150,d2=150,d3=150,d4=150,d5=150,d6=150;break;} if(x>0){lcd.setCursor(e1,0);lcd.write((uint8_t)d1);} lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3); lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);}
Форум — http://forum.rcl-radio.ru/viewtopic.php?id=421
Datasheet — Si4703_datasheet
Привет. Приемник заработал сразу , только надо увеличит громкость ,видно стоит на 0.
Мои LCD2004 имеет адрес 0 x 3F .
Громкость берется из EEPROM, стоит защита, если в EEPROM записано значение больше 15, то громкость сбрасывается на 0.
В новых платах всегда EEPROM имеет значение 255
Приёмник не заработал. Проблемы такие же как в сообщениях на форуме. На экране кракозябры. Плата приёмника такая же как у Вас. Сиреневая. на обратной стороне написаноCJMCU-470
Дисплей рабочий 100 процентов