apiotics_factory 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/License +9 -0
- data/bin/apiotics_factory +3 -0
- data/lib/apiotics_factory/clear_credentials.rb +25 -0
- data/lib/apiotics_factory/configuration.rb +30 -0
- data/lib/apiotics_factory/generator.rb +133 -0
- data/lib/apiotics_factory/my_command.rb +15 -0
- data/lib/apiotics_factory/portal.rb +33 -0
- data/lib/apiotics_factory/publish.rb +83 -0
- data/lib/apiotics_factory/underscore.rb +11 -0
- data/lib/apiotics_factory/version.rb +3 -0
- data/lib/apiotics_factory.rb +28 -0
- data/lib/templates/apiotics_driver.rb.erb +244 -0
- data/lib/templates/apiotics_interfaces.rb.erb +33 -0
- data/lib/templates/config.json.erb +172 -0
- data/lib/templates/exec.rb.erb +8 -0
- data/lib/templates/grove_pi/grove_pi.rb +270 -0
- data/lib/templates/grove_pi/i2c/device/acm1602ni.rb +19 -0
- data/lib/templates/grove_pi/i2c/device/adt7410.rb +149 -0
- data/lib/templates/grove_pi/i2c/device/aqm0802.rb +70 -0
- data/lib/templates/grove_pi/i2c/device/bmp180.rb +207 -0
- data/lib/templates/grove_pi/i2c/device/d6t-44l.rb +52 -0
- data/lib/templates/grove_pi/i2c/device/hd44780.rb +172 -0
- data/lib/templates/grove_pi/i2c/device/hdc1000.rb +42 -0
- data/lib/templates/grove_pi/i2c/device/mpl115a2.rb +38 -0
- data/lib/templates/grove_pi/i2c/driver/gpio.rb +213 -0
- data/lib/templates/grove_pi/i2c/driver/i2c-dev.rb +60 -0
- data/lib/templates/grove_pi/i2c/driver.rb +28 -0
- data/lib/templates/grove_pi/i2c/i2c.rb +45 -0
- metadata +114 -0
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'i2c'
|
2
|
+
|
3
|
+
# Implements the I2C-Device BMP085/BMP180
|
4
|
+
# This code was inspired by https://github.com/adafruit/Adafruit_Python_BMP
|
5
|
+
#
|
6
|
+
# Datasheet: https://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
|
7
|
+
#
|
8
|
+
# Currently this code was tested on a Banana Pi with a BMP185 device. It should work on a Raspberry or any other Linux with I2C-Dev
|
9
|
+
#
|
10
|
+
# ==Example
|
11
|
+
# Using i2c-2 device (e.g. if you using a banana pi)
|
12
|
+
#
|
13
|
+
# bmp = I2CDevice::Bmp180.new(driver: I2CDevice::Driver::I2CDev.new("/dev/i2c-2"), mode: 0)
|
14
|
+
# puts "#{bmp.read_temperature / 10.0}°C"
|
15
|
+
# sleep 1
|
16
|
+
# puts "#{bmp.read_pressure / 100.0}hPa abs"
|
17
|
+
# sleep 1
|
18
|
+
# m_above_sealevel = 500 # position realtive to sealevel in m
|
19
|
+
# puts "#{bmp.read_sealevel_pressure(m_above_sealevel) / 100.0}hPa rel"
|
20
|
+
#
|
21
|
+
class I2CDevice::Bmp180 < I2CDevice
|
22
|
+
# BMP085 default address.
|
23
|
+
BMP085_I2CADDR = 0x77
|
24
|
+
|
25
|
+
# Operating Modes
|
26
|
+
BMP085_ULTRALOWPOWER = 0
|
27
|
+
BMP085_STANDARD = 1
|
28
|
+
BMP085_HIGHRES = 2
|
29
|
+
BMP085_ULTRAHIGHRES = 3
|
30
|
+
|
31
|
+
# BMP085 Registers
|
32
|
+
BMP085_CAL_AC1 = 0xAA # R Calibration data (16 bits)
|
33
|
+
BMP085_CAL_AC2 = 0xAC # R Calibration data (16 bits)
|
34
|
+
BMP085_CAL_AC3 = 0xAE # R Calibration data (16 bits)
|
35
|
+
BMP085_CAL_AC4 = 0xB0 # R Calibration data (16 bits) unsigned
|
36
|
+
BMP085_CAL_AC5 = 0xB2 # R Calibration data (16 bits) unsigned
|
37
|
+
BMP085_CAL_AC6 = 0xB4 # R Calibration data (16 bits) unsigned
|
38
|
+
BMP085_CAL_B1 = 0xB6 # R Calibration data (16 bits)
|
39
|
+
BMP085_CAL_B2 = 0xB8 # R Calibration data (16 bits)
|
40
|
+
BMP085_CAL_MB = 0xBA # R Calibration data (16 bits)
|
41
|
+
BMP085_CAL_MC = 0xBC # R Calibration data (16 bits)
|
42
|
+
BMP085_CAL_MD = 0xBE # R Calibration data (16 bits)
|
43
|
+
BMP085_CONTROL = 0xF4
|
44
|
+
BMP085_TEMPDATA = 0xF6
|
45
|
+
BMP085_PRESSUREDATA = 0xF6
|
46
|
+
|
47
|
+
# Commands
|
48
|
+
BMP085_READTEMPCMD = 0x2E
|
49
|
+
BMP085_READPRESSURECMD = 0x34
|
50
|
+
|
51
|
+
# initialize the device and read the calibration registers
|
52
|
+
#
|
53
|
+
# ==params
|
54
|
+
# * args : hash defaults to {}
|
55
|
+
# ** :mode : one of BMP085_ULTRALOWPOWER | BMP085_STANDARD | BMP085_HIGHRES | BMP085_ULTRAHIGHRES defaults to BMP085_STANDARD see datasheet for more information
|
56
|
+
# ** :address : device address defaults to 0x77
|
57
|
+
def initialize(args={})
|
58
|
+
@mode = args.delete(:mode) || BMP085_STANDARD
|
59
|
+
args = {
|
60
|
+
address: BMP085_I2CADDR
|
61
|
+
}.merge(args)
|
62
|
+
|
63
|
+
super args
|
64
|
+
|
65
|
+
raise "Mode must be between #{BMP085_ULTRALOWPOWER} and #{BMP085_ULTRAHIGHRES}" unless [BMP085_ULTRALOWPOWER, BMP085_STANDARD, BMP085_HIGHRES, BMP085_ULTRAHIGHRES].include?(@mode)
|
66
|
+
|
67
|
+
calibration
|
68
|
+
end
|
69
|
+
|
70
|
+
# read the current real temperature in 0.1°C
|
71
|
+
def read_temperature
|
72
|
+
return calc_real_temperature(read_raw_temperature)
|
73
|
+
end
|
74
|
+
|
75
|
+
# read the current relative pressure in Pa
|
76
|
+
def read_pressure
|
77
|
+
return calc_real_pressure(read_raw_temperature, read_raw_pressure)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Read current temperature and realtive pressure
|
81
|
+
#
|
82
|
+
# ==return
|
83
|
+
# * temperature in 0.1°C, pressure in Pa
|
84
|
+
def read_temperature_and_pressure
|
85
|
+
ut = read_raw_temperature
|
86
|
+
up = read_raw_pressure
|
87
|
+
|
88
|
+
return calc_real_temperature(ut), calc_real_pressure(ut, up)
|
89
|
+
end
|
90
|
+
|
91
|
+
# calculate the current pressure at sealevel from the current relative pressure and the gitven altitude
|
92
|
+
#
|
93
|
+
# ==params
|
94
|
+
# * altitude : curren altitude above sealevel in m defaults to 0
|
95
|
+
def read_sealevel_pressure(altitude = 0.0)
|
96
|
+
pressure = read_pressure()
|
97
|
+
return cacl_sealevel_pressure(pressure, altitude)
|
98
|
+
end
|
99
|
+
|
100
|
+
# calculate the current pressure at sealevel from the given relative pressure and the gitven altitude
|
101
|
+
#
|
102
|
+
# ==params
|
103
|
+
# * altitude : curren altitude above sealevel in m
|
104
|
+
# * pressure : current relative pressure in Pa
|
105
|
+
def cacl_sealevel_pressure(pressure, altitude)
|
106
|
+
return pressure.to_f / ((1.0 - altitude.to_f / 44330.0) ** 5.255)
|
107
|
+
end
|
108
|
+
|
109
|
+
# get the calibration values
|
110
|
+
#
|
111
|
+
# ==return
|
112
|
+
# array of calibration data
|
113
|
+
def get_cal
|
114
|
+
return @cal_AC1, @cal_AC2, @cal_AC3, @cal_AC4, @cal_AC5, @cal_AC6, @cal_B1, @cal_B2, @cal_MB, @cal_MC, @cal_MD
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
# read the current raw temperature value
|
119
|
+
def read_raw_temperature
|
120
|
+
i2cset(BMP085_CONTROL, BMP085_READTEMPCMD)
|
121
|
+
sleep 0.005
|
122
|
+
return i2cget(BMP085_TEMPDATA, 2).unpack('s>')[0]
|
123
|
+
end
|
124
|
+
|
125
|
+
# read the current raw pressure value
|
126
|
+
def read_raw_pressure
|
127
|
+
i2cset(BMP085_CONTROL, BMP085_READPRESSURECMD + (@mode << 6))
|
128
|
+
|
129
|
+
if @mode == BMP085_ULTRALOWPOWER
|
130
|
+
sleep 0.005
|
131
|
+
elsif @mode == BMP085_HIGHRES
|
132
|
+
sleep 0.014
|
133
|
+
elsif @mode == BMP085_ULTRAHIGHRES
|
134
|
+
sleep 0.026
|
135
|
+
else
|
136
|
+
sleep 0.008
|
137
|
+
end
|
138
|
+
|
139
|
+
sleep 1 # safety for testing
|
140
|
+
|
141
|
+
msb, lsb, xlsb = i2cget(BMP085_PRESSUREDATA, 3).unpack('C*')
|
142
|
+
up = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - @mode)
|
143
|
+
|
144
|
+
return up
|
145
|
+
end
|
146
|
+
|
147
|
+
# load the calibration registers into instance variables
|
148
|
+
def calibration
|
149
|
+
@cal_AC1, @cal_AC2, @cal_AC3, @cal_AC4, @cal_AC5, @cal_AC6, @cal_B1, @cal_B2,
|
150
|
+
@cal_MB, @cal_MC, @cal_MD = i2cget(BMP085_CAL_AC1, 22).unpack('s>s>s>S>S>S>s>s>s>s>s>')
|
151
|
+
end
|
152
|
+
|
153
|
+
# calculate the read temperature using the calibration registers
|
154
|
+
#
|
155
|
+
# ==params
|
156
|
+
# * ut : raw templerature value
|
157
|
+
# ==return
|
158
|
+
# true temperature in 0.1°C -> 150 = 15.0 °C
|
159
|
+
def calc_real_temperature(ut)
|
160
|
+
x1 = ((ut - @cal_AC6) * @cal_AC5) / 2**15
|
161
|
+
x2 = (@cal_MC * 2**11) / (x1 + @cal_MD)
|
162
|
+
b5 = x1 + x2
|
163
|
+
t = (b5 + 8) / 2**4
|
164
|
+
|
165
|
+
return t
|
166
|
+
end
|
167
|
+
|
168
|
+
# calculate the read pressure using the calibration registers
|
169
|
+
#
|
170
|
+
# ==params
|
171
|
+
# * up : raw pressure value
|
172
|
+
# ==return
|
173
|
+
# true pressure in Pa
|
174
|
+
def calc_real_pressure(ut, up)
|
175
|
+
x1 = ((ut - @cal_AC6) * @cal_AC5) / 2**15
|
176
|
+
x2 = (@cal_MC * 2**11) / (x1 + @cal_MD)
|
177
|
+
b5 = x1 + x2
|
178
|
+
|
179
|
+
# Pressure Calculations
|
180
|
+
b6 = b5 - 4000
|
181
|
+
x1 = (@cal_B2 * (b6 * b6) / 2**12) / 2**11
|
182
|
+
x2 = (@cal_AC2 * b6) / 2**11
|
183
|
+
x3 = x1 + x2
|
184
|
+
b3 = (((@cal_AC1 * 4 + x3) << @mode) + 2) / 4
|
185
|
+
|
186
|
+
x1 = (@cal_AC3 * b6) / 2**13
|
187
|
+
x2 = (@cal_B1 * ((b6 * b6) / 2**12)) / 2**16
|
188
|
+
x3 = ((x1 + x2) + 2) / 2**2
|
189
|
+
b4 = (@cal_AC4 * (x3 + 32768)) / 2**15
|
190
|
+
|
191
|
+
b7 = (up - b3) * (50000 >> @mode)
|
192
|
+
|
193
|
+
if b7 < 0x80000000
|
194
|
+
pr = (b7 * 2) / b4
|
195
|
+
else
|
196
|
+
pr = (b7 / b4) * 2
|
197
|
+
end
|
198
|
+
|
199
|
+
x1 = (pr / 2**8) * (pr / 2**8)
|
200
|
+
x1 = (x1 * 3038) / 2**16
|
201
|
+
x2 = (-7357 * pr) / 2**16
|
202
|
+
pr += ((x1 + x2 + 3791) / 2**4)
|
203
|
+
|
204
|
+
return pr
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
|
4
|
+
class I2CDevice::D6T44L < I2CDevice
|
5
|
+
class InvalidParityException < Exception; end
|
6
|
+
|
7
|
+
def initialize(args={})
|
8
|
+
args[:address] = 0x0a
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def read_data
|
13
|
+
data = i2cget(0x4c, 35)
|
14
|
+
unless checkPEC(data, false)
|
15
|
+
raise InvalidParityException
|
16
|
+
end
|
17
|
+
|
18
|
+
# PTAT はセンサ内部の参照温度データ
|
19
|
+
ptat, *pixels = data[0..-2].unpack("v*")
|
20
|
+
{
|
21
|
+
:PTAT => ptat,
|
22
|
+
:PIXELS => pixels.each_slice(4).to_a
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def calc_crc(data)
|
28
|
+
8.times do
|
29
|
+
tmp = data
|
30
|
+
data = (data << 1) & 0xff
|
31
|
+
if tmp & 0x80 != 0
|
32
|
+
data ^= 0x07
|
33
|
+
end
|
34
|
+
end
|
35
|
+
data
|
36
|
+
end
|
37
|
+
|
38
|
+
def checkPEC(data, userr=true)
|
39
|
+
crc = 0
|
40
|
+
if userr
|
41
|
+
crc = calc_crc(0x14)
|
42
|
+
crc = calc_crc(0x4c ^ crc)
|
43
|
+
crc = calc_crc(0x15 ^ crc)
|
44
|
+
else
|
45
|
+
crc = calc_crc(0x15)
|
46
|
+
end
|
47
|
+
(data.size - 1).times do |i|
|
48
|
+
crc = calc_crc(data[i].ord ^ crc)
|
49
|
+
end
|
50
|
+
data[data.size-1].ord == crc
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "i2c"
|
4
|
+
|
5
|
+
# I2C interface with HD44780 compatible commands
|
6
|
+
class I2CDevice::HD44780 < I2CDevice
|
7
|
+
MAP = Hash[
|
8
|
+
[
|
9
|
+
"。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚".split(//).map {|c|
|
10
|
+
c.force_encoding(Encoding::BINARY)
|
11
|
+
},
|
12
|
+
(0b10100001..0b11011111).map {|c|
|
13
|
+
c.chr
|
14
|
+
}
|
15
|
+
].transpose
|
16
|
+
]
|
17
|
+
|
18
|
+
def initialize(args={})
|
19
|
+
super
|
20
|
+
@lines = []
|
21
|
+
initialize_lcd
|
22
|
+
end
|
23
|
+
|
24
|
+
# Initialize LCD controller sequence
|
25
|
+
# Display is cleared.
|
26
|
+
def initialize_lcd
|
27
|
+
function_set(1, 1, 0)
|
28
|
+
sleep 4.1e-3
|
29
|
+
function_set(1, 1, 0)
|
30
|
+
sleep 100e-6
|
31
|
+
function_set(1, 1, 0)
|
32
|
+
function_set(1, 1, 0)
|
33
|
+
display_on_off_control(1, 0, 0)
|
34
|
+
clear
|
35
|
+
end
|
36
|
+
|
37
|
+
# <tt>line</tt> :: [Integer] Line number
|
38
|
+
# <tt>str</tt> :: [String] Display string
|
39
|
+
# <tt>force</tt> :: [true | false] Write data forcely.
|
40
|
+
#
|
41
|
+
# Note: This method keep previous put_line strings and does not write without change.
|
42
|
+
# You must specify _force_ to override this behaviour.
|
43
|
+
def put_line(line, str, force=false)
|
44
|
+
str.force_encoding(Encoding::BINARY)
|
45
|
+
str.gsub!(/#{MAP.keys.join('|')}/, MAP)
|
46
|
+
|
47
|
+
str = "%- 16s" % str
|
48
|
+
|
49
|
+
if force || str != @lines[line]
|
50
|
+
# set ddram address
|
51
|
+
set_ddram_address(0x40 * line)
|
52
|
+
sleep 60e-6
|
53
|
+
i2cset(*str.unpack("C*").map {|i| [0x80, i] }.flatten)
|
54
|
+
sleep 60e-6
|
55
|
+
end
|
56
|
+
@lines[line] = str
|
57
|
+
end
|
58
|
+
|
59
|
+
# <tt>n</tt> :: [Integer] Character code.
|
60
|
+
# <tt>array</tt> :: [Array[Integer]] Character data.
|
61
|
+
# Usage:
|
62
|
+
# lcd.define_character(0, [
|
63
|
+
# 0,1,1,1,0,
|
64
|
+
# 1,0,0,0,1,
|
65
|
+
# 1,1,0,1,1,
|
66
|
+
# 1,0,1,0,1,
|
67
|
+
# 1,1,0,1,1,
|
68
|
+
# 1,0,0,0,1,
|
69
|
+
# 1,0,0,0,1,
|
70
|
+
# 0,1,1,1,0,
|
71
|
+
# ])
|
72
|
+
def define_character(n, array)
|
73
|
+
raise "n < 8" unless n < 8
|
74
|
+
raise "array size must be 40 (5x8)" unless array.size == 40
|
75
|
+
|
76
|
+
array = array.each_slice(5).map {|i|
|
77
|
+
i.inject {|r,i| (r << 1) + i }
|
78
|
+
}
|
79
|
+
set_cgram_address(8 * n)
|
80
|
+
sleep 60e-6
|
81
|
+
i2cset(*array.map {|i| [0x80, i] }.flatten)
|
82
|
+
sleep 60e-6
|
83
|
+
end
|
84
|
+
|
85
|
+
def clear_display
|
86
|
+
@lines.clear
|
87
|
+
i2cset(0, 0b00000001)
|
88
|
+
sleep 2.16e-3
|
89
|
+
end
|
90
|
+
|
91
|
+
alias clear clear_display
|
92
|
+
|
93
|
+
def return_home
|
94
|
+
i2cset(0, 0b00000010)
|
95
|
+
sleep 1.52e-3
|
96
|
+
end
|
97
|
+
|
98
|
+
# <tt>i_d</tt> :: [Integer] Increment or decrement
|
99
|
+
# 0 :: Decrement
|
100
|
+
# 1 :: Increment
|
101
|
+
# <tt>s</tt> :: [Integer] Shift entire display
|
102
|
+
# 0 :: Right
|
103
|
+
# 1 :: Left
|
104
|
+
def entry_mode_set(i_d, s)
|
105
|
+
i2cset(0, 0b00000100 | (i_d<<1) | (s))
|
106
|
+
sleep 60e-6
|
107
|
+
end
|
108
|
+
|
109
|
+
# <tt>d</tt> :: [Integer] Set entire display on/off
|
110
|
+
# 0 :: Off
|
111
|
+
# 1 :: On
|
112
|
+
# <tt>c</tt> :: [Integer] Cursor on/off
|
113
|
+
# 0 :: Off
|
114
|
+
# 1 :: On
|
115
|
+
# <tt>b</tt> :: [Integer] Blink cursor
|
116
|
+
# 0 :: Off
|
117
|
+
# 1 :: On
|
118
|
+
def display_on_off_control(d, c, b)
|
119
|
+
i2cset(0, 0b00001000 | (d<<2) | (c<<1) | (b))
|
120
|
+
sleep 60e-6
|
121
|
+
end
|
122
|
+
|
123
|
+
# <tt>s_c</tt> :: [Integer] Cursor or display
|
124
|
+
# 0 :: Cursor shift
|
125
|
+
# 1 :: Display shift
|
126
|
+
# <tt>r_l</tt> :: [Integer] Direction
|
127
|
+
# 0 :: Left
|
128
|
+
# 1 :: Right
|
129
|
+
def cursor_or_display_shift(s_c, r_l)
|
130
|
+
i2cset(0, 0b00010000 | (s_c<<3) | (r_l<<2))
|
131
|
+
sleep 60e-6
|
132
|
+
end
|
133
|
+
|
134
|
+
# <tt>dl</tt> :: [Integer] Data length
|
135
|
+
# 0 :: 4bit
|
136
|
+
# 1 :: 8bit
|
137
|
+
# <tt>n</tt> :: [Integer] Number of display lines
|
138
|
+
# 0 :: 1-line
|
139
|
+
# 1 :: 2-line
|
140
|
+
# <tt>f</tt> :: [Integer] Character font
|
141
|
+
# 0 :: Normal
|
142
|
+
# 1 :: Double font
|
143
|
+
def function_set(dl, n, f)
|
144
|
+
i2cset(0, 0b00100000 | (dl<<4) | (n<<3) | (f<<2))
|
145
|
+
sleep 60e-6
|
146
|
+
end
|
147
|
+
|
148
|
+
# <tt>address</tt> :: [Integer] CGRAM address 6-bit
|
149
|
+
def set_cgram_address(address)
|
150
|
+
address = address & 0b00111111
|
151
|
+
i2cset(0, 0b01000000 | address)
|
152
|
+
sleep 60e-6
|
153
|
+
end
|
154
|
+
|
155
|
+
# <tt>address</tt> :: [Integer] DDRAM address 7-bit
|
156
|
+
def set_ddram_address(address)
|
157
|
+
address = address & 0b01111111
|
158
|
+
i2cset(0, 0b10000000 | address)
|
159
|
+
sleep 60e-6
|
160
|
+
end
|
161
|
+
|
162
|
+
# <tt>Returns</tt> :: [Hash] Result
|
163
|
+
# :busy :: [true | false] Busy flag
|
164
|
+
# :address_counter :: [Integer] Current address count. 7-bit
|
165
|
+
def read_busy_flag_and_address
|
166
|
+
read = i2cget(0b01000000)
|
167
|
+
{
|
168
|
+
:busy => (read & 0b10000000) != 0,
|
169
|
+
:address_counter => read & 0b01111111
|
170
|
+
}
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "i2c"
|
4
|
+
|
5
|
+
# http://www.ti.com/product/HDC1000
|
6
|
+
# A Digital humidity/temperature sensor
|
7
|
+
|
8
|
+
class I2CDevice::HDC1000 < I2CDevice
|
9
|
+
def initialize(args = {})
|
10
|
+
args = {
|
11
|
+
address: 0x40
|
12
|
+
}.merge(args)
|
13
|
+
super args
|
14
|
+
configuration
|
15
|
+
end
|
16
|
+
|
17
|
+
def configuration
|
18
|
+
i2cset(
|
19
|
+
0x02, # Configuration register
|
20
|
+
0x10, # TRES 14bit
|
21
|
+
0x00 # HRES 14bit
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_data
|
26
|
+
i2cset(0x00)
|
27
|
+
sleep 6.35e-3 + 6.5e-3
|
28
|
+
raw = i2cget(nil, 4).unpack("C4")
|
29
|
+
{
|
30
|
+
temperature: calc_temperature(raw[0], raw[1]),
|
31
|
+
humidity: calc_humidity(raw[2], raw[3])
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def calc_temperature(d1, d2)
|
36
|
+
((d1<<8 | d2).to_f / 2**16 * 165) - 40
|
37
|
+
end
|
38
|
+
|
39
|
+
def calc_humidity(d1, d2)
|
40
|
+
(d1<<8 | d2).to_f / 2**16 * 100
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "i2c"
|
2
|
+
|
3
|
+
class I2CDevice::MPL115A2 < I2CDevice
|
4
|
+
def initialize(args={})
|
5
|
+
args[:address] = 0x60
|
6
|
+
super
|
7
|
+
coefficient = i2cget(0x04, 8).unpack("n*")
|
8
|
+
|
9
|
+
@a0 = fixed_point(coefficient[0], 12)
|
10
|
+
@b1 = fixed_point(coefficient[1], 2)
|
11
|
+
@b2 = fixed_point(coefficient[2], 1)
|
12
|
+
@c12 = fixed_point(coefficient[3], 0) / (1<<9)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fixed_point(fixed, int_bits)
|
16
|
+
msb = 15
|
17
|
+
deno = (1<<(msb-int_bits)).to_f
|
18
|
+
if (fixed & (1<<15)).zero?
|
19
|
+
fixed / deno
|
20
|
+
else
|
21
|
+
-( ( (~fixed & 0xffff) + 1) / deno )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def calculate_hPa
|
26
|
+
i2cset(0x12, 0x01) # CONVERT
|
27
|
+
|
28
|
+
sleep 0.003
|
29
|
+
|
30
|
+
data = i2cget(0x00, 4).unpack("n*")
|
31
|
+
|
32
|
+
p_adc = (data[0]) >> 6
|
33
|
+
t_adc = (data[1]) >> 6
|
34
|
+
|
35
|
+
p_comp = @a0 + (@b1 + @c12 * t_adc) * p_adc + @b2 * t_adc
|
36
|
+
hPa = p_comp * ( (1150 - 500) / 1023.0) + 500;
|
37
|
+
end
|
38
|
+
end
|