万事、塞翁が馬

人生の幸・不幸は予測しがたい。京都の酒造ベンチャー"FLFS"の「名目上の社長」こと姉崎亮太の平凡な日常の記録。

arruino mega のタイマー割込みについて調べる。

開発日記

ボトリング(瓶詰め)を自動化するにあたって「arduino mega を使って複数のモータを同時に稼働させてON/OFFや速度をバラバラに制御したい」のだが、こういう複数を同時に動かす作例が入門書には載っていない。調べてみると"タイマー割込み"という機能を使うとできるらしい。色々試してみているのだが腹にストンと落ちない感じでてこずっている。 部分的に動くからと言って全体で動いてくれるかというとそれは別の問題だったり。
ボトリングマシンにはDCモータ5つとステッピングモータ1つの合計6つPWMを使用する予定で、megaにはpwmのピンが15あるので余裕だと思ってたんだがそうでもないようだ。同じタイマーの複数のピンのPWMを動かせるのか?モータ数減らすべきか?
あるいはarduino uno や arduino pro miniを複数個つないでマスターとスレーブにする設計に変えるべきか。ちょっと悩んでいる。いや、ホント言うとESP8266を使ったarduino unoのコピー品のWemosD1をマスターにしてその上にslaveのunoを積んでいく構成にしたらwifi使えてスマホから操作できて便利だよな、とは思ってる。

備忘録

arruinoの頭脳であるavrマイコンにはタイマーがあり、それを使った「タイマー割込み」という機能が実装されている。それを使うと指定の時間が来たら動いて何秒かたったら止まるというプログラムが組める(らしい)。

arduinoでそれを使うにはタイマーライブラリをインクルードすればいいわけだが、このタイマーはPWMの制御にも使っているので「タイマーを使うかPWMを使うかを場合によっては選ばないといけない」との事である。

PWMのピンにはそれぞれ対応するタイマーがあり、そのタイマーを使うプログラムを動かしているときはPWMが使えない普通のピンになる。 Timer2を使うライブラリが人気があるようだ。 ただこれを使うとtone()が使えなくなる。"終了時にブザー鳴らす"というのがしたかったんだがな。いやー、なかなか難しい。

検索したところ2010年から13年くらいのブログが多くヒットした。2015以後はほぼない。すでに克服された過去の話題なのかな?ありがたいことだ。枯れた技術は初心者に優しい。 arduino unoについてはいっぱいヒットするがmegaはあまりヒットしない。ベースになってるunoの出来がいいので機能拡張版の需要が少ないのかも。

arduinoなら知識無くても適当につないだら動く」「arduino megaならピン多いし特に考えなくて大丈夫だろう」と思っていたがそういうわけではなく、ピンアサインは内部構造の制約を元に考えないといけないみたい。 そらそうか。マシンのスペックをフルに使いたいと思うなら理解が必要だわね。

リンク

主要なAVRマイコンでは、Timer0、Timer1、Timer2の3つのタイマーがある。これらのハードウェアのタイマーを利用し、一定時間ごとにある関数を「割り込み(interrupt)」で呼び出すことをArduinoのタイマー系ライブラリは実現している。 https://miso-engine.hatenablog.com/entry/2015/07/20/221014

MsTimer2を使うとtone( )関数が利用できません、また13番ピンと11番ピンからのPWM出力(analogWrite( )関数)もできません。 http://www.geocities.jp/zattouka/GarageHouse/micon/Arduino/TIMERtoLED/TIMERtoLED.htm

このMsTimer2というライブラリがarduino mega 2560に対応していないが、ライブラリを書き換えると使えるとの事。 [arduino]Arduino Mega ADK or Arduino Megaでタイマ割り込みを使う http://mironal-memo.blogspot.com/2012/02/arduinoarduino-mega-adk-or-arduino-mega.html

Timer1、3を使ったライブラリもある。 http://megalodon.jp/2015-0721-0425-17/miso-engine.hatenablog.com/entry/2015/07/20/221014

arduino mega はタイマーが0-5の6つあるそうだ。それぞれのピン配置と関数についても書いてくれていて非常に助かる。 https://tomixrm.wordpress.com/2017/08/24/arduino-mega%E3%81%AE%E3%82%BF%E3%82%A4%E3%83%9E%E3%83%BC%E6%83%85%E5%A0%B1/

timer0はシステムが使用していて、これをいじってしまうとdelay()関数の待つ時間がずれます。 またtimer0,2は8bit timerで残りの1,3,4,5は16bit timerです。8bit timerでは精度が低くて、しっかりしたモーター用のPWMを出すには適しません。 timer5は後述するservoライブラリを使うと使用されてしまうために使えなくなります。 よってまともに使えるPWMはtimer1,3,4の8本のPWMになります。これらは自由にDuty比を変更することがありますが、周期を変更する場合は注意が必要です。 https://qiita.com/eri_aka/items/68981b6e695e6f4468ff

タイマー0はシステムで使っているのでPWMの「デューティー比がちょいと高めに出る」とのこと。 http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2153

メイン側と割り込み関数側で共用する変数は、「volatile」属性というものを付けて宣言する必要が あります。 http://nekosan0.bake-neko.net/library_timer.html

Timer機能全般に関する解説。 https://qiita.com/suzukinori/items/939cc9f49e535c4eadd7