apiotics_factory 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,172 @@
|
|
1
|
+
{
|
2
|
+
"ociVersion": "1.0.0",
|
3
|
+
"process": {
|
4
|
+
"terminal": false,
|
5
|
+
"user": {
|
6
|
+
"uid": 0,
|
7
|
+
"gid": 0
|
8
|
+
},
|
9
|
+
"args": [
|
10
|
+
<%= "\"/#{@driver_name.downcase}\""%>
|
11
|
+
],
|
12
|
+
"env": [
|
13
|
+
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
14
|
+
"TERM=xterm"
|
15
|
+
],
|
16
|
+
"cwd": "/",
|
17
|
+
"capabilities": {
|
18
|
+
"bounding": [
|
19
|
+
"CAP_AUDIT_WRITE",
|
20
|
+
"CAP_KILL",
|
21
|
+
"CAP_NET_BIND_SERVICE"
|
22
|
+
],
|
23
|
+
"effective": [
|
24
|
+
"CAP_AUDIT_WRITE",
|
25
|
+
"CAP_KILL",
|
26
|
+
"CAP_NET_BIND_SERVICE"
|
27
|
+
],
|
28
|
+
"inheritable": [
|
29
|
+
"CAP_AUDIT_WRITE",
|
30
|
+
"CAP_KILL",
|
31
|
+
"CAP_NET_BIND_SERVICE"
|
32
|
+
],
|
33
|
+
"permitted": [
|
34
|
+
"CAP_AUDIT_WRITE",
|
35
|
+
"CAP_KILL",
|
36
|
+
"CAP_NET_BIND_SERVICE"
|
37
|
+
],
|
38
|
+
"ambient": [
|
39
|
+
"CAP_AUDIT_WRITE",
|
40
|
+
"CAP_KILL",
|
41
|
+
"CAP_NET_BIND_SERVICE"
|
42
|
+
]
|
43
|
+
},
|
44
|
+
"rlimits": [
|
45
|
+
{
|
46
|
+
"type": "RLIMIT_NOFILE",
|
47
|
+
"hard": 1024,
|
48
|
+
"soft": 1024
|
49
|
+
}
|
50
|
+
],
|
51
|
+
"noNewPrivileges": true
|
52
|
+
},
|
53
|
+
"root": {
|
54
|
+
"path": "rootfs",
|
55
|
+
"readonly": true
|
56
|
+
},
|
57
|
+
"hostname": "runc",
|
58
|
+
"mounts": [
|
59
|
+
{
|
60
|
+
"destination": "/proc",
|
61
|
+
"type": "proc",
|
62
|
+
"source": "proc"
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"destination": "/dev",
|
66
|
+
"type": "tmpfs",
|
67
|
+
"source": "tmpfs",
|
68
|
+
"options": [
|
69
|
+
"nosuid",
|
70
|
+
"strictatime",
|
71
|
+
"mode=755",
|
72
|
+
"size=65536k"
|
73
|
+
]
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"destination": "/dev/pts",
|
77
|
+
"type": "devpts",
|
78
|
+
"source": "devpts",
|
79
|
+
"options": [
|
80
|
+
"nosuid",
|
81
|
+
"noexec",
|
82
|
+
"newinstance",
|
83
|
+
"ptmxmode=0666",
|
84
|
+
"mode=0620"
|
85
|
+
]
|
86
|
+
},
|
87
|
+
{
|
88
|
+
"destination": "/dev/shm",
|
89
|
+
"type": "tmpfs",
|
90
|
+
"source": "shm",
|
91
|
+
"options": [
|
92
|
+
"nosuid",
|
93
|
+
"noexec",
|
94
|
+
"nodev",
|
95
|
+
"mode=1777",
|
96
|
+
"size=65536k"
|
97
|
+
]
|
98
|
+
},
|
99
|
+
{
|
100
|
+
"destination": "/dev/mqueue",
|
101
|
+
"type": "mqueue",
|
102
|
+
"source": "mqueue",
|
103
|
+
"options": [
|
104
|
+
"nosuid",
|
105
|
+
"noexec",
|
106
|
+
"nodev"
|
107
|
+
]
|
108
|
+
},
|
109
|
+
{
|
110
|
+
"destination": "/sys",
|
111
|
+
"type": "none",
|
112
|
+
"source": "/sys",
|
113
|
+
"options": [
|
114
|
+
"rbind",
|
115
|
+
"nosuid",
|
116
|
+
"noexec",
|
117
|
+
"nodev",
|
118
|
+
"ro"
|
119
|
+
]
|
120
|
+
}
|
121
|
+
],
|
122
|
+
"linux": {
|
123
|
+
"uidMappings": [
|
124
|
+
{
|
125
|
+
"hostID": 1000,
|
126
|
+
"containerID": 0,
|
127
|
+
"size": 1
|
128
|
+
}
|
129
|
+
],
|
130
|
+
"gidMappings": [
|
131
|
+
{
|
132
|
+
"hostID": 1000,
|
133
|
+
"containerID": 0,
|
134
|
+
"size": 1
|
135
|
+
}
|
136
|
+
],
|
137
|
+
"namespaces": [
|
138
|
+
{
|
139
|
+
"type": "pid"
|
140
|
+
},
|
141
|
+
{
|
142
|
+
"type": "ipc"
|
143
|
+
},
|
144
|
+
{
|
145
|
+
"type": "uts"
|
146
|
+
},
|
147
|
+
{
|
148
|
+
"type": "mount"
|
149
|
+
},
|
150
|
+
{
|
151
|
+
"type": "user"
|
152
|
+
}
|
153
|
+
],
|
154
|
+
"maskedPaths": [
|
155
|
+
"/proc/kcore",
|
156
|
+
"/proc/latency_stats",
|
157
|
+
"/proc/timer_list",
|
158
|
+
"/proc/timer_stats",
|
159
|
+
"/proc/sched_debug",
|
160
|
+
"/sys/firmware",
|
161
|
+
"/proc/scsi"
|
162
|
+
],
|
163
|
+
"readonlyPaths": [
|
164
|
+
"/proc/asound",
|
165
|
+
"/proc/bus",
|
166
|
+
"/proc/fs",
|
167
|
+
"/proc/irq",
|
168
|
+
"/proc/sys",
|
169
|
+
"/proc/sysrq-trigger"
|
170
|
+
]
|
171
|
+
}
|
172
|
+
}
|
@@ -0,0 +1,270 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module GrovePi
|
4
|
+
require_relative 'i2c'
|
5
|
+
require_relative 'i2c/driver/i2c-dev'
|
6
|
+
|
7
|
+
# Commands.
|
8
|
+
CMD_READ_DIGITAL = 1
|
9
|
+
CMD_WRITE_DIGITAL = 2
|
10
|
+
CMD_READ_ANALOG = 3
|
11
|
+
CMD_WRITE_ANALOG = 4
|
12
|
+
CMD_PIN_MODE = 5
|
13
|
+
CMD_READ_FIRMWARE_VERSION = 8
|
14
|
+
|
15
|
+
# Arduino pin mappings.
|
16
|
+
A0 = 14
|
17
|
+
A1 = 15
|
18
|
+
A2 = 16
|
19
|
+
|
20
|
+
PINS_ANALOG = [A0, A1, A2]
|
21
|
+
|
22
|
+
D2 = 2
|
23
|
+
D3 = 3
|
24
|
+
D4 = 4
|
25
|
+
D5 = 5
|
26
|
+
D6 = 6
|
27
|
+
D7 = 7
|
28
|
+
D8 = 8
|
29
|
+
|
30
|
+
PINS_DIGITAL = [D2, D3, D4, D5, D6, D7, D8]
|
31
|
+
|
32
|
+
# Pin modes.
|
33
|
+
PIN_MODE_IN = 0
|
34
|
+
PIN_MODE_OUT = 1
|
35
|
+
|
36
|
+
# Configuration settings.
|
37
|
+
CONFIG_RETRIES = 10
|
38
|
+
GROVE_PI_I2C_SLAVE_ADDRESS = 4
|
39
|
+
|
40
|
+
# The initialized I2C object.
|
41
|
+
@_i2c_grove_pi = nil
|
42
|
+
|
43
|
+
# Storage for I2C slave addresses present on ports I2C-1, I2C-2 or I2C-3.
|
44
|
+
@_i2c_slave_addresses = Hash.new
|
45
|
+
|
46
|
+
# Internal functions.
|
47
|
+
#
|
48
|
+
# These functions are not intended to be used directly by the user but by the
|
49
|
+
# functions which are exposed to the user.
|
50
|
+
def self._grove_pi_discover()
|
51
|
+
begin
|
52
|
+
i2c_device_files = Dir['/dev/i2c-*']
|
53
|
+
|
54
|
+
if i2c_device_files.length < 1
|
55
|
+
return false, nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# Iterate over I2C device files.
|
59
|
+
for f in i2c_device_files
|
60
|
+
device_file = f
|
61
|
+
f = f.strip
|
62
|
+
f.slice! '/dev/i2c-'
|
63
|
+
lines = %x(#{'i2cdetect -y ' + Integer(f).to_s}).split("\n")
|
64
|
+
|
65
|
+
# Get rid of the first line.
|
66
|
+
lines.shift
|
67
|
+
|
68
|
+
if lines.length < 1
|
69
|
+
next
|
70
|
+
end
|
71
|
+
|
72
|
+
# Process i2cdetect command output for the I2C device file.
|
73
|
+
for i in 0..lines.length - 1
|
74
|
+
line = lines[i].strip
|
75
|
+
line = line.split ':'
|
76
|
+
|
77
|
+
if line.length != 2
|
78
|
+
next
|
79
|
+
end
|
80
|
+
|
81
|
+
for i2c_address in line[1].split(' ')
|
82
|
+
begin
|
83
|
+
if Integer(i2c_address) == GROVE_PI_I2C_SLAVE_ADDRESS
|
84
|
+
return true, device_file.strip
|
85
|
+
end
|
86
|
+
rescue
|
87
|
+
next
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
rescue
|
93
|
+
return false, nil
|
94
|
+
end
|
95
|
+
|
96
|
+
return false, nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def self._grove_pi_init()
|
100
|
+
status, i2c_device_file = self._grove_pi_discover
|
101
|
+
|
102
|
+
if status && i2c_device_file != nil
|
103
|
+
return I2CDevice.new address: GROVE_PI_I2C_SLAVE_ADDRESS,
|
104
|
+
driver: I2CDevice::Driver::I2CDev.new(i2c_device_file)
|
105
|
+
else
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def self._ensure_init()
|
111
|
+
if @_i2c_grove_pi == nil
|
112
|
+
@_i2c_grove_pi = self._grove_pi_init
|
113
|
+
|
114
|
+
if @_i2c_grove_pi == nil
|
115
|
+
raise 'No GrovePi found.'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def self._set_pin_mode(pin, mode)
|
121
|
+
self._ensure_init
|
122
|
+
@_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_PIN_MODE, pin, mode, 0
|
123
|
+
end
|
124
|
+
|
125
|
+
def self._read_analog(pin)
|
126
|
+
self._ensure_init
|
127
|
+
@_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_READ_ANALOG, pin, 0, 0
|
128
|
+
bytes = @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 3).chars
|
129
|
+
return (bytes[1].ord * 256) + bytes[2].ord
|
130
|
+
end
|
131
|
+
|
132
|
+
def self._write_analog(pin, value)
|
133
|
+
self._ensure_init
|
134
|
+
@_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_WRITE_ANALOG, pin, value, 0
|
135
|
+
end
|
136
|
+
|
137
|
+
def self._read_digital(pin)
|
138
|
+
self._ensure_init
|
139
|
+
@_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_READ_DIGITAL, pin, 0, 0
|
140
|
+
return @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 2).chars[0].ord
|
141
|
+
end
|
142
|
+
|
143
|
+
def self._write_digital(pin, value)
|
144
|
+
self._ensure_init
|
145
|
+
@_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_WRITE_DIGITAL, pin, value, 0
|
146
|
+
end
|
147
|
+
|
148
|
+
# Functions exposed to the user.
|
149
|
+
|
150
|
+
# Analog read functions.
|
151
|
+
def self.read_analog(pin)
|
152
|
+
if !PINS_ANALOG.include? pin
|
153
|
+
raise 'Invalid analog pin.'
|
154
|
+
end
|
155
|
+
|
156
|
+
for i in 0..CONFIG_RETRIES - 1
|
157
|
+
begin
|
158
|
+
self._set_pin_mode pin, PIN_MODE_IN
|
159
|
+
return self._read_analog pin
|
160
|
+
rescue Errno::EREMOTEIO
|
161
|
+
next
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Analog write functions (PWM on digital pins D3, D5 and D6).
|
167
|
+
def self.write_analog(pin, value)
|
168
|
+
if !PINS_DIGITAL.include? pin
|
169
|
+
raise 'Invalid analog pin. Note: PWM based analog write is applicable on digital ports.'
|
170
|
+
end
|
171
|
+
|
172
|
+
for i in 0..CONFIG_RETRIES - 1
|
173
|
+
begin
|
174
|
+
self._set_pin_mode pin, PIN_MODE_OUT
|
175
|
+
self._write_analog pin, value
|
176
|
+
return
|
177
|
+
rescue Errno::EREMOTEIO
|
178
|
+
next
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Digital read function.
|
184
|
+
def self.read_digital(pin)
|
185
|
+
if !PINS_DIGITAL.include? pin
|
186
|
+
raise 'Invalid digital pin.'
|
187
|
+
end
|
188
|
+
|
189
|
+
for i in 0..CONFIG_RETRIES - 1
|
190
|
+
begin
|
191
|
+
self._set_pin_mode pin, PIN_MODE_IN
|
192
|
+
return self._read_digital pin
|
193
|
+
rescue Errno::EREMOTEIO
|
194
|
+
next
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Digital write function.
|
200
|
+
def self.write_digital(pin, value)
|
201
|
+
if !PINS_DIGITAL.include? pin
|
202
|
+
raise 'Invalid digital pin.'
|
203
|
+
end
|
204
|
+
|
205
|
+
for i in 0..CONFIG_RETRIES - 1
|
206
|
+
begin
|
207
|
+
self._set_pin_mode pin, PIN_MODE_OUT
|
208
|
+
self._write_digital pin, value
|
209
|
+
return
|
210
|
+
rescue Errno::EREMOTEIO
|
211
|
+
next
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Functions for reading and writing I2C slaves connected to
|
217
|
+
# I2C-1, I2C-2 or I2C-3 ports of the GrovePi.
|
218
|
+
def self.read_grove_pi_i2c(i2c_slave_address, length)
|
219
|
+
_ensure_init
|
220
|
+
|
221
|
+
if !@_i2c_slave_addresses.key?(i2c_slave_address)
|
222
|
+
path =
|
223
|
+
@_i2c_grove_pi.instance_variable_get(:@driver)
|
224
|
+
.instance_variable_get(:@path)
|
225
|
+
|
226
|
+
@_i2c_slave_addresses[i2c_slave_address] = I2CDevice.new address: i2c_slave_address,
|
227
|
+
driver: I2CDevice::Driver::I2CDev.new(path)
|
228
|
+
end
|
229
|
+
|
230
|
+
bytes = []
|
231
|
+
_bytes = @_i2c_slave_addresses[i2c_slave_address].i2cget(i2c_slave_address, length).chars
|
232
|
+
|
233
|
+
for b in _bytes
|
234
|
+
bytes << b.ord
|
235
|
+
end
|
236
|
+
|
237
|
+
return bytes
|
238
|
+
end
|
239
|
+
|
240
|
+
def self.write_grove_pi_i2c(i2c_slave_address, *data)
|
241
|
+
_ensure_init
|
242
|
+
|
243
|
+
if !@_i2c_slave_addresses.key?(i2c_slave_address)
|
244
|
+
path =
|
245
|
+
@_i2c_grove_pi.instance_variable_get(:@driver)
|
246
|
+
.instance_variable_get(:@path)
|
247
|
+
|
248
|
+
@_i2c_slave_addresses[i2c_slave_address] = I2CDevice.new address: i2c_slave_address,
|
249
|
+
driver: I2CDevice::Driver::I2CDev.new(path)
|
250
|
+
end
|
251
|
+
|
252
|
+
@_i2c_slave_addresses[i2c_slave_address].i2cset i2c_slave_address, *data
|
253
|
+
end
|
254
|
+
|
255
|
+
# Miscellaneous functions.
|
256
|
+
def self.read_firmware_version()
|
257
|
+
for i in 0..CONFIG_RETRIES - 1
|
258
|
+
begin
|
259
|
+
self._ensure_init
|
260
|
+
@_i2c_grove_pi.i2cset @_i2c_grove_pi.address, CMD_READ_FIRMWARE_VERSION, 0, 0, 0
|
261
|
+
bytes = @_i2c_grove_pi.i2cget(@_i2c_grove_pi.address, 4).chars
|
262
|
+
return [bytes[1].ord, bytes[2].ord, bytes[3].ord]
|
263
|
+
rescue Errno::EREMOTEIO
|
264
|
+
next
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# TODO: Implement rest of the commands that are supported by the firmware.
|
270
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require "i2c/device/hd44780"
|
5
|
+
|
6
|
+
# 16x02 LCD module with I2C.
|
7
|
+
# Note: This device only run under speed=50kHz.
|
8
|
+
# http://akizukidenshi.com/catalog/g/gP-05693/
|
9
|
+
class I2CDevice::ACM1602NI < I2CDevice::HD44780
|
10
|
+
def initialize(args={})
|
11
|
+
args[:address] ||= 0x50
|
12
|
+
super
|
13
|
+
@lines = []
|
14
|
+
initialize_lcd
|
15
|
+
end
|
16
|
+
|
17
|
+
undef i2cget
|
18
|
+
undef read_busy_flag_and_address
|
19
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "i2c"
|
4
|
+
|
5
|
+
# Analog Devices ADT7410 (temperture sensor)
|
6
|
+
# http://www.analog.com/en/mems-sensors/digital-temperature-sensors/adt7410/products/product.html
|
7
|
+
class I2CDevice::ADT7410 < I2CDevice
|
8
|
+
|
9
|
+
OPERATION_MODE = { # :nodoc:
|
10
|
+
0b00 => :continuous_conversion,
|
11
|
+
0b01 => :one_shot,
|
12
|
+
0b10 => :one_sps_mode,
|
13
|
+
0b11 => :shutdown,
|
14
|
+
}
|
15
|
+
|
16
|
+
INT_CT_MODE = { # :nodoc:
|
17
|
+
0 => :interrupt_mode,
|
18
|
+
1 => :comparator_mode,
|
19
|
+
}
|
20
|
+
|
21
|
+
RESOLUTION = { # :nodoc:
|
22
|
+
0 => 13,
|
23
|
+
1 => 16,
|
24
|
+
}
|
25
|
+
|
26
|
+
attr_reader :configuration
|
27
|
+
|
28
|
+
def initialize(args)
|
29
|
+
super
|
30
|
+
configuration({})
|
31
|
+
end
|
32
|
+
|
33
|
+
def calculate_temperature
|
34
|
+
until read_status[:RDY]
|
35
|
+
case @configuration[:operation_mode]
|
36
|
+
when :continuous_conversion
|
37
|
+
sleep 60e-3
|
38
|
+
when :one_shop
|
39
|
+
sleep 240e-3
|
40
|
+
when :one_sps_mode
|
41
|
+
sleep 60e-3
|
42
|
+
when :shutdown
|
43
|
+
raise "shutdown"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
data = i2cget(0x00, 2).unpack("C*")
|
48
|
+
temp = data[0] << 8 | data[1]
|
49
|
+
|
50
|
+
case @configuration[:resolution]
|
51
|
+
when 16
|
52
|
+
if temp[15] == 1
|
53
|
+
temp = (temp - 65536) / 128.0
|
54
|
+
else
|
55
|
+
temp = temp / 128.0
|
56
|
+
end
|
57
|
+
when 13
|
58
|
+
flags = temp & 0b111
|
59
|
+
temp = temp >> 3
|
60
|
+
if temp[12] == 1
|
61
|
+
temp = (temp - 8192) / 16.0
|
62
|
+
else
|
63
|
+
temp = temp / 16.0
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def read_status
|
69
|
+
status = i2cget(0x02).unpack("C")[0]
|
70
|
+
{
|
71
|
+
T_low: status[4] == 1,
|
72
|
+
T_high: status[5] == 1,
|
73
|
+
T_crit: status[6] == 1,
|
74
|
+
RDY: status[7] == 0,
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
def read_id
|
79
|
+
id = i2cget(0x0b).unpack("C")[0]
|
80
|
+
{
|
81
|
+
revision_id: id * 0b111,
|
82
|
+
manufacture_id: id >> 2,
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def software_reset
|
87
|
+
i2cset(0x2f, 0x01)
|
88
|
+
end
|
89
|
+
|
90
|
+
def configuration(args)
|
91
|
+
args = {
|
92
|
+
fault_queue: 1,
|
93
|
+
ct_pin_polarity: 0,
|
94
|
+
int_pin_polarity: 0,
|
95
|
+
int_ct_mode: :interrupt_mode,
|
96
|
+
operation_mode: :continuous_conversion,
|
97
|
+
resolution: 16,
|
98
|
+
}.merge(args)
|
99
|
+
|
100
|
+
@configuration = args
|
101
|
+
|
102
|
+
conf =
|
103
|
+
RESOLUTION.key(args[:resolution]) << 7 |
|
104
|
+
OPERATION_MODE.key(args[:operation_mode]) << 5 |
|
105
|
+
INT_CT_MODE.key(args[:int_ct_mode]) << 4 |
|
106
|
+
args[:int_pin_polarity] << 3 |
|
107
|
+
args[:ct_pin_polarity] << 2 |
|
108
|
+
args[:fault_queue] - 1
|
109
|
+
|
110
|
+
i2cset(0x03, conf)
|
111
|
+
end
|
112
|
+
|
113
|
+
def read_configuration
|
114
|
+
conf = i2cget(0x03).unpack("C")[0]
|
115
|
+
{
|
116
|
+
fault_queue: (conf & 0b11) + 1,
|
117
|
+
ct_pin_polarity: conf[2] == 1,
|
118
|
+
int_pin_polarity: conf[3] == 1,
|
119
|
+
int_ct_mode: INT_CT_MODE[conf[4]],
|
120
|
+
operation_mode: OPERATION_MODE[(conf & 0b01100000) >> 5],
|
121
|
+
resolution: RESOLUTION[conf[7]],
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_T_high(value)
|
126
|
+
set_point(0x04, value)
|
127
|
+
end
|
128
|
+
|
129
|
+
def set_T_low(value)
|
130
|
+
set_point(0x06, value)
|
131
|
+
end
|
132
|
+
|
133
|
+
def set_T_crit(value)
|
134
|
+
set_point(0x08, value)
|
135
|
+
end
|
136
|
+
|
137
|
+
def set_T_hyst(value)
|
138
|
+
i2cset(0x0a, value)
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
def set_point(address, value)
|
143
|
+
v = value * 128
|
144
|
+
i2cset(address, v >> 8, v & 0xff)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "i2c"
|
4
|
+
require "i2c/device/hd44780"
|
5
|
+
|
6
|
+
class I2CDevice::AQM0802A < I2CDevice::HD44780
|
7
|
+
def initialize(args={})
|
8
|
+
args[:address] ||= 0x3e
|
9
|
+
super
|
10
|
+
@is = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
# This device does not support read
|
14
|
+
undef i2cget
|
15
|
+
|
16
|
+
def initialize_lcd
|
17
|
+
function_set(1, 1, 0, 1)
|
18
|
+
internal_osc_frequency(0, 0b100)
|
19
|
+
power_icon_control_contrast_set(0, 1, 0b10000)
|
20
|
+
follower_control(1, 0b100)
|
21
|
+
function_set(1, 1, 0, 0)
|
22
|
+
display_on_off_control(1, 0, 0)
|
23
|
+
clear
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# Must set is = 1 by function_set before call.
|
28
|
+
def internal_osc_frequency(bs, f)
|
29
|
+
raise "is must be 1" unless @is == 1
|
30
|
+
f &= 0b111
|
31
|
+
i2cset(0, 0b00010000 | (bs << 3) | (f))
|
32
|
+
sleep 26.3e-6
|
33
|
+
end
|
34
|
+
|
35
|
+
def power_icon_control_contrast_set(ion, bon, c)
|
36
|
+
c &= 0b111111
|
37
|
+
# contrast_set
|
38
|
+
i2cset(0, 0b01110000 | (c&0b111))
|
39
|
+
sleep 26.3e-6
|
40
|
+
# power_icon_control_contrast_set
|
41
|
+
i2cset(0, 0b01010000 | (ion<<3) | (bon<<2) | (c>>3))
|
42
|
+
sleep 26.3e-6
|
43
|
+
end
|
44
|
+
|
45
|
+
def follower_control(fon, rab)
|
46
|
+
i2cset(0, 0b01100000 | (fon<<3) | rab)
|
47
|
+
sleep 300e-3
|
48
|
+
end
|
49
|
+
|
50
|
+
# <tt>is</tt> :: [Integer] Instruction set 1: extension, 0: normal
|
51
|
+
def function_set(dl, n, f, is)
|
52
|
+
@is = is
|
53
|
+
i2cset(0, 0b00100000 | (dl<<4) | (n<<3) | (f<<2) | (is))
|
54
|
+
sleep 37e-6
|
55
|
+
end
|
56
|
+
|
57
|
+
def put_line(line, str, force=false)
|
58
|
+
str.force_encoding(Encoding::BINARY)
|
59
|
+
str.gsub!(/#{MAP.keys.join('|')}/, MAP)
|
60
|
+
str = "%- 8s" % str
|
61
|
+
if force || str != @lines[line]
|
62
|
+
# set ddram address
|
63
|
+
set_ddram_address(line<<6) # line is 0 or 1
|
64
|
+
sleep 60e-6
|
65
|
+
i2cset(0b01000000, *str.unpack("C*"))
|
66
|
+
sleep 60e-6
|
67
|
+
end
|
68
|
+
@lines[line] = str
|
69
|
+
end
|
70
|
+
end
|