GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
GR-KURUMI の attachMicroIntervalTimerHandler() やそれを内部で呼んでる MsTimer2 ライブラリに不具合がありました。
下記のスケッチは attachMicroIntervalTimerHandler() を使用して 1000μ秒(=1m秒)毎のタイマー割り込みを行い、1000000μ秒(=1秒)間に実際何回割り込みが発生するかを計測するものですが
/*GR-KURUMI Sketch Template Version: V1.13*/ #include <Arduino.h> #include <MsTimer2.h> volatile unsigned long timerCount = 0; void timer() { timerCount++; } void setup() { Serial.begin(9600); Serial.println("\x1b[2J\x1b[;Hstart"); #if 1 attachMicroIntervalTimerHandler(timer, 1000); #elif 1 MsTimer2::set(1, timer); MsTimer2::start(); #elif 1 MsTimer2::setMicros(1000, timer); MsTimer2::start(); #endif } void loop() { static unsigned long lastMicros = micros(); unsigned long currentMicros; do { currentMicros = micros(); } while (currentMicros - lastMicros < 1000000UL); lastMicros = currentMicros; unsigned long securedTimerCount; do { securedTimerCount = timerCount; } while (securedTimerCount != timerCount); Serial.println(securedTimerCount); }
これを実行した結果が
となりました。
1m秒間隔の割り込み処理なので 1秒間では 1000回の割り込みが発生する筈ですが、実際は 999回の割り込みが発生しています。
setup() 中の条件コンパイルの箇所を弄り MsTimer2 を使用するよう変更しても同様の結果となります。
これは、原因として
RLduino78_basic.cpp:
void attachMicroIntervalTimerHandler(void (*fFunction)(void), uint16_t interval) { FUNC_MUTEX_LOCK; _startTimerChannel( HOOK_TIMER_CHANNEL, INTERVAL_MICRO_MODE, interval, false, true ); INT_TM_HOOK = fFunction; FUNC_MUTEX_UNLOCK; }
_startTimerChannel() を呼ぶ際に interval の値を -1 してないことが原因で、1000 を引数として呼び出すと 1001μ秒毎に割り込みが発生してしまい、結果として1秒間に 999回の割り込み処理となっていました。これを修正したものが0677.attachMicroIntervalTimerHandler.20170305.zipとなります。添付の .zip ファイルの内容を GR-KURUMI のライブラリソースに上書きすると先のプログラムの動作が正常化します。
GR-SAKURA の MsTimer2 にμ秒より短いクロック単位でのタイマー割り込みを設定する機能を追加したので、今回の GR-KURUMI のライブラリにも同様の機能を追加しています。
void attachClockIntervalTimerHandler(void (*fFunction)(void), uint16_t interval) 32MHz のクロック単位でタイマー割り込みタイマーを設定する
void MsTimer2::setClock(unsigned short fclk, void (*f)()) 32MHz のクロック単位でタイマー割り込みタイマーを設定する
これらを使用すると、従来の 1μ秒単位でのタイマー割り込みよりも細かい単位でのタイマー割り込みが指定できます。
/*GR-KURUMI Sketch Template Version: V1.13*/ #include <Arduino.h> #include <MsTimer2.h> volatile unsigned long timerCount = 0; void timer() { timerCount++; } void setup() { Serial.begin(9600); Serial.println("\x1b[2J\x1b[;Hstart"); // 16kHz(62.5μ秒単位) での割り込みを設定 MsTimer2::setClock(configCPU_CLOCK_HZ / 16000, timer); MsTimer2::start(); } void loop() { static unsigned long lastMicros = micros(); unsigned long currentMicros; do { currentMicros = micros(); } while (currentMicros - lastMicros < 1000000UL); lastMicros = currentMicros; unsigned long securedTimerCount; do { securedTimerCount = timerCount; } while (securedTimerCount != timerCount); Serial.println(securedTimerCount); }
実行結果