基板が完成したので、今回も最初は直流モータで実験。

プリンタ用のモータでは問題がなかったので、540モータでも実験を継続。しばらくは問題なく動いていました。ところが…調子にのって回していてうっかり出力をショートさせてしまい、動かなくなってしまったのです… 

その状態でしばらく通電しているとゲートドライバが異常発熱していることが判明。なのでとりあえず、ショートしたFETにつながる2つのゲートドライバを交換して、出力が出ていることを確認してから再度、モータを回します。

瞬間だけ動くような気がしたものの、動かない… もしかして、のこりの2つのゲトドラが悪さしている?とか考えて全部交換してもやっぱりだめ。ああやこうやしているうちにゲトドラの死骸が増えていきます…
P_20171103_165620_vHDR_Auto

しばらくして、ようやく原因っぽいものが判明。それは「モータからのサージ」なのです。実はこの時、電源の個数を減らすためにモータ駆動用とゲート駆動用の電源を一緒にしていたので、モータからのサージがゲートドライバに流れてしまうというものでした…

とりあえず、電源を分離して実験開始。あっさり問題なく動作しました。

 

ということで、今度はステッピングモータを回すプログラムを作成。

とりあえずは、通信なしてArduinoを使ってプログラミングをします。

1

汚いけど、一応ソースコードです。上の方で、モータの励磁ピンの配列を作成しておき、励磁のプログラムを書きやすくしています。そして、残りは音階の定義ですね。

2

続いて、初期設定と音階の設定のプログラムです。Arduinoじゃない何かが大量に混入しているとか気にしない… AVRのレジスタを叩けば軽量化した上に、処理が簡単なので…

3

次がステッピングを演奏するコアの部分です。周波数を入力すると、その周波数の音を奏でているのです。マイコンのタイマー割り込みの機能を使うことで、こんなにも簡単に書けます。ちなみに、このプログラムはレジスタを叩かなければ書けません!

 

そして、音楽を入れて演奏…


だいたい、音楽にはなっているものの、時々変な挙動をしています…

しばらくは、ステッピングモータが起動するのに若干脱調しているのだと思い込んでいました…(実は後から別の原因だと気が付きます…

 

続いて、和音を鳴らすことができるように、ID指令式のシリアル通信を実装。

最初はArduinoで書いていたのですが、ちょっとめんどくさくなったので、Arduinoのシステムを捨てて、Atmel Studioでプログラムを書くことに変更しました。

AVRのマイコンを触る時はデータシートがないとわけがわからなくなるとおもうので、こちらを参考に(https://avr.jp/user/DS/PDF/mega328P.pdf

いろいろとマイコンの内部的なお話がいろいろと書かれています。細かいところを読んでいると結構面白いですが、難しいし量が多すぎるので、必要なところだけを読んでいます。

 

とりあえず、このデーターシートを読みながらプログラムを作成

 4

最初は定義とか読み込みです。Arduinoと違っていくつかincludeしなければならないものがあります。<util/interrupt.h>は割り込みを使用するヘッダーファイル、<util/delay.h>delayを使うヘッダーファイルです。Delayを使うにはCPUのクロック数を与えないといけないので、ここで宣言をしています。(delay.hを読み込む前にF_CPUで定義)

5

ここでは、ピンの入出力の設定やタイマー割り込みの初期設定、シリアル通信の初期設定をしています。割り込みは種類がいくつかあるうちから、音楽を鳴らすのに最も適していそうな位相/周波数基準でOCR1ATOP値とした割り込みにしています。シリアル通信についてはArduinoと通信する関係で、通信速度以外この設定以外にはできません…

 
6

次は、入力された周波数から、その周波数分のパルスを生成する割り込みの設定を行う関数です。OCR1AでタイマーのTOP値を変更することで、割り込みの周波数を自由に変更できるという、マイコンの機能を使用しています。また、OCR1Bの割り込みを併用してduty比を落とせるようにしています。
実は先ほどのArduinoの時はタイマーのTOP値をICR1にしていたのですが、データシートを読んでいると、周波数変更をする場合はOCR1AをTOP値にするべき、と書かれていたのです…さっきの音がおかしくなっていた原因はこれだったというわけです。

7
そして、これがステッピングモータのパルスを生成するプログラムの実行部分です。割り込み処理を使うことで、ここまで簡単にパルス生成とduty比を下げるプログラムが書けてしまいます。

 
8

そして、これが今回のメインである通信の処理部分です。シリアル通信のデータを受信すると、この割り込み処理が開始され、最初に受信データを読み込みます。その後、データの最上位bitを解析し、最上位bit1であればID信号を意味するので、ID受信のモードに入ります。受信したIDが自分のIDと同じであれば、続行のデータを受信できるようにします。そして、受信データのバッファーのクリアを行います。(配列を最初に戻す)

自分のID宛ての情報だった場合で最上位bit0であった場合は、バッファーにデータを蓄えていき、既定のデータ数に達すると、バッファーのデータから周波数を抜き取ります。最終的に、パルス生成の割り込みの設定の関数へ周波数を引き渡すことで、モータを演奏します。

 

汚いソースコードですが、このような感じで複数のモータを1つのシリアルで管理できるようにやってみました。マイコンの機能を有効に使えば、案外簡単にかけてしまうのです。

 

続きは次回