PR

【CNC自作②】リミットスイッチ実装|原点出し(ホーミング)で精度を出す

スポンサーリンク
CNC自作
スポンサーリンク

はじめに

なぜ「動く」だけではダメなのか?

前回はArduinoを使って、とりあえずXYテーブルのモーターを回すところまで進めました。 しかし、このままではまだ「CNC」としては未完成です。

なぜなら、「機械が自分の現在地を分かっていない」からです。

今回のゴール

・リミットスイッチを使い、原点(0, 0)を確定させる。

これによって、「ただ動くおもちゃ」から「毎回同じ位置から正確に加工を始められるツール」へと進化させます。

スポンサーリンク

なぜリミットスイッチが必要なのか?

CNC(コンピュータ数値制御)の世界では、「位置の再現性」が命です。

  • 1mmのズレが命取り: 穴の位置がズレれば、部品は組み立てられません。
  • ズレの蓄積: モーターの「脱調(ステップ抜け)」や電源投入時のバラつきにより、位置は少しずつズレていきます。
  • 絶対的な基準がない: 電源を入れた場所が勝手に「0」になってしまうと、毎回手動で位置合わせをしなくてはなりません。

ここで登場するのがリミットスイッチです。物理的なスイッチに触れることで、「ここが本当の0地点だ」という**物理的な基準(原点)**を作ります。

スポンサーリンク

CNCの基本動作「ホーミング(原点復帰)」の仕組み

リミットスイッチに当たって止まるだけの動作を、専門用語でホーミング(Homing)と呼びます。実はこれ、単純にスイッチにぶつけるだけではありません。

動作のステップ

  • アプローチ: 軸をスイッチ方向に高速で動かす。
  • 接触: スイッチに当たった瞬間に停止。
  • バックオフ(プルオフ): 少しだけ反対方向に引き返す。
  • 再接触: 非常にゆっくりした速度で再度スイッチに触れる。
💡 なぜ2回も当てるのか?

1回目の高速移動では、慣性で停止位置が微妙にバラつきます。2回目に超低速で触れることで、機械的なバラつきを排除し、ミクロン単位の精度で原点を特定しているのです。

スポンサーリンク

ハードウェアの準備と配線

今回追加するパーツはシンプルです。

用意するもの

  • リミットスイッチ ×2(X軸・Y軸用)

カチッと音がする「マイクロスイッチ」が扱いやすくておすすめです。

配線方法

配線は「プルアップ」という方式を使います。

ドライバーボードではボード上の「END STOPS」に接続します。

  • スイッチの片側: Arduinoの入力ピン
  • もう片側: GND(接地)
💡 なぜ「プルアップ」なのか?

配線が浮いている状態(どこにも繋がっていない状態)だと、ノイズを拾って勝手にスイッチが押されたと誤検認することがあります。プログラム側で「常にHIGH(電圧あり)」にしておき、スイッチが押されたときだけ「LOW(0V)」に落とすことで、ノイズに強い確実な検出が可能になります。

スポンサーリンク

テストコードで動作確認

結線が完了したら、テストコードで動作させてみましょう

クリックしてテストコードを表示する
// テストコード test_code_XY_SWITCH.ino
#define X_STEP 2
#define X_DIR 5

#define Y_STEP 3
#define Y_DIR 6

#define ENABLE 8

#define X_LIMIT 9
#define Y_LIMIT 10

// ===== 調整パラメータ =====
#define BACKOFF_STEPS 250
#define HOMING_FAST 800
#define HOMING_SLOW 2000

// ===== ホーミング方向 =====
#define X_HOME_DIR HIGH // ← Xだけ逆にした
#define Y_HOME_DIR LOW // Yはそのまま

bool stopFlag = false;

void setup() {
pinMode(X_STEP, OUTPUT);
pinMode(X_DIR, OUTPUT);
pinMode(Y_STEP, OUTPUT);
pinMode(Y_DIR, OUTPUT);
pinMode(ENABLE, OUTPUT);

pinMode(X_LIMIT, INPUT_PULLUP);
pinMode(Y_LIMIT, INPUT_PULLUP);

digitalWrite(ENABLE, LOW);

Serial.begin(115200);
Serial.println("Press 's' to STOP, 'g' to HOME");
}

// ===== 入力チェック =====
void checkInput() {
if (Serial.available()) {
char c = Serial.read();
if (c == 's' || c == 'S') stopFlag = true;
if (c == 'g' || c == 'G') homeXY();
}
}

// ===== 停止処理 =====
void stopAll() {
Serial.println("STOPPED");
digitalWrite(ENABLE, HIGH);
while (1);
}

// ===== 1軸ホーミング =====
void homeAxis(int stepPin, int dirPin, int limitPin, bool homeDir) {

// ① 高速で当たる
digitalWrite(dirPin, homeDir);
while (digitalRead(limitPin) == LOW) {
checkInput();
if (stopFlag) stopAll();

digitalWrite(stepPin, HIGH);
delayMicroseconds(HOMING_FAST);
digitalWrite(stepPin, LOW);
delayMicroseconds(HOMING_FAST);
}

delay(100);

// ② BACKOFF(逆方向)
digitalWrite(dirPin, !homeDir);
for (int i = 0; i < BACKOFF_STEPS; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(HOMING_FAST);
digitalWrite(stepPin, LOW);
delayMicroseconds(HOMING_FAST);
}

delay(200);

// ③ ゆっくり再接触
digitalWrite(dirPin, homeDir);
while (digitalRead(limitPin) == LOW) {
checkInput();
if (stopFlag) stopAll();

digitalWrite(stepPin, HIGH);
delayMicroseconds(HOMING_SLOW);
digitalWrite(stepPin, LOW);
delayMicroseconds(HOMING_SLOW);
}

delay(100);
}

// ===== XYホーミング =====
void homeXY() {
Serial.println("HOMING START");

homeAxis(X_STEP, X_DIR, X_LIMIT, X_HOME_DIR);
homeAxis(Y_STEP, Y_DIR, Y_LIMIT, Y_HOME_DIR);

Serial.println("HOMING DONE");
}

// ===== モーター動作 =====
void moveMotor(int stepPin, int dirPin, bool dir, int steps) {
digitalWrite(dirPin, dir);

for (int i = 0; i < steps; i++) {
checkInput();
if (stopFlag) stopAll();

digitalWrite(stepPin, HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin, LOW);
delayMicroseconds(1000);
}
}

void loop() {
checkInput();

stopFlag = false;

// ===== X軸 =====
moveMotor(X_STEP, X_DIR, LOW, 300);
delay(500);
moveMotor(X_STEP, X_DIR, HIGH, 300);

delay(1000);

// ===== Y軸 =====
moveMotor(Y_STEP, Y_DIR, HIGH, 300);
delay(500);
moveMotor(Y_STEP, Y_DIR, LOW, 300);

delay(2000);
}

👇リンクよりダウンロードできます。

test_code_XY_switch.ino をダウンロード(ZIP)
  • Arduino IDEを開く
  • 上部のプルダウンよりArduinoが接続されているポートを選択します。
  • デフォルトで入力されているコードを削除する。
  • テストコードを張り付ける
  • 画面左上の→矢印をクリックし、Arduino Uno R3に書き込まれます。
  • 自動でX軸Y軸の動作が実行されます。
※アプリ画面右上の「シリアルモニタ」のボタンをクリックし、シリアルモニタを開く
 ・キーボードの「S」を入力しEnterで動作がストップされます
 ・キーボードの「g」を入力しEnterで原点復帰が開始されます。

動作動画

スポンサーリンク

よくあるトラブルと対策

いざ動かしてみると、意外とうまくいかないこともあります。

トラブル内容原因と対策
チャタリングスイッチの接点が細かくバタつく現象。ソフト側で「数ミリ秒待つ」か、コンデンサを入れて電気的に平滑化します。
ノイズで勝手に止まるモーターの配線からノイズを拾っている可能性。配線をツイストするか、シールド線を使うのが効果的です。
位置が毎回数ミリズレるスイッチの固定が甘い(剛性不足)かもしれません。ネジの緩みや、ステーのたわみをチェックしましょう。
スポンサーリンク

まとめと次回の予告

リミットスイッチが機能すれば、ついにあなたのXYテーブルは**「自分の居場所」**を理解できるようになります。これでCNCとしての土台は完璧です。

ここまでの進捗:

  • [x] モーターが動く
  • [x] 原点が決まる(←今ここ!)

次回はいよいよ、このハードウェアをPCから自在に操るためのソフトウェア**「GRBL」の導入と、操作画面である「CNCjs」**の設定に入ります。

いよいよ「本格的な工作機械」になっていきますよ!

コメント