2017年11月29日水曜日

Nucleo(mbed)で電圧を監視する

MAU106±5V電源でDigital+5Vの出力を1/2に分圧して取り出せるようにしているので、Nucleoでその電圧を測定して電圧監視するClassを作ってみた。

Class内でTickerを使うには、attach()を
t.attach(this, &VoltageMonitor::blinkLed, 0.5);
と、第一引数に自分自身を指定する必要がある。(参考:「https://os.mbed.com/forum/mbed/topic/1964/」)
Warning: Function "mbed::Ticker::attach(T *, M, float) [with T=VoltageMonitor, M=void (VoltageMonitor::*)()]" (declared at <a href="#" onmousedown="mbed_doc_goto('/VoltageMonitor_Test//extras/mbed_e7ca05fa8600/drivers/Ticker.h', '102'); return false;">/extras/mbed_e7ca05fa8600/drivers/Ticker.h:102</a>) was declared "deprecated" in "VoltageMonitor/VoltageMonitor.h", Line: 67, Col: 24
というWarningが出るが、mbed-srcのdirvers/Ticker.hに
    template<typename T, typename M>
    MBED_DEPRECATED_SINCE("mbed-os-5.1",
        "The attach function does not support cv-qualifiers. Replaced by "
        "attach(callback(obj, method), t).")
    void attach(T *obj, M method, float t) {
        attach(callback(obj, method), t);
    }
と宣言されていて、cv-qualifiers(constやvolatileの修飾子)をサポートしていないので(mbed-os-5.1以降?)非推奨というような事が書いてある。

mbed OS 5はなんだかイマイチこなれていない感があるので今回はmbed 2で使うことにして、
void attach(T *obj, M method, float t)
をそのまま使うことにした。そもそも
attach(callback(obj, method), t);
の「callback()」が何なのかよくわからない。←そのうち調べるかも?

ブレッドボード配線図

Test Program
https://os.mbed.com/users/ryood/code/VoltageMonitor_Test/ Revision:1

VoltageMonitor Class
https://os.mbed.com/users/ryood/code/VoltageMonitor/ Revision:1

VoltageMonitor Classのコンストラクタで
    // パラメータ
    // _ain: 電圧監視用ADC
    // _vdd: VDDの電圧値(実測値を指定)
    // _loThreshold: 電圧低下閾値
    // _hiThreshold: 過電圧閾値
    // _pLed: 警告用LED (NULL: LEDを使用しない)
VoltageMonitor(AnalogIn* _pAin, float _vdd, float _loThreshold, float _hiThreshold, DigitalOut* _pLed=NULL)
とパラメータを指定し、check()を呼び出す。
    // 返り値
    // -1: 電圧低下
    //  0: 正常
    //  1: 過電圧
    int check()
Nucleo自体には内部レファレンスがあるが、3.3VのVDDを実際にテスタ等で測定して基準電圧として使うことにした。

動作としては電圧が低下した場合はLEDがゆっくり点滅、過電圧の場合ははやく点滅、正常時は常時点灯としている。

内蔵基準電圧


Nucleoをmbedで使って内蔵基準電圧を使いたい場合は
AnalogIn   vrefint(ADC_VREF);
と指定すれば使えるようだ。

参考「https://os.mbed.com/questions/75910/How-to-get-the-value-of-inbuilt-vref-int/

内蔵基準電圧は1.21Vなので今回は使用していない。(入力が0V~2.7V以上を想定)

2017年11月26日日曜日

Raspberry Pi 3とCortex-M7のNucleo F767ZIの浮動小数点演算を比較

Nucleo用にmbedで書いたプログラムとほぼおなじものをRaspberry Pi3用にC++で書いて比較してみた。

Nucleo用プログラム (mbed)
https://os.mbed.com/users/ryood/code/FloatingPointTest/ Revison:1

Raspberry Pi 3用プログラム <floating_point_test.cc>

#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdint.h>

#define LOOP_N  (10000)

float buffer[LOOP_N];

clock_t start;

void floatTest()
{
    // divf
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = (float)i / LOOP_N;
    }
    int elapse = clock() - start;
    printf("divf\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);
    
    // sinf
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = sinf((float)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("sinf\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);

    // cosf
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = cosf((float)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("cosf\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);

    // expf
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = expf((float)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("expf\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);
    
    // logf
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = logf((float)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("logf\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);
    
    // sqrtf
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = sqrtf((float)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("sqrtf\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);      
}

void doubleTest()
{
    // div
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = (double)i / LOOP_N;
    }
    int elapse = clock() - start;
    printf("div\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);
    
    // sin
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = sin((double)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("sin\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);

    // cos
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = cos((double)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("cos\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);

    // exp
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = exp((double)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("exp\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);
    
    // log
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = log((double)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("log\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);
    
    // sqrt
    start = clock();
    for (int i = 0; i < LOOP_N; i++) {
        buffer[i] = sqrt((double)i / LOOP_N);
    }
    elapse = clock() - start;
    printf("sqrt\t%d\t%f\r\n", elapse, (float)elapse / LOOP_N);      
}

int main()
{
    printf("\nFloating Point Test\n");
    printf("CLOCKS_PER_SEC: %ld\n", CLOCKS_PER_SEC); 
    
    // 単精度浮動小数点演算
    printf("\nFloating Point Test\n");
    printf("float\n");
    printf("op\ttotal\t1-op\n");
    printf("-------------------------------\n");
    floatTest();
    
    // 倍精度浮動小数点演算
    printf("double\n");
    printf("op\ttotal\t1-op\n");
    printf("-------------------------------\n");
    doubleTest();
}


pi@raspberrypi:~ $ gcc -o floating_point_test -lm floating_point_test.cc

pi@raspberrypi:~ $ cat /etc/debian_version
8.0

Raspberry PiのプログラムはLinux上で実行しているのでNucleoの方が有利ですが、Raspberry PiをOSなし(ベアメタルと言うそうです)で動かすのはかなり難しいので、実用的な性能比較ということになると思います。

実行結果

Floating Point Test
CLOCKS_PER_SEC: 1000000

Floating Point Test
float
op      total   1-op
-------------------------------
divf    629     0.062900
sinf    2124    0.212400
cosf    2163    0.216300
expf    3632    0.363200
logf    2659    0.265900
sqrtf   3630    0.363000
double
op      total   1-op
-------------------------------
div     753     0.075300
sin     4805    0.480500
cos     4829    0.482900
exp     5356    0.535600
log     4408    0.440800
sqrt    4871    0.487100

※Raspberry Pi上では実行ごとに結果が異なる。



float型ではsqrtf()以外ではNucleo F767はRasPi3の約0.6倍の性能。なぜだかsqrtf()だけはNucleo F767の方が速い。

double型ではsqrt()以外はNucleo F767はRasPi3の約0.2倍~0.5倍の性能。これもsqrt()はNucleo F767の方が速い。

駆動クロックは

Nucleo F767ZI: 216MHz
Raspberry Pi 3: 1.2GHz

で約6倍差があるので、Cortex-M7のNucleo F767ZIは、まあまあ健闘していると思う。

Nucleo F767ZIの消費電流は98mAで(ボード上のJP5 IDDで測定)、Raspberry Pi 3よりかなり少ない。

2017年11月24日金曜日

KIK01 作戦検討その5

現状の配線を記録しておきます。


リズムマシンとのカラミ



まずはSync線1本を使ってKICKパートとしてリズムマシンと同期させてみる予定。

KIK01の筐体の構想




本体を操作子系とを二段積みしてスペースを節約しようと思う。

KIK01を(むりくり)二段積みして、リズムマシンとベースマシンといっしょに並べてみた


台座に使ってるラックの一面だけでは面積的につらくなってきました。

ラックに使っているホーム・エレクタは丈夫で使いやすいんですが、いかんせん値段が高いから増設はきっついが・・・

そうか!ラックの2段めのガラクタをどっかにやって有効利用する手もあるか?!


MAU106 ±5V電源 KIK01に接続してみた。


基板間接続用のケーブルを作って、MAU106±5V電源をKIK01の電源ユニットとして使ってみた。

なかなかうまく動作しなかったので地獄のデバッグをしながらの作業でした(^q^;

なおした不良箇所


Dual_OTA_VCAのハンダ不良


ケーブルの差し方で片チャンネル音が出たりでなかったりしたのではんだ付けしなおした。


おそらく上の画像の赤丸で囲った部分のハンダ不良だったと思う。はんだ付けしなおしたらちゃんと音が出るようになった。

いつもはんだ付け後に一通り導通チェックをしているが、一旦パスしてしまうと発見するのがなかなか難しい(ーー;

圧着ピンのハウジングへの差し込み不足



電源ケーブルを圧着ピン(EIコネクタ)で作ったが、ハウジングへの差し込みが甘くて導通していなかった。これも各部の電圧を測ったりしてわかったが、発見が難しかった。

MAU106 ±5V電源をKIK01につないだ状態の各部の電圧


電源電流: 252mA~264mA(自作電流計で測定)

テスタDCモードで測定


MAU106 ±5V電源 Digital+5V: +5.04V
MAU106 ±5V電源 Analog+5V: +5.35V
MAU106 ±5V電源 Analog-5V: -5.35V
MAU106 Monitoring: +2.51V

Nucleo F446 +5V(Arduino Header): +5.03V
Nucleo F446 +3V3(Arduino Header): +3.32V

AD8402_WeinBridge_DCO Digital+5V: +5.04V

NOS01 Analog+5V: +5.35V
NOS01 Analog-5V: -5.35V

Dual_OTA_VCA Analog+5V: +5.35V
Dual_OTA_VCA Analog-5V: -5.35V

2017年11月19日日曜日

Nucleo F767ZI 浮動小数点演算の比較

Cortex-M7のNucleo F767ZIを買ってみた。

RS-Onlineで発注して到着まで3日。佐川急便で届いたので国内で再発送してるような感じです。

サイズ



左上がArduino Uno Rev.3、右上がNucleo F446RE、下がNucleo F767ZI。ボードもでかいが144PinのMCUもでかい。

ST Link側のUSBコネクタはmicro-USB(Nucleo F446REなどのNucleo64はmini-USB)。本体側にも別にmicro-USB端子がついていて、有線LAN用のRJ45ジャックもついている。

GPIO等のコネクタは、Aruduino Headerを2列にしたようなZIO Headerと、その外側にmorpho Header(ピンヘッダは実装されていない)がある。

なかなか豪勢な仕様で、お値段3000円しないのでコスパはいいように思う。

浮動小数点演算


Nulceo F401/F446/F303でやったのと同じように浮動小数点演算を試してみた。

Nucleo F767ZIは単精度浮動小数点数ではなく倍精度浮動小数点数のFPUがついているので、F446とF767でそれぞれ比較してみた。

mbed Repository:
https://os.mbed.com/users/ryood/code/FloatingPointTest/ Revision:1

測定結果


F446 float
op total 1-op
-------- -------- ---------------
divf 1168 0.1168
sinf 4939 0.4939
cosf 4665 0.4665
expf 6758 0.6758
logf 6140 0.614
sqrtf 2392 0.2392

F446 double
op total 1-op
-------- -------- ---------------
div 10754 1.0754
sin 94134 9.4134
cos 110762 11.0762
exp 105595 10.5595
log 137396 13.7396
sqrt 16633 1.6633

F767 float
op total 1-op
-------- -------- ---------------
divf 974 0.0974
sinf 3690 0.369
cosf 3532 0.3532
expf 5374 0.5374
logf 4884 0.4884
sqrtf 2294 0.2294

F767 double
op total 1-op
-------- -------- ---------------
div 3985 0.3985
sin 9511 0.9511
cos 11023 1.1023
exp 10358 1.0358
log 13603 1.3603
sqrt 3730 0.373



float型ではF767の方が若干処理が速くなっていて、double型ではかなり差がついている。

F446の駆動クロックは180MHzで、F767は216MHzなので、float型ではクロック分速いぐらいか。

F446とF767で処理速度の比をグラフ化してみた。



float型ではおおよそ0.8程度。180MHz / 216MHz ≒ 0.83。

double型では、div(割り算)とsqrt以外ではおおよそ0.1程度になっている。

Cortex-M7なので、float型でも速くなってて欲しいな~と思っていましたが、クロック分しか速くなっていない。

Cortex-Aで1.2GHz駆動のRapberry Pi3ぐらいは行ってほしかったのですが。

2017年11月18日土曜日

MAU106 ±5V電源 はんだ付け完了

回路図

基板図

部品面

ハンダ面

出力を測定



抵抗を負荷として出力を測定した。

Digital +5V: 47Ω//47Ω(約+213mA)
Analog  +5V: 100Ω(約+50mA)
Analog  -5V: 100Ω(約-50mA)

電源電流: 456mA(自作電流計)


出力電圧(テスタDCモード)


Digital +5V: +5.01V
Analog  +5V: +5.26V
Analog  -5V: -5.26V
WATCH      : +2.51V

電圧変動(オシロACモード)


Digital +5V

ch1:Digital+5V ch2:PWIN

Analog ±5V

ch1:Analog+5V ch1:Analog-5V

Digital+5V、Analog±5Vともスパイクノイズが載っている。周波数は約150kHz程度で、MAU106由来のもの。

MAU106はSIPソケットを使って実装しているので取り外してDigital+5Vのみを測定した。


ベースマシンで使っているLT1054を使った両電源(±9V)と比べると、スイッチング・ノイズのレベルは大きいがリプルは少ないと思う。

Github:

2017年11月15日水曜日

Tr回路の実験 プッシュプル2段直結

ダイアモンドバッファと呼ばれる回路(←違ってたらすみません。)

シミュレーション回路図

正側、負側が対称で、電源を両電源にしたので入出力のACカップリングは不要になる。回路の設計としてはR2とR3の抵抗値でQ1、Q2のエミッタ電流を決めるだけ。

Q1のエミッタ電流をIe1、Q1のVbeを0.6Vとすると、

Ie1 = (4.5V - 0.6V) / 3.3k ≒ 1.2mA

正負対称なのでQ2のエミッタ電流も同じになる。

R1は発振防止用で、実際にやってみないとその効果はわからないと思う。

電源は9Vを分圧して±4.5Vとすることを想定し、信号源は1kHz/2Vp-pのサイン波にした。

入出力のシミュレーション



負荷抵抗RLを10Ω、22Ω、33Ωにしてパラメータ解析してみた。RLが22Ωまでは振幅は±0.9Vp-p程度とあまり小さくならず、歪もなさそうに見える。RLが10Ω(緑色)の場合は振幅が小さくなり、0V付近で歪が発生している。

出力のシミュレーションの拡大

2段目のTrのベース電位



V(vb3)はQ3のベース電位、V(vb4)はQ4のベース電位で特に歪んでいるようには見えない。

1段目のTrのエミッタ電流



1段目のTrのエミッタ電流は、Ie(Q1)、Ie(Q2)とも、概算どおり1.2mA程度を中心として流れている。

だがしかし、RLが10Ω(緑色)の場合、1段目のTrのエミッタ電流が1.2mA付近から少なくなると電流の変化がハッキリと非線形になっている。原因はパラメータ解析しているRLの値だが、間に2段目のQ3が入っているので具体的にイメージしにくい。

出力の歪も軽微なので、実験でこれを確かめるのは難しそう。

AC解析



10MHzあたりまではフラット。ACカップリングしていないのでDCレベルまで使える。(正負の非対称性が出るのでそうはかんたんにいかないと思いますが)

ステップ応答



500kHzの矩形波を入力して過渡解析してみた。1ms後の波形。

.tran 0 1000us 994us

ほとんど遅れはなさそう。

メモ:


2段プッシュプルは両電源が必要となるが、バッファ回路としての特性はいろいろと優秀。

シミュレーション・レベルだとバッファアンプのLME49600より特性が良さそう(参考「LME49600を使ったヘッドホン・アンプをLTSpiceでシミュレーション

「定本 トランジスタ回路の設計」の第4章以降にでてきますが、実用的にスピーカーやヘッドホンを駆動しようと思うと熱や発振が問題となってきます。


MAU106 ±5V電源の設計

回路図

基板図

部品並べ

テスト用ブレッドボード配線図

出力測定


製作中のKIK01を接続して出力を測定した。


電圧(テスターDCモード)

6VACアダプタ +5.73V
+6V(コモン・モード・チョーク後) +5.50V
Digital +5V +4.81V
Analog +5V +4.93V
Analog -5V -4.93V
Monitor +2.39V

ACアダプタからの+6V出力の電圧が下がっていて、全体に出力電圧が低下している。

抵抗を負荷として6VACアダプタ(GF12-US0618)単体の出力電圧を測定すると

47Ω//47Ω//100Ω≒約20Ω 約300mA 5.80V
47Ω//47Ω//47Ω ≒約16Ω 約382mA 5.74V

定格では最大1.8Aとなってますが、そこそこ出力低下しますね。

出力波形

オシロのACモードで出力変動を測定。

6VACアダプタ、6V(コモン・モード・チョーク通過後)

ch1:6VACアダプタ ch2:6V

Digital 5V

Analog ±5V

ch1:Analog+5V ch2:Analog-5V

※KIK01を負荷としている。

Github:
https://github.com/ryood/-5V_PSU

2017年11月13日月曜日

Nucleo F401REの3.3V電源を破壊してしもうた(T_T;

製作中の±5V電源にNucleoをつないでテストしているときに、NucleoのE5Vピンに+5Vかけるのを、間違えて±5Vの両極(10V分)につないでしまい、NucleoがPCから認識しなくなった。


Nucleoをつないで認識されるストレージに、FAIL.TXTというのが現れ
The interface firmware FAILED to reset/halt the target MCU
と書いてある。

MCUを壊したかと思ったが、基板をチェックすると3.3V LDOを破壊してしまったようだ。

Nucleoボード全体では、3.3V LDOは2個あり、


本体側の3.3V LDOの回路図

ST-LINK側の3.3V LDOの回路図

テスタで電圧を測ると、U1の「+3V3_ST_LINK」は3.29V、「Vin」は4.43V。U4の「+3V3」は0.303V、「+5V」は4.72V。

どうやらU4が壊れてしまったようだ。

試しにU4の近くのJP6のVDD側に外部から3.3V供給してUSB接続してみると、FAIL.TXTは出なくなり、Lチカのプログラムが動作した(^q^/

ST_LINK側のU1から3.3Vを供給するとか3V3 LDOを外付けすれば復旧できそうですが…

2017年11月10日金曜日

Minmax MAU106とNJM2396で±5V電源を作る


ブレッドボード配線図

+6V入力は秋月の6V ACアダプタを使った。

コモン・モード・チョークを入れると出力波形がきれいになるので入力に入れている。

NJM2396からの+5V(Digtal +5Vと表記)には、47Ωの酸金を2本並列にして負荷とした。(約213mA)

MAU106からの±5V(Analog +5V/-5Vと表記)には、それぞれ100Ωの酸金を負荷とした。(約±50mA)

Digital +5V


出力電圧:4.70V

出力波形(AC結合

Analog +5V/-5V


出力電圧:+4.75V/-4.74V

出力波形(AC結合)

ch1:Analog +5V ch2:Analog -5V

Analog +5V/-5Vは、5V/3.3V安定化電源Ver.2を電源としたときより悪くなっている。

表面温度


NJM2396

15分で22.2℃から29.2℃に上昇。

MAU106

15分で22.35℃から35.75℃に上昇。

とりあえず作ってみてKIK01の電源として使ってみるつもり。問題が出たら別の手を考えます。

2017年11月9日木曜日

Switching Distortion Effectorの妄想

こういう猛烈なスイッチング歪が出る回路に音楽信号を通したらどうなるんだろうか。

ギターエフェクターではあんまり聞いたことがないのでギターはダメなんだろうが、シンセだとどうかと?