Skip to content

Instantly share code, notes, and snippets.

@hotchpotch

hotchpotch/file0.txt

Last active Aug 29, 2015
Embed
What would you like to do?
A/D コンバータの MCP3002, MCP3208 を raspberry pi 上の Ruby から扱う ref: http://qiita.com/hotchpotch/items/5c47ae210a7a8e9fd6d1
require 'spi_mcp'
mcp = MCP3208.new
val = mcp.channel(0)
puts val # 0 ~ 4095
$ watch -n 1 sudo ruby spi_mcp.rb MCP3208
# spi_mcp.rb
require 'pi_piper'
class SpiMCP
attr_reader :bit_resolution
attr_reader :channels
def initialize(options = {})
@bit_resolution = options[:bit_resolution] or ArgumentError.new("require :bit_resolution")
@channels = options[:channels] or ArgumentError.new("require :channels")
end
def channel(ch)
raise ArgumentError.new("channel #{ch} is not support.") unless channels.include?(ch)
result = 0
PiPiper::Spi.begin do |spi|
result = convert spi.write(*write_data(ch))
end
result
end
def convert(raw_data)
((raw_data[-2] << 8) + raw_data[-1]) & (2**bit_resolution - 1)
end
end
class MCP3002 < SpiMCP
def initialize
super bit_resolution: 10, channels: 0..1
end
def write_data(ch)
[
0b01101000 | (ch<<4),
0b00000000
]
end
end
class MCP3208 < SpiMCP
def initialize
super bit_resolution: 12, channels: 0..7
end
def write_data(ch)
control_bit = channel_control_bit(ch)
[
0b00000100 | (control_bit>>2), # 0b000001#{SINGLE/DIFF}#{D2}
(control_bit & 0b11) << 6, # 0b#{D1}#{D0}000000 (D1, D0)
0b00000000
]
end
# return 4-bit (SINGLE/DIFF, D2, D1, D0)
def channel_control_bit(ch)
(0b1000 | ch) & 0b1111
end
end
if __FILE__ == $0
begin
mcp_class = Object.const_get(ARGV[0])
rescue NameError => e
abort "usage: $ ruby #{__FILE__} MCP3208"
end
mcp = mcp_class.new
mcp.channels.each do |ch|
puts "ch #{ch}: #{mcp.channel(ch)}"
end
end
git clone https://github.com/jwhitehorn/pi_piper.git
cd pi_piper
gem install bundler rake
bundle install
rake gem
sudo gem install pkg/pi_piper-2.0.beta.4.gem
# spi_mcp.rb
require 'pi_piper'
class SpiMCP
attr_reader :bit_resolution
attr_reader :channels
def initialize(options = {})
@bit_resolution = options[:bit_resolution] or ArgumentError.new("require :bit_resolution")
@channels = options[:channels] or ArgumentError.new("require :channels")
end
def channel(ch)
raise ArgumentError.new("channel #{ch} is not support.") unless channels.include?(ch)
result = 0
PiPiper::Spi.begin do |spi|
result = convert spi.write(*write_data(ch))
end
result
end
def convert(raw_data)
((raw_data[-2] << 8) + raw_data[-1]) & (2**bit_resolution - 1)
end
end
class MCP3002 < SpiMCP
def initialize
super bit_resolution: 10, channels: 0..1
end
def write_data(ch)
[
0b01101000 | (ch<<4),
0b00000000
]
end
end
class MCP3208 < SpiMCP
def initialize
super bit_resolution: 12, channels: 0..7
end
def write_data(ch)
control_bit = channel_control_bit(ch)
[
0b00000100 | (control_bit>>2), # 0b000001#{SINGLE/DIFF}#{D2}
(control_bit & 0b11) << 6, # 0b#{D1}#{D0}000000 (D1, D0)
0b00000000
]
end
# return 4-bit (SINGLE/DIFF, D2, D1, D0)
def channel_control_bit(ch)
(0b1000 | ch) & 0b1111
end
end
if __FILE__ == $0
begin
mcp_class = Object.const_get(ARGV[0])
rescue NameError => e
abort "usage: $ ruby #{__FILE__} MCP3208"
end
mcp = mcp_class.new
mcp.channels.each do |ch|
puts "ch #{ch}: #{mcp.channel(ch)}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment