A Day in the Life

HX711で重さを量る

ハカリなど重さを量るには、一般的にロードセルとひずみゲージセンサーを使って実現している。HX711 は安価なひずみゲージを読み取るためのICで、24bit ADCを搭載していて、ICにクロックを送ることでデータを受け取る。ebay では実装済の物が一つ100円以下で買える。

ロードセルは単体で買っても、ロードセルを設置ことが大変。その辺のハカリをバラすと入っているし、そのまま設置できるので大変楽。ロードセルにはVDD/GNDと、ひずみゲージの+-の線があるので、それをHX711のE+(VDD),E-(GND)、A+, A- (チャンネルAを使う場合)に接続すればOK。

HX711 用ライブラリ

Arduino 用はあるけど、mbed 用でちゃんと動く物がなかったので書いた。

HX711 hx711(dataPin, clockPin);
hx711.setScale(100000f); # ひづみゲージにや電源よって最適な値は異なる
hx711.tare();
float gram = hx711.getGram();

で動く。HX711 の仕様書を読んだメモ

https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf

  • DOUT が LOW になったら準備完了
  • 同期に用いる PD_SCK にあわせて 24bit 分のデータをDOUTから MSB で出力する
  • その後のPD_SCKでのHIGH/LOWの回数にあわせて、次回のゲインが決まる
    • 標準は 128 (1回のHIGH/LOW)
    • CH A を使う場合は 128 もしくは 64
    • CH B を使う場合は 32 をセットする。
# HX711.hpp

#ifndef HX711_h
#define HX711_h

#include <mbed.h>

const float defautScale = 490000.0f;
const float lbToGram = 453.5f;

class HX711
{
  private:
    DigitalIn dataPin;
    DigitalOut clockPin;
    uint8_t gainPulse;
    uint32_t offset;
    float scale;
  public:
    HX711(PinName dataPinName, PinName clockPinName) :
      dataPin(dataPinName), clockPin(clockPinName, 0)
    {
      offset = 0;
      gainPulse = 1;
      scale = defautScale;
    }

    void tare() {
      offset = avg(10);
    }

    const float getOffset() {
      return offset;
    }

    float readGram(uint8_t times = 10) {
      float res = (float)avg(times) - offset;
      return res / scale * lbToGram;
    }

    uint32_t avg(uint8_t times = 10) {
      uint32_t res = 0;
      for(uint8_t i = 0; i < times; i++) {
        res += read();
      }
      return res / times;
    }

    bool isReady() {
      return dataPin == 0;
    }

    void setGainPulse(uint8_t _gainPulse) {
      gainPulse = _gainPulse;
      read();
    }

    void setScale(const float _scale) {
      scale = _scale;
    }

    const float getScale() {
      return scale;
    }

    uint32_t read() {
      uint32_t res = 0;
      uint8_t i = 0;

      while (!isReady());

      for(i = 0; i < 24; i++) {
        clockPin = 1;
        res = res << 1;
        clockPin = 0;
        if (dataPin == 1) {
          res++;
        }
      }

      for (int i = 0; i < gainPulse; i++) {
        clockPin = 1;
        clockPin = 0;
      }

      res ^= 0x00800000;
      return res;
    }
};

#endif
記事の一覧 >

関連するかもエントリー

HX711 の準備完了時間、mbed OS5 での thread
HX711 では、データ出力準備が整ったら、DOUTが HIGH -> LOW になる。この出力時間の待ち受け時間を計ったところ、約77msかかる。メインループで待ち受けすると77msは割と支配的でUIのレスポンスに悪化に繋がる。AVR の Arduino なら Timer のハ...
HX711 では、データ出力準備が整ったら、DOUTが HIGH -> LOW になる。この出力時間の待ち受け時間を計ったところ、約77ms...
mbed SDK での C++ コーディングルール
https://github.com/ARMmbed/mbed-os/blob/master/docs/COMMITTERS.mdにコーディングルールが書かれていた。今まで C++ でちゃんとしたコーディングルール上で開発をしたことがなかったので読んでみた。ルールThe mbed...
https://github.com/ARMmbed/mbed-os/blob/master/docs/COMMITTERS.mdにコーディ...
Keras を使わずに TensorFlow 2 を使い素朴な全層結合ニューラルネットワークを作る
TensorFlow では、高レベルAPIであるKerasを使うことで、簡単にニューラルネットワークのモデル作成~訓練、その他NNで行いたい様々なことを実現できる。しかしながら、自分のようなNN初心者にとっては何をやってるか解らないで使ってしまっていたため、簡単な順伝播型のNNを...
TensorFlow では、高レベルAPIであるKerasを使うことで、簡単にニューラルネットワークのモデル作成~訓練、その他NNで行いたい...