以前も同様の投稿(ESP32でPCM510xA-V3を使う)をしました。しかしその後、PCM5102A 基板が突然息をしなくなりました。使い方が悪かったかも知れないので、このままではマズイと判断、同じ物を
再度購入、見直して動作確認できた最新版を上げることにしました。
ESP32ボード(ArduinoIDE2.3.2 上では、Heltec WiFi Kit 32)とは次のような接続に。
Heltec WiFi Kit 32 | PCM5102A |
---|---|
- | GND |
- | MCLK |
25 | BICK(BCK) |
27 | DATA(DOUT,DIN) |
26 | LRCK(LCK) |
GND | GND |
- | MUTE |
5V | VCC |
新たな取組みとして、チャンネルを変更するためにタクトスイッチを利用しました。恥ずかしながら、これまでタクトスイッチを利用できずにいました。次の記事
を参考にし、使えました。
今回は回路のショートなどにも気を付けることにします。
1.ESP32ボードは2列ピンメスソケットでユニバーサル基板に取り付けます。
2.ユニバーサル基板はESP32ボードとほぼ同じ大きさに切り詰めて使います。
ただし、2列ピンの外側にアクセスできるよう、またGNDを増設するために少し大きくします。
3.そうしたESP32ボードとPCM5102を、丁度良い大きさの百均の糸ようじケースの中に収めます。
4.左の写真の右下にあるようにケース側面にタクトスイッチを取り付けます。
5.Pin21番からタクトスイッチを介しGNDに繋がるようにジャンパー線をはんだ付けします。
6.スケッチの中であらかじめ Pin21番は「INPUT_PULLUP」で「HIGH」にしておく。
7.タクトスイッチを押したときだけGNDに繋がり、Pin21番は「LOW」になります。
8.ちょい押しでチャンネルアップ、1秒以上押しでチャンネルダウンとしました。
ArduinoIDE 2.3.2 上にて下のスケッチで動作します。チャンネル変化のためダブルコアにしてあります。コンパイルサイズが大きくなるようなので、
Partition Scheme: "Huge APP (3MB ...)"
としておきます。
ビルトインディスプレイ(ssd1306)に情報を表示できるように工夫しましたが、邪魔になれば「display」の箇所はカットしてください。
NetRadio_2.ino
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define I2S_DOUT 27 // 22 DIN
#define I2S_BCLK 25 // BCK
#define I2S_LRC 26 // LCK
#define OLED_SCL 15
#define OLED_SDA 4
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define intPin0 21 // Connecting GND makes
// channel++, channel--
String ssid = "Your SSID";
String password = "Your Password";
Audio audio;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);
uint8_t volume = 21; // 0...21
uint8_t cur_station = 0; // current station No.
#define EofRadios 10 // 0 - 10
String stations[] = {
"WRTI_CLASSICAL https://playerservices.streamtheworld.com/api/livestream-redirect/WRTI_CLASSICAL.mp3",
"WRTI_JAZZ https://playerservices.streamtheworld.com/api/livestream-redirect/WRTI_JAZZ.mp3",
"relax.stream.publicradio.org/relax.mp3", // Your Classical - Relax
"ais-sa2.cdnstream1.com/b22139_128mp3", // 101 SMOOTH JAZZ
"smoothjazz.cdnstream1.com/2585_128.mp3",
"avw.mdr.de/streams/284310-0_mp3_low.m3u",
"www.radiomonique.nl/winamp_RM_64.pls",
"ice1.somafm.com/illstreet-128-mp3", // SomaFM / Illinois Street Lounge
"ice1.somafm.com/secretagent-128-mp3", // SomaFM / Secret Agent
"ice1.somafm.com/seventies-128-mp3", // SomaFM / Left Coast 70s
"ice1.somafm.com/bootliquor-128-mp3" // SomaFM / Boot Liquor
//audio.connecttoFS(SD, "/test.wav"); // SD
};
TaskHandle_t thp[1];
void setup() {
Serial.begin(115200);
pinMode(intPin0, INPUT_PULLUP);
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);
Wire.begin(OLED_SDA, OLED_SCL);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
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"));
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(volume); // 0...21
audio.connecttohost(stations[cur_station].c_str());
//audio.connecttoFS(SD, "/test.wav"); // SD
display.setCursor(0, 0);
display.print("NetRADIO:No.");
display.setCursor(72, 0);
display.print("0");
display.setCursor(0, 8);
display.print(stations[cur_station].c_str());
display.display();
xTaskCreatePinnedToCore(Core0, "Core0", 4096 * 2, NULL, 3, &thp[0], 0);
// if 4096, resetted by WDTimer in some cases.
}
void loop() {
audio.loop();
}
void Core0(void *args) {
while (1) {
delay(1);
if (digitalRead(intPin0) == LOW) { // Once GND
audio.stopSong();
delay(1000);
if (digitalRead(intPin0) == LOW) { // Again GND
cur_station--;
if (cur_station >= 255) { cur_station = EofRadios; }
} else { // Once open, soon GND connected
cur_station++;
if (cur_station > EofRadios) { cur_station = 0; }
}
delay(1000);
Serial.print(F("\n\rStation : "));
Serial.print(cur_station);
Serial.print(F(" > "));
Serial.println(F(stations[cur_station].c_str()));
audio.connecttohost(stations[cur_station].c_str());
display.clearDisplay();
display.setCursor(0, 0);
display.print("NetRADIO:No.");
display.setCursor(72, 0);
display.print(cur_station);
display.setCursor(0, 8);
display.print(stations[cur_station].c_str());
display.display();
}
}
}
char BITRATE[6];
void audio_showstreamtitle(const char *info) {
Serial.print(F("Title : "));
Serial.println(info);
display.clearDisplay();
display.setCursor(0, 0);
display.print("NetRADIO:No.");
display.setCursor(72, 0);
display.print(cur_station);
display.setCursor(0, 8);
display.print(stations[cur_station].c_str());
display.setCursor(0, 8 * 6);
display.print(info);
display.setCursor(90, 0);
display.print(" ");
display.setCursor(90, 0);
display.print(BITRATE); // ?
display.display();
}
void audio_bitrate(const char *info) {
Serial.print(F("bitrate "));
Serial.println(info);
strncpy(BITRATE, info, 6);
display.setCursor(90, 0);
display.print(" ");
display.setCursor(90, 0);
display.print(BITRATE); // ?
display.display();
}
// optional
void audio_info(const char *info) {
Serial.print("info->Serial = ");
Serial.println(info);
}
/*
void audio_id3data(const char *info){ //id3 metadata
Serial.print("id3data "); Serial.println(info);
}
void audio_eof_mp3(const char *info){ //end of file
Serial.print("eof_mp3 "); Serial.println(info);
}
void audio_showstation(const char *info) {
Serial.print("station "); Serial.println(info);
}
void audio_commercial(const char *info){ //duration in sec
Serial.print("commercial "); Serial.println(info);
}
void audio_icyurl(const char *info){ //homepage
Serial.print("icyurl "); Serial.println(info);
}
void audio_lasthost(const char *info){ //stream URL played
Serial.print("lasthost "); Serial.println(info);
}
*/
駄文を最後まで見ていただきありがとうございました。