i2c-devices 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b3513dbcf14f87bf4c6f8c53b3b5e26a0c82f406
4
+ data.tar.gz: bf21da782f160272187c5631fa50c8f8b22d11f1
5
+ SHA512:
6
+ metadata.gz: 03e1802fbca28f590fda962582901c34dcd35755c93d7d050ca02eb7808853110eb1b7e30254edd666f9a6d69bfbe57985aab31c2c77ef10354a23d098e967f8
7
+ data.tar.gz: 5309612e7dd287a78e315566b707da4deb4e9466d3e26b699ed4e0b568e1bc481830304948e07c251c7fa3cc454a699307a0e12c5e3dbe692971fc58bee78beb
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ sketch.rb
3
+
data/ChangeLog ADDED
@@ -0,0 +1,4 @@
1
+ 2014-02-20 SATOH Hiroh <cho45@lowreal.net>
2
+
3
+ * 0.0.1: initial release
4
+
data/README.md ADDED
@@ -0,0 +1,130 @@
1
+ ruby-i2c-devices
2
+ ================
3
+
4
+ i2c-devices is a library for using [I2C]( http://www.i2c-bus.org/ ) devices.
5
+
6
+ SYNOPSYS
7
+ ========
8
+
9
+ Usage of I2CDevice class directly:
10
+
11
+ ```
12
+ require "i2c"
13
+
14
+ device = I2CDevice.new(address: 0x60, driver: I2CDevice::Driver::I2CDev.new("/dev/i2c-1"))
15
+
16
+ # like i2c-tools's i2cget command
17
+ length = 3
18
+ device.i2cget(0x01, length)
19
+
20
+ # like i2c-tools's i2cset command
21
+ device.i2cset(0x01, 0x11, 0x12 ... )
22
+
23
+ ```
24
+
25
+ or pre-defiend device driver class:
26
+
27
+ ```
28
+ require "i2c/device/acm1602ni"
29
+
30
+ lcd = ACM1602NI.new
31
+
32
+ lcd.put_line(0, "0123456789ABCDEF")
33
+ ```
34
+
35
+
36
+ with driver class
37
+
38
+ ```
39
+ require "i2c/device/mpl115a2"
40
+ require "i2c/driver/i2c-dev"
41
+
42
+ mpl = MPL115A2.new(driver: I2CDevice::Driver::I2CDev.new("/dev/i2c-0"))
43
+ p mpl.calculate_hPa
44
+ ```
45
+
46
+ or GPIO backend driver (this is very slow)
47
+
48
+ ```
49
+ require "i2c/device/mpl115a2"
50
+ require "i2c/driver/gpio"
51
+
52
+ mpl = MPL115A2.new(driver: I2CDevice::Driver::GPIO.new(
53
+ sda: 23, # pin 16 in raspberry pi
54
+ scl: 24, # pin 18 in raspberry pi
55
+ ))
56
+
57
+ p mpl.calculate_hPa
58
+
59
+ ```
60
+
61
+ Class
62
+ =====
63
+
64
+ I2CDevice
65
+ ---------
66
+
67
+ Generic class for manipulating I2C device.
68
+
69
+ ### I2CDevice.new(address: address, driver: driver)
70
+
71
+ * address : Integer : 7-bit slave address without r/w bit. MSB is always 0.
72
+ * driver : I2CDevice::Driver : backend driver class. (default: I2CDevice::Driver::I2CDev)
73
+
74
+ ### I2CDevice#i2cset(*data) #=> Integer
75
+
76
+ Write `data` to slave.
77
+
78
+ Returns `Integer` which is bytes length wrote.
79
+
80
+ ### I2CDevice#i2cget(param, length=1) #=> String
81
+
82
+ This method read data from slave with following process:
83
+
84
+ 1. Write `param` to slave
85
+ 2. re-start
86
+ 3. Read data until NACK or `length`
87
+
88
+ Returns `String`.
89
+
90
+ I2CDevice::Driver::I2CDev
91
+ -------------------------
92
+
93
+ This depends on /dev/i2c-* (i2c-dev) feature on Linux. You may load i2c-dev kernel module.
94
+
95
+ ### I2CDevice::Driver::I2CDev.new(path)
96
+
97
+ * path : String : Path to /dev/i2c-*
98
+
99
+
100
+ I2CDevice::Driver::GPIO
101
+ -----------------------
102
+
103
+ This depends on /sys/class/gpio feature on Linux and implements by bit-banging.
104
+
105
+ ### I2CDevice::Driver::I2CDev.new(sda: sda, scl: scl, speed: speed)
106
+
107
+ * sda : Integer : Pin number of SDA.
108
+ * scl : Integer : Pin number of SCL.
109
+ * speed : Integer : I2C clock speed in kHz. (default: 1)
110
+
111
+ Pin number of `sda` and `scl` is not real pin number but logical pin number.
112
+ Eg. In Raspberry Pi, specifing `sda: 23, scl: 24` means using 16 and 18 pin.
113
+
114
+ You can specify 100 kHz or 400 kHz (or more) to `speed` but speed is rate-limited by host CPU speed.
115
+ Typically, this module fall short of requirements of I2C spec (in Raspberry Pi, clock speed is about 1.3kHz).
116
+ But most slave devices support DC~100kHz clock speed.
117
+
118
+ REQUIREMENTS
119
+ ============
120
+
121
+ Currently this library depends on Linux's i2c-dev or sysfs with GPIO feature.
122
+
123
+ * I2CDevice::Driver::I2CDev /dev/i2c-0 (i2c-dev), default
124
+ * I2CDevice::Driver::GPIO /sys/class/gpio (GPIO)
125
+
126
+ TODO
127
+ ====
128
+
129
+ * More supported devices
130
+
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'pathname'
3
+
4
+ ROOT = Pathname(__FILE__).parent
5
+
6
+ load ROOT + "lib/i2c.rb"
7
+
8
+ warn "I2CDevice::VERSION = #{I2CDevice::VERSION}"
9
+
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ task :default => :spec
13
+
14
+ task :release do
15
+ sh %{gem build i2c-devices.gemspec}
16
+ sh %{gem push i2c-devices-#{I2CDevice::VERSION}.gem}
17
+ sh %{git add -u}
18
+ sh %{git commit -m '#{I2CDevice::VERSION}'}
19
+ sh %{git tag #{I2CDevice::VERSION}}
20
+ sh %{git push}
21
+ sh %{git push --tags}
22
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
3
+ require 'i2c'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'i2c-devices'
7
+ s.version = I2CDevice::VERSION
8
+ s.date = '2014-02-15'
9
+ s.summary = "i2c device drivers"
10
+ s.description = "i2c-devices is a drivers for i2c devices"
11
+ s.authors = ["cho45"]
12
+ s.email = 'cho45@lowreal.net'
13
+ s.files = `git ls-files`.split($/)
14
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+ s.homepage = 'https://github.com/cho45/ruby-i2c-devices'
17
+ s.license = 'MIT'
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency "bundler", "~> 1.5"
21
+ s.add_development_dependency "rake"
22
+ end
data/lib/i2c.rb ADDED
@@ -0,0 +1,28 @@
1
+ class I2CDevice
2
+ VERSION = "0.0.1"
3
+
4
+ class I2CException < Exception; end
5
+ class I2CIOError < I2CException; end
6
+ class I2CBUSBusy < I2CIOError; end
7
+
8
+ attr_accessor :address
9
+
10
+ def initialize(args={})
11
+ if args[:driver].nil?
12
+ require "i2c/driver/i2c-dev"
13
+ args[:driver] = I2CDevice::Driver::I2CDev.new
14
+ end
15
+
16
+ @driver = args[:driver]
17
+ @address = args[:address] or raise I2CException, "args[:address] required"
18
+ end
19
+
20
+ def i2cget(param, length=1)
21
+ @driver.i2cget(@address, param, length)
22
+ end
23
+
24
+ def i2cset(*data)
25
+ @driver.i2cset(@address, *data)
26
+ end
27
+ end
28
+
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+
3
+ require "i2c/device/hd44780"
4
+
5
+ # Note: This device only run under speed=50kHz
6
+ # http://akizukidenshi.com/catalog/g/gP-05693/
7
+ class ACM1602NI < HD44780
8
+ def initialize(args={})
9
+ args[:address] ||= 0x50
10
+ super
11
+ @lines = []
12
+ initialize_lcd
13
+ end
14
+
15
+ undef i2cget
16
+ undef read_busy_flag_and_address
17
+ end
18
+
@@ -0,0 +1,146 @@
1
+ # coding: utf-8
2
+
3
+ require "i2c"
4
+
5
+ class ADT7410 < I2CDevice
6
+ OPERATION_MODE = {
7
+ 0b00 => :continuous_conversion,
8
+ 0b01 => :one_shot,
9
+ 0b10 => :one_sps_mode,
10
+ 0b11 => :shutdown,
11
+ }
12
+
13
+ INT_CT_MODE = {
14
+ 0 => :interrupt_mode,
15
+ 1 => :comparator_mode,
16
+ }
17
+
18
+ RESOLUTION = {
19
+ 0 => 13,
20
+ 1 => 16,
21
+ }
22
+
23
+ attr_reader :configuration
24
+
25
+ def initialize(args)
26
+ super
27
+ configuration({})
28
+ end
29
+
30
+ def calculate_temperature
31
+ until read_status[:RDY]
32
+ case @configuration[:operation_mode]
33
+ when :continuous_conversion
34
+ sleep 60e-3
35
+ when :one_shop
36
+ sleep 240e-3
37
+ when :one_sps_mode
38
+ sleep 60e-3
39
+ when :shutdown
40
+ raise "shutdown"
41
+ end
42
+ end
43
+
44
+ data = i2cget(0x00, 2).unpack("C*")
45
+ temp = data[0] << 8 | data[1]
46
+
47
+ case @configuration[:resolution]
48
+ when 16
49
+ if temp[15] == 1
50
+ temp = (temp - 65536) / 128.0
51
+ else
52
+ temp = temp / 128.0
53
+ end
54
+ when 13
55
+ flags = temp & 0b111
56
+ temp = temp >> 3
57
+ if temp[12] == 1
58
+ temp = (temp - 8192) / 16.0
59
+ else
60
+ temp = temp / 16.0
61
+ end
62
+ end
63
+ end
64
+
65
+ def read_status
66
+ status = i2cget(0x02).unpack("C")[0]
67
+ {
68
+ T_low: status[4] == 1,
69
+ T_high: status[5] == 1,
70
+ T_crit: status[6] == 1,
71
+ RDY: status[7] == 0,
72
+ }
73
+ end
74
+
75
+ def read_id
76
+ id = i2cget(0x0b).unpack("C")[0]
77
+ {
78
+ revision_id: id * 0b111,
79
+ manufacture_id: id >> 2,
80
+ }
81
+ end
82
+
83
+ def software_reset
84
+ i2cset(0x2f, 0x01)
85
+ end
86
+
87
+ def configuration(args)
88
+ args = {
89
+ fault_queue: 1,
90
+ ct_pin_polarity: 0,
91
+ int_pin_polarity: 0,
92
+ int_ct_mode: :interrupt_mode,
93
+ operation_mode: :continuous_conversion,
94
+ resolution: 16,
95
+ }.merge(args)
96
+
97
+ @configuration = args
98
+
99
+ conf =
100
+ RESOLUTION.key(args[:resolution]) << 7 |
101
+ OPERATION_MODE.key(args[:operation_mode]) << 5 |
102
+ INT_CT_MODE.key(args[:int_ct_mode]) << 4 |
103
+ args[:int_pin_polarity] << 3 |
104
+ args[:ct_pin_polarity] << 2 |
105
+ args[:fault_queue] - 1
106
+
107
+ i2cset(0x03, conf)
108
+ end
109
+
110
+ def read_configuration
111
+ conf = i2cget(0x03).unpack("C")[0]
112
+ {
113
+ fault_queue: (conf & 0b11) + 1,
114
+ ct_pin_polarity: conf[2] == 1,
115
+ int_pin_polarity: conf[3] == 1,
116
+ int_ct_mode: INT_CT_MODE[conf[4]],
117
+ operation_mode: OPERATION_MODE[(conf & 0b01100000) >> 5],
118
+ resolution: RESOLUTION[conf[7]],
119
+ }
120
+ end
121
+
122
+ def set_T_high(value)
123
+ set_point(0x04, value)
124
+ end
125
+
126
+ def set_T_low(value)
127
+ set_point(0x06, value)
128
+ end
129
+
130
+ def set_T_crit(value)
131
+ set_point(0x08, value)
132
+ end
133
+
134
+ def set_T_hyst(value)
135
+ i2cset(0x0a, value)
136
+ end
137
+
138
+ private
139
+ def set_point(address, value)
140
+ v = value * 128
141
+ i2cset(address, v >> 8, v & 0xff)
142
+ end
143
+ end
144
+
145
+
146
+
@@ -0,0 +1,58 @@
1
+ # coding: utf-8
2
+
3
+ require "i2c"
4
+ require "i2c/device/hd44780"
5
+
6
+ class AQM0802A < 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 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
+ # is : 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
+ end
57
+
58
+