pi_piper の example に入っていた MCP3008 向けのデータロードアプリを、読み書きのタイミングを秋月電子で購入した時についてきたデータシートを元に調整して、12bitの精度に修正したもの。
Raspberry Pi の PIN と MCP3208 の接続は下記のように接続してます。
(http://d.hatena.ne.jp/seinzumtode/20130918/1379501130 を参照しながら結線しました)
PI | MCP3208 |
---|---|
P1-01(3.3v) | Vdd,Vref |
GPIO 8 | CS/SHDN |
GPIO 9 | D_OUT |
GPIO10 | D_IN |
GPIO11 | CLK |
GND | Agnd,Dgnd |
測定したい CH を adc_chs[] に設定しておくと一度の計測で順次読み出しします。
基準電圧 3.3V として測定範囲を 0v 〜 3300mv と仮定して mvolts に MCP3208 のピン入力の電圧値を、rvolts に 100kΩ : 4.7kΩx2 で分圧したときの推定入力値を表示してますのでこのへんは自分の回路に合わせて変更してください。
実行部分を細工してあるので、このまま他のスクリプトから require なり load して関数部分だけ使えます。
ad_read_test.rb
# -*- coding: utf-8 -*-
# port of the Adafruit MCP3008 interface code found @ http://learn.adafruit.com/send-raspberry-pi-data-to-cosm/python-script
#
# adjast timing and resolution for MCP3208 (12bit)
#
require 'pi_piper'
def read_adc(adc_pin, clockpin, adc_in, adc_out, cspin)
cspin.on
clockpin.off
adc_in.off
# clockpin が low の状態で cspin を立ち下げると SPI モード 0,0
cspin.off
command_out = adc_pin
command_out |= 0x18
command_out <<= 3
(0..4).each do
adc_in.update_value((command_out & 0x80) > 0)
command_out <<= 1
clockpin.on
clockpin.off
end
result = 0
# 2clock skip (1clock gap(sampling end) + null bit)
(0..1).each do
clockpin.on
clockpin.off
end
# load data
(0..11).each do
clockpin.on
clockpin.off
result <<= 1
adc_out.read
if adc_out.on?
result |= 0x1
end
end
cspin.on
result >> 1
end
# ---
# main when boot this script
# +++
if __FILE__ == $0
clock = PiPiper::Pin.new :pin => 11, :direction => :out
adc_out = PiPiper::Pin.new :pin => 9
adc_in = PiPiper::Pin.new :pin => 10, :direction => :out
cs = PiPiper::Pin.new :pin => 8, :direction => :out
# watch channels from 0 to 7(MCP3208) or 3(MCP3204)
adc_chs = [0, 1, 2]
# 12bit
RESOLUTION = 4096
loop do
adc_chs.each do |adc_pin|
value = read_adc(adc_pin, clock, adc_in, adc_out, cs)
invert = RESOLUTION - 1 - value
mvolts = value * (3300.0 / RESOLUTION.to_f)
rbolts = value * 3.3 * 109.4 / 9.4 / RESOLUTION.to_f
puts "#{Time.now.to_s}, CH:#{adc_pin}, Value = #{value}, invert = #{invert}, mvolts = #{mvolts.round(3)}, rvolts = #{rbolts.round(3)}"
end
sleep 1
end
end
ToDoとしては
・データシートなどなどから測定範囲を正確にする事
・計測間隔が sleep(sec) なのでどんどんずれていく事