踏切警報音 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;
}
2023-12-16 00:56
nice!(0)
コメント(0)
コメント 0