Laser加工機製作 ~その12 LinxCNCにレーザーラスター加工インストール~

LinuxCNCでのレーザーラスター加工について、基本的なところは前ページに書きました。今回はインストールです。

ほいほい堂レーザー加工機の構成
インストールに入る前に対象の加工機がどういう構成になっているか、特にレーザー出力のON/OFF制御部分について説明しておきます。
LinuxCNCが稼動するPCとレーザー加工機の間はパラレルポート(プリンターポート)を介して接続しており、回路は下図の通りです。 基板への入力はアンフェノール36pinコネクタで、主に使用している14pinまではPC側のD-Sub25コネクタの1~14pinと1対1で接続されています。

LaserControllerSchematic

レーザー加工機コントローラー回路図

回路を簡単に説明すると、2pin~7pinはX,Y,Zのモーター制御に割当てています。実際にはZ軸のモーターはありませんが、LinuxCNCの設定上はZ軸がある事にしており、Z-DIR(回転方向信号)をレーザーのON/OFF制御に使います。
10pin~13pinは非常停止信号や各軸のリミットスイッチからの入力です。いづれもGNDとの間をスイッチで繋ぎます。 非常停止スイッチは1個でLinuxCNCとレーザー電源の両方に入力するため、ショットキーダイオードで分離し、更にレーザー電源側にはフォトカプラを介して接続しています(図中P7コネクタ経由)。
14pinはスピンドルON/OFFの出力信号でNCコードのM03/等で制御します。
最終的にレーザー電源に入れるON/OFF信号は、14pinのスピンドル信号と7pinのZ-DIR信号のANDを取った結果をフォトカプラを介して接続しています(図中P1コネクタ経由)。

必要なファイルのダウンロード
Rastering With a Laserの記載に従って必要なファイルをダウンロードするのですが、一部リンクが切れがある様です。最低限必要なのは次のファイルでした。

http://wiki.linuxcnc.org/uploads/graster-example.tgz

https://github.com/jedediah/hacklab-engraver/archive/master.zip


https://github.com/jedediah/graster/archive/master.zip

加工機側の設定
作業を大きく分けるとGrasterのインストールと加工機側の設定に分かれます。
Grasterは画像を加工データに変換するRubyのプログラムです。 ダウンロードしたgraster-example.tgzの中には変換済みの加工データがあるので、まずはこれで動作を試す事として加工機側の設定を先に実施しました。

M101プログラムのインストール
M101プログラムはNCプログラム中のM101コマンドで呼び出される外部プログラムでPythonで書かれています。 このファイルは先にダウンロードしたhacklab-engraver-master内に’M101′(拡張子も何も無いこのままの名前)があります。
外部プログラムファイルはLinuxCNCがNCコードを読みに行く際のデフォルトディレクトリ(特に変更していなければ~linuxcnc/nc_filesになっていると思います)から読み込むのでここにコピーしておきます。
なおこのままでは私の環境(Ubuntu上のLinuxCNC2.5)ではエラーになりました。恐らく古いLinuxCNC用の記載になっていると思われ、下の点を変更しました。
各所にある’emc’はLinuxCNCの古い名称で、これらをすべて’linuxcnc’に変更しています。
また’emc.nmlfile = ini.find(“EMC”,”NML_FILE”)’行は削除しました。ここは今ひとつわからないのですがバージョン2.5では不要になったっぽいです。

diff M101.ORG M101
13c13
< import emc, os, sys, threading, gtk, time, popen2, signal, select
---
> import linuxcnc, os, sys, threading, gtk, time, popen2, signal, select
15,18c15,17
< os.chdir("/home/hacklab/emc2/configs/hacklab-engraver3")
< ini = emc.ini("hacklab-engraver3.ini")
< emc.nmlfile = ini.find("EMC","NML_FILE")
< s = emc.stat()
---
> os.chdir("/home/konchi/linuxcnc/configs/Laser1")
> ini = linuxcnc.ini("Laser1.ini")
> s = linuxcnc.stat()

INIファイルの変更
INIファイルはLinuxCNCの基本的な設定ファイルです。実際のファイルは~linuxcnc/configs/装置名/装置名.iniです。ほいほい堂加工機は装置名をLaser1にしているので~/linuxcnc/configs/Laser1/Laser1.iniとなっています。
このファイルをテキストエディタで開くと[HAL]というセクション行が見つかります。この中に’HALFILE = custom.hal’という行があるのでこの下に’HALFILE = Raster.hal’行を追加します。

[HAL]
HALFILE = Laser1.hal
HALFILE = custom.hal
HALFILE = Raster.hal

HALとは’Hardware Abstraction Layer’の略で、加工機のハードウェア情報が色々と書かれています。ラスターでの動作もここに追記するのですが、基本の’Laser1.hal’ファイルに追記すると読みづらくなるので新たな’Raster.hal’を作成しました。INIファイルに上記行を追加する事で’Raster.hal’が有効になります。
なおダウンロードしたhacklabのhalファイルは基本部分とラスター部分が一つのファイルに書かれています。

xxx.raster.gmaskファイル

話が飛びますが、ここでxxx.raster.gmaskファイルの説明をしておきます。
このファイルは元画像をGrasterプログラムで処理する際、その他のファイルと共に生成されます(xxxの部分は元画像のファイル名です)。 このファイルはNCコードM101実行時にStreamerに読み込まれ、後はNCプログラムと平行して進んでいきます。
StreamerとはLinuxCNCが加工中にリアルタイムで読み出せるメモリーの様な物です。 gmaskファイルの中は下図の様に4つのフィールドがスペースで区切られた形をしています。4つのフィールドは左から、reset,beam,xop,xargで、resetが1だとリセット、beamが1だとレーザーON、xopが1だとX軸は増加方向,0だと減少方向、xargはX軸がこの値に達すると次の行のデータに進むポイントを示します。
下の例では1行目でリセットし、2行目の時にはNCプログラムがX軸を増加方向に移動させていて、X軸が53.365のポイントに達したらgmaskは次の行に進みます。3行目もxargが53.365ですが、この時はX軸が減少方向に進んでいます。ここまでは全てレーザーはOFFです。3行目でXが減少しながら53.365に達したとき、Streamerは4行目の値に進みます。ここではbeamが1なのでレーザーがONとなります。その後X軸は減少方向に進み続け、53.315のポイントに達すると5行目に進み、ここではbeamが0なのでレーザー出力はOFFとなります。これにより53.365から53.315の間レーザーがONで描画した事になります。
この例ではX軸が減少方向に移動する時にのみレーザーを出力する記述になっています。
次項で説明するHALファイルには、Streamerから取り出した内容を元にレーザーのON/OFFをどの様に制御するか、またStreamerに対して次のステップに進める信号をどの様に生成するかを記述しています。

1 0 0 0
0 0 1 53.365
0 0 0 53.365
0 1 0 53.315
0 0 0 52.248
0 1 0 52.146
0 0 1 53.772
0 0 0 53.772
  :

 

Raster.halの作成
ここが一番面倒な部分です。まずHALに書かれる内容の内、ラスター動作に関係しそうな部分を列記します。

  • HALには加工機のハード的な動作を記載します。ステッピングモーターに送るパルス関連もここに記載してあります。
  • LinuxCNCの中ではリアルタイムの動作が必要な部分があります。本当のハードウェアならANDやORの回路を使うところをHAL内に記載しておくと加工機動作時にリアルタイムに(実際には周期的に)実行します。 これは回路CADで使うネットリストをイメージすると判り易いのかもしれません。
  • hacklab-engraver3.halの記載からレーザー出力制御にかかわる部分を抜き出し、下の回路図に直してみました。
  • この中で、「axis.0.joint-pos-fb」は現在レーザーヘッドがあるX座標を示します。
  • Streamer.0.pin.0~3はStreamerから読み出した値で、0:reset、1:beam、2:xop、3:xargの順に入ります。データ型は0,1,2がbit、3がfloatです。
  • Streamer.0.pin.empty:型はbit。これはStreamerの内容が空になると1になります。
  • Streamer.0.pin.enable:型はbit。これはStreamerに入力する信号で、次のデータに進めという意味です。
  • gmaskファイルのところで説明した様に、レーザーヘッドのX座標が指定したポイントに達する度にStreamerから次のデータを取り出しながらレーザー出力のON/OFFを制御していきます。
  • motion.spindle-on:スピンドルON信号で、NCコードのM3,M4,M5等で制御されます。
  • motion.digital-out-00:デジタルアウト0信号で、M62,M63で制御します。hacklabの加工機はベクター加工時にはこの信号でレーザーON/OFFを制御する様です。
  • axis.2.joint-pos-fb:これはZ軸の位置情報です。hacklabの加工機はZ軸がマイナスの場合にレーザーがONになる動作もできる様です。
  • parport.0.pin-01-out:最終的にレーザーをON/OFFする信号です。
    この信号がONになる条件は、まずスピンドルONは絶対条件で、ベクター加工用にデジタルアウトが1またはZ軸がマイナスだとON、ラスター加工用にはStreamerが空でなくてStreamer.0.pin.1が1の時にONとなります。
    spindle AND digitar0 OR Z<0  OR ( /empty AND beam)
  • これらはHALの記述によりソフト的に処理しています。
  • ほいほい堂加工機ではスピンドルとZ-DIR(X軸の方向)をハードウェア的にANDしているのでこの部分は何らかの変更が必要となります。
hacklab-engraver3.hal

hacklab-engraver3.halのレーザー出力制御部分を回路図に直してみた。

 

以上の通りほいほい堂の加工機はハード的にスピンドルとZ-DIRのANDでレーザーをONにしているのでHALファイルの変更が必要です。変更後のHALも回路図にしてみました。

Faser1.halの回路図

変更点は・・・

  • 最終的なレーザーON/OFF信号はparport.0.pin-07-outに変更した(パラレルポート7pinはZ-DIRに割当てています)。
  • motion.digital-out-00(デジタル0信号)は使用しない。
  • axis.2.joint-pos-fb(Z軸位置)の代りにLaser1.hal内の信号’zdir’を用いた。
  • スピンドルONとのANDはハード上で実施しているが、HAL内にも残した。
  • 以上の設定によりレーザーONの条件は、まずスピンドルONが絶対条件で、ベクター加工の為にZdirが1だと出力ON,ラスター加工の為にStreamerが空ではなくStreamer.0.pin.1が1ならば出力ONとなる。
    spindle AND Z-DIR  OR ( /empty AND beam)

Raster.hal追加に伴いLaser1.halにも下記の変更を加えています。ベクター加工のみの場合、zdir信号をパラレルポート7pinに出力していましたが、ラスター加工の為にzdirとパラレル7pinの間にRaster.halで記述する回路を挿入する為、この行をコメントアウトしています。

~Laser1.hal~

diff Laser1.hal.ORG  Laser1.hal
26c26
< net zdir => parport.0.pin-07-out
---
> #net zdir => parport.0.pin-07-out     # set by Raster.hal

最後にRaster.halを掲載します。
画像を加工機に送るデータに変換するGrasterについては次回の投稿に記載します。

~Raster.hal~

# Generated by stepconf at Sun Mar  8 21:32:59 2009
# If you make changes to this file, they will be
# overwritten when you run stepconf again

loadrt threads name1=mask-thread period1=1000000

# Boring components that emc makes me load explicitly because it is a cunt
loadrt comp names=comp-mask-lte,comp-discrete-z
loadrt not names=not-mask-ffw,not-mask-not-empty
loadrt xor2 names=xor2-mask-test
loadrt and2 names=and2-mask-forward,and2-laser-mask,and2-laser-final
loadrt or2 names=or2-mask-command-done,or2-mask-not-ffw,or2-mask-read,or2-laser-gcode,or2-laser-fine

###################################################################################
# Raster Mask - stream in laser on/off commands behind AXIS's back
# Input stream format: reset beam xop xarg
#   reset:  0=mask command 1=reset (begin mask sequence with "1 0 0 0", every other command starts with 0)
#   beam:   0=off 1=on
#   xop:    X axis comparison operation 0=less-or-equal 1=greater
#   xarg:   X axis comparison operand

loadrt streamer depth=256 cfg="bbbf"
net mask-reset     <= streamer.0.pin.0
net mask-beam      <= streamer.0.pin.1
net mask-xop       <= streamer.0.pin.2
net mask-xarg      <= streamer.0.pin.3
net mask-empty     <= streamer.0.empty
net mask-read => streamer.0.enable

# hardware reported X axis position
net motion-xpos-fb <= axis.0.joint-pos-fb

# mask-lte <= motion-xpos-fb < mask-xarg
addf comp-mask-lte mask-thread
net motion-xpos-fb => comp-mask-lte.in0
net mask-xarg => comp-mask-lte.in1
net mask-lte <= comp-mask-lte.out

# mask-test <= mask-xop ^ mask-lte
addf xor2-mask-test mask-thread
net mask-xop => xor2-mask-test.in0
net mask-lte => xor2-mask-test.in1
net mask-test <= xor2-mask-test.out

# if job is running, read only if test is true or reset
# if job is not running, read until reset
# mask-read <= (laser-coarse && (mask-test || mask-reset)) || !(laser-coarse || mask-reset)

addf or2-mask-command-done mask-thread
net mask-test => or2-mask-command-done.in0
net mask-reset => or2-mask-command-done.in1
net mask-command-done <= or2-mask-command-done.out

addf and2-mask-forward mask-thread
#net laser-coarse => and2-mask-forward.in0
net spindle-on => and2-mask-forward.in0
net mask-command-done => and2-mask-forward.in1
net mask-forward <= and2-mask-forward.out

addf or2-mask-not-ffw mask-thread
#net laser-coarse => or2-mask-not-ffw.in0
net spindle-on => or2-mask-not-ffw.in0
net mask-reset => or2-mask-not-ffw.in1
net mask-not-ffw <= or2-mask-not-ffw.out

addf not-mask-ffw mask-thread
net mask-not-ffw => not-mask-ffw.in
net mask-ffw <= not-mask-ffw.out

addf or2-mask-read mask-thread
net mask-forward => or2-mask-read.in0
net mask-ffw => or2-mask-read.in1
net mask-read <= or2-mask-read.out

# laser-mask <=  mask-not-empty && mask-beam
addf not-mask-not-empty mask-thread
net mask-empty => not-mask-not-empty.in
net mask-not-empty <= not-mask-not-empty.out

addf and2-laser-mask mask-thread
net mask-beam => and2-laser-mask.in0
net mask-not-empty => and2-laser-mask.in1
net laser-mask <= and2-laser-mask.out

addf streamer.0 mask-thread

# Raster Mask - end
#######################################################################

# coarse laser control, wired to spindle on/off (M3/M5), not realtime
#net laser-coarse <= motion.spindle-on

# fine laser control, wired to digital output 0 (M62 P0/M63 P0), realtime
net laser-gate <= motion.digital-out-00

# legacy laser control, wired to Z < 0, can be used instead of M62/M63
#addf comp-discrete-z servo-thread
#net motion-zpos-fb <= axis.2.joint-pos-fb
#net motion-zpos-fb => comp-discrete-z.in0
#setp comp-discrete-z.in1 0
#net discrete-z <= comp-discrete-z.out

# laser-final <= laser-coarse & (laser-gate | discrete-z | laser-mask)
#addf or2-laser-gcode mask-thread
#net laser-gate => or2-laser-gcode.in0
#net discrete-z => or2-laser-gcode.in1
#net laser-gcode <= or2-laser-gcode.out

addf or2-laser-fine mask-thread
#net laser-gcode => or2-laser-fine.in0
net zdir => or2-laser-fine.in0
net laser-mask => or2-laser-fine.in1
net laser-fine <= or2-laser-fine.out

addf and2-laser-final mask-thread
net laser-fine => and2-laser-final.in0
#net laser-coarse => and2-laser-final.in1
net spindle-on => and2-laser-final.in1
net laser-final <= and2-laser-final.out

# laser-final => hardware
# net laser-final => parport.0.pin-01-out
net laser-final => parport.0.pin-07-out

 

※「必要なファイルのダウンロード」のところでgrasterのファイルがリンク切れのアドレスとなっていたので修正しました。 2016-02-27

 

Laser加工機製作 ~その11 LinxCNCでレーザーラスター加工の詳細~

LinuxCNCでのラスター加工について、最初はそれ用のNCコードを作ればいいという程度に考えていましたが、そう簡単ではなさそうです。
図の様にA地点からB地点、およびC地点からD地点までレーザー照射する場合、普通にNCコードで制御すると基本的に各地点で一旦停止します。刃物で切削するならこれで問題ないのですがレーザーの場合は速度を落とす部分では余分にレーザーを当ててしまう事になります。

Vector

NCコードのみで記述(ベクター動作と同じ)

ラスター動作では下図の様に、レーザーヘッドを一定の速度で移動しながら所定の位置でレーザーをON/OFFするのが理想です。

Raster

ラスター動作

たぶんNCコードだけではこれを実現できないと思います。
>どうなんでしょう?プロの方。

LinuxCNCでレーザーのラスター加工を検索してもあまり多くの例が見つかりませんでした(しかも全部英語なんです)。それでも比較的詳しく書かれた例が次のサイトでした。
Rastering With a Laser
主にHackLab Trontというところのマシンを例に説明されています。
インストール方法は後で説明するとして基本的な使い方は次の通りです。

  1. 元画像ファイルをGrasterというソフト(Rubyで書かれている)で処理すると次の3つのファイルが得られます。
    • 元画像ファイル名.raster.ngc
    • 元画像ファイル名.raster.gmask
    • 元画像ファイル名.cut.ngc
  2. LinuxCNCを立ち上げ、’元画像ファイル名.raster.ngc’を読ませて実行します。
    このファイルにはラスタースキャンの動作が書かれています。具体的にはマーキングしたい画像よりも左右(X軸方向)に少し広い範囲で往復しながらY軸を少しずつ動かしていくNCコードです。 また先頭部分には’M101′というNCコードが書かれています。
  3. NCコードM101の行を実行した時点で’M101′というファイル名(拡張子も何も無くこの通りのファイル名)に書かれた外部プログラムを実行します。
    (M101外部プログラムのファイルはLinuxCNCがNCコードを読みに行く際のデフォルトディレクトリに置いておきます。特に変更していなければ~/linuxcnc/nc_filesだと思います。)
  4. M101プログラムはPythonで書かれたスクリプトです。この中から自動的に’元画像ファイル名.raster.gmask’を読み込みます。
  5. ‘元画像ファイル名.raster.gmask’にはレーザーをON/OFFするタイミングが書かれており、LinuxCNCのStreamerという機能に読み込ませます。 Streamerは加工機が実行中、リアルタイムにデータを取りだせるメモリーみたいなもの(私の勝手な解釈)で、Streamerから取り出したデータをどうあつかうかはhal(設定ファイルの一つ)に記載しておきます。
  6. 後はラスタースキャン動作をしながらStreamerからレーザーをON/OFFするタイミングを取り出し、これに従って画像を描いていきます。
  7. ‘元画像ファイル名.cut.ngc’は画像の外形を囲んだシンプルなNCファイルなので、描画した画像を切り離す場合等に必要に応じて使用します。

大体の動作としてはこんな感じです。
面倒だったのはインストール方法で、このいきさつを書くと長くなりそうなのでページを改めて書こうと思います。

下の物を描画してみました。

RaterKumamon

くまモンです。
左上で切れているのは何かをミスって途中で止めた為。

台車札

ヨットの台車につけておくセール番号札(ちょっと薄かった?)

 

Laser加工機製作 ~その10 カバーと排気~

レーザー加工機を動作させると煙や匂いが激しく出るので全体のカバーと排気を取付けます。

側面、裏面パネル

側板と裏板は4mm厚の合板を切ってアルミフレームにネジ止めしました。裏板には排気ダクトを取り付ける為の金具(丸型ガラリという様です)を取付けました。

側板裏板

内側から見た側板と裏板。
家屋の排気用「ガラリ」を取付けた。

上蓋、前面パネル

上蓋と前面パネルは中が見える窓にしたいので、合板を切って窓を接着してとか色々考えましたが結局全面アクリルにしました。
材料は近所のホームセンター「ハンズマン」のガラクタ市で以前購入しておいた激安アクリル板を使います。

アクリル板

ホームセンターのガラクタ市で見つけたアクリル板。いいずれも550mm×650mmで、2mm厚が145円、3mm厚が190円。 それぞれ2枚ずつあったので迷わず全部買いました。

上蓋は熱した単管パイプに押し当て曲げててみます。

アクリル曲げ設備

単管パイプをヒートガンで熱してアクリル板を曲げます。

曲がりましたが直線になっていません。再びヒートガンで熱して修正します。

アクリル曲げ

真直ぐ曲げるのは難しいです。再加熱して何とか修正しました。

と、ここで大きな間違いに気付きました。アクリルの長辺を曲げるつもりが短辺を曲げていたのです。 アホな事をしました。再び熱しても一度曲げたものが平らに戻るとは思えません。
仕方ないので同じアクリルを使って左右に縦長の上面パネルを取付けました。真ん中部分だけが開きます。

フタを明けた図

上蓋の幅が短くなったので左右に縦長パネルを固定しました。

蓋を閉めたところ。結構イイ感じかも。

上蓋と全面パネル取付けた図

上蓋と全面パネルを取付けました。
激安アクリルとはいえ贅沢です。

レーザー管の保護

レーザー管を保護するカバーはトタンだかブリキだかの薄板を曲げて作りました(売り場には材質が書いてなかったんですよね。隣に並んでいたのはガルバリウム鋼板でした)。
0.3mm程の厚みですが硬くて綺麗には曲がらずデコボコです。 横は百均アルミ板で塞いであります。

レーザー管カバー

レーザー管の保護カバー。
デコボコに曲がりましたがガラスむき出しのときよりも安心になりました。

排気

アルミのダクトでトイレファンに繋ぎます。 壁に穴を開けていないので、当面は窓から排出します。

ダクトとファン

ダクトとファン

これでかなり安心して稼動できる様になりました。

Laser加工機製作 ~その9 LinuxCNCでラスター加工~

レーザー加工機の用途として材料をカットする以外にラスター加工で絵や文字をマーキングするというのがあります。材料のカットは何とか動き出したので今度はラスター加工をやってみます。

LinuxCNCでレーザーのラスター加工の例があまり見つからないのですが、検索すると必ず最初に出るこのサイトを参考にしました。Hack-Labトロントのレーザー加工機を対象にしている様です。 これをウチの機械に合う設定するのに色々あったのですが、それはまたいづれ纏めようと思います。
とりあえずこのサイトから辿れるサンプルデータをダウンロードして出力した結果がこれ。

Laserラスター加工1

ラスター加工一発目

元の画像データはこれ

Rasterサンプル

元の画像データ

だいたい動作していますが、なぜか文字の囲み枠が一部出ていません。これは後で調べる事とします。
また、任意の画像を出力データに変換するプログラムを動作させる必要があります。
できたらまた報告します。

Laser加工機製作 ~その8 レーザー管の電極~

私が購入したレーザー管の電極ってこんな感じです。実測すると太さ1.4mm、長さ4mm。真空管の電極っぽくガラスから直接生えているのでハンダ付けするのが怖くて今までワニ口クリップで接続していました。

LaserTube Terminaal

レーザー管の電極

先日用事があって実家に帰った際、日本橋のシリコンハウス共立でこの写真を見せて使えるコネクタがあるかどうか、ダメ元で聞いてみました。まあ案の定、それ用というのはありませんが、さすが店員さんはプロ、太さと長さから使えそうな物を探してくれました。

それがこれ、ELコネクタ。差し込む相手の太さは1.3mmなので微妙に違いますがたぶん大丈夫でしょう。ピンだけ使います。

ELコネクタ

ELコネクタ
ピンだけ買えばよかったのになぜかハウジングまで買ってしまった。

このままだと長いので不要な部分を切り取りハンダ付けします。

電極1

ハンダ付け

そしてレーザー管の電極に差し込んで・・・

電極2

管に取り付け

管には水も通すので防水と補強を兼ね、自己融着テープを巻きました。

電極3

ガラス部分にも掛かる様に自己融着テープを巻きます。

これで少し安心感が出ました。
レーザー出力側の電極も同様ですが、こちらは電極付近のスペースに若干の余裕があったのでピンは切らずカシメて取付けました。

電極4

レーザー出口側の電極。ピンは切っていないので若干長い。

この方法で暫く使ってみます。