ソロでたのしむ

キャンプ、電子工作、DIY、乗り物などの趣味を紹介

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

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

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

 

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

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

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

ステップモーターは、低速ほどトルクがでます。

今回は低速作動で、さらに外部ギヤでも減速して使用するので、安価な28BYJ-48でも動くと考えて選択しました。

この28BYJ-48ですが、作動電圧が5Vと12Vの2種類あります。

はじめは5Vのものを使用してみましたがトルクに余裕がなかったために、12Vのものを採用しました。

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


オートフリップダウンモニターのギヤ部

 
回路図

 

ステップモーター28BYJ-48回路図回路図は、Fritzingで作成しています。

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

 左半分のArduino本体以外が、自作した回路です。

それでは、回路図の詳細について補足説明させていただきます!

Reverse Signal

車のギアをリバースに入れた時の信号で、具体的には後退灯の12Vを分岐してきています。

そのままだと12Vなので、抵抗3個とダイオード1個で5Vのデジタル信号にして、ArduinoのD10につないでいます。

Full Close SW

ステップモーターには位置情報がないのですが、モニターの現位置がわからないと、制御できません。

そのため、モニターを全閉した時に押される位置にプッシュスイッチをつけて、全閉するたびに位置情報をリセットするようにしています。

スイッチの状態を5Vのデジタル信号にするために、抵抗1個を使用して、ArduinoのD8につないでいます。

LED5

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

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

モニターが開く(降りる)方向は、モーターのステップ数だけで位置管理しています。

そのため、開いている途中でモニターの動きを強制的に止めると、中途半端に開いた状態でも全開だと誤認識して止まります。

全開検出スイッチを追加すれば回避できるのですが、そもそもモニターの自重が開き方向に働いているので、開く途中でモーターが脱調する確率は、0%に近いと考えられます。

開き方向はステップ数だけで位置管理して止める事にしました。

 

モニターが閉じる方向は、徐々にゆっくり閉まるようにしています。

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

 

モニターの動きがわかる動画をアップしました!

 


Arduino project #2 「リバースギヤ連動 オートフリップダウン バックモニター」Auto flip down rear view monitor

 スケッチ

最後に、ご参考でスケッチを紹介しておきます。

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));
}