0

node.jsとarduinoでジョグシャトルのシャトルを取得


ジョグシャトル


ジョグシャトルは昔のビデオデッキのリモコンや、パチンコのハンドル部分についている回転部品。
「ジョグシャトル」でGoogle検索するとパチンコの攻略動画がたくさんでてくる。


内側の無限回転するジョグダイヤルと、外側の左右に30〜45度くらいまで回転するシャトルで構成される。

shuttleというのはシャトルランという英語のように「左右に素早く動く」という意味がある。
シャトル部分は左右にどれだけ回転させたかを細かく取得する事ができるアナログ入力装置で、今でもUSB接続のジョグシャトルがプロ用のビデオ編集機器として売られている。



ハードオフなどでビデオデッキのリモコンを買ってきて分解すると、こういうジョグシャトル部品が得られる。
ピンが8本出ているが、そのうち3本はnode.jsとarduinoでロータリーエンコーダーで書いたロータリーエンコーダで、のこり5本のがジョグシャトルのシャトル部分になっている。


この5本のピンが現在のシャトルの回転状態を2進数で表していると思いきや、グレイコードで表している。

グレイコード


グレイコードとは (グレイコードとは) [単語記事] – ニコニコ大百科
グレイコード – Wikipedia


かならず1桁ずつピン状態が変わるコードで、まあたしかにCPU等を持たない入力センサー側に搭載しやすそうだし変なチャタリングでなそう。

wikipediaより4bitのグレイコード

0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000



回路

ロータリーエンコーダと同じく、1つのピンがコモンなのでそこに5Vを入れる(基板のパターンを読めばどれかわかる)
残り4ピンを10KΩでGNDにプルダウンしつつ、Ardunoのデジタルピン(今回は5,6,7,8ピン)に入れた。


arduinoでジョグシャトルの制御

arduino-firmata npmを使った。


内側のジョグダイヤルは、ロータリーエンコーダのclassを使えばいい。2つ同時に使えるように実装してある。

外側のシャトルは、グレイコードから10進数の数値に変換するのは面倒そうだし、そもそもハードオフで買ってきたリモコンのシャトルだからどのピンが何番ピンかわからない。
よく考えたら16通りしか無いので、ちょっとずつ回転させながら全部確かめてJogShuttle.codes配列にメモした。

JogShuttle.coffee
events = require 'eventemitter2'
ArduinoFirmata = require 'arduino-firmata'

module.exports = class JogShuffle extends events.EventEmitter2
constructor: (@arduino, @pinA, @pinB, @pinC, @pinD) ->
console.log "set jogshuffle pin : #{@pinA}, #{@pinB}, #{@pinC} and #{@pinD}"

if @arduino.isOpen()
@initPins()

@arduino.on 'connect', =>
@initPins()

@arduino.on 'digitalChange', (e) =>
@pastState = @state
@state = @getState()
if @state isnt @pastState
@emit 'shuttle', @state ## shuttleイベントを発行

initPins: ->
@arduino.pinMode @pinA, ArduinoFirmata.INPUT
@arduino.pinMode @pinB, ArduinoFirmata.INPUT
@arduino.pinMode @pinC, ArduinoFirmata.INPUT
@arduino.pinMode @pinD, ArduinoFirmata.INPUT

getState: ->
@code = [@pinA, @pinB, @pinC, @pinD].map (i) =>
if @arduino.digitalRead i then 1 else 0
.join ''
return @codes.indexOf(@code) - @codes.length/2

codes: [
"1001"
"1101"
"1111"
"1011"
"0011"
"0111"
"0101"
"0001"
"0000" # neutral
"0100"
"0110"
"0010"
"1010"
"1110"
"1100"
"1000"
]


JogShuttle classを使う。
回転させるごとに”shuttle”イベントが発行され、初期状態が0、左に回すほどに-1,-2,-3…-7と減り、右に回すほど1,2,3…7と増えていく。
path = require 'path'
ArduinoFirmata = require 'arduino-firmata'
JogShuttle = require path.resolve 'JogShuttle'

jogshuttle = new JogShuttle arduino, 5, 6, 7, 8 ## digital pin 5,6,7,8 を使う

## 回転した時のイベントを受信
jogshuttle.on 'shuttle', (state) ->
console.log state

arduino-firmata npmのon “digitalChange”イベントを使うと、ジョグシャトルみたいな謎の入力インタフェースもかんたんにnodeらしくイベント駆動で使えて便利。

0

node.jsとarduinoでロータリーエンコーダー

ロータリーエンコーダー

2相出力のふつうの秋月で200円で売ってるやつを使った


マウスのホイールなどの中にも入っているセンサーで、上のツマミの部分を回すと両端の2つのピンからon-on・on-off・off-on・off-offの4状態を送ってくる。
中央のピンに5V入れて、両端の出力ピンは10kΩの抵抗でGNDにプルダウンしてArduinoのデジタルIOピンに入れた。

以前にも使ったことある。


プログラム

nodeとarduino-firmata npmでarduinoを制御した


こういうRotaryEncoderクラスを作った。回転させると”rotate”イベントを発行してくれる。

RotaryEncoder.coffee
events = require 'eventemitter2'
ArduinoFirmata = require 'arduino-firmata'

module.exports = class RotaryEncoder extends events.EventEmitter2
constructor: (@arduino, @pinA, @pinB) ->
console.log "set rotary encoder pin : #{@pinA} and #{@pinB}"
@state = 0

if @arduino.isOpen()
@initPins()

@arduino.on 'connect', =>
@initPins()

@arduino.on 'digitalChange', (e) =>
@pastState = @state
@state = @getState()
if (@state+3+1)%3 is @pastState
@emit 'rotate', 'right'
else if (@state+3-1)%3 is @pastState
@emit 'rotate', 'left'

initPins: ->
@arduino.pinMode @pinA, ArduinoFirmata.INPUT
@arduino.pinMode @pinB, ArduinoFirmata.INPUT

getState: ->
if @arduino.digitalRead @pinA
if @arduino.digitalRead @pinB
return 2
else
return 0
else
if @arduino.digitalRead @pinB
return 1
else
return 3


使う
path = require 'path'
ArduinoFirmata = require 'arduino-firmata'
RotaryEncoder = require path.resolve 'RotaryEncoder'

arduino = new ArduinoFirmata().connect()
rotenc = new RotaryEncoder arduino, 4, 3 ## digital pin 4,3を使う

rotenc.on 'rotate', (direction) ->
console.log "#{direction}に回った"

arduino-firmata npmはデジタルIOピンの状態が変化した時に発行してくれる、on “digitalChange”イベントがあるのでこういうハードウェアも簡単にイベント駆動で扱える。

0

lodash.throttleとarduinoで5秒に1回ドアのカギを開ける

throttleは「UIイベントの過剰な発火を間引く」とか説明されるけど、Arduinoなどのデバイスを使う際に「アクチュエーターが動いてる間命令を受け付けないようにする」のにも使えるよ
という話。


参考

javascriptで発生するイベントを間引く – 終わる世界とコンテンツ
lodashとunderscoreにあるthrottle・debounceという関数について説明している。
関数をthrottoleやdebounceに渡すと、無駄な連続呼び出しを無視するようにしてくれる。
実装を見るとthrottleはdebounceのラッパーになっている。


5秒に1回

nodeで制御してるarduinoでサーボモーターを回してドアのカギ(サムターンキー)を開けてるんだけど、連続でカギ回せ命令が来たら無視したい。

今までDate.now()で最後の呼び出し時刻を保存したりしてた。

lodashのthrottleで1つ目の命令だけ通して、以降5秒間は命令を無視するにはこうする。5秒たったらまた命令を受け付ける。
door_open = (onComplete = ->) ->
arduino.servoWrite 9, 0 # 開けて
setTimeout ->
arduino.servoWrite 9, 180 # 閉める
onComplete()
, 2000

door_open_throttled = _.throttle door_open, 5000, trailing: false

on '開けろや', ->
door_open_throttled ->
console.log "開けました"

{trailing: false}というオプションをthrottleに渡さないと、スロットルが閉じた時に最後の命令も通してしまう。
つまりカギ開けろ命令がたくさん来たら2個通してしまう。
trailing: falseすると最初の1つだけ通る。


nodeでのarduino制御にはarduino-firmata npmを使ってる。

0

文字単位でgit diff

行単位ではなく文字単位でdiffを見たい。

–word-diff-regexオプションを使う

英語などの空白文字で単語が分けられる言語は、git diff –word-diffを使えばいい。

日本語なら、git diffに–word-diff-regexオプションをつければいい。

% git diff --word-diff-regex="\w+"

こうすると日本語でも化けずに比較できた。でも、たまに差分が表示されない行がでる。


毎回–word-diff-regexオプションを付けるのが面倒なので、適当なパスの通っている場所にgit-chardiffというシェルスクリプトを作って実行権限付けた。

~/bin/git-chardiff
#!/bin/sh
git diff --word-diff-regex="\w+" $@

gitは頭に「git-」と付く実行可能コマンドをサブコマンドとして使ってくれるので、これで


% git chardiff

で文字単位のdiffが見れる。


なおdocdiffを使う方法もあるけどRuby2.0だと動かなかった。


diff-highlightを使う

参考:Git の diff を美しく表示するために必要なたった 1 つの設定 #git – 詩と創作・思索のひろば (Poetry, Writing and Contemplation)

これは通常のgit diffの行単位のdiffに、文字単位の変更もハイライトするもの。
でもこっちは日本語が化ける部分がある。

homebrewでgitを入れて、contrib/diff-highlightを使う
% brew install git
% ln -s /usr/local/Cellar/git/1.9.1/share/git-core/contrib/diff-highlight/diff-highlight /usr/local/bin/diff-highlight


~/.gitconfig に追加
[color]
ui = auto
[pager]
log = diff-highlight | less
show = diff-highlight | less
diff = diff-highlight | less

ふつうに
% git diff
すると文字単位の変更がハイライトされる

0

艦これ専用ブラウザ Teitoku v0.3.1でてる

艦これをフルスクリーンでプレイできたり、スクリーンショットがキーボードショートカット一発で撮れたりするTeitoku.appの新しいバージョン(0.3.1)が出た。
command+qやcommand+wなどのブラウザ閉じちゃう系のショートカットも無効にしている専用アプリなので、ながらプレイに便利である。

艦これ専用ブラウザー Teitoku – geta6 | makebooth




Teitokuはgeta6という人が作っているアプリで、v0.2.x系からv0.3.0にかけてほぼ全て書き直されていたんだけど、99%できてる状態でなぜかあとひと押しで動かない感じだったので、俺がE5の最後のひと押し前に三重キラ付けしながらプルリクをキメたら無事0.3.0リリースされた。

ソースコードはhttps://github.com/geta6/teitokuにある。
node-webkitとcoffeeで実装されていて、なかなか読み応えのある実装で面白い。


前:橋本商会 » 艦これをフルスクリーンでやる