背景
loopでdelayMicroseconds関数を利用してパルスを作っていたところ、同時に別のタスクもさせたくなったので、loopの外部でパルスを作る方法を探してみました。いくつか実現方法が分かったので、備忘録を兼ねて方法を共有します。
使ったもの
- ArduinoIDEかPlatformIOをインストールしたPC
- ProMicro
Arduino Leonardoの互換機です。
Arduinoで作るもの
GPIO5から200usの間隔(400us周期、2500Hz)でHighとLowを繰り返す信号を作ります。波形の確認にはAnalogDiscovery2を利用しました。
方法1: loopでdelayMicrosecondsを利用
loopの処理を専有してしまいますが、delayMicrosecondsを利用することで200us周期のパルスを作れます。#include <Arduino.h> #define OUTPUT_PIN 5 void setup() { pinMode(OUTPUT_PIN, OUTPUT); } unsigned long waitMicroSec = 200; void loop() { digitalWrite(OUTPUT_PIN, HIGH); delayMicroseconds(waitMicroSec); digitalWrite(OUTPUT_PIN, LOW); delayMicroseconds(waitMicroSec); }
AnalogDiscoveryで確認すると、約210usの間隔で信号が変わることを確認できました。
digitalWriteやloopの繰り返し処理により、delayMicrosecondsの他に約10usの遅延が発生してしまうようです。
方法2: Toneを利用
Toneとは周波数を指定して音を出すための関数です。これに周波数を渡すことで、欲しい周期のパルスを作れます。
今回は200us周期が欲しいので、(1/0.0002)/2 = 2500HzをToneで作ります。
#include <Arduino.h> #define OUTPUT_PIN 5 void setup() { tone(OUTPUT_PIN, 2500); // (1(1sec) / 0.0002(200us)) / 2 = 2500Hz } void loop() { delay(1000); }
AnalogDiscoveryで確認すると、約205usの間隔で信号が変わることを確認できました。
Toneは間隔が長くなる形で誤差が発生するようです。
方法3: FlexiTimer2を利用
FlexiTimer2とはTimerの割り込みを設定できるライブラリです。外部のライブラリなので、開発環境へのインストールが必要です。
Arduinoの場合の設定方法
zipファイルをダウンロード・展開してArduinoのライブラリディレクトリに配置してください。(勝手が分からない場合は「Arduino ライブラリ zip 配置」とかで検索すると、やり方が出てくると思います。)
zipファイルはgithubのリリースページのzipをクリックするとダウンロードできます。
PlatformIOの場合の設定方法
platformio.iniに「lib_deps = FlexiTimer2」を記述してください。
platformio.ini
lib_deps = FlexiTimer2
プログラムと実行結果
200us毎の割り込みで信号線のHighとLowを繰り返すことで、200us周期のパルスを作れます。#include <Arduino.h> #include <FlexiTimer2.h> #define OUTPUT_PIN 5 void flash() { static boolean pinState = true; pinState = !pinState; digitalWrite(OUTPUT_PIN, pinState); } void setup() { pinMode(OUTPUT_PIN, OUTPUT); FlexiTimer2::set(2, 1.0/10000, flash); FlexiTimer2::start(); } void loop() { delay(1000); }
AnalogDiscoveryで確認すると、約190us周期で信号が出ていることを確認できました。
タイマー割り込みなので数usの誤差で信号を出せても良い気がしますが、約-10usの誤差がありました。
「FlexiTimer2::set(2, 1.0/10000, flash)」の割り算の誤差によるものと自分は推測します。
まとめ
実装方法によって約5%があるようですが、いくつかの方法で200us間隔でHighとLowを切り替える信号を作れました。ToneやTimer割り込みを使えばloopの処理を専有すること無く欲しい長さのパルスを作れるので、パルス波を作りつつ他の処理を行うプログラムが書けます。
このような書き方をするために調べていたので、狙い通りの方法が見つかって嬉しいです。
後日、パルスを読み取る方法も調べて実装してみました。
良かったらこちらも見てみてください。
Arduinoでパルスを読み取る方法
参考
タイマー割り込みでLEDを点滅させます変更履歴
2019.08.03「Arduinoでパルスを読み取る方法」をまとめで紹介しました。
2019.11.29
platformioの設定ファイルを「platformio.ino」と間違えていたので、「platformio.ini」 に修正しました。
0 件のコメント :
コメントを投稿