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,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
|