Bright Muff

09_273_1bmP.jpg
第1回改造エフェクターコンテストに向け、Electro-Harmonix Little Big Muff Piにデジタル制御による3チャンネル化を施しました。コンテストにはオリジナルの自作エフェクターでも応募可能だったのですが、コンテスト名に改造とありますし、以前から考えていたデジタルポテンショメータを使ったアナログエフェクターの制御に取り組んでみることにしました。中にスペースがあるエフェクターが改造しやすいので、大きいケースのビッグマフが最適ですが、ケース加工の大変さを考えてLittleサイズの方にしました。ただ、やはりフットスイッチの間隔が狭く踏み間違えそうです(一応スイッチの高さには差をつけてあります)。

単純に多チャンネル化すると、保存していたプリセットを呼び出した時、各パラメータがどのようになっているか目視できないという問題があります。そこでDarkglassのADAMのように、ポット周囲のLEDでセッティング状況がわかるようにしました(見た目を派手にする目的も兼ねています)。後から思ったことですが、3チャンネル程度だと同じ回路基板を3つ積む方が早い気がします。7セグLEDを使って無駄に10チャンネルあった方が面白かったかもしれません。

▽回路図・基板画像
09_273_2bmS.png09_273_3bmB.jpg
この基板の裏側に元のビッグマフの基板が取り付けられています。ビッグマフ基板はコンデンサの交換等いろいろと変更が必要ですが、マネする人はいないと思うので詳細は省きます。マイコンは、使い慣れている手持ちのSTM32F405を使用しました。
  • デジタルポテンショメータ(DPOT)
    ビッグマフの3つのポット(100kA、100kB、500kA)をDPOTで置き換えることになります。DPOTは抵抗値やカーブの種類が少ないため、全て100kBを使用しており、カーブは内部プログラムで調整しています。また、大抵のDPOTは5Vまでしか扱えないので、より高い電圧が可能なMCP41HV51を使用しています。本来は10V以上推奨ですが、9Vでも問題ないようです。元の回路ではポットを通る信号がGND中心なので、バイアス電圧4.5V中心となるよう変更し、出力にバッファを設けました。
    さらに問題点として、DPOTは抵抗値を飛び飛びの値(今回は256段階)でしか設定できないので、抵抗値を変更した時にプツっというノイズがどうしても入ってしまいます。入力信号がゼロに近い(ゼロクロス)時に抵抗値を変更させる回路で軽減できるようですが、演奏時に支障はないのでそこまでは検討しませんでした。プリセット切替時には、切替ノイズを最小限にするため、VOLUMEを1段階ずつ下げて0にする→TONE、SUSTAINの設定変更→音量を1段階ずつ上げるという順番の内部処理となっています。

  • LEDドライバ
    LED点灯の方式にはダイナミック点灯とスタティック点灯があります(参考ページ→LEDのダイナミック点灯)。最初はマイコンとLEDを直接接続してダイナミック点灯させていましたが、ノイズが乗ってしまいました。そこでPCA9635というI2C制御のLEDドライバICを3つ使ってスタティック点灯へ変更しました。このICは簡単に個別のLEDの明るさをPWM制御することができ、大変便利です。

  • アナログ-デジタル変換(ADC)
    元のポットがあった所に別のポットを配置し、このポットの回転角度に応じた電圧をADCで取得することになります。昔NucleoボードのADCを使うという記事を書いていたのが役に立ちました。AD変換速度は遅くてもよいと思っていましたが、ADC完了割り込みのタイミングで少しノイズが発生していたので、ノイズが可聴域外になるよう高速にしています。ADCを高速にすると取得値が揺れ動きやすくなるので、256個の移動平均値を算出するようにしました。

▽取扱説明書
コンテスト応募時に同封した説明書です。
09_273_4bmP.png
見た目のインパクトのためにLEDはできるだけ明るくしましたが、直視することができず実用上支障が出そうなので、調光モードで明るさを調整できるようにしました。普段はLEDの色による明るさの違いを気にしたことがなかったですが、比べてみると結構な違いでした。青と緑のLEDは電流制限抵抗の値を変えてあります。

アナログエフェクターのデジタル制御という面では、Tremolecのようにフォトカプラを使った方が自由度が高いように思います。セルフキャリブレーションのような機能を付けることができればフォトカプラのバラつきも許容できるかもしれません。コンテストが続くのかどうかはわかりませんが、また機会があればフォトカプラを使った改造にも挑戦してみたいと思います。

タグ : 市販エフェクター 歪み マイコン 

COOLMUSIC JAMMER Looper 分解・特性測定

09_276_1jaP.png
現在、様々な格安エフェクターが販売されています。その中でルーパーはやや価格が高くなっており、中身が気になったので買ってみることにしました。選んだのは、独特の薄いケースが採用されているCOOLMUSIC A-LP01 JAMMER Looperです。分解・特性測定を行っておきます。



【分解】

▽中身画像 COOLMUSIC A-LP01 JAMMER Looper Gut Shots
09_276_2jaI1.jpg09_276_3jaI2.jpg
ケースのみの大きさは縦114mm横60mm高さ21mmです。裏フタ固定ネジは六角穴付きボルト(キャップボルト)ですが、普通のM3ネジが使えます。フットスイッチやポットは通常より高さが低くなっており、特注なのかもしれません。アナログGNDとデジタルGNDは、電源部で接続されているように見えます。

ICは以下の通りです。
・マイコン STM32F205RBT6
・オーディオコーデック TLV320AIC3104
・フラッシュメモリ MKDV4GIL-AS
・オペアンプ TL072



【特性測定】

▽周波数特性・ノイズ・歪率

低音域が少しカットされているので、どこかのコンデンサを交換すれば改善するかもしれません。録音したものを再生した時、低音域側のノイズが多くなっていますが原因不明です。

私が製作したデジタルエフェクターSodiumの方が可聴域内のノイズが少ないです。SodiumのオーディオコーデックPCM3060のSN比は99dB、TLV320AIC3104のSN比は92dBなので妥当な結果だと思います。



【内部プログラムの読み取り】

STM32CubeProgrammerを使って基板上側のJ5からマイコンへ接続してみました。接続には成功しているようですが、読み取りや消去はできませんでした。もっと技術力があれば可能かもしれませんが、マイコンを新品にした方が簡単そうです。いつか半導体不足が解消し、STM32F205RBT6が手に入ったら交換してみたいと思います。

タグ : 市販エフェクター マイコン 周波数特性 歪率 

Sodium

03s_265_1sodP.jpg
自分でプログラミング可能なエフェクターは高価なものが多く(2~3万円)、デジタルエフェクターを始める上でのハードルの一つとなっていると思います。そこで、低価格なデジタルエフェクター入門機の販売に向けて製作したのがこのペダルです。
【販売ページはこちら】

金属ケースの加工は自分で行うには大変すぎるし、外注すると高額になってしまうので、Elecrowのアクリル加工サービスを利用した筐体となっています。本体は下写真のように基板とアクリル板計7枚から構成されています。アクリルのデータもKiCadで作成しました。(図面データはGitHubへ)
03s_265_4sodP3.jpg03s_265_3sodP2.jpg
メイン基板は表面実装部品のみElecrowのPCBA(部品実装)サービスを利用しました。詳細は別記事にまとめる予定です。

▽回路図(KiCadデータはGitHubへ)
03s_265_2sod.png
最低限の機能ということで、ステレオ不可、入出力は単純な1次ローパスフィルタとなっています。レギュレータはそれなりの発熱が予想されたため、抵抗器を入れるといった対策を行っていますが、実測では消費電流150mA程度だったのであまり要らない心配だったかもしれません。

操作系は以前製作したSrempyと同じで、ディスプレイとスイッチ5つという構成です。ポットだとどうしてもフットスイッチとの干渉が気になりますし、ディスプレイを付けたかったのでこの形になりました。

オペアンプはOwm PedalではOPA1678でしたが、入力がRail to Railでないことに気づいていませんでした。やはり許容入力が大きい方がよいので、TLV9062(5V駆動可、入出力Rail to Rail)を使っています。未検証ですがGS8632もよいかもしれません。(TL072等を9V駆動で使い、オーディオコーデックの入出力にカップリングコンデンサを入れる方式が標準的だと思います。少しスペース的に厳しくなりますが…)

オーディオコーデックICはPCM3060を採用しました。CS4270、ES8388を使ったプロトタイプとのノイズ比較データは下図の通りです。GNDにスリットを入れてみましたが、効果の程はわかりません。概ねICのスペック通りの結果なのかなと思います。
03s_265_5sodN.png
コーデックICの検討を進めている時、旭化成の工場火災の影響かコーデックIC全体が品薄となりました。CS4270を使いたかったのですが、入手が難しく採用をあきらめました。PCM3060はリードタイムが比較的短く、ある程度供給は大丈夫だろうと思います。ES8388もコストパフォーマンスがよいので別の機会に使ってみたいところです。

マイコンはSTM32F722で、処理能力やメモリ容量を考えるとそれなりの価格になってしまいますが、ここは妥協できないところです。SAIペリフェラルを使いこなすのはあまり自信がなかったので、いつも通りI2Sを2つ使う方式で通信しています。

見た目はあまり気にしていないのですが、アクリルを使っているおかげで暗いところでは目立ちそうです。赤LEDにPWM出力が設定できないピンを選んでしまったので、ここは変更するかもしれません。
03s_265_5sodP4.jpg



そもそもデジタルエフェクターのプログラミングをやってみたいという人はそんなに多くはないと思います。それでもデジタルエフェクター普及を進めたいので、ほとんど利益はない価格設定です。私自身プログラミングは初心者に毛が生えたようなものなので、うまくいかない部分も出てくるかもしれませんが、できるだけ継続販売していきたいと思います。

タグ : 自作エフェクター 回路図 マイコン 

STM32 LittlevGLを使う

03s_255_1lvp.jpg
LittlevGLは、組み込み機器のGUI向けのグラフィックライブラリです。これを使いこなせれば、きれいな画面や使いやすい操作が実現できると思われます。公式の導入方法ではわかりにくい部分があるので、デモの実行方法をまとめておくことにしました。使用したNucleoボードはNUCLEO-F401REです。※メモリ使用量はRAM46kB、FLASH407kBとなったので、それなりに容量が必要となります。



<準備>
まずは以前の記事(STM32 SPI接続タッチパネル付ディスプレイを使う)の手順を行って、ディスプレイの動作確認をします。そしてそのプロジェクトをそのまま利用し、以下の操作をしていきます。



<ダウンロード>
  • LittlevGL本体(v6.1.1)
    右側の [Clone or download] ボタンからZIPダウンロード、解凍
    →フォルダ名「lvgl-master」を「lvgl」へ変更後、プロジェクトのIncフォルダへフォルダごとコピー

  • LittlevGLサンプル集
    右側の [Clone or download] ボタンからZIPダウンロード、解凍
    →フォルダ名「lv_examples-master」を「lv_examples」へ変更後、プロジェクトのIncフォルダへフォルダごとコピー



<LittlevGLコンフィグファイル編集>
  • lvglフォルダ内のlv_conf_template.hを開き、下記3か所編集
    10行目 #if 1 /*Set it to "1" to enable content*/
    23行目 #define LV_HOR_RES_MAX (240)
    36行目 #define LV_COLOR_16_SWAP 1
    →ファイル名「lv_conf_template.h」を「lv_conf.h」へ変更後、プロジェクトのIncフォルダへ移動

  • lv_examplesフォルダ内のlv_ex_conf_templ.hを開き、下記2か所編集
    9行目 #if 1 /*Set it to "1" to enable content*/
    42行目 #define LV_USE_DEMO 1
    →ファイル名「lv_ex_conf_templ.h」を「lv_ex_conf.h」へ変更後、プロジェクトのIncフォルダへ移動
    ※壁紙画像不使用にするとメモリ使用量を減らせます。→44行目 #define LV_DEMO_WALLPAPER 0



<main.cファイル編集>
以前の記事(STM32 SPI接続タッチパネル付ディスプレイを使う)で記述したものは消去し、下記4か所に記載
(参考ページ→How start with the LittlevGL on the Disco F746NG with Mbed

▼/* USER CODE BEGIN Includes */ の下
#include "ili9341.h"
#include "ili9341_touch.h"
#include "lvgl/lvgl.h"
#include "lv_examples/lv_apps/demo/demo.h"

▼/* USER CODE BEGIN 0 */ の下
lv_disp_buf_t disp_buf;               // ディスプレイバッファの構造体
lv_color_t buf_1[ILI9341_WIDTH * 10]; // ディスプレイバッファ1
lv_color_t buf_2[ILI9341_WIDTH * 10]; // ディスプレイバッファ2

lv_disp_drv_t disp_drv; // ディスプレイドライバの構造体
lv_indev_drv_t indev_drv; // タッチパッドドライバの構造体

void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) // 画面描画
{
int32_t w = area->x2 - area->x1 + 1;
int32_t h = area->y2 - area->y1 + 1;
ILI9341_DrawImage(area->x1, area->y1, w, h, (uint16_t*)color_p);
lv_disp_flush_ready(disp_drv); // 描画終了をライブラリへ知らせる
}

bool my_input_read(lv_indev_drv_t * drv, lv_indev_data_t * data) // タッチパッドのタッチ検出とタッチ位置取得
{
static uint16_t x = 0, last_x = 0;
static uint16_t y = 0, last_y = 0;
if(ILI9341_TouchPressed())
{
ILI9341_TouchGetCoordinates(&x, &y);
data->point.x = x;
data->point.y = ILI9341_HEIGHT - y; // 上下逆さま
last_x = data->point.x;
last_y = data->point.y;
data->state = LV_INDEV_STATE_PR; // タッチあり
}
else
{
data->point.x = last_x;
data->point.y = last_y;
data->state = LV_INDEV_STATE_REL; // タッチなし
}
return false;
}

void init() // ディスプレイ初期化
{
ILI9341_Unselect();
ILI9341_TouchUnselect();
ILI9341_Init();
}
my_flush_cb関数に画面描画を行うコードを、my_input_read関数にタッチパッドに関するコードを記述します。他のディスプレイを使う場合でも、ここに該当するコードを記述すればうまく動作するはずです。

▼/* USER CODE BEGIN 2 */ の下
  init();    // ディスプレイ初期化
lv_init(); // ライブラリ初期化
lv_disp_buf_init(&disp_buf, buf_1, buf_2, ILI9341_WIDTH*10); // ディスプレイバッファ初期化

lv_disp_drv_init(&disp_drv); // ディスプレイドライバ初期化
disp_drv.buffer = &disp_buf; // ディスプレイバッファ登録
disp_drv.flush_cb = my_flush_cb; // 画面描画関数登録
lv_disp_drv_register(&disp_drv); // ディスプレイドライバ登録

lv_indev_drv_init(&indev_drv); // タッチパッドドライバ初期化
indev_drv.type = LV_INDEV_TYPE_POINTER; // 入力タイプをタッチパッドに指定
indev_drv.read_cb = my_input_read; // タッチ検出関数登録
lv_indev_drv_register(&indev_drv); // タッチパッドドライバ登録

demo_create(); // デモ呼び出し

▼/* USER CODE BEGIN 3 */ の下
    HAL_Delay(100);
lv_tick_inc(100); // ライブラリへ経過時間を知らせる
lv_task_handler(); // ライブラリ実行(画面更新)
メインループ内で100msごとに画面を更新します。画面描画が速ければもっと短い間隔で更新してもよいでしょう。ライブラリへ経過時間を知らせるのは、アニメーションの動作に関係していると思われます。

ビルドには1分程度かかる場合があります。SPIの通信速度が遅いので、アニメーションはさすがに無理がありそうです。狭い範囲の表示更新については特に問題なさそうな感じです。

タグ : マイコン 

Owm Pedal H7 ソフトウェア編

自作デジタルエフェクター「Owm Pedal H7」の各設定、内部プログラミングをしていきます。
Owm Pedal H7 ハードウェア編はこちら
内部データはGitHub

<開発環境について>
STM32CubeIDEのバージョン1.1.0ではクロック設定がうまく動作しなかったので、STM32CubeMXを併用していました。バージョン1.2.1では修正されているようで、今のところ問題は起きていません。

main.cファイルを「main.cpp」にリネームすればC++を使うことができます。main.cppに追加記載しているのは下記3か所です。主にuser_main.cppを編集することになります。
 「/* USER CODE BEGIN Includes */」の下→#include "user_main.hpp"
 「/* USER CODE BEGIN 2 */」の下→mainInit();
 「/* USER CODE BEGIN 3 */」の下→mainLoop();

コンパイラの最適化設定を高速動作向けに変更しておきます。
Project→Properties→C/C++ Build→Settings→Tool Settingsタブ
→MCU G++ Compiler→Optimization→Optimization level [Optimize for speed (-Ofast)]



<STM32CubeIDE iocファイル設定>
・ST-LINK接続(結線はOwm Pedal ソフトウェア編参照)
Trace and Debug→DEBUG→Debug [Serial Wire]

・処理高速化のためDキャッシュを有効化
System Core→CORTEX_M7→Cortex Interface Settings→CPU DCache : Enabled

・クロック源として外部水晶振動子を使用
System Core→RCC→High Speed Clock (HSE) [Crystal/Ceramic Resonator]

・動作モード設定(480MHz動作のために必要)
System Core→RCC
→System Parameters→Product revision : rev.V
→Power Parameters→Power Regulator Voltage Scale : Power Regulator Voltage Scale 0

▽SPI設定
タッチパネル付ディスプレイの接続はSPIです。詳細は以前の記事(STM32 SPI接続タッチパネル付ディスプレイを使う)をご参照ください。
※通信速度を上げ過ぎるとタッチ位置をうまく取得できないので、本来はディスプレイとタッチを別々のSPIにした方がよいと思われます。

▽SAI設定
03s_254_1owmHSAI.png
Multimedia→SAI1→SAI A→Mode [Asynchronous Slave] I2S/PCM Protocol にチェック
同SAI B→Mode [Synchronous Slave] I2S/PCM Protocol にチェック
SAI A Data Size : 32 Bits
SAI A FIFO Threshold : Half Full
SAI B Audio Mode : Slave Transmit
SAI B Data Size : 32 Bits
SAI B FIFO Threshold : Half Full

NVIC Settingsタブ→SAI1 global interrupt→Enabledにチェック(2020年3月16日追記)

※STM32H7でDMAを利用するのは大変そうなので、今回は利用していません。
→参考ページ:STM32H7でキャッシュ一貫性を保持したDMA転送(Memory-to-Peripheral)

▽クロック設定図
03s_254_2owmHCK.png
SAIクロックは、オーディオサンプリングレート44.1kHzに対する誤差が少なくなるような設定としました(44.1×2048=90316.8)。

▽全ピン設定図
03s_254_3owmHPin.png



<信号処理>
Owm Pedalと同じように半分ずつデータ処理しようとしましたが、HalfCpltCallbackが呼び出されないようなので、2つのバッファ配列を準備しました(下図ではaとb、ソースコード内では[0]と[1])。
03s_254_4owmHI2S.png
mainInit処理の中で最初のSAI受信呼び出しを行います(HAL_SAI_Receive_IT)。その後、受信完了時にHAL_SAI_RxCpltCallbackが呼び出され、その中で次の受信とSAI送信(HAL_SAI_Transmit_IT)を行います。送受信にFIFOを設定しておかないと、処理が連続的にならず途切れ途切れになってしまうことがあります。遅延時間(レイテンシ)実測値は、ブロックサイズ32で2.5ms程度でした。まとめて信号処理ではなく、1サンプルずつ処理するようなやり方をすればバッファ配列は1つで済むかもしれません。

<SAIエラー対処>
Owm Pedalのときの反省を生かし、オーディオコーデックV4220Mをマイコンからリセットできるようにしました。mainInit処理内でSAIのエラーが起こった場合、リセット処理するようになっています。ただ、今のところエラーが発生したことがなく、正しい処理なのかわかりません。

<スイッチ・タッチ検出>
SAIの割り込みは32ブロックサイズ(約0.7ms)ごとに起こるので、これをタイマーのように利用しています。割り込みが起こるたびにGPIOの状態をチェックし、スイッチ操作やタッチを検出するというやり方です。タッチ検出時はすぐにタッチ位置を算出したいところですが、SPI通信にそれなりに時間がかかるので、タッチ位置関係処理は割り込み内ではなくメインループ処理内に入れています。現状の操作方法は下記の通りです。
・画面上部:パラメータページ切替、長押しでデータ保存(→STM32 内蔵フラッシュメモリへのデータ保存
・各ノブ部:上側で増加、下側で減少(長押しで10ずつ変化)
・画面下部:長押しでエフェクト切替
・スイッチ:エフェクトオン・オフ

<エフェクト処理>
とりあえず6つのエフェクト(オーバードライブ、ディレイ、トレモロ、イコライザ、コーラス、リバーブ)を実装していますが、細かい音質については検討していません。今後別記事で紹介していきたいと考えています。

タグ : 自作エフェクター マイコン 

管理人

管理人

自己紹介のページ
記事一覧
X(旧Twitter)
Instagram
GitHub
BOOTH

ブログ内検索
カテゴリー
タグ

回路図   自作エフェクター   歪み   周波数特性   市販エフェクター   レイアウト   マイコン   波形・倍音   PureData   RaspberryPi   エレキギター   アンプ   歪率   エレキベース   エフェクター自作方法   コーラス   真空管   ピックアップ   静音ギター   SansAmpBDDI   ヘッドフォンアンプ   擬似ギター出力   ブースター   アコースティックギター   ソロギター   イコライザー   ポールピース   コンデンサ   コンプレッサー   ディレイ   TAB譜   DIY_Layout_Creator   ビブラート   フェイザー   トレモロ   バッファー   ワウ   オートワウ   

最近の記事
最新コメント
RSS
メールフォーム
当ブログに関するお問い合わせはこちらからお願いします。 ※FAQ(よくある質問)もお読みください。

お名前
メールアドレス
件名
本文

アクセスカウンター