レビューメディア「ジグソー」


Galileo開発ボード

Galileo開発ボード

Galileo 雑談

Galileoに関してのノウハウや、ハマっている事、気になってる事、みんなで話しましょう。
  • 2014/02/18
  • しばさん
    >>はにゃさん
    ありがとうございます。
    パターンカットして使うかもです。
    ふたを開閉するためだけにDCモーターを駆動させる予定なので(^^;)

    海外フォーラムでこんなの見つけました。
    IDE上で/dev/tty* permission denied.などと出る方は参考にしてください。
    https://communities.intel.com/thread/45751

    2014/03/06

  • はにゃさん
    attachInterrupt(pin, handler, RISING)と
    attachInterrupt(pin, handler, FALLING)が動作していないようです。

    となると動くのは
    attachInterrupt(pin, handler, CHANGE)だけ?

    2014/03/08

  • つきさん
    23: はにゃ さん

    タイマ割り込みできました。
    1か所変更しました。
    Timer1.attachInterrupt( timerIsr ); // attach the service routine here
     ↓
    Timer1.attachInterrupt( timerIsr, 500000 ); // attach the service routine here

    C言語のライブラリを使うときは
    -----
    #include <interrupt.h>

    void setup() {
    setMinimumTimerFreq(100000);
    attachTimerInterrupt(timerIsr, 500000);
    pinMode(13, OUTPUT);
    }

    void loop() {
    }

    void timerIsr()
    {
    // Toggle LED
    digitalWrite( 13, digitalRead( 13 ) ^ 1 );
    }

    2014/03/08

  • はにゃさん
    つきさん

    2にタクトスイッチ
    12,13にLED(制限抵抗つき)
    という回路で
    13はタクトスイッチの押下時のみ点灯
    12はタイマーで 50%デューティー 1Hz点灯
    させてみました。

    さすがにちゃんと動きますね。
    次はこれをもう少し工夫して タクトスイッチ押下時間を計測しますかね。

    #include <TimerOne.h>

    volatile int led1;
    volatile int led2;

    void setup() {
    // put your setup code here, to run once:
    pinMode(2, INPUT_FAST);
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    led1 = LOW;
    led2 = LOW;
    attachInterrupt(2, proc1, CHANGE);
    Timer1.initialize(100000);
    Timer1.attachInterrupt(timerProc, 500000);
    }

    void proc1() {
    int p2;
    p2 = digitalRead(2);
    if (p2) {
    led1 = HIGH;
    } else {
    led1 = LOW;
    }
    }

    void timerProc() {
    led2 = !led2;
    }

    void loop() {
    // put your main code here, to run repeatedly:
    digitalWrite(13, led1);
    digitalWrite(12, led2);
    }

    2014/03/08

  • はにゃさん
    タクトスイッチの押下時間を簡単に計測したバージョンです。
    100ms弱までは計測できました。

    このあと矩形波を入力してみてどうなるか見てみたい気がします。
    GalileoのattachInterruptは疑似割り込みだと思うので、Fast GPIOが動作したとしても、
    1KHzは超えられないような気がします。

    #include <TimerOne.h>

    volatile int led1;
    volatile int led2;
    volatile int last_mills;
    volatile int duration;
    volatile int flg_display;

    void setup() {
    // put your setup code here, to run once:
    pinMode(2, INPUT_FAST);
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    led1 = LOW;
    led2 = LOW;
    last_mills = 0;
    duration = 0;
    flg_display = false;
    attachInterrupt(2, proc1, CHANGE);
    Timer1.initialize(100000);
    Timer1.attachInterrupt(timerProc, 500000);
    }

    void proc1() {
    int p2;
    p2 = digitalRead(2);
    if (p2) {
    led1 = HIGH;
    last_mills = millis();
    } else {
    led1 = LOW;
    duration = millis() - last_mills;
    flg_display = true;
    }
    }

    void timerProc() {
    led2 = !led2;
    }

    void loop() {
    // put your main code here, to run repeatedly:
    digitalWrite(13, led1);
    digitalWrite(12, led2);
    if (flg_display) {
    Serial.print(duration);
    Serial.print("\n");
    flg_display = false;
    }
    }

    2014/03/09

  • ちばとどさん
    TimerOne.h のタイマ割り込みの実測をしました。

    Timer1.initialize(1000); // 最小間隔 1msec=1kHz
    (1000より小さいパラメータでは、コンパイルできるが、プログラムが開始されない)
    としても、
    ハンドラ側でGPIOを使ってLEDを1個点滅させているときは230Hz、(GPIOの仕組み上の限界?)
    ハンドラで何もしないで帰るようにしても、480Hzくらいでした。

    これより速くできる工夫の余地はありますか?

    2014/03/20

  • はにゃさん
    hardware/arduino/x86/libraries/TimerOne/TimerOne.cppを読んで、
    TimerOneの実装を確認したところ、

    TimerOne::initilize は、setMinimumTimerFreqの、
    TimerOne::attachInterrupt は、attachTimerInterruptのラッパーでした。

    次にhardware/arduino/x86/cores/arduino/interrupt.c を読んで、
    Galileoのタイマ割り込み実装を確認しました。

    Galileoのタイマ割り込みは高精度イベントタイマー(HPET)を使用してます。
    HPETはx86で以前のIntel 8253(PIT)やリアルタイムクロック割り込みに代わり導入されたもので、Vista以降、現代のLinux/FreeBSD などでは普通に使用されています。

    Galileoは Linux のHPETサポート,libGPIO,pthreadを使って、Arduino風味の ピン割り込み、タイマ割り込みを実現していますね。

    main() から interrupt_init() を呼び出し、pthread_create で
    タイマ割り込みハンドラ interrupt_main のスレッドを作成します。

    interrupt_main は、割り込みか、シャットダウンコマンドが来るまでループしますが、
    ループ内で、
    1)GPIOによる割り込みをチェックするために FD_SET
    2)HPETによる割り込みをチェックするために FD_SET
    3)非同期I/O(select) で無限に待つ
    4)selectの返り値>0なら どの要因だったか確認
    ピンベースの割り込みなら
    コールバック関数をキック
    LinuxGPIOライブラリのreopenする(GPIO Lib.がそういう仕様らしい)
    タイマベースなら
     カウンタ値を増やす
    カウンタ値が周期に応じたカウンタ閾値を超えれば カウンタをリセットして、コールバック関数をキック

    という実装になってます。

    HPETの周期は、setMinimumTimerFreq関数で
    μsで指定したパラメータを、1000000で除して周期(Hz)に変換して与えていますが、
    ここで
    MAX_VARIANT_HPET_FREQ_HZ より高い周波数なら -EINVAL を返して異常終了となります。
    MAX_VARIANT_HPET_FREQ_HZは variant.h で 1000と定義されていますから、
    1KHz未満に設定する必要があります。

    ちばとどさんが、1000μS未満を与えて実行できなかったのは、このせいですね。

    Arduinoが使うタイマ割り込みの周期は attachTimerInterrupt関数で指定しますが、
    周期(μs)は周波数に変換したのちに、setMinimumTimerFreqが設定した HPETタイマの値で除して、カウンタ閾値となります。

    ところで、
    #include <TimerOne.h>

    volatile int t;

    void setup() {
    // put your setup code here, to run once:
    Timer1.initialize(1000);
    t = 0;
    Timer1.attachInterrupt(timer1_proc, 1000000);
    Timer1.attachInterrupt(timer2_proc, 1000);
    }

    void timer1_proc() {
    char buf[100];
    sprintf(buf, "Times %d \n", t);
    Serial.print(buf);
    t=0;
    }

    void timer2_proc() {
    t++;
    }

    void loop() {
    // put your main code here, to run repeatedly:
    // Serial.print("X");
    // Serial.print("\n");
    // sleep(1);
    //t=0;
    }
    というサンプルを作って実行してみたところ
    1s周期で500 or 501回でした。

    2014/03/21

  • kilifさん
    割り込みだと数msはかなり厳しそうですね。そもそもLinux上のC、C++プログラムで1ms刻みの処理をタイマーでやることが可能なんでしょうか。

    私は高周波の処理をPCにやらせる時には、
    スリープ時間でチューニングするか、時刻を逐次取得するしかないと認識しているので、
    ArduinoIDE上ではloop()の中で何とかするしか無いと感じます。

    Windowsでの少ない経験しかないので的外れかもしれませんが、いかがでしょう。

    2014/03/22

  • 蒼-aoi-さん
    私事の些細な報告ですが、私のレビューでアップしていたマトリクスLEDのダイナミック点灯ですが、なめらか化できたので一応。

    レビューに書いた通り、シフトレジスタタイプのエキスパンダでLEDのA/Kを挟んだ形にしています。
    信号はDAT/CLK/STB(LAT)/CLR(OE)の4本ですが、CLR(OE)は使用していないので、実質3本です。
    DAT/CLKはOUTPUT_FASTで高速化しましたが、STBは普通のGPIOだったため、それに引っ張られてチラつきが大分ありました。


    結論としてはSTBの出力を高速化した結果、滑らかに。
    STB周期を計測すると4.3kHz、24ラインなので約180fps相当ということでしょうか。

    あくまでSketchで対応できる範囲で試しています。

    2014/04/05

  • 蒼-aoi-さん
    日記にソースを載せみました。
    ユーザー登録してない人は見られないわけですが、画像だとコピペできないので、自分のバックアップ用に掲載しました。



    <pre>ないの改行が上手くいかないのと、<table>が認識しないのは痛いですが、それほど手間でもなく載せられました。
    今後もレビュー更新都度、アップしたいと思います。
    リンク貼り忘れたので、あとでものリンク張っておきます。

    ちなみに上の動画のソースはアップしてません。

    2014/04/12


ZIGSOW にログイン

ZIGSOW会員登録(無料)はこちらから