SHT30を使ってみた


スイスのセンサーメーカーのSensirionのSHT30なモジュルが手に入ったのでmruby on YABM(BCM/mips)で使ってみました。

このチップは単発測定と周期的連続測定ができます。以下は単発測定で気温と湿度を取得しています。

SHTADDR = 0x44

class SHT3x
  def init yabm
    @y = yabm
  end
  def chkcrc dat
    crc8 = 0xff
    for i in 0..1 do
      crc8 = crc8 ^ dat[i]
      8.times {
        if crc8 & 0x80 == 0x80 then
          crc8 = crc8 << 1
          crc8 = crc8 ^ 0x31
        else
          crc8 = crc8 << 1
        end
      }
    end
    if (crc8 & 0xff) == dat[2] then
      return true
    else
      return false
    end
  end
  def getStatus
    @y.i2cwrite(SHTADDR, 0xf3, 0x2d)
    delay(@y, 100)
    arr = @y.i2creads(SHTADDR, 3)
    return (arr[0] << 8) | arr[1]
  end
  def getCelsiusAndHumidity
    while @y.i2cchk(SHTADDR) == 0 do
      delay(@y, 1)
    end
    @y.i2cwrite(SHTADDR, 0x24, 0x00)
    delay(@y, 500)
    while 1 do
      arr = @y.i2creads(SHTADDR, 6)
      if arr then
        break
      end
      delay(@y, 1)
    end
    t = -4500 + 17500 * ((arr[0] << 8) | arr[1]) / 65535
    h = 10000 * ((arr[3] << 8) | arr[4]) / 65535
    return t, h
  end
end

mruby on YABMではfloatが使えないので、整数で計算しています。100倍で計算して小数点以下2桁を計算しています。温度の計算式をmathcha.ioで書いてみました。




1000倍にして四捨五入しようとしたらオーバーフローしてダメでした。100倍でも今は寒いのでオーバーフローしないだけかもしれないので、念のために60度(39321)の計算もさせてみましたが、大丈夫でした。これ結構危険ですね。^ ^;

そもそも昔はセンサーなどの組み込みで使われるチップの処理はfloat無しに処理できることが常識でしたが、最近のチップはfloatの計算式がデーターシートにのっていたりします。

小数点で扱うときは文字列にします。pointstrはpが整数値で、cが小数点以下の桁数になり文字列を返します。

def pointstr(p, c)
  if p == 0 then
    return "0." + "0" * c
  elsif p.abs < 10 ** c
    l = c - p.abs.to_s.length + 1
    s = p.to_s.insert(p < 0 ? 1 : 0, "0" * l)
    return s.insert(-1 - c, ".")
  else
    return p.to_s.insert(-1 - c, ".")
  end
end

chkcrcは計算できることは確認しましたが、使っていません。

crcは大きなデータを処理する場合はテーブルを使った実装が一般的ですが、このチップの場合は2バイトなので素直に計算で良いと思います。

2015年くらいに作られた新しいチップのようで、データの処理が非常に簡潔です。

ThingSpeakにデータを投げて安定度を見たいと思います。

このチップ、なんと日本語のデーターシートが用意されていました。