70歳の挑戦... PCM5102A DAC（32bit 384kHz）でネットラジオ再び

　しばらく眠っていた「PCM510xA-V3」を使おうとしたらハマったので、備忘録として投稿します。次のサイトは今も見ることが出来ます（初出2017年）。
 （保護されていない通信）http://nfj2019.livedoor.blog/archives/2601664.html
 
![PCM510xA.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/3eca4d75-45cd-3c21-c562-d1275579775b.jpeg)
　1年程前に購入し１・２度使用した記憶です。しかし今回あれれ？という感じで動きません。壊れたのかと諦めかけましたが、色々試して音が出るようになりました。またゴミになっちゃたかと思いましたが、良かった良かった（音もgood:heart:）。
　結果、「ESP32ボード」と次のような接続になります。
 |Heltec WiFi LoRa32(V2)|PCM5102A|注目|
 |------|------|----|
 | 22   | DATA(DOUT,DIN) ||
 | 25   | LRCK(LCK)  ||
 | 26   | BICK(BCK)  ||
 | 5V   | VCC   ||
 | 3V3  | <ins> MUTE |これを見つけるのに苦労しました|
 |      | GND,MCLK(隣接)| ジャンパーピンで繋いでおく|
 | GND  | GND | |
 
34ピンをGNDに接続しておき、１秒弱のオープンにてチャンネルアップできる仕様です。ArduinoIDEにて次のスケッチで動作します。ダブルコアのつもりですが（？）
```c:NetRadio.ino
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include "SPI.h"
//#include "SD.h"
//#include "FS.h"

#define I2S_DOUT 22  // DIN
#define I2S_BCLK 26  // BCK
#define I2S_LRC 25   // 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 34  // GND connected
                    // channel++, channel--

#define EofRadios 6  // 0-6

Audio audio;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

String ssid = "Your SSID";
String password = "Your Password";

String stations[] = {
  "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
  "ais-sa2.cdnstream1.com/b22139_128mp3",  // 101 SMOOTH JAZZ
  "smoothjazz.cdnstream1.com/2585_128.mp3",
  "relax.stream.publicradio.org/relax.mp3"        // Your Classical - Relax
  //  audio.connecttoFS(SD, "/test.wav");     // SD
};

uint8_t cur_station = 0;  // current station No.
int volume = 12;
TaskHandle_t thp[1];

void setup() {
  Serial.begin(115200);

  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("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("NET RADIO ");
  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 (analogRead(intPin0) > 1000) { // Once open
      audio.stopSong();
      delay(1000);
      if (analogRead(intPin0) > 1000) { // Again open
        cur_station--;
        if (cur_station < 0) { 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(stations[cur_station].c_str());
      audio.connecttohost(stations[cur_station].c_str());

      display.clearDisplay();
      display.setCursor(0, 0);
      display.print("Internet RADIO ");
      display.setCursor(0, 8);
      display.print(stations[cur_station].c_str());
      display.display();
    }
  }
}

void audio_showstreamtitle(const char *info) {
  Serial.print("Title : ");
  Serial.println(info);

  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Internet RADIO ");
  display.setCursor(0, 8);
  display.print(stations[cur_station].c_str());
  display.setCursor(0, 32);
  display.print(info);
  display.display();
}

void audio_bitrate(const char *info) {
  Serial.print("bitrate     ");
  Serial.println(info);

  display.setCursor(0, 56);
  display.print("                ");
  display.setCursor(0, 56);
  display.print(info); // ?
  display.display();
}

// optional
/*
void audio_info(const char *info){
  Serial.print("info        "); 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);
}
*/
```
　駄文を最後まで見ていただきありがとうございました。