オーディオアンプモジュール いろいろ [Arduino]
オーディオアンプモジュールを3種類購入してみた。
LM358というのを使ったモジュール。
使い方がわからなかった。
HAA2018というを使ったモジュール。(販売元の説明ではXS9871であった。)
muteがHIGHのときミュートになるらしいが、デフォルトではGNDにつながっていないのに音が出た。muteに5Vかけたらミュートになった。
UNO R4のA0のDACからの電圧を可変抵抗でだいぶ落とさないと音が割れた。
XPT8871というを使ったモジュール。(販売元の写真ではLTK5128のやつもあった。)
こっちはmuteをGNDに落とさないと音が出なかった。
これも可変抵抗で電圧を落として入力。
裏面に各ピンの説明がシルク印刷されていて、普通のヘッダーピンだと見えなくなるので、L字のものを使ってみた。
ちょっと調べてみると、ライン入力は1Vっぽいので、5VのUNO R4の場合、可変抵抗に入力する前に、その4倍以上の抵抗を挟まないといけなさそう。
オーディオアンプモジュール GF1002 [Arduino]
PAM8403を搭載したアンプモジュール。
amazon や Aliexpress でよく見かけるやつ。
可変抵抗もついてて便利そうなんだけど、これの問題は、スルーホールのピッチが微妙なところ。
入力部、電源部、出力部のそれぞれの内部は2.54mmピッチだけど、パート間のピッチは2.54mmピッチとは全く異なりブレッドボードに載らない、、。
そこで、ちょっと考えた。
・電源だけピンを立てる
・それ以外はソケットに
・Arduinoの電源に直刺しのとき、モジュールの基盤が邪魔にならないようL字ピン
(電源のGNDとオーディオのGNDをつなげておいてもいいと思う)
これをArduino UNO R4に載せてみる。
ちょっとしたDACからの音声テストには便利。
ブレッドボートでもOK。
VKLSVAN 5個 PAM8403 2X3Wミニ 5V デジタル アンプ基板 USB 電源 オーディオ アンプ モジュール
- 出版社/メーカー: VKLSVAN
- メディア:
踏切警報音 UNO R4 [Arduino]
踏切警報音スケッチをUNO R4用にも作ってみた。
UNO R4にはDACがあるのと、速度も速いので、レジスタ操作なしの純粋Arduinoでいけた。
量子化ビット数は DACの12ビット。
micros()でタイミングをとっているので、サンプリング周波数は 1,000,000(μsec)の約数。そのなかで処理が間に合う最大の50kHzとした。
UNO R4はAVRマイコンに比べてドライブ能力が低いので、アンプを使わないとそこそこの音量が出ないのが難点。
とりあえず圧電サウンダで。
UNO R4にはDACがあるのと、速度も速いので、レジスタ操作なしの純粋Arduinoでいけた。
量子化ビット数は DACの12ビット。
micros()でタイミングをとっているので、サンプリング周波数は 1,000,000(μsec)の約数。そのなかで処理が間に合う最大の50kHzとした。
UNO R4はAVRマイコンに比べてドライブ能力が低いので、アンプを使わないとそこそこの音量が出ないのが難点。
とりあえず圧電サウンダで。
// railroad crossing sounds and signals : UNO R4
#define F_SAMP 50000 // sampling frequency (Hz) (divisor of 1,000,000 (usec))
#define F_SIGN 100 // light signal : 100/min (1.666Hz, 0.6 sec)
#define F_DING 130 // ding sound : 130/min (2.166Hz, 0.461sec)
#define ATHALF 200 // attenuation half-life : 200 msec
static const uint16_t FRQ[][2] = { // frequency combination (Hz)
{ 700, 750 }, // JR etc.
{ 450, 550 }, // ODAKYU
{ 550, 650 }, // TOKYU, KEIKYU
{ 600, 650 }, // TOBU
{ 520, 660 } // SEIBU
};
static uint16_t SIN[256]; // array of sine wave
void setup() {
analogWriteResolution(12); // A0 : DAC
pinMode( A1, OUTPUT ); // A1 : LED1
pinMode( A2, OUTPUT ); // A2 : LED2
pinMode( A3, INPUT_PULLUP ); // A3 : SW
for (uint16_t i = 0; i < 256; i++) {
SIN[i] = 32767.9 * (1 - cos(6.283185 * i / 256)) / 2; // 15bit
}
}
void loop() {
static uint8_t ch;
uint16_t cDing, iDing = 60 * F_SAMP / F_DING; // counter and initial cycles of ding sound
uint16_t cSign, iSign = 60 * F_SAMP / F_SIGN; // counter and initial cycles of lignt signal
uint16_t cAttn, iAttn = ATHALF * F_SAMP /1000 /356; // counter and initial cycles of attenuation
uint16_t iA, diA = (FRQ[ch][0] << 16) / F_SAMP; // array subscript and its difference
uint16_t iB, diB = (FRQ[ch][1] << 16) / F_SAMP;
uint16_t env; // envelope
uint32_t usInt = 1000000 / F_SAMP; // sampling time interval(usec)
uint32_t usPre = micros(); // sampling time previous value(usec)
digitalWrite( A1, HIGH ); // LED1 On
digitalWrite( A2, LOW ); // LED2 Off
cDing = cSign= 0;
do {
if( !cDing-- ) { // reset ding counter
cDing = iDing;
cAttn = iAttn;
env = 0xffff;
iA = 0;
iB = 0;
}
if( !cAttn-- ) { // reset attenuation counter
cAttn = iAttn;
env -= env >> 9;
}
if( !cSign-- ) { // reset light counter
cSign = iSign;
digitalWrite( A1, !digitalRead(A1) );
digitalWrite( A2, !digitalRead(A2) );
}
analogWrite( DAC, (SIN[(iA+=diA)>>8] + SIN[(iB+=diB)>>8]) * env >> 20 );
while( micros() - usPre < usInt );
usPre += usInt;
} while( digitalRead(A3) ); // Press the tact switch to end
analogWrite( DAC, 0 );
digitalWrite( A1, LOW ); // LED1 Off
digitalWrite( A2, LOW ); // LED2 Off
delay(1000);
if( ++ch == sizeof(FRQ)/sizeof(*FRQ) ) ch = 0;
}
踏切警報音 リトライ [Arduino]
以前にも踏切の音を出してみるのをやったけど、もうちょっとリアルに。
以下から情報をいただきました。感謝。
【参考にさせていただいたところ】
Web Nucky Blog |踏切警報音の実験 その1
https://webnucky.blog.fc2.com/blog-entry-296.html
踏切警報音 - くるまや軽便鉄道 PartⅡ
https://kurumayakeiben.wordpress.com/category/%E8%B8%8F%E5%88%87%E8%AD%A6%E5%A0%B1%E9%9F%B3/
鉄道マニヤに捧ぐ 首都圏主要鉄道会社の踏切音に使用される微分音:左近治の囈(たはごと):SSブログ
https://tawauwagotsakonosamu.blog.ss-blog.jp/2019-09-19
★いきなりまとめ
・本物の踏切の音と光は安全のため別回路になっていて、同期していない。
・現在の電子ホーン式のほかに電鈴式、電鐘式がある。
・音は2(~3(京急))和音で、12音階に属さない「微分音」というものらしい。
JR、相鉄、名鉄、京阪、近鉄、阪神、西鉄、阪急、南海、京成 他 700Hz、750Hz
小田急 450Hz、550Hz
東急、京急 550Hz、650Hz
東武 600Hz、650Hz
西武 520Hz、660Hz
★スケッチの方向性
・ATtiny202 (megaTinyCore) を使う
・TCA0のPWMをDACもどきとして使用 (mills(), micros()や他のPWMは使用不可)
・電子ホーン式のみ
・CPU周波数に依存しない
スケッチつくったけど、半分くらいが初期値の設定やレジスタ設定や正弦波の配列などで埋まりました。
音の周波数の組み合わせを選択できるようにした。
音のリズムはとりあえず130/分にしたけど変更可能。
正弦波、鋸歯状波、矩形波を試してみたけど、正弦波が一番近いかな?
踏切の動画をミュートで見ながら、手元で音を出しても違和感なし。
小さいスピーカより大きめのスピーカのほうがいい音が出た。
音の減衰具合。半分の値になるのが、356cyclesくらい。
以下から情報をいただきました。感謝。
【参考にさせていただいたところ】
Web Nucky Blog |踏切警報音の実験 その1
https://webnucky.blog.fc2.com/blog-entry-296.html
踏切警報音 - くるまや軽便鉄道 PartⅡ
https://kurumayakeiben.wordpress.com/category/%E8%B8%8F%E5%88%87%E8%AD%A6%E5%A0%B1%E9%9F%B3/
鉄道マニヤに捧ぐ 首都圏主要鉄道会社の踏切音に使用される微分音:左近治の囈(たはごと):SSブログ
https://tawauwagotsakonosamu.blog.ss-blog.jp/2019-09-19
★いきなりまとめ
・本物の踏切の音と光は安全のため別回路になっていて、同期していない。
・現在の電子ホーン式のほかに電鈴式、電鐘式がある。
・音は2(~3(京急))和音で、12音階に属さない「微分音」というものらしい。
JR、相鉄、名鉄、京阪、近鉄、阪神、西鉄、阪急、南海、京成 他 700Hz、750Hz
小田急 450Hz、550Hz
東急、京急 550Hz、650Hz
東武 600Hz、650Hz
西武 520Hz、660Hz
★スケッチの方向性
・ATtiny202 (megaTinyCore) を使う
・TCA0のPWMをDACもどきとして使用 (mills(), micros()や他のPWMは使用不可)
・電子ホーン式のみ
・CPU周波数に依存しない
スケッチつくったけど、半分くらいが初期値の設定やレジスタ設定や正弦波の配列などで埋まりました。
音の周波数の組み合わせを選択できるようにした。
音のリズムはとりあえず130/分にしたけど変更可能。
正弦波、鋸歯状波、矩形波を試してみたけど、正弦波が一番近いかな?
踏切の動画をミュートで見ながら、手元で音を出しても違和感なし。
// railroad crossing sound and signals : ATtiny202 (megaTinyCore 4-20MHz)
#include <util/delay.h>
#define F_SIGN 100 // light signal : 100/min (1.666Hz, 0.6 sec)
#define F_DING 130 // ding sound : 130/min (2.166Hz, 0.461sec)
#define ATHALF 200 // attenuation half-life : 200 msec
static const uint16_t FRQ[][2] = { // frequency combination (Hz)
{ 750, 700 }, // JR, SOTETSU, MEITETSU, KEIHAN, KINTETSU, HANSHIN, NISHITETSU, HANKYU, NANKAI, KEISEI..
{ 450, 550 }, // ODAKYU
{ 550, 650 }, // TOKYU, KEIKYU
{ 600, 650 }, // TOBU
{ 520, 660 } // SEIBU
};
static const uint8_t SIN[] = { // array of sine wave
0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, 79, 82, 85, 88, 90, 93, 97,100,103,106,109,112,115,118,121,124,
128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173, 176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,
218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244, 245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,
255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246, 245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,
218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179, 176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,
128,124,121,118,115,112,109,106,103,100, 97, 93, 90, 88, 85, 82, 79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40,
37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0
};
void setup() {
PORTA.DIRSET = PIN7_bm; // PA7 SP OUTPUT (mTC:1) (mTC default : PA3(mTC:4) to PA7(mTC:1) )
PORTA.DIRSET = PIN1_bm | PIN2_bm; // PA1,2 LED OUTPUT (mTC:2,3)
PORTA.DIRCLR = PIN3_bm; // PA3 SW INPUT (mTC:4)
PORTA.PIN3CTRL = PORT_PULLUPEN_bm;
TCA0.SINGLE.INTCTRL = 0; // turn off Arduino(mTC) time system
TCA0.SINGLE.CTRLD = 0; // turn off split mode
TCA0.SINGLE.CTRLC = 0; // PWM output pins override - disable
TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm // enable compare channel 0
| TCA_SINGLE_WGMODE_SINGLESLOPE_gc; // set Single-slope PWM mode
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc // 20MHz / 1 / 256 -> 78,125Hz
| TCA_SINGLE_ENABLE_bm; // start timer
TCA0.SINGLE.PERBUF = 0xff; // top value = 255
}
void loop() {
static uint8_t ch = 0;
uint16_t cDing, iDing = 60 * (F_CPU >> 8) / F_DING; // counter and initial cycles of ding sound
uint16_t cSign, iSign = 60 * (F_CPU >> 8) / F_SIGN; // counter and initial cycles of lignt signal
uint16_t cAttn, iAttn = ATHALF * (F_CPU >> 8) / 1000 / 356; // counter and initial cycles of attenuation
uint16_t iA, diA = FRQ[ch][0] * 0x010000 / (F_CPU >> 8); // array subscript and its difference
uint16_t iB, diB = FRQ[ch][1] * 0x010000 / (F_CPU >> 8);
uint16_t env; // envelope
PORTA.OUTSET = PIN1_bm; // LED On
PORTA.OUTCLR = PIN2_bm; // LED Off
cDing = cSign= 0;
do{
if( !cDing-- ) { // reset ding conter
cAttn = iAttn; env = 0xffff; cDing = iDing;
iA = iB = 0;
}
if( !cAttn-- ) { // reset attenuation conter
cAttn = iAttn; env -= (env>>9);
}
if( !cSign-- ) { // reset light counter
cSign = iSign;
PORTA.OUTTGL = PIN1_bm | PIN2_bm; // toggle LEDs
}
TCA0.SINGLE.CMP0BUF = ( SIN[ (iA+=diA)>>8 ] + SIN[ (iB+=diB)>>8 ] ) * (env>>9) >>8;
while( !(TCA0.SINGLE.INTFLAGS & TCA_SINGLE_OVF_bm) ); // Waiting for TCA0 overflow
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; // cleared by writing a '1'
} while( (PORTA.IN & PIN3_bm) );
PORTA.OUTCLR = PIN1_bm | PIN2_bm; // turn LEDs off
TCA0.SINGLE.CMP0 = 0;
_delay_ms(1000);
if( ++ch == sizeof(FRQ)/sizeof(*FRQ) ) ch = 0;
}
小さいスピーカより大きめのスピーカのほうがいい音が出た。
音の減衰具合。半分の値になるのが、356cyclesくらい。