The jonki

呼ばれて飛び出てじょじょじょじょーんき

DCモーターとポテンションメーターのスライダー機構

Maker Faireの出展に向けてスライダーの機構を模索していたのですが、なかなかうまい方法が見つからず悩んでいるとEsper Dominoで有名なじゃらし君(じゃらしTV)にsparkfunの面白いパーツを紹介してもらい、ちゃっかり借りてきました。自分でもポチったのですがスイッチサイエンスでも売ってました。

レゴが乗っかっている黒いところです。
f:id:jonki:20140802151556j:plain


これを使って遊んでみたのがこれです。内蔵されているのはDCモーターですが、任意のポジションに移動できているのがミソです。

sparkfun Slide Pot - Motorized (10k Audio Taper) - YouTube


こちらはsparkfunの紹介動画です、何個か使ってホッケーみたいなゲームを作ってますね。

SparkFun Motorized Potentiometer - YouTube


仕組みとしてはDCモーターとテープ式の細長いポテンションメーター(可変抵抗テープ)を使っているだけです。DCモーターを普通に動かしてベルトを回しているだけなのですが、真ん中の金属部分が動くことでポテンションメーターから上がってくる値が変わってくるわけです。この値をフィードバックとして利用し、モーターの正転・逆転・停止を毎フレーム決めれば良い、という仕組みです


各端子の割り当てはこちらに書いてありました。今回利用するのはDCモーターの2端子と①、②、③のポテンションメーターの部分です。①と③に電圧をかけ、②の部分でどれだけ電圧降下したかわかります。この使い方はよくある可変、半固定抵抗と同じです。


電子回路に関しては、モータードライバのTA7291Pを利用しています。回路はこちら様のサイトをベースに組みました。ただしSerial通信の際に利用する1番ピン(TX)がこれだと使われてしまっているので、1、2ピン利用しているところを、2、4ピンを利用することにしました。

スケッチ

モーターを操作するために、A1ピンで半固定抵抗の値を取れるようにしました。ここで取れる値とSlide Potのポテンションメーターからの値も0~1023ですが、扱いやすくするためどちらも0.0~1.0にマップしています。あとは半固定抵抗とSlide Potの値が近づくようにDCモーターを動かすだけです。ただしモーターの速度を上げるとピッタシ同じ値にはなりにくいので、2つの値の差がupdateDiff以内であればモーターをストップさせています。この値は良い感じに調整してバタつかない落とし所を見つけてください。

int mortor1 = 2;
int mortor2 = 4;
int mortorOut = 3;
int speed = 200;
float updateDiff = 0.04;
int lastPos = -100;

void setup(){
  pinMode(1,OUTPUT);
  pinMode(2,OUTPUT);
  
  Serial.begin(9600);  
}

void loop() {
  int input = analogRead(1);
  float pos = (map(input, 0, 1023, 0, 100)) / 100.0;
  float feedback = (map(analogRead(0), 0, 1023, 0, 100)) / 100.0;
  move(pos, feedback);
  lastPos = pos;
}

// pos: 0.0 - 1.0
void move(float pos, float feedback) {
  Serial.print(pos);
  Serial.print('-');
  Serial.println(feedback);
  if(abs(pos - feedback) < updateDiff) {
    stop(); 
  } else if(pos < feedback) {
    forward();
  } else if(pos > feedback) {
    backward();
  } 
}

void stop() {
  digitalWrite(mortor1, LOW);
  digitalWrite(mortor2, LOW); 
}

void forward() {
    digitalWrite(mortor1,HIGH);
    digitalWrite(mortor2,LOW);
    analogWrite(mortorOut,speed);
}

void backward() {
  digitalWrite(mortor1,LOW);
  digitalWrite(mortor2,HIGH);
  analogWrite(mortorOut,speed);
}
最後に

こういった機構の想定はあったのですが、なかなか自分で作るには大変なのでこういったパーツがあるのはとても助かります。もう少し長いものやギヤ比でトルク稼いだようなものも出てくると嬉しいですね。