お父にゃんの電子工作

お父にゃんの電子工作

暇なおじさんが、電子工作(主にラジオ製作)をして勝手な感想を書く

Webラジオ3号機を作っている。こないだ、アルバムアートワークを大きく表示する版を作って、もうそろそろ完成版にしようかな?と思っていた。

 

ところが、Google Geminiに別件で色々訊いていたら、ESP32-audioI2SにVUメーターを表示するための機能が備わっていることが判明した。

この機能については、ESP32-audioI2SのGitHubを見ても特に何も書いてないので、知らない人は多いと思う。もちろん、おじさんは全く知らなかった。

 

使い方は簡単で、audio.getVUlevel()を呼ぶと直近の音量の平均値?が符号なし16ビットの値として返ってくる。上位8ビットがL側の音量、下位8ビットがR側の音量がセットされている。

 

以下のようなプログラムでloop()の中でVU_meter()を呼んで100msごとにaudio.getVUlevel()で音量を取得して表示させる。

今回は、昔のカセットデッキ(今どきの若者は知らないか・・)なんかに付いていたLED  VUメーター風に16段階に表示させてみた。

なお、audio.getVUlevel()で返ってくる値は最大で180くらいだったので、そのくらいで最大表示となるようにした。

// VUメーター用変数
unsigned long lastUpdate = 0;
const int updateInterval = 100; // 100ms

 

//----------------------------
//100msごとにVUメーターを更新
//----------------------------
void VU_meter(){
  // 100ms毎に画面更新
  if (millis() - lastUpdate >= updateInterval) {
 
    uint16_t vum = audio.getVUlevel();
 
    uint8_t rawL = vum >> 8;
    uint8_t rawR = vum & 0x00FF;
 
    // あとは16段階に変換して表示
    int levelL = (rawL > 0) ? (rawL / 11)  : 0; // 175/16 ≒ 11
    int levelR = (rawR > 0) ? (rawR / 11)  : 0;
 
    tft.setFont(&fonts::FreeSansBold12pt7b);
    // Rチャンネル 
    tft.setCursor(0,110);
    tft.setTextColor(TFT_RED);
    tft.print("R");
    drawVUMeter(21, 110, levelR);
    // Lチャンネル 
    tft.setCursor(0,132);
    tft.setTextColor(TFT_YELLOW);
    tft.print("L");
    drawVUMeter(21, 132, levelL);
    lastUpdate = millis();
  }
}
//----------------------------
// VUメーター描画関数
//----------------------------
void drawVUMeter(int x, int y, int level) {
    if (level > 16) level = 16;
 
    // 2. 描画処理 (16個のセグメントを描く)
    int segW = 9; // セグメントの幅
    int segH = 18; // セグメントの高さ
    int gap  = 2;  // 隙間
 
    for (int i = 0; i < 16; i++) {
        uint16_t color;
        if (i < 8)  color = TFT_GREEN;  // 低域
        else if (i < 12) color = TFT_YELLOW; // 中域
        else color = TFT_RED;           // ピーク域
 
        if (i < level) {
          tft.fillRect(x + (i * (segW + gap)), y, segW, segH, color);
        } else {
          tft.drawRect(x + (i * (segW + gap)), y, segW, segH, TFT_DARKGREY);
          tft.fillRect(x+1 + (i * (segW + gap)), y+1, segW-2, segH-2, TFT_BLACK);
        }
    }
}

 

こんな感じ

 

大きなアルバムアートと、ブンブン動くVUメーターのおかげで、表示がにぎやかになって画面を見ているだけで楽しくなってくる。とても良い感じなのである。

ticker表示モードにすると、文字も横スクロールして、更に にぎやかに。

 

これで、今度こそ機能的には打ち止めにして、次は組み上げて完成版にしたい。

 

今回のスケッチは以下に置いておきますのでご自由にどうぞ

(ただし、動作・品質・その他一切の責任は負いませんので、あしからず)

 

ESP32S3_WB35_V05

 

 

「とても良い感じになってきたニャ」

 

---------------------------------------------------------------------------

<補足>

Arduino IDEでコンパイル時の注意点は以前の記事と同様に、ツールメニューから

・USB CDC On BootをEnabledに設定 

 これをしないとシリアルモニタが動かない

・Flash ROMサイズを8MBに

・パーテーションを8Mで、3M APP/1.5MB SPIFFSに

・PSRAM:OPI PSRAM に設定

 PSRAM無しではこのプログラムは動作しない。

 

ボードライブラリは3.3.7を使

・ESP32-audioI2S-master ライブラリは3.0.13を使用

 このプログラムでは3.0.13が安定動作 

 

インストールが必要なライブラリ

・ESP32-audioI2S-master (ver3.0.13を強く推奨、3.4.0以降は動作しない)

・WiFiManager(2.0.17を使用している)

・LovyanGFX(1.2.21を使用している)

 

回路図はこちら

LCDのRSTラインに0.1uF程度のコンデンサを付けないとLCDが起動しないので注意

(内部のPull up抵抗とセットでRSTの立ち上がりを遅らせてリセット)

ブレッドボードでこんな感じ

主な部品

Seeed Studio XIAO ESP32S3

・PCM5102Aモジュール(ジャンパー設定はこちらを参照)

・3.5インチLCD (320x480)(ST7796)(Ali-Expressあたりで売っている)
 (TENSTAR ROBO LCD等で検索)

・Push SW付きロータリエンコーダー (Ali-Expressで安く売ってるのでOK)

 

注1)エンコーダー のセンターSWを押すと、Ch、Vol切り替え。

  センターSW長押しで、Tickerモード ↔ 全体表示モード切替え

注2)WiFi設定はセンターSWを押しながら電源オンでWiFi設定モードが立ち上がるので、

  スマホ等からアクセスして設定してください。こちらを参考に。

 

その他

 ここにアクセスすると、世界中のWebラジオステーション情報が手に入る。

 お好みのステーションを探して組み込んで欲しい。