ソロでたのしむ

DIY、電子工作、キャンプ用品などの趣味を紹介します。

ステップモーター28BYJ-48で、リバース連動オートフリップダウン式モニターを自作。Arduinoのスケッチ

スポンサーリンク

JB23ジムニー フリップダウンバックモニター 自作 1
JB23ジムニー フリップダウンバックモニター 自作 2

リバース連動で開閉する自作バックモニター、サーボモーターを使った1号機が思いのほか騒がしい為、ステップモーター(ステッピングモーター)に変更します。この2号機が、現在の最新状態です。

前回の記事↓

solocamptouring.hatenablog.com

使用するステップモーター;28BYJ-48

JB23ジムニー フリップダウンモニター自作 ステップモーターとサーボモーター

右が、ステップモーター(5V用)とドライバー

ステップモーターは、低速ほどトルクがでます。今回は低速作動で、さらに外部ギヤでも減速して使用するので、安価な28BYJ-48でも動くと考えて選択しました。

この28BYJ-48ですが、作動電圧が5Vと12Vの2種類あります。はじめは5Vのものを使用してみましたがトルクに余裕がなかったために、12Vのものを採用しました。

 外部減速用のギヤ(ドライブギヤとドリブンギヤ)は、28BYJ-48の出力軸径に合うものを市販品から見つけられず、やむなく壊れたプリンターから取り出したギヤを加工して使っています。

f:id:solocamptouring:20180405050147j:plain

 
回路図

f:id:solocamptouring:20171223183150j:plain

回路図は、Fritzingで作成しています。

右側半分の回路は、ステップモーターとドライバーです。セットで安く入手できるので、自作してはいません。

 左半分の、Arduino本体以外が、自作した部分となります。

<Reverse Signal>

車のギアをリバースに入れた時の信号で、具体的には後退灯の12Vを分岐してきています。そのままだと12Vなので、抵抗3個とダイオード1個で5Vのデジタル信号にして、ArduinoのD10につないでいます。

<Full Close SW>

ステップモーターには位置情報がないのですが、モニターの現位置がわからないと、制御できません。そのため、モニターを全閉した時に押される位置にプッシュスイッチをつけて、全閉するたびに位置情報をリセットするようにしています。スイッチの状態を5Vのデジタル信号にするために、抵抗1個を使用して、ArduinoのD8につないでいます。

<LED5>

故障時のトラブルシュートが簡単になるように、モーターへの回転指令が出ているかどうかの確認用でつけておきました。

Arduinoを使った位置と速度管理

モニターが開く(降りる)方向は、モーターのステップ数だけで位置管理しています。そのため、開いている途中でモニターの動きを強制的に止めると、中途半端に開いた状態でも全開だと誤認識して止まります。

全開検出スイッチを追加すれば回避できるのですが、そもそもモニターの自重が開き方向に働いているので開く途中でモーターが脱調することは0%に近いと考えられます。開き方向はステップ数だけで位置管理して止める事にしました。

 

モニターが閉じる方向は、徐々にゆっくり閉まるようにしています。動きに高級感を出しつつ、多少の外乱があったとしても徐々にトルクが強くなる効果でいつかは閉まることを狙っています。 

 

モニターの動きがわかる動画をアップしました。最初と2:30あたりで動かしています 。


JB23ジムニー 室内DIY

 

 スケッチ

int reversePin = 10;    // reverse signal input
int operationPin = 9;     // operation indicator led output
int motororiginPin = 8;    // motor initial position sw input
int motorPin1 = 4;    // Blue   - 28BYJ48 pin 1
int motorPin2 = 5;    // Pink   - 28BYJ48 pin 2
int motorPin3 = 6;    // Yellow - 28BYJ48 pin 3
int motorPin4 = 7;    // Orange - 28BYJ48 pin 4
int motorSpeed;  
int count = 0;          // count of steps made
int speedcontr = 0;
int countsperrev = 320; // number of steps for full open
int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
unsigned long timeZero = millis();
boolean fullOpenning =false;
boolean fullClosing =false;
void setup() {
  pinMode(reversePin,INPUT) ;  
  pinMode(operationPin,OUTPUT) ; 
  pinMode(motororiginPin,INPUT) ;
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  if (digitalRead(reversePin) == HIGH) { 
       timeZero = millis();
       fullClosing =false;    
         if(count < countsperrev ){
         digitalWrite(operationPin, HIGH);
         speedcontr = (1*count);
         motorSpeed = 900;
         clockwise();
         count++;
         } else {
         digitalWrite(operationPin, LOW);    
         digitalWrite(motorPin1,LOW);
         digitalWrite(motorPin2, LOW);
         digitalWrite(motorPin3, LOW);
         digitalWrite(motorPin4, LOW); 
         fullOpenning =true;
        }    
   } else {
     if (digitalRead(motororiginPin) == LOW) {
          if (fullOpenning == true){ 
               if (millis() - timeZero > 1000) {
               digitalWrite(operationPin,HIGH);
                 if (count > 100){
                 motorSpeed = 1000;
                 anticlockwise();
                 count--;
                 } else {
                 speedcontr = (30*count);
                 motorSpeed = (4000-speedcontr);
                 anticlockwise();
                 count--;  
                 }
               } else {
               digitalWrite(operationPin,HIGH);
               }
           } else if (fullClosing == true){
           digitalWrite(operationPin, LOW);    
           digitalWrite(motorPin1,LOW);
           digitalWrite(motorPin2, LOW);
           digitalWrite(motorPin3, LOW);
           digitalWrite(motorPin4, LOW); 
           } else {           
               if (millis() - timeZero > 1000) {
               digitalWrite(operationPin,HIGH);
                 if (count > 100){
                 motorSpeed = 1000;
                 anticlockwise();
                 count--;
                 } else {
                 speedcontr = (5*count);
                 motorSpeed = (1500-speedcontr);
                 anticlockwise();
                 count--;  
                 }
               } else {
               digitalWrite(operationPin,HIGH);
               }
           }           
      } else {
       digitalWrite(operationPin, LOW);    
       digitalWrite(motorPin1,LOW);
       digitalWrite(motorPin2, LOW);
       digitalWrite(motorPin3, LOW);
       digitalWrite(motorPin4, LOW); 
        count = 0;
        fullOpenning =false;
        fullClosing = true;
      }
    }   
 }
void anticlockwise() 
{
  for(int i = 0; i < 8; i++)
  {
    setOutput(i);
    delayMicroseconds(motorSpeed);
  }
}
void clockwise() 
{
  for(int i = 7; i >= 0; i--)
  {
    setOutput(i);
    delayMicroseconds(motorSpeed);
  }
}
void setOutput(int out)
{
  digitalWrite(motorPin1, bitRead(lookup[out], 0));
  digitalWrite(motorPin2, bitRead(lookup[out], 1));
  digitalWrite(motorPin3, bitRead(lookup[out], 2));
  digitalWrite(motorPin4, bitRead(lookup[out], 3));
}