2019年4月30日火曜日

オペアンプ・チェッカー OPACHK-VFの製作

というわけでOPAMPの生き死にを判定するためのチェッカーを作りました。

回路図

基板図

ボルテージフォロワーで入出力をチェックするかんたんなものです。単にDCを入力しLEDを点灯させるだけでも生死は判定できますが、微妙にダメージをくらっているかどうかも見られるようにしました。

ファンクション・ジェネレーターから波形を入力し、オシロで出力を観測します。

TLE2426で仮想GNDを作っているので、この回路自体は電池電源など、測定器とGNDが分離されている必要があります。

基板面

ハンダ面

測定しているようす

新品のNJM4580DDをチェック


電源: 単3×6
電源電流: 4mA

1kHz/2Vp-p サイン波 (PCM5102A-FG使用)

ch1:IN ch2:OUT

100kHz/2Vp-p サイン波 (AD9833-FG使用)

ch1:IN ch2:OUT

メモ:


電源スイッチをつけておいたほうが良かったかも。

OPAMPの出力負荷抵抗を入れておいたほうがよかった思います。改造はかんたんですが。


2019年4月28日日曜日

DASS01でやらかした。

VCFのTLF01とアンチログ回路のAntilog-NPNOを結合するついでに、電源ケーブルを整理していたら、うっかり配線を間違えてしまっていたようで、プシューッという音ともに電子部品が焼けた匂いが。

電源ケーブルは逆差し防止の為、XHコネクタみたいな片側にしか挿入できないものを使っているのですが、コンタクトをハウジングに挿入する順番を間違えていました。


上のケーブルを切断しているのが、間違えて挿入したコネクタ(赤・黒・白が逆)ですが、何が間違いなのかは基板の設計次第なので、ほんとにうっかりミスです。逆差しできないのがかえって仇になってしまった気もします。←今後ハウジングに挿入するときは念入りにチェックするようにします。

また、今まで使っていた電源はせいぜい±9Vまで。今回は電源電圧が±12Vで即死の原因になったかもしれません。


画像は故障したっぽいAntilog-NPNO、Antilog-MM、TLF01ですが、この中から故障箇所を特定しなければいけません。(この中に必ずあるとは限りませんが)

基板をよく観察するとTLF01の電源のデカップリング用のアルミ電解が焦げています。


一番イヤな基板です(@@;

極性があるのはトランジスタ、OPAMP、アルミ電解ですが、デカップリングが死んでも全く動作しなくなることはまずないと思います。2SC1815のエミッタ・ベース間電圧(逆電圧)の絶対定格が5Vなので、これクサいんですが。

数が多い上に互いに絡んでいるので調べるのが大変そうです。せっかくVBEのマッチングまでしたのに。。。

と嘆いていてもしょうがないので、気を取り直すために、まずはOPAMPの生死を判定していきたいと思います。

畑村洋太郎さんの著作に「失敗学のすすめ」という本があります。今回の「やらかし」もまた、今後の糧になることを願って、まあ、ぼちぼちやっていきます。

2019年4月20日土曜日

Antilog-NPNO はんだ付け完了

TLF01用のアンチログ兼電圧→電流変換回路のAntilog-NPNOをはんだ付けしました。

回路図

基板図

部品面

ハンダ面

抵抗値をあとから変更できるように、結構多めのピンソケットを使いました。

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


負荷抵抗RL=10kΩ、LFOを+2Vp-pののこぎり波とし、Cutoffに加える電圧を-10V、0V、+7.2V、+10Vで、パラメータ解析しました。

シミュレーション回路図

過渡解析

変換カーブが指数関数的になっているかどうか確認するために、縦軸を対数軸としてRLに流れる電流を過渡解析しました。

過渡解析(縦軸は対数軸)

ほぼ、直線になっていると思います。→変換カーブは指数関数的。

測定結果


Cutoff端子に10kΩのPOTをつないで所望の電圧を作り、回路図のOUT端子のGNDに対する電位を測定しました。

電源電圧: -11.59V / +11.73V
負荷抵抗: 10kΩ

Cutoff=9.54V

ch1:IN ch2:OUT

Cutoff=7.20V

ch1:IN ch2:OUT

Cutoff=0V

ch1:IN ch2:OUT

Cutoff=-9.36V

ch1:IN ch2:OUT

シミュレーションと似たような結果になっていると思います。アナログ回路なので誤差はかなりありますが。

DASS01TLF01)につないで、Anitlog-MMと出音を比較してみる予定です。

2019年4月18日木曜日

Blog 5周年記念: 製作物のまとめ(2018/05~2019/04)

いつのまにか5年もたってしまいました。

この1年はデジタル・アナログ混在でいろいろやってました。

チップチューンも好きなんですが、アナログ音源も好きなので、合わせ技で何かできないかという模索です。デジタルの正確さとアナログの自然さ(音のぬくさ)を共存できないかと頭を悩ませています。

コンセプトはピュンピュンマシン。バカでもガキでもラリって(※1)ても、つまみをひねれば面白い音が出てくる」です。

デジタル・アナログ混在で開発すると、マイコンの処理速度によって、特に(UI系の処理も含めた)1回毎の処理の周期性によって可聴帯域でノイズが発生することに気づいてに留意しました。

デジタルの演算ですべてを済ませて、最後にいっせーのせでアナログ信号に変換すれば、デジタルノイズは最後の最後で除去するのに集中できますが、マイコンとアナログ回路を行ったり来たりすると、可聴帯域に入ったノイズは容易には除去できません。

未だ試行錯誤中です。聞こえないからヨシとするのは性分に合いませんが、突き詰めると泥沼にはまりそうです。

また去年は、諸事情(※2)によりIoTにも手を出しました。

※1)私の場合は、飲酒によるラリりです。
※2)去年の夏の猛暑のせいで両親が熱中症でダウンしたので、環境パラメータを測定したくなりました。両親はおかげさまで健在です。

制作物


Nucleo DCO


外観

中の配線

筐体はまだ製作途中です。

ブロック図

Nucleo-F767ZIをコアとして製作しました。基本的にはDDSで波形を生成しているだけですが、3OSCなので操作子が増えて複雑な配線になってしまいました。

Nucleo-F767ZI(Nucleo-144 Board)はADCの入力端子が多いので、外付けICなしで済みました。端子が多いだけでもNucleo-144 Boardはありがたいと思います。

パラメータを表示するのに中華製のI2C接続のOLED(SSD1306)を使っていますが、表示が遅すぎて実用的にはかなり厳しい状態です。Nucleo-F767ZIから直接制御するのではなくて、別のマイコン(Arduinoなど)に任せようと思っていたのですが、IC間通信のテストが上手く行かず保留しています。

OLEDの表示を抑止すると操作子のレスポンスがあからさまによくなるので、なんとかしたいところです。

DACの出力波形はデジタル的なガタガタが乗っているので、出力部で6次LPFをかけて波形をなめらかにしています。今回はベッセル特性のフィルタを使いました。出力波形がサイン波だけではなく、のこぎり波や矩形波などエッジが尖っている波形も出力しないといけないので、過渡特性を重視しました。

ベッセル特性はバターワース特性のフィルターよりキレが悪いのですが、過渡特性がよく、フィルター通過後ものこぎり波はのこぎり波、矩形波は矩形波らしい原型をとどめてくれます。参考「Nucleo DCO 出力部(LPF)の検討

アナログ的にマスターピッチを揺らすことも考えていたのですが、MIDI CV ConverterのMIDI_CV_CONVでMIDIでピッチを変調できるので保留しています。

PWMや各OSCのDetuneはCVで揺らせられた方がおもしろいと思うのでいずれやってみたいと思います。

DASS01



ブロック図(現状)

現状では、VCOはNucleo_DCOから入力で、VCF(TLF01)、VCA(Dual_OTA_VCA)のみのアナログ・シンセです。

TLF01


トランジスタ・ラダーフィルターです。実際に回路を組んでみてDr.Moogの恐ろしさを改めて痛感しました。AIが発達してもこの回路を発明するのは相当難易度が高いと思います。普通のフィルターとはまるで異なる発想のフィルター回路で、このぬくさ。しかも帰還をかけて発振スレスレの出音の面白さを出しているところも特筆すべきだと思います。

トランジスタ・ラダーは電流制御されるため、電圧で制御するためには電圧→電流変換が必要になります。TLF01に載せている電圧→電流変換回路はFETを使ったリニアなものです。ジャンパーによって外部の電圧→電流変換回路も使えるようにしています。

AntiLog_MM


NPNとPNPトランジスタを使った、シンプルなアンチログ&電圧→電流変換回路です。アンチログとはリニアな電圧変化を音階のような指数関数的な変化に変換するものです。プログラムで書くなら、y = exp(x)です。これをトランジスタの特性を利用して電子回路で実現します。

トランジスタは電流出力のため、そのままトランジスタ・ラダーのカットオフ周波数を制御する電圧電流変換回路となります。

CV_AMP


マイコンを使った自作のモジュールは、3.3V系、5V系が多いのでアナログ回路に突っ込みやすくするために可変アンプを作成しました。-∞~3倍増幅で可変できます。なんのヒネリもないオーソドックスな非反転増幅回路ですが、それなりに役に立ちます。

±12V_+5V電源



ジャンク品で買った±15V、+5V出力のスイッチング電源をもとにしています。

DoepferのEuroRackの規格にならって、±12Vと+5Vの電源にしました。3端子レギュレータを使って±12Vに降圧しています。アナログ回路用の電源なので(心配事をなくすために)電源ノイズを減らしたいと思っています。

今の所DASS01では+5V電源は使っていないので±12Vのみの電源として使っています。たぶん必要になると思うので、+5Vも使えるようにすると思います。

Arduino EG 



Arduino Pro Miniを使ったエンベロープ・ジェネレーターです。エンベロープ生成の基本部分はNE555を使った作例が多いんですが、Arduinoでやってみました。マイコン由来のノイズが乗るというデメリットがありますが、ものは試しで作りました。

電源をOFFにしていても、Gate信号(5V)が入力されるとArduinoが動作してしまうようです(Arduino Pro Miniボード上のPWR LEDが点灯してしまう)。壊れはしないようですが、なんか嫌な感じです。

その他は今のところ問題は無いように思います。

MIDI CV Converter



ブロック図

MIDI信号をCV/Gate信号に変換します。CV2系統、Gate6系統です。コアはArduino Pro Miniです。

機能的には動作しているのですが、マイコンを使っているせいなのかMIDI信号の影響なのか、他の機材と電源を共有すると激しいノイズが発生するので、これだけ別電源で運用しています。追い込むのも大変なので難儀中。

MIX0401


DJ機材はRCAプラグ/ジャックが多いので最初は入出力にRCAジャックを使用していましたが、ノイズが乗るので試しに3.5φミニジャックに換装しました。原因がこれとは言えませんが、今のところ順調のようです。

マスター・ボリュームの配線に問題があり、ガリが出ます。

MIX0401のジャックをRCAジャックから3.5φミニジャックに変更

ESP WROOM


IoTといえば無線LANが載っているESP WROOM。プログラミングもArduinoでできる手軽さもあってなかなか便利です。センサのBME280を使って、少し離れた場所の気温、湿度、気圧を測定しました。

長時間WiFi接続していると無線LANアクセスポイントがハングアップするようなので、ESP WROOMでの実験は保留しています。Arduino Pro Miniを使ってローカルな環境センサとして動作させています。


mbed-cli (mbed OS 5)


mbedの利点の一つは手軽に使えるオンラインIDEですが、ローカルの開発環境のmbed-cliも使いはじめました。mbed-cliは基本的にmbed OS 5を使い、mbed OS 5はオンライン環境がありません。

オンライン環境のmbedのメリットは手軽さですが、ネットに繋がっていないと何もできないという脆さもあり、ソース管理も煩雑です。mbed-cliは導入が少しめんどくさく、昔ながらのコマンドラインで開発します。mbed OS 5の目玉ははRTOSの統合で、セキュリティなど新しい機能もmbed OS 5でしか利用できません。慣れてしまえばどうということもないので、今はmbed-cliを中心に使っています。

Arduinoほどではないですが、各種デバイスのライブラリもいろいろと揃っていて、お手軽プログラミングできるのも魅力です。

Nucleo_DCOのファームウェアはmbed-cliで開発しています。

STM32Cube


只今勉強中の、STM32のネイティブ環境です。STM32はとにかくARMのCortex-Mの新規格の導入が速い。しかも中華製ほどではないですが、値段も安い。

STM32Cubeは、意外なことにmbedの方が処理が速い場合があり、mbedと比較して速度面のアドバンテージがあるとはいい切れません。mbedでは使えない機能(DMA、I2S、CMSIS-DSPなど)を使えればなあと思っています。

英文も含めてドキュメントが少なすぎて、なかなかきついですが少しずつやっていこうと思っています。

中華製のパーツ



AliExpressでいろいろと部品を調達しました。到着まで時間はかかりますが送料も含めて激安です。なんで中国からの送料が40円前後で済むんだという。むしろ、いらんもんを買いすぎないように注意したほうがいいかもしれません。買ったはいいけど触りもしていないデバイスが増えると心理的に負担になります。

と、いいつつちょこっと動作確認したあと、使っていない非-中華製のデバイスもかなりあります。(小さい開発ボードだけ入れてる箱)


壊れても惜しくないという意味では、中華製のデバイスはありがたい存在だと思います。

2019年4月17日水曜日

Antilog-NPNOの構想

トランジスタ・ラダー・フィルターのTLF01の電圧電流変換&アンチログ回路のバリエーションを作る構想です。

参考
アンチログ(電圧→電流変換)回路
アンチログ(電圧→電流変換)回路 その2

NPNトランジスタとOPAMPの組み合わせなので、Antilog-NPNOと言う名前にしました。

回路は比較的かんたんですが、定数を決めるのが難しいので、ある程度試行錯誤できるようにして、ユニバーサル基板で実装したいと思います。

回路図

ブレッドボードで実験


MOD1(JP2)にArduinoLFOからのこぎり波を入力、CUTOFF(バイアス電圧)を-5V、0V、+5Vにして入出力を測定しました。出力は電流出力(吸い込み型)のため、RL=10kΩとして下記シミュレーション回路図のR10とRLの間の電位を測定しました。

ブレッドボード配線図


シミュレーション回路図

過渡解析

電源電圧: +8.96V / -9.00V

Cutoff=-4.93V RL=10kΩ

ch1:Vlfo ch2:Out

Cutoff=57.0mV RL=10kΩ

ch1:Vlfo ch2:Out

Cutoff=+4.98V RL=10kΩ

ch1:Vlfo ch2:Out

2019年4月14日日曜日

STM32: u8g2を使おうという試み(未完)

Arduinombedで、中華製のSSD1306のOLEDとu8g2ライブラリを組み合わせてよく使っています。STM32Cubeでも使えないか試してみました。

参考
「Elastic Notes」さんの「u8g2 library usage with STM32 MCU
「olikraus」さんの「Use U8g2 with STM32 #356
「olikraus」さんの「Template for the GPIO and Delay callback

「Elastic Notes」さんの記事がよくできているので、ほとんどそのまま試しました。

プロジェクト
https://github.com/ryood/STM32Cube_Test/tree/master/SW4STM32/Nucleo-F446_u8g2_Test1

実行環境

  • Nucleo-F446RE
  • STM32CubeMX Version 5.1.0
  • System Workbench for STM32 - C/C++ Embedded Development Tools for MCU Version: 2.8.1.201903050911

配線図


SSD1306 Arduino Header Pin Name Function Lavel
D0 D13 PA5 SPI1 SPI1_SCK
D1 D11 PA7 SPI1 SPI1_MOSI
CS D10 PB6 GPIO SPI1_CS
DC D9 PC7 GPIO OLED_DC
RES D8 PA9 GPIO OLED_RES

一応100uFのOSコンで電源をデカップリングしています。

STM32CubeMXの設定


Clock Configuration
  PLL Source Mux: HSE
  HCLK (MHz): 180

GPIO-GPIO

GPIO-SPI1

SPI1

SW4STM32でコードを追加


GPIOと遅延と、SPI通信の2つのCallback関数を追加

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t u8x8_stm32_gpio_and_delay(U8X8_UNUSED u8x8_t *u8x8,
    U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int,
    U8X8_UNUSED void *arg_ptr)
{
  switch (msg)
  {
  case U8X8_MSG_GPIO_AND_DELAY_INIT:
    HAL_Delay(1);
    break;
  case U8X8_MSG_DELAY_MILLI:
    HAL_Delay(arg_int);
    break;
  case U8X8_MSG_DELAY_10MICRO:
    for (uint16_t n = 0; n < 320; n++)
    {
      __NOP();
    }
  break;
  case U8X8_MSG_DELAY_100NANO:
    __NOP();
  break;
  case U8X8_MSG_GPIO_CS:
    HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, arg_int);
    break;
  case U8X8_MSG_GPIO_DC:
    HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, arg_int);
    break;
  case U8X8_MSG_GPIO_RESET:
    HAL_GPIO_WritePin(OLED_RES_GPIO_Port, OLED_RES_Pin, arg_int);
    break;
  }
  return 1;
}

uint8_t u8x8_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
    void *arg_ptr)
{
  switch (msg)
  {
  case U8X8_MSG_BYTE_SEND:
    HAL_SPI_Transmit(&hspi1, (uint8_t *) arg_ptr, arg_int, 10000);
    break;
  case U8X8_MSG_BYTE_INIT:
    break;
  case U8X8_MSG_BYTE_SET_DC:
    HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, arg_int);
    break;
  case U8X8_MSG_BYTE_START_TRANSFER:
    HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
    __NOP();
    break;
  case U8X8_MSG_BYTE_END_TRANSFER:
    __NOP();
    HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
    break;
  default:
    return 0;
  }
  return 1;
}
/* USER CODE END 0 */

「Elastic Notes」さんは、CSピンがないタイプのSSD1306 OLEDを使われていますが、私の手持ちのものはCSピンがあるタイプなので、Callback関数にCSの処理を追加しています。

u8g2ライブラリの準備


u8g2/csrcをプロジェクトのDriverディレクトリに配置、名前をu8g2に変更。

このパスをインクルードに追加。[Project]->[Properties]->[C/C++ Build]->[Setting]->[Includes]で
../Drivers/u8g2
を追加。

main.cファイルの先頭にu8g2.hを追加。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "u8g2.h"
/* USER CODE END Includes */

グローバル変数u8g2を配置。

/* USER CODE BEGIN PV */
static u8g2_t u8g2;
/* USER CODE END PV */

u8g2をセットアップ。

  /* USER CODE BEGIN 2 */

  u8g2_Setup_ssd1306_128x64_noname_1(&u8g2, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay);
  u8g2_InitDisplay(&u8g2);
  u8g2_SetPowerSave(&u8g2, 0);
  /* USER CODE END 2 */

メインループで描画処理

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    u8g2_FirstPage(&u8g2);
    do
    {
      u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
      u8g2_DrawStr(&u8g2, 0, 15, "Hello World!");
      u8g2_DrawCircle(&u8g2, 64, 40, 10, U8G2_DRAW_ALL);
    } while (u8g2_NextPage(&u8g2));
  }
  /* USER CODE END 3 */

Buildすると実行可能ファイルが大きすぎてエラーになるので、未使用のコードとデータを除去するオプションを設定。


実行結果


以上で冒頭の画像の通りOLEDに描画されるのですが、なぜだかSCKにオシロのプローブを当てていないと描画されません。SCKにプローブを当てていれば必ずOKというわけでもなく、たまに描画に失敗します。オシロのプローブもx1モードではだめで、x10モードのときにだけ描画されます。どういうこと?

オシロのプローブの仕様から、入力インピーダンス10MΩ・20pFぐらいでGNDにプルダウンすれば動作するんでしょうか?とりあえず1MΩ以上の抵抗は持ち合わせていないので検証できません。

それにしても、あまりにも厳しい条件です。

Arduinoでは似たような条件で特別なことをしなくても問題なく動作します。

参考「温度・湿度・気圧センサーのBME280をArduino Pro Miniで使う。

問題はおそらく違うところにあると思うので、しばらく放置して、気が向いたらまたテストしたいと思います。

メモ:


SPI1のSCKに割り当てているPA5(D13)はNucleo Board上でLEDに接続されている。ただし、Arduinoも同様で、Elastic Notesさんの検証でもSCKはPA5。

SPI通信波形


MOSI

ch1:MOSI(D1) ch2:SCK(D0)

RES

ch1:RES ch2:SCK(D0)

RESはReset時にLow。通常はHigh


DC

ch1:DC ch2:SCK(D0)

DCはWrite Command時にLow。Write Data時にHigh。

CS

ch1:CS ch2:SCK(D0)

CSはSlave選択時にLow。