2013年6月12日水曜日

ruby gem 'arduino_firmata' の sysex を使ってADT7410使用の温度モジュールから値を取得する

2013/06/14-18:11JST u2sで負の値を求め方の間違いを修正(緑色)
2013/06/14-13:30JST 返り値のバイト数が要求バイト数と合っていないことがあるのでその場合スキップするように修正(青色)
2013/06/13-16:34JST "arduino.sysex I2C_REQUEST, [ADDRESS_ADT7410, _WRITE, 0x03, 0x00, 0x00, 0x001]"で16bit-modeで動くこともあるが, ケースによっては13bitのままだったりする.

  • 0.1度の中に複数の計測点があるので16bit modeであることがわかる.
2013/06/13-15:36JST 16bit mode指定がやっぱり正しく動いてないので削除
2013/06/13-15:06JST 16bit mode指定の間違いを訂正
2013/06/13-01:53JST readDataの間違いを訂正(奇数バイトは128倍(8bit目?))
2013/06/12-23:27JST readDataの間違いを訂正(shiftの係数が2だった)
これを使って,やってみた.のでメモ.
#!/usr/bin/env ruby -Ku
require 'rubygems'
require 'arduino_firmata'
$stdout.sync = true

ADDRESS_ADT7410= 0x48
I2C_READ= 0x08

def readData(data, shift)
  msb= data[4+4*shift]+data[5+4*shift]*128
  lsb= data[6+4*shift]+data[7+4*shift]*128
  return (msb*256+lsb)
end

def readDataS(data, shift)
  v= readData(data, shift)
  return (v<(1<<15)) ? v : v-(1<<15)*2
end

def data2string(data)
  i=0
  msg= ''
  while i+1<data.length
    msg+= data[i].chr
    i+= 2
  end
  return msg;
end

arduino = ArduinoFirmata.connect ENV["ARDUINO"], :nonblock_io => true
puts "firmata version #{arduino.version}"

arduino.on :sysex do |command, data|
  puts "command : #{command}"
  puts "data    : #{data.inspect}"
  if command == 0x77
    if data[0] == ADDRESS_ADT7410
      if data.length == 8
        t= readDataS(data, 0) / (1<<7).to_f #デフォルトは13bit modeで下位三ビットが1固定で無効ですが割っちゃいます.
        puts "#{t} [度]"
      end
    end
  else
    if command == 0x71
      p data2string(data);
    end
  end
end

#i2c enable
arduino.sysex 0x78, [0x00, 0x00]

loop do
  arduino.sysex 0x76, [ADDRESS_ADT7410, I2C_READ, 0x00, 0x00, 0x02, 0x00]
  sleep 1
end

0 件のコメント: