製作モジュール一覧

2018年12月8日土曜日

MIDI-CV Converter MIDI_CV_CONVの構想

BSM02でシーケンサー+D/A混在シンセを作りましたが、打ち込んだデーターを外に取り出す仕組みは作っていないので、Nucleo_DCOに音階を与えるために流用するのは少しめんどうです。BSM02のハードウェア/ソフトウェアに手を入れる必要があるので、思いつきで崩してしまうのは抵抗があります。

ひとまずは、パソコン上のDAWを使ってMIDI信号を出力し、CV/GATE信号に変換する、MIDI-CVコンバーターを作ってみることにしました。

作戦


ArduinoとmbedのMIDI Libraryを簡単に試したことがありますが(https://dad8893.blogspot.com/search/label/MIDI%20Library)、サイズの小さいNucleo F303K8を使ってmbedでやってみると、どうもMIDIメッセージを読みこぼすようです。

Nucleo-F303K8は12bit DACが3系統内蔵されていて、性能もCortex-M4でそこそこ高スペックなので使ってみたかったのですが、まずはArduinoでやってみることにしました。

Arduino NANOかArduino Pro Miniを使うつもりです。

想定している使用例

ArduinoにSPI/DACのMCP4922を接続し、アナログ値を出力してCVとします。MCP4922は2ch DACなのでうまく行けば2ch分CVを出力できます。

Nucleo_DCOは3.3V系(5Vトレラント)なのでCVの信号レベルは0V~3.3Vとします。

「DASS01」(「ASS01」という名前にしようと思ってましたが、「DASS01」に変更します)はアナログ系でCV信号にもう少し振幅が欲しいので「DASS01」内の「Amp」で増幅します。増幅率は「Mod Level」POTで可変します。

GATE信号はGPIOから出力します。「Arduino_EG」のプロセッサーは5V駆動のArduino Pro Miniなので入力するGATE信号レベルは5VでOKです。「KIK01」はNucleo-F446RE、「BSM02」はNucleo-F401REでSyncIn(GATEの立ち上がりで評価)は3.3V系ですが5Vトレラントなのでこれも5VでOKです。

開発環境


ArduinoでMIDI Libraryを使うとデフォルトではハードウェアUART(D0, D1)を使うので、デバッグ用にArduinoのSerialクラスが使えません。簡単なメッセージの表示しかできませんが、I2C接続のキャラクタLCD(秋月のAE-AQM1602A)を使うことにしました。

ブレッドボード配線図

※Arduinoで書き込むときは、RXの配線を抜く。


※MCP4922はまだ接続していません。

Arduinoのスケッチ


AE-AQM1602Aのライブラリは「I2CLiquidCrystal-1.5 https://n.mtng.org/ele/arduino/i2c.html」を使いました。

<MIDI_Display_Message_I2C_LCD_Gate.ino>

#include <Wire.h>
#include <I2CLiquidCrystal.h>
#include <MIDI.h>

#define LCD_TRACE   (0)
#define PIN_CHECK   (1)
#define TITLE_STR1  ("MIDI to GATE    ")
#define TITLE_STR2  ("20181204        ")

// Pin assign
const int GateOutPin1 = 2;
const int GateOutPin2 = 3;
const int GateOutPin3 = 4;
const int GateOutPin4 = 5;
const int GateOutPin5 = 6;
const int GateOutPin6 = 7;

const int CheckPin1   = 8;

// MIDI
MIDI_CREATE_DEFAULT_INSTANCE();

// I2C LCD
#if (LCD_TRACE)
I2CLiquidCrystal lcd(32, (bool)true);
#endif

// MIDI -------------------------------------------------------------------------

#if (LCD_TRACE)
void printNoteOnOff(const char* type, byte inChannel, byte inNote, byte inVelocity)
{
  lcd.setCursor(0, 1);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print(type);
  lcd.print(' ');
  lcd.print(inChannel);
  lcd.print(' ');
  lcd.print(inNote);
  lcd.print(' ');
  lcd.print(inVelocity);
}
#endif

void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
{
  digitalWrite(GateOutPin1, HIGH);
#if (LCD_TRACE)
  printNoteOnOff("On", inChannel, inNote, inVelocity);
#endif
}

void handleNoteOff(byte inChannel, byte inNote, byte inVelocity)
{
  digitalWrite(GateOutPin1, LOW);
#if (LCD_TRACE)
  printNoteOnOff("Off", inChannel, inNote, inVelocity);
#endif
}

// -----------------------------------------------------------------------------

void setup()
{
  pinMode(GateOutPin1, OUTPUT);
  pinMode(GateOutPin2, OUTPUT);
  pinMode(GateOutPin3, OUTPUT);
  pinMode(GateOutPin4, OUTPUT);
  pinMode(GateOutPin5, OUTPUT);
  pinMode(GateOutPin6, OUTPUT);
  pinMode(CheckPin1,   OUTPUT);

  MIDI.setHandleNoteOn(handleNoteOn);
  MIDI.setHandleNoteOff(handleNoteOff);
  MIDI.begin(MIDI_CHANNEL_OMNI);

#if (LCD_TRACE)
  lcd.begin(16, 2);
  lcd.print(TITLE_STR1);
  lcd.setCursor(0, 1);
  lcd.print(TITLE_STR2);
  delay(2000);
#endif
}

void loop()
{
#if (PIN_CHECK)
  digitalWrite(CheckPin1, HIGH);
#endif

  if (MIDI.read()) {

    // Display Raw Midi Message

    byte type    = MIDI.getType();
    byte channel = MIDI.getChannel();
    byte data1   = MIDI.getData1();
    byte data2   = MIDI.getData2();

#if (LCD_TRACE)
    lcd.setCursor(0, 0);
    lcd.print("                ");
    lcd.setCursor(0, 0);
    lcd.print(type, HEX);
    lcd.print(' ');
    lcd.print(channel, HEX);
    lcd.print(' ');
    lcd.print(data1, HEX);
    lcd.print(' ');
    lcd.print(data2, HEX);
#endif
  }
#if (PIN_CHECK)
  digitalWrite(CheckPin1, LOW);
#endif
}

メモ:


LCD_TRACEを有効化(1)するとMIDIメッセージを読みこぼす。

中華製のArduino NANOはプロセッサでATMega328P(Old bootloder)を指定する必要がある場合がある。

メインループの処理時間は92kHzぐらいで変わらない?

DACからの出力にはLPFを入れる。Nucleo_DCOはADCにCV信号を入力するので注意。

厳密にするならDACやGPIOからの信号はデジタル回路でラッチをかけて同期させたいけど、そこまでは必要ないか・・・

2018年12月7日金曜日

STM32CubeMX + Atollic TRUEStudioでLチカ

STM32のネイティブ環境でLチカを動作させられたので、メモです。いろいろ試行錯誤しているのでこの手順通りで動作できるかどうかはわかりません。

STM32の統合開発環境には、

  • IAR Embedded Workbench(有償)
  • ARM MDK-ARM(有償)
  • AC6 SW4STM32(無償)
  • Atollic TRUEStudio(無償)

などがありますが、今回はAtollic TRUEStudioを使いました。パソコンはWindows10で、ターゲットボードはNucleo-F446REです。

参考にした記事
「楽しくやろう。」さんの「TrueSTUDIO fo STM32を動かしてみた https://blog.boochow.com/article/456508260.html
「HappyTech Blog」さんの「STM32CubeMXの使い方 http://happytech.jp/wordpress/2017/06/05/how-to-use-stm32cubemx/

TrueSTUDIOのインストール


https://atollic.com/truestudio/よりAtollic_TrueSTUDIO_for_STM32_windows_x86_v9.0.1_20180420-1214.exeを入手してインストール。

Quickstart guideを一読


EclipseベースのIDEを使うのは10年ぶり?ぐらいです。[ヘルプ] - [Information Center]より「Quickstart Guide」を一読してなんとなく操作法を確認しました。パースペクティブの切り替えなど少しクセがあります。

新規プロジェクトの作成


[新規] - [C++ Project] で現れる[C++ Project]ダイアログでプロジェクト名を指定。

[Project type:]を[Embedded C++ Project]を指定。

[ターゲット]で[Boards]-[NUCLEO_F446RE]を指定。

[デバッグプローブ]で[ST-LINK]を指定。

以上でカウンターをインクリメントするプロジェクトが作成され、コンパイル&デバッグできますが、これだけでは周辺機能のドライバが何もありません。

STM32CubeMX & STM32Cubeのインストール


STM32CubeはSTM32の開発を行うためのHALその他もろもろのソフトウェアを集めたもので、F3とかF4などのSTM32のシリーズごとに別れています。STM32CubeMXはSTM32Cubeを使ったプログラムに必要な初期化コードを生成するグラフィカルなツールです。

まずは、STM32CubeMXをインストールします。途中で「Java Runtime Enviroment」のインストールが促され、インストールしました。

STMicroの日本語の記事
https://www.stmcu.jp/design/sw_dev/pc_soft/52798/?gclid=EAIaIQobChMI-P6p9qfD3QIVQamWCh3FhQNcEAAYASAAEgIFxvD_BwE

インストールファイルはSTMicroの本家サイトhttps://www.st.com/ja/development-tools/stm32cubemx.html)から入手しました。

STM32CubeMXのスタンドアロン版の[Help]で「UM1718 User manual」が参照でき、これに従って以降の設定を行いました。

4.3  Installing STM32CubeMX plug-in version

プラグインバージョンのインストールです。TRUEStudio上でCubeMXを利用できるようになります。

4.5.2  Installing STM32 MCU packages

STM32Cubeのインストールです。NucleoF446REを使うので、「STM32F4 1.21.0」をインストールしました。

動作テスト


STM32F4Discovery & Keilの記事ですが、
「@gkmaro634」さんの「STM32CubeMXでSTM32F4Discoveryを動かす1~Lチカ編~ (https://qiita.com/gkmaro634/items/7b2ce4f72615c96f41d3)」を参考にしてLチカさせました。

CubeMXでBoardを指定してデフォルトの設定のまま初期化コードをを生成するものです。とりあえず動かしてみるにはちょうどいいと思います。

CubeMXの[New Project] - [Board Selector]で[Nucleo-F446RE]を選択、デフォルト・モードで初期化。

[Project] - [Settings...]で[Project Name]、[Project Location]を設定。

[Toolchain / IDE]で[TrueSTUDIO]を選択。

[Project] - [Generate Code]でコードを生成。

以上でTRUEStudio用の雛形プロジェクトが生成されます。コード生成後あらわれるダイアログで、「Open Project」を選択するとエラーメッセージが表示されましたが、TrueSTUDIOで生成されたプロジェクトを開けば大丈夫でした。

プロジェクト内のmain.cppのmain()関数内のwhile()ループ内にLチカさせるコードを追加します。


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
   HAL_Delay(500);
   HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
   HAL_Delay(500);
   HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

[実行] - [デバッグ]で、PCに接続したNucleoにプログラムが書き込まれ、LEDがチカチカします。

HAL_GPIO_WritePin()、HAL_Delay()などはSTM32CubeのAPIで、ドキュメントを参照しながら習得する必要があります。

参考になりそうなドキュメント:
UM1725 Description of STM32F4 HAL and LL drivers
UM1730 Getting started with STM32CuberF4 MCU Package for STM32F4 Series
STM32Cube ファームウエア テクニカル・プレゼンテーション STM32Cube_training_JPN_rev1.pdf
STM32F4 シリーズ テクニカルトレーニング STM32F40x_training_JPN_rev1.pdf
Best-practices / FAQ: TrueSTUDIO + STM32CubeMx http://blog.atollic.com/best-practices-faq-truestudio-stm32cubemx

STM32CubeF4のExample:
<ドキュメントフォルダ>\STM32Cube\Repository\STM32Cube_FW_F4_V1.21.0\Projects\

2018年12月1日土曜日

ASS01 仮組み

TLF01 + Antilog-MM + Dual_OTA_VCA を組み合わせてASS01(アナログ・シンセ・システムの略)と名付けて、仮組みしました。

ASSはあんまりいい意味の言葉ではないですが、気にしません。

<追記: 2018.12.07>

デジタル系システムからの入力もあるので、思い直して、「Digital-Analog Synth System」という意味で「DASS01」とします。

</追記>


電源もいずれ作るつもりですが、とりあえず単3×6の9V電池ボックスを2つ使って±9V電源としました。



WaveInはNucleo_DCOから、EnvelopeはArduino_EGから入力しています。

左上のブレッドボードはArduino_EGに入力するGate信号を発生させるものです。Arduino NANOでとりあえず組んでいます。MIDI-CVコンバーターを作って置き換えるつもりです。

MoogerFoogerをリスペクトして個別筐体でいろいろ作ってきましたが、機材の置き場所に苦慮しています。そろそろEurorackみたいにラック・マウントすることも考えるべきか・・・