エントリー

カテゴリー「オーディオ」の検索結果は以下のとおりです。

ページ移動

ESP32で音出しとMP3を再生したまとめ

ESP32ではメモリ不足で「ESP32-audioI2S」ライブラリは動作不可であったが「ESP8266Audio」というライブラリがありESP32でも使えることが判ったので音出しを実験

まずはネットで情報収集した結果ESP32で音出しする際の構成をまとめてみた

20260412_Fig01.png

ESP32の音出しには2つの方法がある(I2S

①内蔵DACを使って,I2SとDACドライバを経由で音を出力

②内蔵DACを使用しないで直接I2S信号をGPIOで出力させ外付けDACで音を出力

注)②の場合直接I2Sへデーターを送出する方法とライブラリを利用する方法がある

①の方法で出力

サイン波を生成して出力させるスケッチを試したが今一つだったので以下からスケッチを拝借

https://kghr.blog.fc2.com/blog-entry-126.html

I2S_1bit_output.png

注)直接SPを接続すると音量最大時が3.3Vとなるので大電流がGPIOに流れないよう注意

(再生)

②の方法で出力

(テスト用音源の準備)

②の方法で「ESP8266Audio」を使って音を再生するための音源データ(MP3)を準備

当初はWeb経由で行おうとして正常に動作しないので以下を参考にしてESP32のフラッシュに置いた

https://hatakekara.com/spiffs/(SPIFFS)

https://qiita.com/kumakumao/items/be51f174bfeb0e4a6a06 (LittleFS)

音源データが1MB少々でも1.5MBでは不足となるので「NO OTA(2MB APP/2MB SPIFFS)」で対応

■ 簡易的なモノラル出力

「ESP8266Audio」でDACがなくてもDOUTからPWMで再生する方法がある

サンプリング周波数は低いのだろうが,1bitのパルス波形の密度(ON/OFF)で表現するDSDってことかな

I2S_1bit_output.png

スケッチ(音源はSPIFFS)

#define NODAC 1

#include <Arduino.h>
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#ifdef NODAC
#include "AudioOutputI2SNoDAC.h"
#else
#include "AudioOutputI2S.h"
#endif

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
#ifdef NODAC
AudioOutputI2SNoDAC *out;
#else
AudioOutputI2S *out;
#endif

void setup() {
Serial.begin(115200);
delay(1000);
Serial.printf("MP3 Play Start\n");
SPIFFS.begin();
file = new AudioFileSourceSPIFFS("/hoshi45s.mp3");
#ifdef NODAC
out = new AudioOutputI2SNoDAC();
#else
out = new AudioOutputI2S();
#endif
out->SetPinout(26, 25, 22); //BCK=26, WCLK=25, DOUT=22
out->SetGain((float)30/100.0); //音量
mp3 = new AudioGeneratorMP3();
mp3->begin(file, out);
}

void loop() {
if(mp3->isRunning()) {
if(!mp3->loop()) mp3->stop();
} else {
Serial.printf("MP3 done\n");
delay(10000);
}
}

(再生)

■ MAX98357Aで出力

I2S_output.png

スケッチ(音源はSPIFFS)

//#define NODAC 1    ← コメントアウト

以下,上記のスケッチと同じ

(再生)

ESP32C3 super miniでMP3を再生

ESP32で音出しが出来たので,低価格でコンパクトなESP32C3 Super miniでのMP3再生を実験smc3-k2-pin-2.jpg

(相違や懸案点)

  • 使用したのは「ESP32 C3 Super Mini(K2)」((K1)以外はPIN互換だったかな)
  • ESP32C3 Super miniは内蔵DACが省かれているので出力は②の方法のみとなる
  • PIN数が異なるのでGPIOを1~5へ変更
  • SPIFFSを作成してファイルを設置できるのだが何故か読めないのでLittleFSを使用
  • arduinoIDE V1ではビルドできても動作が不安定で動作しないためV2でビルド
  • デバッグで利用するSerial出力がIDEの設定で出力PINが変わるので注意(USB CDC On Boot)
■ 簡易的なモノラル出力

IMG_20260412_164740.jpg

アンプ付きスピーカーとの接続はGPIO1

スケッチ(音源はLittleFS)

#define NODAC 1

#include <Arduino.h>
#include "AudioFileSourceLittleFS.h"
#include "AudioGeneratorMP3.h"
#ifdef NODAC
#include "AudioOutputI2SNoDAC.h"
#else
#include "AudioOutputI2S.h"
#endif

AudioGeneratorMP3 *mp3;
AudioFileSourceLittleFS *file;
#ifdef NODAC
AudioOutputI2SNoDAC *out;
#else
AudioOutputI2S *out;
#endif

void setup() {
Serial.begin(115200);
delay(1000);
Serial.printf("MP3 Play Start\n");
LittleFS.begin();
file = new AudioFileSourceLittleFS("/hoshi45s.mp3");
#ifdef NODAC
out = new AudioOutputI2SNoDAC();
#else
out = new AudioOutputI2S();
#endif
out->SetPinout(3, 2, 1); //BCK=3, WCLK=2, DOUT=1
out->SetGain((float)30/100.0); //音量
mp3 = new AudioGeneratorMP3();
mp3->begin(file, out);
}

void loop() {
if(mp3->isRunning()) {
if(!mp3->loop()) mp3->stop();
} else {
Serial.printf("MP3 done\n");
delay(10000);
}
}

(再生)

■ MAX98357Aで出力

esp32c3_output.png

スケッチ(音源はLittleFS)

//#define NODAC 1 ← コメントアウト

以下,上記のスケッチと同じ

(再生)

  • 電源の問題なのかフェージングが発生

MAX98357Aをラズパイで試す

アンプ付で便利そうなDACモジュールのMAX98357Aを試す

アンプがモノラルなのでLRを選択できるモジュールもあるようだが今回手に入れたのはLRが混合されている

IMG_20260330_131722.jpgIMG_20260330_131733.jpg

I2S入力なので簡単に接続できそうなラズパイで動作確認

結線
MAX98357A PIN RasPi PIN 備考
LRC 35 GPIO 19 (PCM_FS) I2S LRクロック
BCLK 12 GPIO 18 (PCM_CLK) I2S Bitクロック
DIN 49 GPIO 21 (PCM_DOUT) I2S DATA(Raspi→MAX98357A)
GAIN -   100kΩでプルアップ
SD -    
GND 6 GND  
Vin 2 5V  

GAIN PIN仕様

GAIN 接続
15dB 100kΩでGND接続
12dB GND
9dB 未接続
6dB VIN
3dB 100kΩでVIN接続

SD PIN仕様

SD 接続
左のみ出力 1.4V以上
右のみ出力 0.77V~1.4V
左右を加算後1/2して出力 0.16V~0.77V
音出力停止 GND

最初はGAINを未接続で試したところ,音量が変化するので電力不足かと考え電源ラインに1000μFのコンデンサを付けたが改善されないのでGAINを下げて3dBに設定

Pi-MAX98357A.png

GAINを下げ再生

音質は良いとは言えない

資料

ラズパイのI2S出力設定

$ sudo vi /boot/config.txt

#dtparam=audio=on # コメントアウト
dtoverlay=hifiberry-dac # 追加

音量変更など

$ sudo vi /etc/asound.conf

pcm.speakerbonnet {
type hw card 0
}

pcm.dmixer {
type dmix
ipc_key 1024
ipc_perm 0666
slave {
pcm "speakerbonnet"
period_time 0
period_size 1024
buffer_size 8192
rate 44100
channels 2
}
}

ctl.dmixer {
type hw card 0
}

pcm.softvol {
type softvol
slave.pcm "dmixer"
control.name "PCM"
control.card 0
}

ctl.softvol {
type hw card 0
}

pcm.!default {
type plug
slave.pcm "softvol"
}

編集後,再起動

接続確認

(接続前)
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 1: vc4hdmi [vc4-hdmi], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0

(接続後)
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_dac], device 0: HifiBerry DAC HiFi pcm5102a-hifi-0 [HifiBerry DAC HiFi pcm5102a-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: vc4hdmi [vc4-hdmi], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0

出力確認

$ alsamixer         #音量調整

$ speaker-test -c2 #ホワイトノイズ

$ aplay test.wav #wav

$ mpg123 test.mp3 #mp3

この後ESP32で試そうとして嵌っている

→ 拙者が持っているESP32ではメモリ不足でESP32-audioI2Sライブラリは動作不可であった(なのでI2Sにサイン波を直出力で鳴らして終わり)

FMステレオトランスミッターボードのケース

3Dプリンタの印刷ついでに,ボードのまま使っていた「FMステレオトランスミッターボード」のケースを作製

(ケース内の配置検討)

IMG_20251101_102051.jpg

  • 電源は3~5Vなので乾電池と充電池兼用で単4を3本とした
  • 電源SWは出力部と同じ左側

IMG_20251102_105912.jpgIMG_20251102_114732.jpg

電池の交換もあるため4隅をインサートナットを使ったネジ止めにしようとしたところ4隅の受け側が小さすぎて失敗

中央の裏蓋の受けとなる補強部に余裕があったので利用して1個止めにした

基板押えは強めるためスポンジを追加している

アンテナのケーブル(150㎜程度)はケース内で丸めた

IMG_20251102_105930.jpg

表側と右側の出力プラグ部は必要な部分を抜いているだけ

LRチャネル独立型FMラジオ

記録不足分を追加

(基板配置)

IMG_20251103_081030.jpg

(実装)

IMG_20251103_095300.jpgIMG_20251103_095310.jpg

  • 操作SWはエンクロージャー内の設置を考慮し逆側に付けた
  • 電源SWは赤の短絡ピンにして外付けSW対応
  • LM386を直付けしたら(熱?で)壊れたのでソケットで実装し直し(不良だったのかもしれない)

(2台目)

ブレッドボードにほったらかしだった2台目を実装したので確認

IMG_20251103_095235.jpg

5Vだと音量がある

IMG_20251103_095349.jpg

2台使用してLR独立で動作させる

還暦ラジオのケース

さらについでに還暦ラジオのケースをABSで印刷

IMG_20251012_193319.jpg

IMG_20251012_193333.jpg

このケースはバリ取り,弱いスピーカー部の補強,パテで整えて塗料を考えている

 

LRチャネル独立型FMラジオの作製

先日のDSP式FMステレオトランスミッターに合わせたLR単独動型受信機を作製している

名称に困って「LRチャネル独立型FMラジオ」って付けたが,FMステレオ放送を受信して左右のどちらかだけアンプを通しスピーカーを鳴らすモノラルラジオということである

元々はゲーム音を耳元で鳴らしたいだけだったのだけど,以下の特徴がありそうだ

  • FMステレオトランスミッターを利用して自由なスピーカー配置で高品質の音楽を聴くことができる
  • 放送局の受信機能も付けるのでFMラジオを手軽に楽しめ,複数スピーカーの配置により臨場感を得る
基本設計概要
  • FMトランスミッターとしては77.0MHzを使用
  • 受信可能放送局をプリセット
  • LRの出力は切替
  • アンプ付きにして音量操作可能
  • エンクロージャー内に設置可能なサイズ
パーツ選定

IMG_20250815_162106.jpg

FMチューナー部はデジタル選局のほうが使い勝手が良いのでRDA5807M(右)を採用

  • 電源電圧:2.7V~3.6V(3V)
  • 消費電流:18mA(max)
  • 受信周波数:76MHz~108MHz
  • 通信方式:I2C(7bitAddress:0x10,0x11,0x60)
  • S/N比:60dB

RDA5807Mのドライブはプログラムサイズの関係からATtiny85(左)を使用

アンプは完成品だと大きくなるのでLM386N(中)を最小で構成

回路図

(チューナー部)

FIG2025081602.png

  • 電源電圧は3.3V
  • ANTへは100pFを追加する予定
  • LRの切り替えはSWではなくショートピンで行う
  • 周波数変更はタクトSW1個でループさせる(初期値はトランスミッターの77.0MHz)
  • タクトSWを2個で音量アップ・ダウン

(アンプ部)

FIG2025081603.png

  • 20ゲインで動作させる
  • R1,C8,R2は無くても問題ない(R1は200ゲイン時のノイズ対策用,C8,R2は発振対策用)
  • 最終的にC9は220μFに変更(47μF~470μFでの試行結果)

(電源部)

FIG2025081601.png

  • 省電力だったので三端子レギュレーターは50mAのS-812C33AY-B-Gに変更(ドロップ電圧が極小なのが魅力)
  • C2は22μFに変更
スケッチ

(最初)

RDA5807MはArduinoでRadioライブラリを使用して試したこと(こちら)があるので同じスケッチを更新して使用したが,ATtiny85はRAMが512BytesしかないのでRadioライブラリをそのまま使うとオーバー(800Bytes超)するため,ライブラリーのデバッグ部分(データとなる文字列があるため)を外して減らす必要があった

WS20250816.png

コード:53,94Bytes,データ:308Bytesになり,なんとかATtiny85用のコンパイルが完了して書き込み

IMG_20250814_161827.jpg

しかし,まったく動作しない

(Arduinoで試行)

ATtiny85でデバッグするのは困難なのでATMega328を搭載したArduinoで確認

IMG_20250815_094713.jpg

これが困ったことに動作済スケッチでありながら動作しないので調査開始

途中,既存のスケッチを探して,こちらのスケッチを使ってみると動作したためRadioライブラリの破壊してしまったのかと再インストールしてみたが変化なし

すったもんだの結果,初期化の際,以下のような順序で構成すると動作することが判る

//最初に実行(initは駄目)
radio.setup(RADIO_FMSPACING, RADIO_FMSPACING_100);

//待ち(whileの方が良いかも)
if(!radio.initWire(Wire)) {
  delay(1000)
}

//バンド設定
radio.setBandFrequency(FIX_BAND, FIX_STATION);

この構成でATtiny85でも動作確認できた

IMG_20250815_161802.jpg

(最終)

結果,Radioライブラリでも確認できたが,スケッチサイズが減らせることもあり(調査途中で使った)上のスケッチのライブラリを使わせてもらうことにした(ラズパイの時も利用させてもらったかな)

スケッチ(SJIS,TAB4)

ライブラリのクラス名は「RDA5807M」から「XRDA5807M」に変更

試作

電源部も追加して,3.6Vで動作させてみたところ,十分な音量もあるようなので高校野球を試聴しながら試行中(公称3.6V830mAHバッテリーで16時間稼働,約0.18WHとなる)

IMG_20250816_122417.jpg

現在1セットを基板に実装中

ページ移動

ユーティリティ

検索

エントリー検索フォーム
キーワード

新着コメント

Re:ArduinoIDEでFTDIチップでの書き込みエラー
2026/01/16 from 権限がありません
Re:ArduinoIDEでFTDIチップでの書き込みエラー
2026/01/15 from admin
Re:ArduinoIDEでFTDIチップでの書き込みエラー
2026/01/14 from 権限がありません
Re:NOAA受信システム復旧
2025/06/11 from admin
Re:NOAA受信システム復旧
2025/06/11 from とおりすがり

過去ログ

Feed