こんにちはマイコン制御

May FORTH be with you.

mbed LPC1114手習い01 / PCMについて学ぶ

以前mbedを触ってから少し間が空いたけれども、再スタート。

前回いじってみて、開発環境C++なのかあ、と思っていたのですが、サンプルプログラムの写経から一歩進んでみても、オブジェクトをいじる時はドットでつなぐオブジェクト言語風の書き方が必要ですが、それ以外はとりあえず素のCっぽく書けてしまうので、判んなくなるまではC言語の文法で進んで行ってみます。

8月中、デジタルの基礎を学んで改めてマイコンに取り組むにあたって感じている事は、プログラム言語はプログラム言語で習得する必要はあるけれど、結局はハードウェアを理解していないと壁にぶつかったときに解決が難しくなるなあ、ということです。

通常はハードウェアはライブラリとかOS越しに扱うのだけれど、そのライブラリについて判らなくなったとか不満があるとか不具合があるとか、そういう時にはハードでどのようにその動作が行われるか判ってないと理解、判断が出来なくなってしまうことが多かったです。

 

まずはミッションに基づいてPWM周りからチャレンジ。こちらの記事がコンパクトにまとまっていて判りやすいので参考にしつつ。しかし、mbedのクラウド上の開発環境はホントに使いやすい。mbedLPC1114のお手軽さと併せて、作業を始めるまでのハードルが非常に低い。

新規プロジェクトでLチカのサンプルを立ち上げると、メインのソースとライブラリ+そのドキュメントが一式プロジェクトに放り込まれるのだけれど、サイトの例に倣って、その中のPWMライブラリである「PwmOut」の解説にあるサンプルソースをとりあえず打ち込み。

http://image.itmedia.co.jp/mn/articles/1505/19/l_hi_mb04.jpg

1:// Fade a led on.
2:#include "mbed.h"
3:PwmOut led(dp1); //LED1からdp1に変更
4:int main() {
5:    while(1) {
6:        led = led + 0.01;
7:        wait(0.2);
8:        if(led == 1.0) {
9:            led = 0;
10:        }
11:    }
12:}

 

コンパイルしてbinファイルをローカルにダウンロードして、USBストレージとして認識されているブレッドボード上のLPC1114に放り込むと、自動的に再起動してとりあえず問題なくLチカ完了。抵抗とコンデンサでローパスフィルタを作って、LEDの代わりに小さなスピーカーを付けたらそれなりにいい感じの音が出せました。とりあえずあてずっぽうに数値を変えてみましたが、思った変化にはならず。そりゃそうか。

近頃はネットの資料は全て落としてきてKindle上で読めるようにしているんですが、webコンパイラ上のPwmOutの資料ページが上手く落とせず、その日はそこで終了。

 

次の日、ライブラリ見たり他のページ見たりしてみると、矩形波で再生周波数を変えて音程を変えている例が多かったけれども、後々DSPをやりたいので8bit11kHz固定で音程を変えるサンプルを書いてみました。(頻繁に数値を変えてみたりしたのでかなり冗長で恥ずかしいですが) 

/*
my pcm test
*/
#include "mbed.h"

float clk    = 1 / 11025; //set 11kHz
float smpl_frq = 11025;
float snd1_frq = 220; //tone A3
float snd2_frq = 659.26; //tone E5
int smpl_rate = 255; //8bit sampling
int max_vol = 255; //Volume for duty
int mid_vol = 128;
int min_vol = 0;

PwmOut snd_out (dp18); //set dp18 pin

int main() {
snd_out.period (clk);
float cnt_frq = 0;
float pluse1_frq = smpl_frq / snd1_frq;
float pluse2_frq = smpl_frq / snd2_frq;
//
for (int i = 0; i < 11025; i++) {
cnt_frq = cnt_frq + 1 ;
if (cnt_frq <= ( pluse1_frq / 2 ))
{
snd_out = max_vol / smpl_rate;
}
else
{
snd_out = min_vol / smpl_rate;
}
if (cnt_frq >= pluse1_frq)
{
cnt_frq = 0;
}
wait(clk);
}
for (int i = 0; i < 11025; i++) {
cnt_frq = cnt_frq + 1 ;
if (cnt_frq <= ( pluse2_frq / 2 ))
{
snd_out = max_vol / smpl_rate;
}
else
{
snd_out = min_vol / smpl_rate;
}
if (cnt_frq >= pluse2_frq)
{
cnt_frq = 0;
}
wait(clk);
}
}

 とりあえずエラーつぶしてコンパイルしてLPC1114で鳴らしてみたところ、周波数固定で音程の変化を伴って音が出るところまでは出来ました。

f:id:SenjiNiban:20150903182553j:plain

ですがいくつか未解決の問題が。

  1. max_volで鳴らすとデューイ比が1、mid_volで鳴らすと0.5になって、半分の音量になるはずなのだけれど音が出なくなる。式の代入ではなくて0.5を直接指定すると鳴る。
  2. A3とE4の音が1音ずつ鳴って停止するはずなのだけれど、なぜか2回繰り返す。

ううむ、良く判らない。