2013/06/14-18:11JST u2sで負の値の求め方の間違いを修正(緑色)
気圧の値も妥当なものになった(と思う).
2013/06/14-13:30JST 返り値のバイト数が要求バイト数と合っていないことがあるのでその場合スキップするように修正(赤色)
これまでの記事(
APT7410と
MPL115A2)でのコードを利用したlinda-arduino-sensor的なもの
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra/rocketio/linda/client'
require 'arduino_firmata'
$stdout.sync = true
url = ENV["LINDA_BASE"] || ARGV.shift || "http://localhost:5000"
space = ENV["LINDA_SPACE"] || "test"
linda = Sinatra::RocketIO::Linda::Client.new url
ts = linda.tuplespace[space]
linda.io.on :connect do ## RocketIO's "connect" event
puts "connect!! <#{linda.io.session}> (#{linda.io.type})"
end
linda.io.on :disconnect do
puts "RocketIO disconnected.."
end
STRING_DATA= 0x71
I2C_REQUEST= 0x76
I2C_REPLY= 0x77
I2C_CONFIG= 0x78
_WRITE= 0x00
_READ= 0x08
ADDRESS_ADT7410= 0x48
ADDRESS_MPL115A2= 0x60
#MPL115A2 coefficients
a0= b1= b2= c12= 0.0
def readByte(data, pos)
return data[pos]+data[pos+1]*(1<<7)
end
def readData(msb, lsb)
return (msb<<8)+lsb
end
def u2s(v)
return (v<(1<<15)) ? v : v-(1<<15)*2
end
def bytes2str(bytes)
ret= ''
bytes.each do |o|
ret+= o.chr
end
return ret;
end
def decodeData(data)
ret= {}
ret[:address]= readByte(data, 0) if (data.length>1)
ret[:register]= readByte(data, 2) if (data.length>3)
ary= [];
i= 4
while i+1<data.length
ary.push( readByte(data, i))
i+= 2
end
ret[:data]= ary
return ret;
end
arduino = ArduinoFirmata.connect ENV["ARDUINO"], :nonblock_io => true
arduino.on :sysex do |command, data|
#puts "command : #{command}"
#puts "data : #{data.inspect}"
data= (command == STRING_DATA) ? bytes2str(data) : decodeData(data)
if command == STRING_DATA
p data
elsif command == I2C_REPLY
if data[:address] == ADDRESS_ADT7410
if data[:data].length == 2
tout= u2s(readData(data[:data][0], data[:data][1])) / (1<<7).to_f
ts.write ["sensor", "temperature", tout]
end
elsif data[:address] == ADDRESS_MPL115A2
if data[:register] == 0x04
if data[:data].length == 8
a0 = u2s(readData(data[:data][0], data[:data][1]))/(1<< 3).to_f
b1 = u2s(readData(data[:data][2], data[:data][3]))/(1<<13).to_f
b2 = u2s(readData(data[:data][4], data[:data][5]))/(1<<14).to_f
c12= u2s(readData(data[:data][6], data[:data][7]))/(1<<24).to_f
end
elsif data[:register] == 0x00
if data[:data].length == 4
padc= readData(data[:data][0], data[:data][1])>>6
tadc= readData(data[:data][2], data[:data][3])>>6
pcomp= a0 + ( b1 + c12 * tadc ) * padc + b2 * tadc
pout= pcomp * 650.0/1023.0 + 500.0
ts.write ["sensor", "pressure", pout] if padc>0
end
end
end
end
end
#i2c enable
arduino.sysex I2C_CONFIG, [0x00, 0x00]
#APT7410 16bit mode
arduino.sysex I2C_REQUEST, [ADDRESS_ADT7410, _WRITE, 0x03, 0x00, 0x00, 0x01]
#MPL115A2 coefficients
arduino.sysex I2C_REQUEST, [ADDRESS_MPL115A2, _READ, 0x04, 0x00, 0x08, 0x00]
loop do
arduino.sysex I2C_REQUEST, [ADDRESS_ADT7410, _READ, 0x00, 0x00, 0x02, 0x00]
arduino.sysex I2C_REQUEST, [ADDRESS_MPL115A2, _WRITE, 0x12, 0x00, 0x01, 0x00]
sleep 0.02
arduino.sysex I2C_REQUEST, [ADDRESS_MPL115A2, _READ, 0x00, 0x00, 0x04, 0x00]
sleep 1
end
0 件のコメント:
コメントを投稿