フォト
2017年7月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
無料ブログはココログ

« IchigoJam用画像コンバータを少々改良 | トップページ | 次はSTM32ボードを積極的に使ていきたい(9) - TVout互換ライブラリ »

2017年3月12日 (日)

次はSTM32ボードを積極的に使ていきたい(8) - PWMで単音演奏

Arduino STM32環境 Blue PillボードでPWMを使った単音演奏

01

Blue Pillボード(STM32F103C8)でPWMを使った「こいのぼり」の単音演奏をやってみました。
音の出力には圧電スピーカー(圧電サウンダ)を使いました。
ゲームなんかの効果音には使えますね。

演奏の様子
(ちょっと音が小さいです)


回路図

02

スケッチ

「こいのぼり」の演奏部分はスイッチサイエンスさんのサンプルスケッチを流用させていただきました。
SWICHI SCIENCE MAGAZINE - Arduinoで童謡「鯉のぼり」を流してみよう

/*
 *  Arduino STN32
 *  Stm32ボード(STM32F103C8T6)で PWMで任意の周波数を生成する
 *  作成日 2017/01/17 by たま吉さん

 *  説明
 *  ・PB9端子の圧電スピーカーを接続することで任意の周波数を音を出す
 *  ・Timer4 チャンネル 4 を利用しているため、PWM出力ピンはPB9固定

 *  参考にした情報
 *  ・Topic: DUE PWM Frequency (Read 51962 times) 
 *    https://forum.arduino.cc/index.php?topic=131323.15
 *    
 *  サンプル作成に参考にしたサイト
 *  ・Arduinoで童謡「鯉のぼり」を流してみよう
 *    http://mag.switch-science.com/2015/04/29/gwprojact_koinobori/
 */

//
// 音出し
// 引数
//  pin     : PWM出力ピン (現状はPB9固定)
//  freq    : 出力周波数 (Hz) 15~ 50000
//  duration: 出力時間(msec)
//
const int pwmOutPin = PB9;  // PWM出力ピン
void _tone(uint8_t pin, uint16_t freq, uint16_t duration = 0) {
  if (freq < 15 || freq > 50000 ) {
     _notone(pin);
  } else {
    uint32_t f =1000000/(uint16_t)freq;
    Timer4.setPrescaleFactor(72); // システムクロックを1/72に分周
    Timer4.setOverflow(f);
    Timer4.refresh();
    Timer4.resume(); 
    pwmWrite(pin, f/2);  
    if (duration) {
      delay(duration);
      Timer4.pause(); 
    }
  }
}

//
// 音の停止
// 引数
// pin     : PWM出力ピン (現状はPB9固定)
//
void _notone(uint8_t pin) {
    Timer4.pause();  
}

//HardwareTimer pwmtimer(2);
#define PIN pwmOutPin
void setup() {  
  pinMode(pwmOutPin, PWM);
  _tone(pwmOutPin,440, 100);
  _tone(pwmOutPin,880,100);  
  delay(500);

  _tone(PIN, 330, 150);
  delay(150);
  _tone(PIN, 294, 150);
  delay(150);
  _tone(PIN, 262, 300);
  delay(300);
  _tone(PIN, 294, 300);
  delay(300);
  _tone(PIN, 330, 300);
  delay(300);
  _tone(PIN, 440, 300);
  delay(300);
  _tone(PIN, 392, 150);
  delay(300);
  _tone(PIN, 330, 150);
  delay(150);
  _tone(PIN, 330, 150);
  delay(150);
  _tone(PIN, 330, 300);
  delay(300);
  _tone(PIN, 294, 150);
  delay(150);
  _tone(PIN, 262, 150);
  delay(150);
  _tone(PIN, 294, 300);
}

void loop() {
  
}


Arduino STM32では音を出すためのAPIとしてtone()関数があります。
  参考:  ・Arduino for STM32 - tone() and notone() have been added to the libmaple core

使ってみると音がちょっと汚いです。濁ったような音です。
原因はタイマー割り込みを使って、出力をオン・オフしているためです。
他の様々な割り込みの影響により、タイミングがずれたりして濁った音になっています。
(USBシリアル、SysTicの時間処理等)

また、このやり方だとCPU負荷もそれなりにかかります。
今後のビデオ出力を使ったゲーム作成なんかに使うにはちょと問題ありです。

そこで、PWM出力に置き換えて綺麗な音が出るようにしました。
音が出ている間はCPU負荷がかかりません。

問題点としては、利用するピンが固定となることです。標準のtone()では任意のピン
を使って音が出せます。

« IchigoJam用画像コンバータを少々改良 | トップページ | 次はSTM32ボードを積極的に使ていきたい(9) - TVout互換ライブラリ »

arduino」カテゴリの記事

ARM」カテゴリの記事

STM32」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/571408/65004715

この記事へのトラックバック一覧です: 次はSTM32ボードを積極的に使ていきたい(8) - PWMで単音演奏:

« IchigoJam用画像コンバータを少々改良 | トップページ | 次はSTM32ボードを積極的に使ていきたい(9) - TVout互換ライブラリ »