ruby hardware programming
今回は 赤外線でモーターを操作できるようにします。
WEBラジコン作成 のモーター制御サーバー作成 を終えている必要があります。
事前に赤外線リモコン学習を確認し、 赤外線リモコン学習を理解しておく必要があります。
| メーカー | 秋月 通販コード | 型番 | 商品名 | 個数 | 備考 |
|–|–|–|–|–:|–|
| Anker | - | A1263011-9 | Anker PowerCore 10000 (モバイルバッテリー 10000mAh) | 1 | |
| 協和ハーモネット | P-02220 | TCW 0.6mm 10m | スズメッキ線(0.6mm 10m) | 1 | |
| 東芝 | I-02001 | TA7291P | モータードライバ | 2 | |
| TAMIYA | - | ITEM 70168 | ダブルギヤボックス | 1 | |
| TAMIYA | - | ITEM 70098 | ユニバーサルプレート | 1 | |
| TAMIYA | - | ITEM 70229 | 32mm径スプロケット&クローラーセット | 1 | |
| logicool | - | C270N HD WEBCAM | ロジクールWebカメラ| 1 | |
| シャープ | I-06487 | GP1UXC41QS | 赤外線リモコン受信モジュール | 1 | |
| ルビコン | P-03120 | 35PK47MEFC5X11 | 電解コンデンサ 47μF | 1 | 赤外線受信モジュール用 |
| FAITHFUL LINK INDUSTRIAL CORP. | R-07964 | CFS100J47RB | カーボン抵抗 47Ω | 1 | 赤外線受信モジュール用
1Wが良いですが、
一時的にであれば1/2Wや1/4Wで代用 |
赤外線受信モジュールのパーツは、https://jumbleat.com/fritzing_custom/ で公開されているパーツを利用させていただきました。
bundle init
cd ~/
mkdir IRMortorControl; cd $_
bundle init
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'pi_piper'
bundle install --path vendor/bundle
ir_mortor_control.rb
を作成し以下メソッドを追加します。
時間差を記録する仕組みのため、毎回同じ学習値の内容となりません。 差分の許容量と一致率を定義し、一致率が80%以上のものを同一とします。
# 受信時比較の許容一致率
EQUALS_PERSENT = 80
# 時間差比較時に許容する時間差
EQUALS_DIFF = 400
# 末尾比較対象外要素数
END_CUT_COUNT = 20
def equlsTimings(array1, array2)
if array1.nil? || array2.nil?
return false
end
if array1.size == 0 || array2.size == 0
return false
end
max = array1.size - END_CUT_COUNT
result = []
array1.each_with_index do |value,index|
break if index == max
break if index >= array2.size
diff = value - array2[index]
diff = diff.abs
if(diff < EQUALS_DIFF)
result.push(true)
else
result.push(false)
end
end
persent = result.count(true) * 100 / result.size.to_f
puts persent
return persent > EQUALS_PERSENT
end
def send_request(function_name)
puts("send request mortor:" + function_name)
socket = TCPSocket.open('localhost', 2000)
socket.puts function_name
socket.flush
response = socket.gets
response if response.present?
rescue
nil
ensure
socket.close if socket
end
# 例 リモコンの学習した時間差をそれぞれの定数値に修正して使用する
# 前進
FORWARD_TIMINGS = []
# 左
LEFT_TIMINGS = []
# 右
RIGHT_TIMINGS = []
# バック
BACK_TIMINGS = []
# ブレーキ
BREAKE_TIMINGS = []
def convert_ir_to_mortor_order(captureTimings)
mortor_order = ""
if equlsTimings(FORWARD_TIMINGS, captureTimings)
mortor_order = "Forward"
elsif equlsTimings(LEFT_TIMINGS, captureTimings)
mortor_order = "Left"
elsif equlsTimings(RIGHT_TIMINGS, captureTimings)
mortor_order = "Right"
elsif equlsTimings(BACK_TIMINGS, captureTimings)
mortor_order = "Back"
elsif equlsTimings(BREAKE_TIMINGS, captureTimings)
mortor_order = "Breake"
end
return mortor_order
end
def watch_ir()
end
def read_ir(ir_receiver, signal)
return captureTimings
end
#
# 赤外線リモコンによるモーター操作
#
require 'pi_piper'
include PiPiper
# =====IR 設定======
# 受信時の記録タイムアウト時間(秒)
RECORDING_TIMEOUT = 1
# 受信時比較の許容一致率
EQUALS_PERSENT = 80
# 時間差比較時に許容する時間差
EQUALS_DIFF = 400
# 末尾比較対象外要素数
END_CUT_COUNT = 20
# ===リモコンとモーター制御の設定===
# 例 リモコンの学習した時間差をそれぞれの定数値に修正して使用する
# 前進
FORWARD_TIMINGS = []
# 左
LEFT_TIMINGS = []
# 右
RIGHT_TIMINGS = []
# バック
BACK_TIMINGS = []
# ブレーキ
BREAKE_TIMINGS = []
def watch_ir()
end
def read_ir(ir_receiver, signal)
return captureTimings
end
def equlsTimings(array1, array2)
if array1.nil? || array2.nil?
return false
end
if array1.size == 0 || array2.size == 0
return false
end
max = array1.size - END_CUT_COUNT
result = []
array1.each_with_index do |value,index|
break if index == max
break if index >= array2.size
diff = value - array2[index]
diff = diff.abs
if(diff < EQUALS_DIFF)
result.push(true)
else
result.push(false)
end
end
persent = result.count(true) * 100 / result.size.to_f
puts persent
return persent > EQUALS_PERSENT
end
def convert_ir_to_mortor_order(captureTimings)
mortor_order = ""
if equlsTimings(FORWARD_TIMINGS, captureTimings)
mortor_order = "Forward"
elsif equlsTimings(LEFT_TIMINGS, captureTimings)
mortor_order = "Left"
elsif equlsTimings(RIGHT_TIMINGS, captureTimings)
mortor_order = "Right"
elsif equlsTimings(BACK_TIMINGS, captureTimings)
mortor_order = "Back"
elsif equlsTimings(BREAKE_TIMINGS, captureTimings)
mortor_order = "Breake"
end
return mortor_order
end
def send_request(function_name)
puts("send request mortor:" + function_name)
socket = TCPSocket.open('localhost', 2000)
socket.puts function_name
socket.flush
response = socket.gets
response if response.present?
rescue
nil
ensure
socket.close if socket
end
watch_ir()
赤外線リモコン学習の資料を参考に赤外線の読み取りメソッドと赤外線監視メソッドの中身を実装しましょう。
回答例はこちら赤外線リモコン学習