インタラプタ設計法
アナログ回路は分かる(テスラコイル本体は作れる)けどデジタル回路・マイコンがよくわからない人向けに書いています。
半導体で駆動するDRSSTCと呼ばれるタイプのテスラコイルはインタラプタと言われるパルス発生装置で制御を行います。
DRSSTCはパルスのON時間の間だけ動作するようになっています。
このインタラプタの設計法について書いていきましょう。
DRSSTCの動作
DRSSTCは一般的に駆動回路をロジックICで組むことが多いです。
その際に、フリップフロップを使った位相に同期した外部制御入力を設け、インタラプタの接続を可能にします。
なぜ、インタラプタが必要なのかというと、SSTCと違い1次側と2次側の両方が共振するためインピーダンスは0になります。
そのため、流れる電流が多く、連続で動作させるとIGBTやコンデンサなどが熱で壊れてしまう現象が起こります。
よって、連続で稼働させることは基本的には不可能で、外部に制御パルスを生成するインタラプタという制御装置が必要になるのです。
一般的に制御パルス自体は、数百usec、周波数を可変できるようにする場合が多いです。
DRSSTC自体は小型のものだと数百kHz、大型のものだと100kHz前後などの共振周波数で動作します。
人間の耳には20kHz以上の周波数は聞こえないため、制御パルスの周波数のみ聞こえる形になります。
そのため、制御パルスの周波数を変えると、その音程となって聞こえてくるのです。
タイマーIC555でのアナログインタラプタ
多く使われているのがこの方式です。
- CTC-LABS NE 555 Interrupter
- Steve's High Voltage Interrupter with Burst Mode
- Steve Conner's Dee-Lux Interrupter schematic
この辺がよく使われているデザインのベースになったものです。
アナログなのでコンデンサと抵抗にて値を調整するものです。
基準となる周波数を生成して、それをトリガーとしてON時間を生成する2段階の動作になっているものです。
どうやって音楽を演奏する?
タイマーIC555にて周波数を決める方法は、可変抵抗を使用しています。
つまり、抵抗値を変化させることによって、音程を変化させることができます。
ではこれで何か音楽を演奏したい場合は、音階をどのように出力しましょう?
ピアノの鍵盤の数、可変抵抗を用意して、スイッチで切り替える?
もちろん実現できますが現実的ではありませんね。
必要なパラメーターは周波数以外にもON時間があるからです。
ON時間が固定のまま、周波数を上げていくと、音圧はどのように変化するでしょう?
周波数(1秒間に何回パルス出力が行われるか)を増加させていけば、それだけ音圧は上がります。
つまり、楽器として演奏に使用したい場合は、補正をかけないと使いづらい楽器として見えてしまいます。
低音こそ聞こえづらいので、ON時間を増加させる必要がありますし、高音になればそれだけIGBT等に熱も発生し回路に負担がかかる上に、音圧も増加してしまって都合が悪いです。
それを考えるとON時間も周波数に応じて変化させることが望ましいと思えてきます。
アナログインタラプタではちょっと厳しいと思います。
マイコンって何?
以上のことを踏まえると、アナログ回路で演奏を行うのは、いまいち現実的に思えません。
このような場合はデジタル回路でインタラプタを製作すると良いでしょう。
ここで登場するのがマイコン(マイクロコントローラ)です。
いわば超小型のコンピューターで、MCUとも呼ばれます。
基板に乗るサイズの小さなコンピューターに、プログラミング言語で命令することで、そのとおりに動作します。
このマイコンを使って制御パルスを生成するところまで実装したいと思います。
プログラミング言語で命令するというのは具体的にどういう言語でしょう?
コンピューターが理解できないので日本語ではありません。英語でもありません。
マイコンのプログラミングはC言語が基本となっています。
ある程度わかっている前提で話をするので、わからないところは「C言語」などと検索ワードを入れて調べてみてください。
ここで注意する点が、マイコンのプログラミングは制約が多く、コンピューター上のアプリケーション製作の話題をそのまま適用できない場合があります。
例えば、参考書を買いたい!などというときは、「組み込み」や「Arduino」などのワードが入ったものを選ぶと良いでしょう。
アナログとデジタルのいいとこ取り?
中にはマイコンで生成したパルスをタイマーIC555で可変させるという手法を取る方もいます。
この方法だとマイコン側ではON時間が固定のため、負担が少なくなりますが、後段にアナログ回路が居るのでON時間を動的に変化させることはできません。
つまり、ある程度簡単に作ることは出来ますが、前述の音圧の話は改善することができません。
マイコンのプログラミング
マイコンのプログラミングは普通のコンピューターと違い超小型のため、性能もその分低いため、プログラミングのテクニックが必要になることがあります。
例えば、数字を保存するための変数という箱があります。
int i;
i = 5;
などとして変数を用意、数字を代入できますが、マイコンのプログラミングだと変数のサイズ、つまりは箱のサイズが問題になってきます。
部屋の荷物を掃除しようとして収納する箱を買うが、そもそも部屋がとても狭いというイメージです。
そのため、入れる物に合わせた箱を用意しないと、すぐに部屋が埋まって身動きが取れなくなってしまいます。
この例だと、int型のiという名前の箱を用意しています。(名前のiについては数学のxと同じで仮に置いているだけで名付けは自由にできます)
int型の箱だと、一般的に4バイトの大きさの箱で、-2147483648 ~ 2147483647の数字を入れられるようになっています。
ここに例えば、1~100程度の数字を保存しておくだけであれば、1バイトのuint8_tなどの型を使用すると、4バイトのint型より3バイト削減できるのです。
この変数の種類は「データ型」といって様々な種類が存在しています。
ちなみに、Arduino Uno R3で使われているマイコン、ATmega328PであればRAMは2000バイトしかありません。
少し大き目のプログラムを書くと、すぐに埋まってしまうのです。
先程のint型の変数を400個用意したとしましょう。
この時点で、1600バイト消費してしまうので、残りは400バイトしか使えません。
uint8_t型の変数を400個用意した場合はどうでしょう?
400バイトの消費なので、残りは1600バイト使用できます。
マイコンでは贅沢なリソースがありませんので、リソースを無駄に消費しないことがプログラミングする上でのコツです。
また、同時に実行できる命令は1つ、というのが大原則です。
マイコンで音を鳴らすには?
マイコン上で制御パルスを生成するにはいくつかの手法があります。
時間を測定して制御パルスを生成するのは誰もが思いつく手法だと思います。
しかし、それだと同時に一つのことしか出来ないコンピューターに対して重荷になります。
作業している人間だと例えると、作業に集中できず常に時計を見ているようなイメージです。
もちろんこの方法でも全然良いのですが、他のことは何も出来なくなってしまいます。
マイコンには周辺機能としていくつものペリフェラルを持っています。
直訳すると周辺機器のことですが、マイコンにおいては、マイコン内に搭載している機能のことを指します。
マイコンの種類がいくつもあるのは、このペリフェラルの機能が違う場合があり、用途に応じて選定するのが基本です。
一般的には、基本的な入出力のGPIOペリフェラル、定期的な実行などが可能になるタイマーペリフェラル、UART,SPI,I2Cなどの外部と通信するための通信ペリフェラル、ADCなど測定のためのペリフェラルなどが搭載されています。
どのマイコンにも搭載されているタイマーペリフェラルは、設定した時間になると割り込み処理を行ったり、GPIOから信号を出力したりするような処理が可能になります。
このタイマーを使用すると、正確な制御パルスを作ることができます。
先程の例えでは、人間が常に時計を見ているようなイメージと言いましたが、タイマーを設定してアラームが鳴ったときに割り込んで別の作業をすれば、普段の作業の邪魔にならず正確な時間に信号を作り出すことができます。
このようにマイコンではペリフェラルを活用することによって、制御パルスを作ることができるのです。
マイコンの種類によってペリフェラルの作りも違うため、目的を達成するにはどのようにペリフェラルを活用できるか、いわばパズルのようで面白いポイントだと思います。
MIDI制御で音楽を鳴らしたい!
シンセサイザーや電子ピアノなどの電子楽器同士を接続するために制定されたMIDIという規格があります。
1981年に公開された規格で、様々な電子楽器に搭載されています。
音自体ではなく、どこの鍵盤を押したかなど、つまり楽譜の情報をリアルタイムにやり取りできるものです。
規格書も公開されており、非常に扱いやすいです。
このMIDI信号を受けて解釈し、その通りに発音、制御パルスを生成すれば、演奏ができそうです。
インタラプタにMIDIコネクタを搭載しておけば、MIDIキーボードを接続してリアルタイムに演奏することも可能ですし、USB-MIDIインターフェースを接続すればコンピューターから任意のMIDIファイルを再生して演奏することも出来ます。
コンピューター上のDAWソフトウェアとしては、CubaseやDigital Performer、Logic Pro、Pro Tools、ABILITYあたりがMIDIを扱う上では良いと思われます。
MIDIを再生するだけなら、Domino、TMIDI Player、KbMedia Playerあたりが良いのではないでしょうか。(XG音源込みならMidRadio Player等)
注意点として、粗悪なMIDIインターフェースが存在しています。
ノーブランドの安いUSB-MIDIインターフェースは内部の変換ICにCH345Tを採用しているようです。
そもそもシステムエクスクルーシブメッセージがうまく通信できないらしく、安物買いの銭失いになる前に有名メーカーのMIDIインターフェースを入手したほうが良いと思われます。
私は、ROLANDとMOTUのMIDIインターフェースを使用しています。
数が多く出回ってるので、オークションサイト等で中古で安価に入手することも可能です。
テスラコイルで和音を鳴らすには?
テスラコイルで単音ではなく和音を鳴らしたい場合はどうしたら良いでしょうか?
それは単純にORを取って合成すると和音に聞こえます。
しかしその場合、ON時間が最大で2倍になってしまうという問題が発生します。
この際にIGBTが焼損してしまうなどの問題が起こります。
そのため、単純にORを取って合成するのではなく、何か策を考えないといけません。
インタラプタ上で和音数分タイマーを使った実装
この実装では和音数分タイマーを使用して、割り込みを発生させ、最後に出力用にタイマーを設けています。
使用しているマイコン「PIC32MX270F256B」では、16bitタイマーが5個存在し、そのうち2個は32bitまで拡張可能なようです。
「Four voice polyphonic」(4和音)と謳っているのはそういう実装になっているためです。
なぜ最後にタイマーを設けるかというと、和音用のタイマーのトリガーで最後の出力用タイマーが駆動されるため、ON時間が重なったとしてもその際に再トリガーされなければON時間自体は伸びないという実装のためです。
インタラプタ上でサンプリングタイマーを使った実装
こちらは一定期間でサンプリングを繰り返すようにタイマーを使用している実装です。
少し複雑になります。
また、処理が重くなると若干のズレが出てくる可能性があります。
本体(ドライバー)側での対策
過電流の際に設定以下までパルスをスキップするフリーホイール機能が実装されているドライバー Freewheeling / Slow Decay / Pulse Skipping Driver 等を使用していればこの限りではありません。
しかしながら、単純なロジックICで作られたテスラコイルが多いと思われますので、インタラプタ側で配慮しておいたほうが良い問題だと思われます。
もちろん、単純なロジックICのドライバでも入力段にパルス幅制限回路等が実装されていればその限りではありませんが…
デジタルはノイズに弱い?
テスラコイルのノイズでインタラプターの動作が不安定になることがあります。
アナログの場合でもノイズで不安定になりますが、デジタルの場合は特に、クロック周り等にノイズが入ると動作が不安定になります。
インタラプタ自体、金属ケースに入れシールドするのはもちろんのこと、よく使われるBNCケーブルでの接続ではなく光ファイバーの使用を視野にいれると良いと思います。
このような光ファイバーで絶縁するシステムを開発しています。
光デジタルオーディオ用のプラファイバー流用や、海外でよく使われるプラファイバーなどのものは、堅牢性に問題があると考えます。
USB通信周りも特にノイズに弱く、USB-MIDIインターフェースを使用する際にも、USB側の通信線をできるだけテスラコイルから離したほうが良いでしょう。
インタラプタを作るための各種マイコン比較
最近は処理能力の高いマイコンボードが安価に手に入るようになってきました。
IC単体ではなく、ボードとしてすぐに使えるものを以下にリストアップしました。(2024/02時点)
名称 | 搭載チップ | コア | 速度 | Flash | RAM | 16bitTMR | 32bitTMR | 実売価格 |
---|---|---|---|---|---|---|---|---|
Arduino Uno R3 | ATmega328P | 8bit AVR | 20MHz | 32KB | 2KB | 1 | 0 | 秋月3,630円 |
Arduino UNO R4 Minima | R7FA4M1AB3CFM | 32bit ARM Cortex-M4 | 48MHz | 256KB | 32KB | 6 | 2 | 秋月3,190円 |
Arduino Mega2560 Rev3 | ATmega2560 | 8bit AVR | 16MHz | 256KB | 8KB | 4 | 0 | 秋月6,920円 |
Arduino Due | SAM3X8E | 32bit ARM Cortex-M3 | 84MHz | 512KB | 100KB | 0 | 9 | 秋月6,920円 |
Arduino Portenta H7 | STM32H747XI | 32bit ARM Cortex-M7+M4 | 480MHz | 2MB | 1MB | 10+5 | 2 | 秋月15,980円 |
Arduino Leonardo | ATmega32U4 | 8bit AVR | 16MHz | 32KB | 2.5KB | 2 | 0 | 秋月3,560円 |
Arduino Micro | ATmega32U4 | 8bit AVR | 16MHz | 32KB | 2.5KB | 2 | 0 | 秋月3,560円 |
Arduino Nano Every | ATmega4809 | 8bit AVR | 20MHz | 48KB | 6KB | 5 | 0 | 秋月2,360円 |
Arduino MKR ZERO | ATSAMD21G18 | 32bit ARM Cortex-M0+ | 48MHz | 256KB | 32KB | 6 (24bit*2) | 0 | 秋月4,780円 |
Seeed XIAO SAMD21 | ATSAMD21G18 | 32bit ARM Cortex-M0+ | 48MHz | 256KB | 32KB | 6 (24bit*2) | 0 | 秋月850円 |
Wio Terminal | ATSAMD51P19A | 32bit ARM Cortex-M4 | 120MHz | 512KB | 192KB | 13 (24bit*2) | 0 | 秋月5,700円 |
Raspberry Pi Pico | RP2040 | 32bit ARM Cortex-M0+ Dual Core | 133MHz | 2MB | 264KB | 0 | 4 Alarms | 秋月770円 |
Seeed XIAO RP2040 | RP2040 | 32bit ARM Cortex-M0+ Dual Core | 133MHz | 2MB | 264KB | 0 | 4 Alarms | 秋月850円 |
Seeed XIAO ESP32C3 | ESP32-C3 | 32bit RISC-V | 160MHz | 384KB | 400KB | 0 | 54bit * 2 | 秋月940円 |
Seeed XIAO ESP32S3 | ESP32-S3 | 32-bit Xtensa LX7 Dual Core | 240MHz | 8MB | 8MB | 0 | 54bit * 4 | 秋月1,300円 |
ESP32-DevKitC-32E | ESP32 | 32-bit Xtensa LX6 Dual Core | 240MHz | 4MB | 520KB | 0 | 64bit * 4 | 秋月1,600円 |
ESP32-DevKitC-VE | ESP32 | 32-bit Xtensa LX6 Dual Core | 240MHz | 8MB | 520KB + 8MB | 0 | 64bit * 4 | 秋月1,750円 |
M5Stack BASIC V2.7 | ESP32 | 32-bit Xtensa LX6 Dual Core | 240MHz | 16MB | 520KB | 0 | 64bit * 4 | 秋月6,900円 |
M5Stack Core2 | ESP32 | 32-bit Xtensa LX6 Dual Core | 240MHz | 16MB | 520KB + 8MB | 0 | 64bit * 4 | 秋月8,680円 |
MaixDock(M1) | Kendryte K210 | 64bit RISC-V Dual Core | 500MHz | 16MB | 8MB | 0 | 3 | 秋月3,460円 |
STM32 Nucleo Board | STM32F103RB | 32bit ARM Cortex-M3 | 72MHz | 128KB | 20KB | 3 | 0 | 秋月2,200円 |
STM32 Nucleo Board | STM32F303K8 | 32bit ARM Cortex-M4 | 72MHz | 64KB | 12KB | 7 | 1 | 秋月2,200円 |
STM32 Nucleo Board | STM32F401RE | 32bit ARM Cortex-M4 | 84MHz | 512KB | 96KB | 6 | 2 | 秋月2,800円 |
STM32 Nucleo Board | STM32F411RE | 32bit ARM Cortex-M4 | 100MHz | 512KB | 128KB | 6 | 2 | 秋月2,800円 |
STM32 Nucleo Board | STM32L476RG | 32bit ARM Cortex-M4 | 80MHz | 1MB | 128KB | 9 | 2 | 秋月2,980円 |
STM32F4DISCOVERY | STM32F407VG | 32bit ARM Cortex-M4 | 168MHz | 1MB | 192KB | 12 | 2 | 秋月4,600円 |
Linuxが必要な規模が大きいボード類は除いてあります。(Raspberry Pi他、Pico除く)
また、8bitタイマーも表から除いてあります。
波形生成をする観点からするとTimerの数が多ければ多いほど良いです。
しかし、8bitのタイマーであると、8bitすなわち、256までしかカウントすることができません。
ON時間のカウントに関してはなんとかなるかもしれませんが、OFF時間(周期)のカウントは絶望的です。
そのため16bit(65536)以上のものを表に記載しています。
性能が高いものはアプリケーションプロセッサとしてよく使われるためか、RTOSの使用が前提でTimer数が少ないようです。
クリティカルな波形生成にはできるだけRTOSを挟みたく無いです。
各種マイコンでインタラプタを作ってみよう!
以下のページにて各マイコンごとに記述しています。
また、マイコン全般の使用方法等については以下ページにて解説しています。
FPGAを用いればタイマー数などの制約は考える必要がないですが、規模が大きくなるので気軽に使えるか?というと微妙なところです。