Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2015:si4703-radio

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
2015:si4703-radio [2016/01/17 14:55]
Adam Štěpánek [Závěr]
2015:si4703-radio [2016/01/17 16:07] (aktuální)
Adam Štěpánek
Řádek 5: Řádek 5:
   * Použijte vývojový kit [[http://​developer.mbed.org/​platforms/​KL25Z/​|FRDM-KL25Z]]   * Použijte vývojový kit [[http://​developer.mbed.org/​platforms/​KL25Z/​|FRDM-KL25Z]]
 =====Integrované rádiové moduly===== =====Integrované rádiové moduly=====
-Většina mobilních telefonů a MP3 přehrávačů mají v sobě automaticky radiový přijímač. Není se čemu divit, výrobci je integrovali do velmi malých pouzder a při jejich masové výrobě je cena příznivá. Všechny potřebné funkce mají již v sobě (RDS, potlačení šumu, AGC, automatické vyhledávání stanic, atd.), takže stačí pouze přidat výstupní zesilovačnebo využít digitálních audio výstupů. Nejvíce mě zaujala nabídka [[http://​www.silabs.com/​products/​audio/​Pages/​default.aspx|Silicon Labs.]] Nabízí mimo přijímačů i vysílače nebo kombinace obojího. Vysílače umožňují velmi jednoduše spojit MP3 přehrávač nebo mobilní telefon přímo s autorádiem. (pozn.: Česká legislativa něco takového neumožňuje)+Většina mobilních telefonů a MP3 přehrávačů mají v sobě automaticky radiový přijímač. Není se čemu divit, výrobci je integrovali do velmi malých pouzder a při jejich masové výrobě je cena příznivá. Všechny potřebné funkce mají již v sobě (RDS, potlačení šumu, AGC, automatické vyhledávání stanic, atd.), takže stačí pouze přidat výstupní zesilovač nebo využít digitálních audio výstupů. Nejvíce mě zaujala nabídka [[http://​www.silabs.com/​products/​audio/​Pages/​default.aspx|Silicon Labs.]] Nabízí mimo přijímačů i vysílače nebo kombinace obojího. Vysílače umožňují velmi jednoduše spojit MP3 přehrávač nebo mobilní telefon přímo s autorádiem. (pozn.: Česká legislativa něco takového neumožňuje)
 =====Hardware===== =====Hardware=====
 Vybral jsem si modul FM rádia [[https://​www.sparkfun.com/​datasheets/​BreakoutBoards/​Si4702-03-C19-1.pdf|Si4703]]. Ten má v sobě zabudovaný i RDS procesor a další funkce. Zapsáním hodnoty do příslušného registru ovládáme VCO (oscilátor řízený napětím), s pomocí kterého obvod naladí frekvenci. Modul již má audiozesilovač,​ takže stačí jen připojit sluchátka, které slouží zároveň i jako anténa. Vybral jsem si modul FM rádia [[https://​www.sparkfun.com/​datasheets/​BreakoutBoards/​Si4702-03-C19-1.pdf|Si4703]]. Ten má v sobě zabudovaný i RDS procesor a další funkce. Zapsáním hodnoty do příslušného registru ovládáme VCO (oscilátor řízený napětím), s pomocí kterého obvod naladí frekvenci. Modul již má audiozesilovač,​ takže stačí jen připojit sluchátka, které slouží zároveň i jako anténa.
Řádek 15: Řádek 15:
 Budeme ho ovládat pomocí vývojového kitu [[http://​www.nxp.com/​products/​software-and-tools/​hardware-development-tools/​freedom-development-boards/​freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:​FRDM-KL25Z|FRDM-KL25Z.]] Budeme ho ovládat pomocí vývojového kitu [[http://​www.nxp.com/​products/​software-and-tools/​hardware-development-tools/​freedom-development-boards/​freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:​FRDM-KL25Z|FRDM-KL25Z.]]
 =====Software===== =====Software=====
-Vývojové prostředí ​[[mbed.org]] umožňuje vyhledat a importovat knihovny, které vytvořili ostatní uživatelé. Takto se podařilo získat knihovny pro FM modul i displej. Následující vytvořený kód má za úkol zobrazit hlavní obrazovku, na které bude zobrazena aktuálně naladěná frekvence, možnost manuálního i automatického ladění, nastavení hlasitosti a dat z RDS.+Vývojové prostředí ​www.mbed.org umožňuje vyhledat a importovat knihovny, které vytvořili ostatní uživatelé. Takto se podařilo získat knihovny pro FM modul i displej. Následující vytvořený kód má za úkol zobrazit hlavní obrazovku, na které bude zobrazena aktuálně naladěná frekvence, možnost manuálního i automatického ladění, nastavení hlasitosti a dat z RDS. 
  
 ---- ----
-**Velký počet proměnných,​ které jsou třeba například pro uložení nastavení ​mě pomohly zpřehlednit struktury** +**Velký počet proměnných,​ které jsou třeba například pro uložení nastavení ​mně pomohly zpřehlednit struktury** 
-<​code>​+<​code ​cpp> 
 +/* 
 ++-----------------------------------------------------+ 
 +|                                                     | 
 +|                                                     | 
 +|                FM radio s Si4703 ​                   | 
 +|                                                     | 
 +|                                                     | 
 ++-----------------------------------------------------+ 
 + */ 
 +// Autor: Adam Stepanek 
 +// Vytvoreno v ramci projektu MPOA 2016 
 +  
 +  
 +// Inkluze knihoven 
 +#include "​mbed.h"​ 
 +#include "​SparkFun-Si4703.h"​ 
 +#include "​SSD1306.h"​ 
 +#include "​millis.h"​ 
 +  
 +// Definice pro tlacitka 
 +#define LEFT    0x01 
 +#define CENTER ​ 0x02 
 +#define RIGHT   ​0x03 
 +  
 +// Definice pro displej 
 +#define MAIN    0x01 
 +#define MENU    0x02 
 +#define ONOFF   ​0x04 
 +#define VOLUME ​ 0x05 
 +  
 +// Konstruktory 
 +Serial pc(USBTX, USBRX); // tx, rx 
 +Si4703_Breakout radio(I2C_SDA,​ I2C_SCL, PTA1, &pc); 
 +  
 +// Nastaveni I/O 
 +DigitalIn btn_left(PTA5);​ 
 +DigitalIn btn_center(PTC8);​ 
 +DigitalIn btn_right(PTC9);​ 
 +  
 +// Definice funkci 
 +int button_pressed(void);​ 
 +void show_frequency(void);​ 
 +void show_screen(int screen, int position);​ 
 + 
 // Prostor pro ulozeni nastaveni // Prostor pro ulozeni nastaveni
 typedef struct{ typedef struct{
Řádek 37: Řádek 82:
    
 Frequency_Info frequency; Frequency_Info frequency;
 + 
 +// Nezbytne promenne
 +char rds[8]; ​               // Zde se uklada vysledek cteni RDS
 +char volume_char[2]; ​       // Aktualni hlasitost prevedena na text
 +char channel_char[4]; ​      // Aktualni frekvence prevedena na text
 +int btn_pressed = false; ​   // Bylo v minulosti zmacknuto tlacitko?
 +bool exit_menu = false; ​    // Navrat z menu
 +bool exit_submenu = false; ​ // Navrat z menu druhe urovne
 +int menu_position = 0;      // Ulozeni aktualni pozice sipky v menu
 +int submenu_position = 0;   // Ulozeni aktualni pozice sipky v submenu
 </​code>​ </​code>​
  
 ---- ----
-**** +**Hlavní funkce programu** 
-<​code>​+<​code ​cpp> 
 +// HLAVNI FUNKCE 
 +int main() { 
 +    init(); ​                        // Inicializace displeje SSD1306 
 +    cls(); ​                         // Smazani obrazovky 
 +    startMillis(); ​                 // Zapnuti pocitani milisekund 
 +    radio.powerOn(); ​               // Zapnuti radia 
 +    setup.volume = 2; 
 +    radio.setVolume(setup.volume); ​ // Nastaveni vychozi hlasitosti 
 +    frequency.current = 760;        // Naladeni vychozi frekvence 
 +    radio.setChannel(frequency.current);​ 
 +     
 +    show_screen(MAIN,​ 0);           // Zobrazeni hlavni obrazovky 
 +    show_frequency(); ​              // Zobrazeni aktualni frekvence 
 +     
 +  
 +   // HLAVNI SMYCKA  
 +   ​while(true){ ​        
 +        if(setup.rds){ ​                 // Cti RDS pokud je tato funkce zapnuta 
 +            radio.readRDS(rds,​ 1500); ​  // Cteni RDS s timeoutem 1.5 sekundy 
 +            OLED_ShowStr(50,​ 5, rds, 1);// Zobrazeni vysledku RDS, pokud byla prijata 
 +        } 
 +             
 +        switch(button_pressed()){ ​      // Ceka, dokud nebude zmacknuto tlacitko 
 +            case LEFT:                                      // Zmacknuto leve tlacitko 
 +                if(setup.tuning) ​                           // Je zapnuto manualni ladeni? 
 +                    radio.setChannel(--frequency.current); ​ // Manualni ladeni 
 +                else 
 +                    frequency.current = radio.seekDown(); ​  // Automaticke ladeni 
 +                if(frequency.current < 760){                // Pokud dosahneme pod minimalni frekvenci,​ 
 +                    frequency.current = 1080;               // bude naladena nejvyssi 
 +                    radio.setChannel(frequency.current);​ 
 +                    }                     
 +                show_frequency();​ 
 +            break; 
 +             
 +            case RIGHT: ​                                    // Zmacknuto prave tlacitko 
 +                if(setup.tuning) ​                           // Je zapnuto manualni ladeni? 
 +                    radio.setChannel(++frequency.current); ​ // Manualni ladeni 
 +                else 
 +                    frequency.current = radio.seekUp(); ​    // Automaticke ladeni 
 +                if(frequency.current < 760)                 // Ochrana proti naladeni neplatne frekvence 
 +                    frequency.current = radio.seekUp();​  
 +                show_frequency(); ​            
 +            break; 
 +         
 +         
 +         
 +            case CENTER: ​                                   // Vstup do MENU 
 +                while(!exit_menu){ 
 +                     
 +                    show_screen(MENU,​ menu_position+2); ​    // Ukaze sipku v menu 
 +                             
 +                    switch(button_pressed()){ ​              // Ceka dokud nebude zmacknuto tlacitko 
 +                         
 +                        case LEFT:                                      // Zmacknuto leve tlacitko, 
 +                            if(menu_position == 0)                      // provede se posunuti sipky 
 +                                menu_position = 3; 
 +                            else 
 +                                menu_position--;​ 
 +                        break; 
 +                         
 +                        case RIGHT: ​                                     // Zmacknuto leve tlacitko, 
 +                            if(menu_position == 3)                       // provede se posunuti sipky 
 +                                menu_position = 0; 
 +                            else 
 +                                menu_position++;​ 
 +                        break; 
 +                         
 +                        case CENTER: ​                   // Vstup do dalsi urovne MENU 
 +                            exit_submenu = false; 
 +                            switch(menu_position){ 
 +                                case 0:                 // SUBMENU Nastaveni Hlasitosti 
 +                                    exit_submenu = false; 
 +                                    while(!exit_submenu){ 
 +                                        radio.setVolume(setup.volume);​ 
 +                                        show_screen(VOLUME,​ 0); 
 +                                        switch(button_pressed()){ ​  // Pridat volume 
 +                                            case LEFT: 
 +                                                if(setup.volume == 0); 
 +                                                else 
 +                                                    setup.volume--;​ 
 +                                            break; 
 +                                            case RIGHT: ​            // Ubrat volume 
 +                                                if(setup.volume == 15); 
 +                                                else 
 +                                                    setup.volume++;​ 
 +                                            break; 
 +                                            case CENTER: ​           // Navrat do hlavniho menu 
 +                                                exit_submenu = true; 
 +                                            break; 
 +                                        } 
 +                                    } 
 +                                     
 +                                break; 
 +                                case 1:     // SUBMENU Manualni ladeni 
 +                                    exit_submenu = false; 
 +                                    while(!exit_submenu){ 
 +                                        cls(); 
 +                                        show_screen(ONOFF,​ setup.tuning+3);​ 
 +                                        if(button_pressed() == CENTER) 
 +                                            exit_submenu = true; 
 +                                        else 
 +                                            setup.tuning = !setup.tuning; ​      // Zapnuti nebo vypnuti 
 +                                    }                                           // manualniho ladeni 
 +                                break; 
 +                                case 2:     // SUBMENU Nastaveni RDS 
 +                                    exit_submenu = false; 
 +                                    while(!exit_submenu){ 
 +                                        cls(); 
 +                                        show_screen(ONOFF,​ setup.rds+3);​ 
 +                                        if(button_pressed() == CENTER) 
 +                                            exit_submenu = true; 
 +                                        else 
 +                                            setup.rds = !setup.rds; ​            // Zapnuti nebo vypnuti RDS 
 +                                    } 
 +                                break; 
 +                                case 3:     // Navrat z menu 
 +                                    show_screen(MAIN,​ 0); 
 +                                    show_frequency();​ 
 +                                    exit_menu = true; 
 +                                break; 
 +                            } 
 +                                 
 +                        break; 
 +                    } 
 +                } 
 +            break; 
 +        } 
 +        exit_menu = false; 
 +        menu_position = 0; 
 +         
 +        OLED_ShowStr(0,​ 5, "​Staince: ​            ",​ 1);         // Smazani informaci z RDS, pokud dojde k preladeni 
 +        }     
 +}
 </​code>​ </​code>​
  
 ---- ----
-**** +**Funkce pro zobrazováni na displeji** 
-<​code>​+<​code ​cpp> 
 +// FUNKCE 
 +  
 +// Funkce pro zjisteni, ktere tlacitko bylo stisknuto 
 +int button_pressed(void){ ​   
 +    btn_pressed = false; 
 +    while(!btn_pressed){ 
 +        
 +        if (btn_left) 
 +            btn_pressed = LEFT;                     // Indikace zmacknuteho leveho tlacitka 
 +             
 +        if (btn_center) 
 +            btn_pressed = CENTER; ​                  // Indikace zmacknuteho prostredniho tlacitka 
 +             
 +        if (btn_right) 
 +            btn_pressed = RIGHT; ​                   // Indikace zmacknuteho praveho tlacitka 
 +        } 
 +    while(btn_left || btn_center || btn_right); ​    // Dokud je tlacitko zmacknute, ceka 
 +    wait_ms(200); ​                                  // Jednoduche odstraneni zakmitu 
 +    return btn_pressed;​ 
 +
 +  
 +// Funkce pro zobrazeni aktualni frekvence 
 +void show_frequency(void){ 
 +                frequency.high = frequency.current / 10; 
 +                frequency.low = frequency.current % 10; 
 +                OLED_ShowStr(38,​ 2, " ​    ",​ 2); 
 +                sprintf(channel_char,​ "​%d.%d",​frequency.high,​ frequency.low);​ 
 +                OLED_ShowStr(38,​ 2, channel_char,​ 2); 
 +
 +  
 +//Funkce pro zobrazeni displeje (menu, hlavni obrazovka...) 
 +void show_screen(int screen, int position){ 
 +    switch(screen){ 
 +         
 +        case MAIN:      // Zobrazeni hlavni obrazovky 
 +            cls(); 
 +            locate(0, 0); 
 +            OLED_ShowStr(0,​ 0, " ​  FM Radio",​ 2); 
 +            OLED_ShowStr(0,​ 2, "< ​        ​MHz ​ >", 2); 
 +            OLED_ShowStr(0,​ 5, "​Staince:",​ 1); 
 +            OLED_ShowStr(0,​ 7, " ​      ​[MENU] ​       ", 1); 
 +            show_frequency();​  
 +        break; 
 +         
 +        case MENU:      // Zobrazeni menu 
 +            cls(); 
 +            OLED_ShowStr(0,​ 0, " ​   MENU", 2); 
 +            OLED_ShowStr(0,​ 2, " ​  ​Hlasitost",​ 1); 
 +            OLED_ShowStr(0,​ 3, " ​  ​Manualni ladeni",​ 1); 
 +            OLED_ShowStr(0,​ 4, " ​  ​RDS",​ 1); 
 +            OLED_ShowStr(0,​ 5, " ​  ​Zpet",​ 1); 
 +            OLED_ShowStr(0,​ 7, " ​      ​[VYBRAT] ​     ", 1); 
 +            OLED_ShowStr(0,​ position, "​->",​ 1);         // Zobrazeni sipky na spravne pozici 
 +        break; 
 +         
 +        case ONOFF: ​    // Zobrazeni submenu volby On/Off 
 +            cls(); 
 +            OLED_ShowStr(0,​ 3, " ​  ​Off",​ 1); 
 +            OLED_ShowStr(0,​ 4, " ​  ​On",​ 1); 
 +            OLED_ShowStr(0,​ position, "​->",​ 1);         // Zobrazeni sipky na spravne pozici 
 +            OLED_ShowStr(0,​ 7, " ​        ​[OK] ​       ", 1); 
 +             
 +        break; 
 +         
 +        case VOLUME: ​   // Volba hlasitosti 
 +            cls(); 
 +            sprintf(volume_char,​ "​%d",​setup.volume); ​   // Zobrazeni aktualni hlasitosti 
 +            OLED_ShowStr(60,​ 3, volume_char,​ 2); 
 +        break; 
 +    } 
 +}
 </​code>​ </​code>​
 +
 +----
 +**Zapojení**
 +
 +{{ :​2015:​si4703-radio:​dsc4343.jpg?​direct500 |}}
  
 ---- ----
Řádek 56: Řádek 321:
 Výsledkem projektu je vytvoření aplikace, které spojuje modul rádia, displeje a tři tlačítka v použitelný radiopřijímač. Kromě automatického ladění je možné frekvenci zadat i ručně, je zde i možnost ovládání hlasitosti. Pomocí dat z RDS se podařilo zobrazit jen název u jedné stanice, a to u EVROPY 2. Lepšího výsledku by šlo dosáhnout pouze s vlastní knihovnou pro ovládání FM modulu. Programování mi zpříjemňoval poslech částečně naprogramovaného rádia. Výsledkem projektu je vytvoření aplikace, které spojuje modul rádia, displeje a tři tlačítka v použitelný radiopřijímač. Kromě automatického ladění je možné frekvenci zadat i ručně, je zde i možnost ovládání hlasitosti. Pomocí dat z RDS se podařilo zobrazit jen název u jedné stanice, a to u EVROPY 2. Lepšího výsledku by šlo dosáhnout pouze s vlastní knihovnou pro ovládání FM modulu. Programování mi zpříjemňoval poslech částečně naprogramovaného rádia.
  
-Kromě tohoto modulu FM přijímače mě zaujal i modul pro vysílání FM signálu, například [[https://​learn.adafruit.com/​adafruit-si4713-fm-radio-transmitter-with-rds-rdbs-support/​overview|Si4713]]. Existují i integrované obvody, které slučují obě funkce (příjem i vysílání). Daly by se použít k bezdrátovému přenosu zvuku například z mp3 přehrávače nebo PC.+Kromě tohoto modulu FM přijímače mě zaujal i modul pro vysílání FM, například [[https://​learn.adafruit.com/​adafruit-si4713-fm-radio-transmitter-with-rds-rdbs-support/​overview|Si4713]]. Existují i integrované obvody, které slučují obě funkce (příjem i vysílání). Daly by se použít k bezdrátovému přenosu zvuku například z mp3 přehrávače nebo PC. Nebo k bezdrátovému přenosu dat, protože mají implementovanou funkci RDS. Dále modul [[http://​www.silabs.com/​products/​audio/​fm-am-receiver/​Pages/​si4707.aspx|​Si4707]] pro příjem zpráv o počasí.
  
-Celý zdrojový kód je uveřejněný na stránkách mbed [[https://​developer.mbed.org/​users/​vodavprasku/​code/​projekt_Si4703/​| Projekt MPOA Si4703 ]].+Celý zdrojový kód je uveřejněný na stránkách mbed.org: [[https://​developer.mbed.org/​users/​vodavprasku/​code/​projekt_Si4703/​| Projekt MPOA Si4703 ]].
2015/si4703-radio.1453038937.txt.gz · Poslední úprava: 2016/01/17 14:55 autor: Adam Štěpánek