押釦プッシャー試作版 2020/09/13~09/19

・2020/09/19 アクリルタイプの画像を追加
・2020/09/16 Cut2D のスクリーンショットを追加
・2020/09/15 Arduino コードを追加

既設制御盤の押釦スイッチを押す装置の試作版です。
単体で、信号入力で一定時間後に押釦を押す動作になります。
消火ポンプの遠隔起動押釦のテスト時にポンプ運転後数秒で停止させるとか、一時的な使用を想定しています。
ベースの取付は磁石です。鉄板以外は使用できません。

DC5V で動作可能です。通常は 500mA 以内ですが、最大 2A 以上流れる可能性があり、モバイルバッテリーでは、使わないほうが良さそうです。

購入品はサーボモーターと磁石のみ(いずれもアマゾンで購入)。本体、ギヤ部は 3D プリンタで作成しています。
φ30 の押釦スイッチを 60mm ピッチで配置した場合を想定して、ベース取付位置から最大 80mm 先のスイッチを押せるようになっています。
試した感じでは、φ20mm の磁石を縦に 2 個以上必要で、4 個が安心ですが強すぎて制御盤から外しずらいです。


動画 (MP4) はこちら

アクリル(t5)タイプ↓
マグネットベース(200N)に変更。見た目は良くなりましたが、200N では磁力不足でした。400N は必要っぽい。
ラックピニオンギヤの MC ナイロン化は、挫折・・・。樹脂用のエンドミルが必要なようです。


3D プリンタ用データ (STL) は、Bricscad で作成。


CNC 用データ(GCODE)は、Cut2D で作成しました。


コントロールは、Arduino nano を使っています。コントロールボックスのケース、基板は未作成。
以下の機能を実装予定。
 ・テストモード : 「押す-戻す」動作を繰り返す。動かしながらストローク調整可能。
 ・オートモード : 外部信号の入力により、1 回だけ「押す-戻す」動作を行う。遅延時間を設定可能。


/* ServoSweep.ino for Arduino nano
 * 2020/09/15 
 * URL: http://www.izawa-web.com/
 * e-mail: f.izawa@dream.com
 * +5V は Aruduino nano USB からの供給では不安定になるため、別電源が必要
 */

#include <Servo.h>
Servo myservo;

const int degLim = 170; //回転角度のリミット値
int degMin = 15;        // 回転角度の最小値
int degMax = degLim;    // 回転角度の最大値
int pos = degMin;       // サーボ位置

const int ain1Pin = 0; // 回転角度 VR 入力
const int ain2Pin = 1; // 待機時間 VR 入力

const int sw1Pin = 2;  // AUTO Mode SW
const int sw2Pin = 3;  // TEST Mode SW
const int led1Pin = 6; // AUTO Mode LED
const int led2Pin = 7; // TEST Mode LED
const int in1Pin = 8;  // RUN Mode INPUT 外部信号入力
const int led3Pin = 9; // RUN LED 点滅=実行待機中、点灯=実行中
const int servoPin = 10; // Servo

// スイッチ入力の前回値を保持
int sw1Old = 0;
int sw2Old = 0;
int in1Old = 0;

// 保持フラグ
int led1Flag = 0; // AUTO Mode
int led2Flag = 0; // TEST Mode
int in1Flag = 0;  // RUN 
int forwardFlag = 1; // 前進中

unsigned long ticks1, ticks2; // 経過 msec
int onceFlag = 0;

void pushOnce() {
  for (pos = degMin; pos <= degMax; pos++){
    myservo.write(pos);
    delay(10); 
  }
  delay(1000);
  for (pos = degMax; pos >= degMin; pos--){
    myservo.write(pos);
    delay(5); 
  }
}

void setup() {
  myservo.attach(servoPin);
  //Serial.begin( 9600 );
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
  pinMode(sw1Pin, INPUT_PULLUP); 
  pinMode(sw2Pin, INPUT_PULLUP); 
  pinMode(in1Pin, INPUT_PULLUP); 
  myservo.write(degMin);
}

void loop() {
  // 前進(突き出し)の最大位置
  int i = analogRead( ain1Pin );// 0~1023
  degMax = int(degLim * float(i) / 1023.0);
  if (degMax < degMin) degMax = degMin; 
  //Serial.println( degMax );

  // ------------------------
  // スイッチ入力(モード切替)  
  // ------------------------
  int val;
  // AUTO モード
  if (!led2Flag){ // TEST モードでない
    val = digitalRead(sw1Pin);
    if (!led1Flag && sw1Old && !val){
      in1Flag = 0;  // AUTO モード初期化
      led1Flag = 1;
      digitalWrite(led1Pin, 1); // LED1 点灯 = AUTO モード開始
      myservo.write(degMin);  
    }
    else if (led1Flag && sw1Old && !val){
      led1Flag = 0;
      digitalWrite(led1Pin, 0); // LED1 消灯 = AUTO モード終了
      myservo.write(degMin);    
    }
    sw1Old = val;
  }
  // TEST モード
  if (!led1Flag){ // AUTO モードでない
    val = digitalRead(sw2Pin);
    if (!led2Flag && sw2Old && !val){
      led2Flag = 1;
      digitalWrite(led2Pin, 1); // LED2 点灯 = TEST モード開始
      pos = degMin;
      myservo.write(degMin);    
    }
    else if (led2Flag && sw2Old && !val){
      led2Flag = 0;
      digitalWrite(led2Pin, 0); // LED2 消灯 = TEST モード終了
      myservo.write(degMin);      
    }
    sw2Old = val;
  }
  // ------------------------
  // サーボ動作
  // ------------------------ 
  // TEST モード(突き出し位置調整用)
  // 前進、後退を繰り返す
  if (led2Flag){
    if (forwardFlag){ // 前進
      pos++;
      myservo.write(pos);
      if (pos >= degMax){
        pos = degMax;
        forwardFlag = 0;
        delay(1000);
      }
      else{
        delay(5);
      }
    }
    else{ // 後退
      pos--;
      myservo.write(pos);
      if (pos <= degMin){
        pos = degMin;
        forwardFlag = 1;
        delay(1000);
      }
    }
  }
  
  // AUTO モード
  // 外部入力により、1 回往復
  if (led1Flag){
    val = digitalRead(in1Pin);
    if (!in1Flag && !in1Old && !val){
      // 一度だけ前進、後退
      in1Flag = 1;
      digitalWrite(led3Pin, 1); // 稼働中 点灯
      ticks1 = millis();
      ticks2 = millis();
      onceFlag = 1;
    }
    else if (in1Flag && val){
      in1Flag = 0;
    }
    in1Old = val;
  }
  else{
    if (digitalRead(led3Pin)) digitalWrite(led3Pin, 0); // 稼働中 消灯
  }
  // AUTO モードで外部信号入力
  if (led1Flag && onceFlag){
    // 待機中
    if (millis() - ticks2 >= 100){ // LED 点滅
      ticks2 = millis();
      digitalWrite(led3Pin, !digitalRead(led3Pin)); // 待機中 点滅
    }
    // 外部信号入力後待機
    if (millis() - ticks1 >= analogRead(ain2Pin) * 60L){ // 待機時間 = 0~1023 * 60 msec(最大:約 1 分)
      digitalWrite(led3Pin, 1); // 稼働中 点灯
      onceFlag = 0;
      pushOnce(); // ワンプッシュ実行
      digitalWrite(led3Pin, 0); // 稼働中 消灯
    } 
  }
  delay(5);
}