0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

71歳の挑戦... PCM510xA-V3でネットラジオ タクトスイッチ選局版(2025/01自家最新)

Last updated at Posted at 2025-01-29

 以前も同様の投稿(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秒以上押しでチャンネルダウンとしました。

Pcm5102A_v3.jpg

ArduinoIDE 2.3.2 上にて下のスケッチで動作します。チャンネル変化のためダブルコアにしてあります。コンパイルサイズが大きくなるようなので、

Partition Scheme: "Huge APP (3MB ...)"

としておきます。

NetRadio_Huge.jpg

ビルトインディスプレイ(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);
}
*/

 駄文を最後まで見ていただきありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?