直動機構を使ってキーボードスライダーを電動化してみた!

10月 13, 2022

電子工作をしていると真っ直ぐに物を動かしたくなるときがあります.
便利な駆動力源にはモーターがありますが, 回転させるので真っ直ぐ動かすイメージからは遠いです.
そうしたとき, 回転方向の力を直線方向に変える直動機構として, ボールねじを使ったものがあります.

ねじ切りされた金属棒であるボールねじを回転させ, その棒の方向に沿って, スクリューナットを備えたブロックが直線的にスライドします.
今回はその直動機構を使って試しにキーボードスライダーを電動化してみました!

準備したもの

キーボードスライダー関連

リードスクリュー 直径8mm 長さ350mm ピッチ14mm

銅ナット ピッチ14mm

モーター部品関連

DDT M0601C_111 ダイレクトドライブモーター 18V/0.96Nm/115rpm

3Dプリンター関連

3Dプリント部品

セットアップ

ハードウェア

組み立て

3Dプリントしたものやモーターをキーボードスライダーに取り付けます.

マイクロスイッチをスライダーの両端につけて, これ以上モーターを回したくない領域の手前でスイッチを押すようにします. マイクロスイッチはスイッチ部分とスライディングブロックが接触するよう内向きに固定します. スイッチはリレーと連動させて, 電源を落とすように設定し, モーターを止めるようにします.

配線

下記のように配線していきます.

Jetson Nano

  • pin1 <—> モータに近いマイクロスイッチ NOピン
  • pin2 <—> リレー DC+
  • pin6 <—> リレー DC-
  • pin7 <—> モータから遠いマイクロスイッチ COMピン
  • pin9 <—> モータから遠いマイクロスイッチ NCピン
  • pin12 <—> リレー IN
  • pin14 <—> モータに近いマイクロスイッチ NCピン
  • pin17 <—> モータから遠いマイクロスイッチ NOピン
  • pin19 <—> モータに近いマイクロスイッチ COMピン

リレー

  • リレー COMピン <—> AC Adapter 18V +
  • リレー NOピン <—> モータ Power Cable VCC

Direct Drive Tech社製のモーター

  • Power Cable GND <—> AC Adapter 18V –
  • Signal Cable A <—> USB-RS485 Serial Converter D+
  • Signal Cable B <—> USB-RS485 Serial Converter D-
Jetson Nanoのピン配置
Direct Drive Tech社製の信号線

ソフトウェア

Jetson.GPIO

マイコンのGPIOを制御するライブラリをインストールします. 今回はJetson向けのものインストールしていますが, 別のボードを使用するのであれば, 別のボード向けのライブラリでも問題ありません.

# install Jetson.GPIO
pip install Jetson.GPIO

Jetson GPIOライブラリを使用するために, 下記のコマンドで正しくユーザーパーミッションを設定します.

# set user permissions/groups
sudo groupadd -f -r gpio
sudo usermod -a -G gpio YOUR_USER_NAME
sudo cp PATH_TO_PYTHON/site-packages/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger

Numpy

モーターの通信情報をリストする際に使用するのでインストールしておきます.

# install numpy
pip install numpy

Auto Slider

キーボードスライダーを駆動させるモーターを制御するライブラリです. モーターの制御が効かなくなったときの対策で, キーボードスライダーの位置が行き過ぎた所まで行くと, マイクロスイッチが押され, そのトリガー信号を使ってモーターの電源供給を遮断するリレーを備えていています.

# get source of alexa like whisper
git clone https://github.com/tech-life-hacking/AutoSlider.git

接続ポートの名前と権限付与

ソフトウェア内で接続ポートを指定するため, /dev/serial/by-id/下に生成されるデバイスファイル名を調べておきます.
USB-RS485変換アダプタをPCやRaspberryPiに挿し, 下記コマンドを実行します.
下記の場合はPORTNAMEです.

# confirm port name
ls -lrt /dev/serial/by-id/

output: PORTNAME -> ../../ttyUSB0

USB-RS485変換アダプタに権限を付与します.

# permit serial port 
sudo chmod 666 /dev/serial/by-id/PORTNAME

上記コマンドを毎回打つのが面倒な場合, 権限を自動付与する設定を行います.

sudo nano /lib/udev/rules.d/50-udev-default.rules

- KERNEL=="tty[A-Z]*[0-9]|ttymxc[0-9]*|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
+ KERNEL=="tty[A-Z]*[0-9]|ttymxc[0-9]*|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout", MODE="0666"

使い方

まず下記について各種設定していきます.

  1. モーターの接続ポート名
  2. マイクロスイッチのCOMピンに対応するJetson上のGPIOピン
  3. リレーのCOMピンに対応するJetson上のGPIOピン
  1. Direct Drive Tech社製のモーターはそのドライバを備えており, マイコンと繋げばシリアル通信でモーター駆動できるようになっています. なのでシリアル通信用のポート名を設定する必要があり, 下記のYOUR_MOTOR_PORTNAMEを取得した接続ポートの名前に置き換えます.
  2. マイクロスイッチが押されているかどうかはそのCOMピンの電圧値に表れます. そのCOMピンの電圧変化をJetsonのGPIOピンで読み取ります. その際に使用するGPIOピンを設定します. このとき, モータに近いマイクロスイッチのCOMピンに対応するGPIOはMICROSWITCH_PIN_CLOSE_TO_MOTOR, モータから遠いマイクロスイッチのCOMピンに対応するGPIOはMICROSWITCH_PIN_FAR_FROM_MOTORに設定します.
  3. リレーを使って, モータに供給している18VのDC電圧をON/OFF切り替えさせます. この際リレーのCOMピンを電圧変化させれば, ON/OFFのスイッチングができるので, JetsonのGPIOピンで電圧を加えます. その際に使用するGPIOピンを設定します.

パラメータが設定できれば, それを用いてAutoSliderクラスを使用していきます.
まずAutoSliderクラスのinitialize機能でキーボードスライダーの最初の位置決めをしています.
モーターがある方向にキーボードスライダーをマイクロスイッチに当たるまで動かして, いつも決まった位置取りができるようにします.

後はリアルタイムにイベントを受け取って, キーボードスライダーを引き出したいときはeventに"pull", 押し込みたいときは"push"を代入すれば, 意図通りに制御できます.

import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), 'AutoSlider'))

import autoslider

if __name__ == '__main__':
    # slider initialize
    PORTNAME = "/dev/serial/by-id/YOUR_MOTOR_PORTNAME"
    MICROSWITCH_PIN_CLOSE_TO_MOTOR = 19
    MICROSWITCH_PIN_FAR_FROM_MOTOR = 7
    RELAY_PIN = 12

    sld = autoslider.AutoSlider(PORTNAME, MICROSWITCH_PIN_CLOSE_TO_MOTOR, MICROSWITCH_PIN_FAR_FROM_MOTOR, RELAY_PIN)

    counter = 0
    while True:
        counter += 1
        if counter % 100 == 0:
            event = "pull"
        elif counter % 50 == 0:
            event = "push"
        else:
            event = "no_event"
        sld.run(event)

おわりに

今回はリレー付きの電動スライダーを紹介しました. キーボード以外にも直線運動するものであれば応用できるので, ぜひ使ってみてください!