Internetové rádio ovládané dálkovým ovladačem

ARDUINO UNO, ETHERNET SHIELD W5100, AUDIO SHIELD VS 1053 B, Infračervená přijímací LED dioda VS 1838 B, I2C LCD displej.
Toto je poslední příklad použití Arduino UNO jako Internetového rádia. Jak již bylo v předchozích článcích napsáno, UNO má poměrně malou paměť pro program a data. U tohoto projektu se dostáváme na jeho maximum, proto je zde snížen počet stanic z 18 na 15.
- Je předvoleno 15 stanic Internetových rádií
- Přepínání stanic a regulace hlasitosti pomocí dálkového ovladače
- Lze si předvolit stanici, která začne hrát po zapnutí Arduina
- Předvolba a název aktuálně přehrávané stanice se zobrazuje na LCD

Pro příjem infračerveného signálu z DO jsem použil IR diodu VS 1838B, která pracuje na střední frekvenci 38 kHz a je poměrně často používána v zařízeních ovládaných DO. V českých obchodech jde sehnat za cca. 5 Kč. Dálkový ovladač jsem použil univerzální za 100 Kč, ale na tom nezáleží, můžete použít jakýkoliv funkční. Důležité je ale znát kódy které vysílá při stisknutí tlačítka. To lze zjistit tak, že do Arduina nahrajeme tento program, otevřeme monitorování sériového portu a zaznamenáme si výpis.
#include <IRremote.h>const int RECV_PIN = 5; // Datový výstup IR připojen na pin 5 Arduino IRrecv irrecv(RECV_PIN); // Deklarace přijímaných dat decode_results results; // Reprezentuj výsledek jako ... void setup(){ Serial.begin(9600); // COM 9,6 kB irrecv.enableIRIn(); // Aktivuj IR přijímač irrecv.blink13(true); // Taktovací frekvence IR } void loop(){ if (irrecv.decode(&results)){ Serial.println(results.value, HEX); // Prezentuj přijatá data v HEX kódu na COM delay(300); // Vyčkej 300 ms do dalších dat irrecv.resume(); // Zpracuj přijatá data } }
Zapneme monitorování sériového portu a mačkáme na DO tlačítka…

Někam si poznačíme, jaký kód vysílá klávesa kterou jsme stiskli a chceme v našem projektu používat. V tomto příkladě se používá tlačítko CH- ( stanice předchozí ), CH + ( stanice následující ), – ( hlasitost snížit ), + ( hlasitost zvýšit ). Kvůli omezením Arduina UNO využijeme jen tyto čtyři klávesy, v projektech pro Arduino MEGA a ESP 32 téměř všechny.
/* Internetové rádio AURUINO UNO ( nebo kompatibilní ) s VS 1053B Shield ( nebo kompatibilní ) a Ethernet Shield W5100 R3 * LCD displej I2C ( 2 řádky, 16 znaků na řádek ), IR přijímací dioda VS 1838B. * Autor : David Kohout 1 / 2020 * * * */ // Standartní knihovny #include <VS1053.h>// Standartní knihovna VS1053 ( Funguje i pod naším Shieldem, originál knihovnu SFEMP3Shield nepožívat, #include <IRremote.h><Ethernet.h> // Knihovna IR Receive pro Arduino - http://z3t0.github.io/Arduino-IRremote/ #include <LiquidCrystal_I2C.h> // Standartní knihovna Ethernet - Shield W5100 #include // Knihovna LCD displeje const int RECV_PIN = 5; // IR přijímací dioda připojena na pin 5 Arduina IRrecv ovladac(RECV_PIN); // IRrecv jako ovladac, připojený na pin viz výše decode_results results; // Přijatá data uložit jako results // SPI porty ARDUINA MEGA // 50 - MISO Při použití ARDUINO MEGA proklemovat 50 Arduino na 12 pin zvukovky // 51 - MOSI Při použití ARDUINO MEGA proklemovat 51 Arduino na 11 pin zvukovky // 52 - SCK Při použití ARDUINO MEGA proklemovat 52 Arduino na 13 pin zvukovky // --------- Nemusí se ohýbat nožičky ze Shieldu, prostě natvrdo dát klemu ----------- VS1053 MP3player(6,7,2,8); // X_CS 6 pin, X_DCS 7 pin, DREQ 2 pin, X_RESET 8 pin byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // Přiřazení MAC adresy síťovce - možno změnit EthernetClient client; // Ethernet jako klient LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD na adrese 0x27, 16 znaků, 2 řádky //--------------------------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------------------------// uint8_t mp3buff[32]; // Velikost bufferu 32 Byte const char *host; // Zde se uloží adresa serveru s požadovaným streamem const char *path; // Zde se uloží cesta serveru s požadovaným streamem int httpPort; // Zde se uloží port serveru s požadovaným streamem int ID_stanice=3; // Zde se uloží číslo aktuálně přehrávané stanice - konstanta číslo stanice, které začne hrát po spuštění Arduina int pamet_ID_stanice; // Zde se uloží číslo posledně přehrávané stanice const char *nazev; // Zde se uloží jméno aktuálně přehrávané stanice int Volume=10; // Výchozí hlasitost rádia po zapnutí void setup() { ovladac.enableIRIn(); // Start IR přijímací diody VS 1838B ovladac.blink13(true); // Frekvence snímkování IR VS 1838B Ethernet.begin(mac); // Start Ethernetového spojení, IP adresu přiřadí router MP3player.begin(); // Start zvukové karty VS1053B Shield MP3player.setVolume(Volume); // Nižší číslo vyšší hlasitost lcd.init(); // Inicializace LCD displeje lcd.backlight(); // Podsvícení LCD displeje client.print(String("GET ") + path + " HTTP/1.1\r\n" + // Adresa serveru se streamem - požadavek při spuštění Arduina "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); } void loop() { // Hlavní program - smyčka if (ovladac.decode(&results)){ // Pokud IR dioda přijme nějaká data, tak hledej níže switch(results.value){ // Nějaká přijatá data z IR... case 0xFFA25D: // Pokud je to kód 0xFFA25D, CH - if (ID_stanice >1) { // a je-li aktuální stanice větší jak 1, ID_stanice=ID_stanice -1; // tak odečti číslo 1 od aktuální stanice } break; case 0xFFE21D: // Pokud je to kód 0xFFE21D, CH + if (ID_stanice <15) { // a je-li aktuální stanice menší jak 13, ID_stanice=ID_stanice +1; // tak přičti číslo 1 k aktuální stanici } break; case 0xFFE01F: // Pokud je to kód 0xFFE01F, VOLUME - if (Volume <95){ // a je-li aktuální hlasitost menší jak 95, Volume=Volume +5; // tak připočti čislo 5 ( vyšší číslo menší hlasitost ) MP3player.setVolume(Volume); // Vyšší číslo menší hlasitost } break; case 0xFFA857: // Pokud je to kód 0xFFA857, VOLUME + if (Volume >5){ // a je-li aktuální hlasitost větší jak 5, Volume=Volume -5; // tak odeči číslo 5 ( menší číslo vyšší hlasitost ) MP3player.setVolume(Volume); // Nižší číslo větší hlasitost } } delay(200); // Čekej 200 ms, ovladac.resume(); // Pak můžeš přijmout další data z IR } switch(ID_stanice){ // Přepínání stanic - ID stanice case 1: nazev = " Hitradio 80 CZ"; host = "ice.abradio.cz"; // Hitrádio 80 path = "/hit80128.mp3"; httpPort = 80; break; case 2: nazev = " Hitradio 90 CZ"; host= "ice.abradio.cz"; // Hitrádio 90 path = "/hit90128.mp3"; httpPort = 80; break; case 3: nazev = " Star*Sat Radio"; host = "starsat-ais-edge-3005.fra-eco.cdn.addradio.net"; // DE STAR*SAT RADIO path = "/starsat/live/mp3/low/stream.mp3"; httpPort = 80;; break; case 4: nazev = " Dance radio"; host = "icecast6.play.cz"; // Dance Radio path = "/dance-radio128.mp3"; httpPort = 80;; break; case 5: nazev = " FUN radio SK"; host = "stream.funradio.sk"; // Fun rádio SK path = "/dance128.mp3"; httpPort = 8000; break; case 6: nazev = " Hitradio Orion"; // CZ Hitrádio Orion Morava host = "ice.abradio.cz"; path = "/orionmorava128.mp3"; httpPort = 8000; break; case 7: nazev = " Blanik FM"; // CZ Rádio Blaník FM host = "ice.abradio.cz"; path = "/blanikfm128.mp3"; httpPort = 80; break; case 8: nazev = " N-Joy Bulgaria"; // BG N-Joy Radio host = "live.btvradio.bg"; path = "/njoy.mp3"; httpPort =80; break; case 9: nazev = "Evropa 2 Top 40"; // CZ Evropa 2 Top 40 host = "ice.actve.net"; path = "/web-e2-top40"; httpPort =80; break; case 10: nazev = " KISS 98 FM"; // CZ Kiss 98 FM host = "icecast4.play.cz"; path = "/kiss128.mp3"; httpPort =80; break; case 11: nazev = "Zlin Best Ballads"; // CZ Rádio Zlín Best Ballads host = "212.111.2.151"; path = "/radiozlin_128.mp3"; httpPort =8000; break; case 12: nazev = "Monte Carlo 98.2"; // Monako RMC 98.2 host = "radiomonaco.ice.infomaniak.ch"; path = "/radiomonaco-128.mp3"; httpPort =80; break; case 13: nazev = " Cherie Ballads"; // FR Chérie Ballads host = "185.52.127.131"; path = "/fr/30297/mp3_128.mp3"; httpPort =80; break; case 14: nazev = " Cherie FM"; // FR Chérie FM host = "185.52.127.163"; path = "/fr/30201/mp3_128.mp3"; httpPort =80; break; case 15: nazev = " Cherie 80s"; // FR Chérie 80s host = "185.52.127.159"; path = "/fr/30237/mp3_128.mp3?"; httpPort =80; break; // case 16: // nazev = " Athens Party GR"; // GR Athens Party // host = "ice.onestreaming.com"; // path = "/athensparty"; // httpPort =80; // break; // case 17: // nazev = " Radio Rubi"; // host = "icecast8.play.cz"; // Radio Rubi // path = "/radiorubi128.mp3"; // httpPort =80; // break; // case 18: // nazev = " SKY Radio SK"; // SK SKY Rádio // host = "stream.skyradio.sk"; // path = "/sky128"; // httpPort =8000; // break; } if(!client.connected() || pamet_ID_stanice!=ID_stanice){ if(client.connect(host, httpPort)){ // Adresa serveru se streamem - ve smyčce client.print(String("GET ") + path + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); pamet_ID_stanice=ID_stanice; lcd.clear(); // Smaž LCD displej, lcd.setCursor(2,0); // Nastav kurzor na 2 znak 1 řádku lcd.print("Predvolba"); lcd.setCursor(13,0); // Nastav kurzor na 13 znak 1 řádku lcd.print(ID_stanice); // Zobraz číslo ( ID ) stanice lcd.setCursor(0,1); // Nastav kurzor na 1 znak 2 řádku lcd.print(nazev); // Zobraz název stanice } } if(client.available() > 0){ // Pokud je server dostupný, tak : uint8_t bytesread = client.read(mp3buff,32); // ulož přijatá data do bufferu MP3player.playChunk(mp3buff,bytesread); // a přehraj na VS1053B Shield } } // To je vše, příjemnou zábavu ! David Kohout 1 / 2020
Jelikož v tomto projektu již nepracujeme s tlačítky, knihovna Bounce2 byla nahrazena knihovnou IRremote pro IR přijímací diodu.
switch(results.value){ // Nějaká přijatá data z IR… case 0xFFA25D: // Pokud je to kód 0xFFA25D, CH – if (ID_stanice >1) { // a je-li aktuální stanice větší jak 1, ID_stanice=ID_stanice -1; // tak odečti číslo 1 od aktuální stanice } break; case 0xFFE21D: // Pokud je to kód 0xFFE21D, CH + if (ID_stanice <15) { // a je-li aktuální stanice menší jak 13, ID_stanice=ID_stanice +1; // tak přičti číslo 1 k aktuální stanici } break;
Pro data z dálkového ovladače použijeme známé instrukce SWITCH a CASE. Na výpisu výše je vidět, jak to funguje. Jsou-li přijata data 0xFFA25D a je-li aktuálně přehrávaná stanice větší jak 1, odečti číslo 1 z aktuálně přehrávané a aktualizuj ho. Takže například hraje-li aktuálně předvolba číslo 4 a dojdou z IR data 0xFFA25D, bude nám hrát stanice na předvolbě č.3. Na stejném principu funguje tlačítko CH+ ( následující stanice ) a regulace hlasitosti.
Můžeme samozřejmě experimentovat s DO dle libosti, tlačítko 1 použít jako předvolba 1, tlačítko 7 jako předvolba 7…. Pozor ale na paměť Arduina, i když Váš projekt do něho nahrajete, zůstane mu tak málo volné paměti, že buď nebude vůbec hrát nebo bude dělat neplechu. Kdo má Arduino MEGA, ten to nemusí řešit 🙂
Zkouška funkčnosti
Jedna odpověď
V prvnim kroku jsem predvedl ovladnuti dalkove ovladanych elektrickych zasuvek, kdy muzeme Arduinem jak poslouchat povely vysilane dalkovym ovladacem (takze vlastne mame sikovny osmitlacitkovy dalkovy ovladac cehokoliv s Arduinem), tak muzeme i sami vysilat povely spinajici elektricke zasuvky. Tim ziskame jednoduchy, levny, elegantni a hlavne bezpecny zpusob spinani i vykonove naruzivych zarizeni Arduinem – a jeste navic fungujici bezdratove na dalku.