ruby hardware programming
今回は WEB画面ででモーターを操作できるようにします。
本工程では、TCPSocket でポートをオープンしたり、ハードウェアに繋がった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 |
bundle init
cd ~/
mkdir RadioControl; cd $_
bundle init
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails", "6.1.3" # ここのコメントアウトを外し、バージョンを指定します。(「,」を忘れずに)
bundle install --path vendor/bundle
# かなり時間がかかります
rails new
bundle exec rails new .
# 途中で Gemfile を上書きするか確認されますが、 Enter キーを押下する
# かなり時間がかかります
bundle exec rails webpacker:install
Gemfile
の最後に次の行を追加します。
gem 'pi_piper' # => PiPiper を使用するので追加
追加した gem をインストールします。
bundle install
mortorcontrol_server
タスクこのタスクは、TCP 2000番ポートで通信を待ち受けて、
クライアントから Foward
,Left
,Right
,Back
,Brake
のトークンが送られた場合に、トークンに応じてモーターを制御します。
まず、コンソールでタスクのファイルを作成します。
bundle exec rails generate task mortorcontrol_server
RadioControl/lib/tasks/mortorcontrol_server.rake
が作成されているので、以下の通り修正します。
require 'socket'
require './lib/components/ta7291p'
namespace :mortorcontrol_server do
task wake_up: :environment do
server_method
end
# モーター左
# GPIO 20 -> 正転?
# GPIO 21 -> 逆転?
# GPIO 12 -> PWM
@motor_left = Ta7291p.new(pwm_pin_id: 12, forward_pin_id: 20, back_pin_id: 21, power_value: 0.7)
# モーター右
# GPIO 5 -> 正転?
# GPIO 6 -> 逆転?
# GPIO 13 -> PWM
@motor_right = Ta7291p.new(pwm_pin_id: 13, forward_pin_id: 5, back_pin_id: 6, power_value: 0.7)
# サーバ接続 OPEN
Server = TCPServer.new(2000)
def server_method
loop do
# ソケット OPEN (クライアントからの接続待ち)
socket = Server.accept
while token = socket.gets
token.chomp!
puts "RECV: #{token}"
case token
when 'Forward'
forward()
puts_result(token, socket)
when 'Left'
left()
puts_result(token, socket)
when 'Right'
right()
puts_result(token, socket)
when 'Back'
back()
puts_result(token, socket)
when 'Breake'
breake()
puts_result(token, socket)
else
puts "Unknown token type. Recived token: #{token}"
end
end
ensure
# ソケット CLOSE
socket.close
end
end
private
def puts_result(recived_request, socket)
puts recived_request
socket.puts "OK"
end
def forward()
@motor_left.forward()
@motor_right.forward()
end
def left()
@motor_left.back()
@motor_right.forward()
end
def right()
@motor_left.forward()
@motor_right.back()
end
def back()
@motor_left.back()
@motor_right.back()
end
def breake()
@motor_left.breake()
@motor_right.breake()
end
end
RadioControl/lib/components/ta7291p.rb
ファイルを作成し、以下の通り修正します。
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()
@back_pin.off
@forward_pin.on
end
def back()
@forward_pin.off
@back_pin.on
end
def breake()
@forward_pin.off
@back_pin.off
end
end
ここまでできたら、動作確認をします。ターミナルを2つ立ち上げて、1つでは、「センサーサーバー」をもう一つでは、「rails console
」 を起動します。
rails console
でTCPサーバーにアクセスして、応答が返ってくるか確認します。
1つめ
cd ~/RadioControl
rbenv sudo bundle exec rails mortorcontrol_server:wake_up
2つめ
cd ~/RadioControl
bundle exec rails console
socket = TCPSocket.open('localhost', 2000)
socket.puts 'Forward'
socket.flush
socket.gets
socket.puts 'Left'
socket.flush
socket.gets
socket.puts 'Right'
socket.flush
socket.gets
socket.puts 'Back'
socket.flush
socket.gets
socket.puts 'Breake'
socket.flush
socket.gets
socket.close
モーターが命令通りに動いていることを確認できたら成功です。
処理を終了する場合はそれぞれCtrl + C
で終了します。
回答例はこちらRailsWebラジコンAPI回答
回答例はこちらRailsWebラジコン画面回答
回答例はこちらカメラストリーム配信