ruby hardware programming
| メーカー | 秋月 通販コード | 型番 | 商品名 | 個数 | 
|---|---|---|---|---|
| Anker | - | A1263011-9 | Anker PowerCore 10000 (モバイルバッテリー 10000mAh) | 1 | 
| 協和ハーモネット | P-02220 | TCW 0.6mm 10m | スズメッキ線(0.6mm 10m) | 1 | 
| シャープ | I-02551 | GP2Y0A21YK | シャープ測距モジュール | 1 | 
| Microchip Technology Inc. | I-09485 | MCP3008-I/P | 10bit 8ch ADコンバータ | 1 | 
| 東芝 | I-02001 | TA7291P | モータードライバ | 2 | 
| TAMIYA | - | ITEM 70168 | ダブルギヤボックス | 1 | 
| TAMIYA | - | ITEM 70098 | ユニバーサルプレート | 1 | 
| TAMIYA | - | ITEM 70229 | 32mm径スプロケット&クローラーセット | 1 | 
 

source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'pi_piper'
bundle install --path vendor/bundle を実行します。
モータードライバー(TA7291P) を制御するコードです。
require 'pi_piper'
class Ta7291p
  attr_reader :forward_pin, :back_pin
  def initialize(pwm_pin_id, forward_pin_id, back_pin_id, power_value = 0.5)
    @pwm_pin = pwm = PiPiper::Pwm.new pin: pwm_pin_id
    @forward_pin = PiPiper::Pin.new pin: forward_pin_id, direction: :out
    @back_pin = PiPiper::Pin.new pin: back_pin_id, direction: :out
    @power = power_value
    @pwm_pin.value = power_value
  end
  def power=(value)
    @power = value
    @pwm_pin.value = value
  end
  def power
    @power
  end
  def forward(drive_time)
    @forward_pin.on
    sleep drive_time
    @forward_pin.off
  end
  def back(drive_time)
    @back_pin.on
    sleep drive_time
    @back_pin.off
  end
  def breake
    @forward_pin.on
    @back_pin.on
  end
end
アナログ・デジタル変換チップ(MCP3008) を制御するコードです。
require 'pi_piper'
class Mcp3008
  attr_reader :channel
  def initialize(channel)
    @channel = channel
  end
  def read
    PiPiper::Spi.begin do |spi|
      adc = spi.write [0x1, (0x8 + @channel) << 4, 0x0]
      ((adc[1] & 0x3) << 8) + adc[2]
    end
  end
end
距離センサー(GP2Y0A21YK0F) から MCP3008 経由で取得した電圧から距離に変換するコードです。
class Gp2y0a21yk0f
  def self.volt_to_distance(volt)
    return 0 if volt == 0
    dist = (6787 / (volt - 3)) - 4
    dist.round(4)
  end
end
動作確認用のコードです。
require './ta7291p'
require './mcp3008'
require './gp2y0a21yk0f'
# モーター1
# GPIO 20 -> 正転?
# GPIO 21 -> 逆転?
# GPIO 12 -> PWM
@motor_1 = Ta7291p.new(12, 20, 21, 0.7)
# モーター2
# GPIO 5 -> 正転?
# GPIO 6 -> 逆転?
# GPIO 13 -> PWM
@motor_2 = Ta7291p.new(13, 5, 6, 0.7)
# ADコンバーター
mcp3008 = Mcp3008.new(0)
def kick_combo_motor
  [@motor_1, @motor_2].map do |motor|
    Thread.new { yield(motor) }
  end.each { |t| t.join }
end
loop do
  # モーターを交互に動かす
  @motor_1.forward(2)
  @motor_2.forward(2)
  sleep 2
  # モーターを左右同時に動かす
  kick_combo_motor { |motor| motor.forward(2) }
  # センサーの値を取得する
  puts Gp2y0a21yk0f.volt_to_distance(mcp3008.read)
  sleep 2
end
これで、モーターが交互に動いた後に、左右のモーターが同時に動きます。 最後に、距離センサーの値をコンソールに表示します。
rbenv sudo bundle exec ruby crawler_test.rb
回答例はこちら