i2c-devices 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+