ESP32でインターネットラジオに挑戦して、面白い事に気付いたり試したりしたので投稿します。
環境は、"ArduinoIDE2.0.4"、"TTGO-LoRa32-OLED V2.0"、"PCM5102"です。
まず1つ目は
外部のDACモジュール(PCM5102など)を使う場合、ピンアサインはかなり自由。OUTPUTできるピンであれば使える?
最初、他の人達の見よう見まねでやっている時には、"PCM5102"に繋ぐピンは決まっていると思っていました。しかし、たまたま私が使用しているボードのGPIO26がダメになっていたので他のピンを使っていて気付いてしまいました。例えば、私の場合
以前 | 今回 | |
---|---|---|
BCK(BCLK) | 27 | 2 |
DIN(DOUT) | 25 | 4 |
LCK(LRCLK,WSEL?) | 22 | 0 |
でも動いています。全てのピンについて試してはいませんので、他のピンにどれだけ使えるものがあるかは解りません。
次の2つ目は、当然のことですが通信状態が悪ければ音はブツブツ途切れます。朝、昼、夕方の通信状態の悪い時に起こり易いです。幸い"TTGO-LoRa32-OLED V2.0"は、付属の外部アンテナのおかげかあまり途切れず快適です。
3つ目。前回投稿後シャープ測距センサーを2個に増設し、音量調整もできるようにしてみました。ただ、delay()設定が微妙で誤動作はありますね。まあこんなものかと思いますが。センサーの前で手をヒラヒラさせている姿を想像してください、笑えるかもですね。でも、魔法か昔夢見た未来感がありますよ。
4つ目。ESP32はデュアルコアだということで、以下の記事を参考にもう一つの「コア0」を動かしてみました。
測距センサーでの処理を全面的にコア0の方に移してみました。無事働いているようです。
最後余談になります。ウェブラジオのURLをどう書くかよくわかっていませんでしたが、次のサイトが勉強になりました。
以下にスケッチを示します。(inoファイルの可読性向上の方法を教えてくださった方に感謝いたします。)
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#define I2S_DOUT 4 // 25 DIN
#define I2S_BCLK 2 // 27 (Pin26 is dead.)
#define I2S_LRC 0 // 22 LCK
#define intPin0 34
#define intPin1 35
#define EofRadios 4 // 0-4
Audio audio;
String ssid = "*******";
String password = "********";
String stations[] = {
"181.fm_TranceJaz http://listen.livestreamingservice.com/181-trancejazz_64k.aac",
"181.fm__Energy93 http://listen.livestreamingservice.com/181-energy93_64k.aac",
"181.fm__Pow[Exp] http://listen.livestreamingservice.com/181-powerexplicit_64k.aac",
"181.fm__The_Beat http://listen.livestreamingservice.com/181-beat_64k.aac",
"181.fm__UK_Top40 http://listen.livestreamingservice.com/181-uktop40_64k.aac"
};
int cur_station = 0; // current station No.
int volume = 12;
TaskHandle_t thp[1];
void setup() {
Serial.begin(115200);
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid.c_str(), password.c_str());
while (WiFi.status() != WL_CONNECTED) delay(1500);
Serial.println(F("WiFi start"));
pinMode(intPin0, INPUT);
pinMode(intPin1, INPUT);
Serial.print(F("\n\rStation : "));
Serial.print(cur_station);
Serial.print(F(" > "));
Serial.println(stations[cur_station].c_str());
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(volume); // 0...21
audio.connecttohost(stations[cur_station].c_str());
xTaskCreatePinnedToCore(Core0, "Core0", 4096 * 2, NULL, 3, &thp[0], 0);
// if 4096, resetted by WDTimer in some cases.
}
void loop() {
audio.loop();
/*
if (analogRead(intPin0) > 2300) {
audio.stopSong();
delay(500);
if (analogRead(intPin0) > 2300) {
cur_station--;
if (cur_station < 0) { cur_station = EofRadios; }
} else {
cur_station++;
if (cur_station > EofRadios) { cur_station = 0; }
}
delay(2500);
Serial.print(F("\n\rStation : "));
Serial.print(cur_station);
Serial.print(F(" > "));
Serial.println(stations[cur_station].c_str());
audio.connecttohost(stations[cur_station].c_str());
}
*/
}
int v0,v1;
void Core0(void *args) {
while (1) {
delay(1);
//サブで実行するプログラムを書く
v0=analogRead(intPin0); // 左センサー
v1=analogRead(intPin1); // 右センサー
if (v0 > 2600) { // 左センサー
delay(250);
if (analogRead(intPin0) > 2600) { // 0.25秒後も手を翳し続けていたら
volume--;
if (volume < 0) { volume = 0; } // 0...21
Serial.print(F(" Volume > "));
Serial.println(volume);
audio.setVolume(volume);
delay(2000);
} else {
audio.stopSong();
delay(100);
cur_station--;
if (cur_station < 0) { cur_station = EofRadios; }
delay(2000);
Serial.print(F("\n\rStation : "));
Serial.print(cur_station);
Serial.print(F(" > "));
Serial.println(stations[cur_station].c_str());
audio.connecttohost(stations[cur_station].c_str());
}
}
if (v1 > 2600) { // 右センサー
delay(250);
if (analogRead(intPin1) > 2600) { // 0.25秒後も手を翳し続けていたら
volume++;
if (volume > 21) { volume = 21; } // 0...21
Serial.print(F(" Volume > "));
Serial.println(volume);
audio.setVolume(volume);
delay(2000);
} else {
audio.stopSong();
delay(100);
cur_station++;
if (cur_station > EofRadios) { cur_station = 0; }
delay(2000);
Serial.print(F("\n\rStation : "));
Serial.print(cur_station);
Serial.print(F(" > "));
Serial.println(stations[cur_station].c_str());
audio.connecttohost(stations[cur_station].c_str());
}
}
}
}
// optional
void audio_showstation(const char *info) {
Serial.print("station ");
Serial.println(info);
}
void audio_showstreamtitle(const char *info) {
Serial.print(F("streamtitle "));
Serial.println(info);
}
void audio_bitrate(const char *info) {
Serial.print(F("bitrate "));
Serial.println(info);
}
余計ですが、次のサイトで多くのウェブラジオ局(外国)を知ることができます。