A Day in the Life

HX711 の準備完了時間、mbed OS5 での thread

HX711 では、データ出力準備が整ったら、DOUTが HIGH -> LOW になる。この出力時間の待ち受け時間を計ったところ、約77msかかる。メインループで待ち受けすると77msは割と支配的でUIのレスポンスに悪化に繋がる。

AVR の Arduino なら Timer のハードウェア割り込みを使って、メインループとは別のところで処理しつつ、適当な volatile 変数に値を入れるような実装を書くと思う。

mbed OS 5 の場合

mbed は指定時間ごとに関数を呼び出せる Ticker クラスが用意されているが、割り込みハンドラは全部合わせて1つなので、Ticker に重い処理を登録すると遅延が発生する。

mbed OS5 では rtos になったので、この辺の優先度付けが出来るのかと思ったら現状特に出来ないので、Thread を使ってメインループ以外で実行し続けることで解決してみた。

例えばこんな感じ。

#include <mbed.h>
#include "HX711.hpp"

class ScaleGauge {
    HX711 *_p_scale;
    Thread _thread;
    volatile float _gram;

    void threadLoop() {
        while(1) {
            _gram = _p_scale->readGram(1);
        }
    }
public:
    ScaleGauge(HX711 *hx711) :
        _p_scale(hx711), _thread(osPriorityLow) {
    }

    void start() {
        _thread.start(callback(this, &ScaleGauge::threadLoop));
    }

    float getGram() {
        return _gram;
    }
};

あとは main で

int main() {
    ScaleGauge sg(&hx711);
    sg.start();

    while(1) { wait_ms(100) };
}

とすれば、ずっと裏側で値をとり続ける。

最初

int main() {
    ScaleGauge sg(&hx711);
    sg.start();

    while(1);
}

としててうまく動かない (threadLoop がよばれない) けど、理由は Thread の優先度をosPriorityLow にしていたからで、その場合 while(1) が延々と呼び出されてしまう。osPriorityNormal の標準プライオリティにするか、わざと割り込みできるように wait_ms() 等を入れるか、yield で処理を戻すか等々をする必要がある。

あわせてよみたい:

追記:

Thread::wait(osWaitForever);

で待ち受ければ良いぽい。

記事の一覧 >

関連するかもエントリー

HX711で重さを量る
ハカリなど重さを量るには、一般的にロードセルとひずみゲージセンサーを使って実現している。HX711 は安価なひずみゲージを読み取るためのICで、24bit ADCを搭載していて、ICにクロックを送ることでデータを受け取る。ebay では実装済の物が一つ100円以下で買える。ロード...
ハカリなど重さを量るには、一般的にロードセルとひずみゲージセンサーを使って実現している。HX711 は安価なひずみゲージを読み取るためのIC...
mbed で Callback 関数を扱う
mbed のコアAPI、 Ticker などでも使われている、FunctionPointer を使う。https://developer.mbed.org/users/mbed_official/code/mbed-src/file/a11c0372f0ba/api/Functi...
mbed のコアAPI、 Ticker などでも使われている、FunctionPointer を使う。https://developer.m...
mbed OS5 の Callback
mbed OS2 までは、引数に関数を受け取る場合、FunctionPointerArg1 を使って抽象化していた。mbed OS 5 では Callback を使う。https://developer.mbed.org/users/mbed_official/code/mbed...
mbed OS2 までは、引数に関数を受け取る場合、FunctionPointerArg1 を使って抽象化していた。mbed OS 5 では...