押しボタンプッシャー試作版 2020/09/13~09/27

・2020/09/27 マグネットベースを 400N に変更
・2020/09/22 ラックピニオンギヤの CAD 図面を追加
・2020/09/19 アクリルタイプの画像を追加
・2020/09/16 Cut2D のスクリーンショットを追加
・2020/09/15 Arduino コードを追加

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

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

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


動画 (MP4) はこちら

ラックピニオンギヤ(モジュール:1.6、歯数:10)の CAD 図面(DXF)はこちら
サーボ軸のギザギザ(25T)はギリギリのサイズです。きつい場合は、0.05mm 外側にオフセットしてください。

アクリル(t5)タイプ↓
マグネットベース(200N)に変更。見た目は良くなりましたが、200N では磁力不足でした。400N は必要っぽい。
ピニオンギヤのみ MC ナイロンに変えました。


ラックギヤを MC ナイロン化。3 個めで何とか使えるレベルに。結構難しい・・・。


ほぼ実用版↓
見た目はそう変わりませんが、マグネットベースが大きく(400N)になっています。


3D プリンタ用データ (STL) は、昔ながらの Bricscad で作成。
赤い部分が 3D プリンタで作成。他は CNC でカット。
s


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