2016年6月18日土曜日

Nucleo(mbed)のPwmOutで波形を出力してみる。

MCP4922とNJM13700でSPI制御のDCA(Nucleo編)」でSPI DACのMCP4922を使ってVCAをコントロールしてみたが、外付けDACを使わないでPWMでできるかどうかやってみた。

mbedにはAnalogOutというDACを使うようなClassもあるが、Nucleo F401REでは使えないようだ(←実際に試したわけではないです。)

参考:https://developer.mbed.org/questions/4255/AnalogOut-problem-on-Nucleo-F401RE/

PWMなら使えるのでLPFを通してモジュレーション波形が出せるかどうか試してみた。

main.cpp

#include "mbed.h"

PwmOut mypwm(PWM_OUT);
DigitalOut led1(LED1);
Ticker ticker;

const float carrier_freq   = 100000.0f;              // 100kHz
const float carrier_period = 1.0f / carrier_freq;

const float update_period  = 0.00001f;               // 10us

volatile uint8_t cnt = 0;

void update()
{
    cnt++;
    float phi = cnt / 256.0f;
    mypwm.pulsewidth(phi * carrier_period);
}

int main()
{   
    mypwm.period(carrier_period);
    mypwm.pulsewidth(carrier_period / 2);
  
    printf("pwm set to %.2f %%\n", mypwm.read() * 100);
    
    ticker.attach(&update, update_period);

    while(1) {
        led1 = !led1;
        wait(0.5);
    }
}

キャリアを可聴帯域の外の100kHzにして10usごとにデューティ比を変化させてみた。サンプリングレートは10usの逆数の100kHz。256段階で変化させているので8bit相当になる。


PWM波形のままだとどうしようもないので2次CR LPFを通した。
fc = 1 / (2 * π * C * R) = 1 / (2 * π * 0.01uF * 1kΩ) ≒ 15.9kHz
の2段積み(とりあえずの値)。

出力波形



ch1:PWM出力 ch2:2次CR LPF通過後

拡大

PWM出力も拡大してみると波形が崩れているようだ。LPFを外すとPWM波形はちゃんと出力される。(オシロの仕様(?)で何回か分の波形が重ねて表示されるようです。)


メモ:


PWM出力にすればMCP4922を省略できそうだが、PWM出力だと何かいろいろ問題が出てきそうなので保留。

Nucleo-F446REという上位バージョンだとDACも搭載されているようだ。

Google+の電子工作部でPDM(Pulse Density Modulation)のマイクを使っている方がおられたので粗密波のサンプリングレートとPCMのサンプリングレート/ビット数の関係を少し考えてみたがやはりよくわからない(^q^;

1bit DACを最初に製品化したのはシャープだったと思うが、ついにホンハイに買収されてなんとも悲しい話。

今、WebでPDMで検索したらシャープのΔΣの技報がひっかかった。あとで読んでみよう(^q^/