旋盤とCNCフライス~その4~

引き続き、頂き物のCNCを稼働させようとしています。
前回は古いPC上で動くLinuxCNCを使って試験動作をしてみました。
このPCは随分前にメインPCとして使っていたPentium4-2.8GHz搭載のマザーが載っており、基板切削CNCやレーザー加工機の制御に現役で稼働しています。この頃のPCは普通にパラレルポートが付いていたのでLinuxCNCでの使用に問題はありません。

このPCの後にメインとして使ったのはCore-i5のマザーボードでした。このボードのパラレルポートは直接背面には出てはいないのですが、ボード上にピンヘッダがあり、ケーブルを挿す事で使用できます。本来ならこのボードが現役を退いた後にCNC制御マシンにしたかったのですが、以前このブログにも書いた通りコイツは壊れてしまいました。

CNC制御にはMach3/4やGrblも候補に上がりますが、費用や慣れの問題もあるので、やっぱりLinuxCNCで行きたいと考えました。という事で、HARD OFFで物色するとPentium4 3GHzのPCが¥2900で売られていたので購入しました。

P4-3GHz
HARD OFFで購入。なかなか絶妙な値段です。

LinuxCNCはバージョン2.7のLiveCDからインストールしました。なおLinuxCNCにはそのPCが向いているかどうかの指標としてレイテンシ・テストがあります。LinuxCNCはステッパーの回転パルスをリアルタイムに生成する為、一定間隔で処理を実行する必要があるのですが、レイテンシが大きいと間に合わなくなるのです。LinuxCNC付属のレイテンシ・テストを実行するとMAXジッターという値が表示されます。ドキュメントによるとこの値が50μSあたりまでならまあまあ良し、100μSを超えるマシンは制御には向かない様な事が書いてあります。
早速このPCで実行したところ直ぐに200μSを超えてしまいました。現用のPentium4-2.8GHzが最大でも55μS程度なので不安視していなかったのですが、ビデオカードを交換してみたりBIOSの設定を変えたりとやっても改善しません。

PC代¥2900円が無駄になるは悔しいので何とかしたいところです。そこで次善の策として考えてたのがこのPCでGrblのコントローラーを動かすという方法です。Grblならリアルタイムの部分はArduinoがやってくれるのでPC側はジッターを気にする必要がありません。BlackIIの制御基板(TRIO)にはサンケン電気のステッパードライバが載っておりこれは活用したいので、Arduino+CNCシールドではなく、ArduinoをTRIOにつないで制御してみたいと思います。
ステッピングモーターの制御信号がDIRとSTEPという基本は変わらないので何とかなると思っています。

そこで実験。

Grbl-TRIO

D-SUB25ピンのコネクタはジャンクのマザーから取り外した物です(なので紫色)。TRIOをイネーブル状態にする信号はSN74HC00を使った非安定マルチバイブレータでチャージポンプ信号を入れて動作させましたが、これではGrblが準備できたらONになるという本来の動きはできないので、最終的にはTRIOのJP1をオープンにする事で、単にLに下がればイネーブルとなる制御にしようと思います。

この段階で色々とマニュアルに記載が見当たらない細かいところも試してみました。以下ここまでで分かった事の備忘録

  • TRIOのSPINDLE入力はLが回転、Hが停止。
  • BlackIIのリミットスイッチ(フォトインタラプタ)は普段はLでセンサーをさえぎるとHになる。
  • ArduinoのA0ピン(GrblではReset/Abort端子。内部プルアップされている。)は動作中にLに落とすと動作がキャンセルされて停止する。続きの動作はできず、HOMINGからやり直す必要あり。たぶん非常停止に使える。
  • CNCシールドのE-STOP端子は回路図を辿るとArduinoのリセットに繋がっている。
  • A0端子で止めてもReset端子で止めても動作は変わらないように見える。
  • Arduinoの A1ピン(GrblではFeed Hold端子。内部プルアップされている。)はLに落とすとスピンドルは回ったままステッピングモーターだけが停止する。コントロールソフト(Candleを使用)のステータスにはHOLDと表示され、Pauseボタンを押すと動作が再開する。
  • ArduinoのA2ピンはGrblではCycleStart/Resume端子であるが、これをLに落としても特に何事も起こらなかった。この用途は何でしょう?
  • ArduinoのA5ピン( GrblではZ-probe/Heightmap)もプルアップされていて、高さ検出の際にこれがLになったら刃物がワークに接触したと認識する。
  • Z-probeはCandle右上ボタン群の下向き矢印みたいなボタンを押すと始まる。
  • Height-mapはCandle右部分のheightmapメニューからCreateを押すと採取用設定が現れる。
  • TRIOにはEMG信号という出力があり、スピンドルに過電流が流れたりするとL→Hに変化する。

一番上の 「TRIOのSPINDLE制御入力はLだと回転」というのがGrblの標準とは異なるのでconfig.hの下の行のコメント記号を外しました。

< // #define INVERT_SPINDLE_ENABLE_PIN
---
> #define INVERT_SPINDLE_ENABLE_PIN

またスピンドルの回転数をPWMで制御する事はTRIOのマニュアルを見る限り書かれておらず、当面はON/OFFだけで実行します。この為以下をコメントアウト。

< #define VARIABLE_SPINDLE
---
> // #define VARIABLE_SPINDLE

なおこのコメントをを外すとGrblは旧版との互換性の為、スピンドルイネーブル端子とZ-LIMIT端子の機能が入替わる(HかLかを切り替えるだけでなく、端子の割り当てまで一緒に変更してしまう)。入替わる前提で使ってもいいが将来的な互換性を考えると端子割り当ては標準のままにしたかったので、cpu_map.hの以下を変更しました。

   68c68,69
   <     #define Z_LIMIT_BIT    3
   ---
   >     //#define Z_LIMIT_BIT    3
   >     #define Z_LIMIT_BIT          4
   87c88,89
   <     #define SPINDLE_ENABLE_BIT    4 
  ---
   >     // #define SPINDLE_ENABLE_BIT    4
   >     #define SPINDLE_ENABLE_BIT    3

ところでGrblのヘッダ類を書き換える場合は~/Arduino/libraries/grblの下にあるファイルを変更しなければなりません。最初普通に~/Arduino/grbl-master下のファイルを変更してコンパイルしても変更が反映されなかったので要注意です。

次に非常停止をスイッチをどうするか、以下を候補に考えています。

  • ArduinoのReset端子をLに下げる。
  • ArduinoのA0端子(Reset/Abort)をLに下げる。
  • TRIOのイネーブル信号(チャージポンプ又はH/L)を使ってOFFにする。

なお非常停止は極力ノーマリONのスイッチにすべきです。ノーマリOFFを使ってしまうと接点が劣化していた場合に非常停止を押しても止まらないという事態が予想されます。Grbl標準はReset端子を使うにしてもA0端子を使うにしてもノーマリOFFが標準なのでA0端子の機能を逆転させる事にします。

もう一つ、TRIOからEMG(エマージェンシー)信号というのが出てきます。これはスピンドルモーターに過電流が流れた場合等にHになる信号なので、何とかGrblに伝えたいと思います。

という事でTRIOのEMG信号と非常停止スイッチを両方生かす為、次の様に配線する事にしました。Grblの設定でA0信号はHとLの意味を反転させ、正常時がL、異常時がHと認識する様に変更しています。
これでTRIOから出るEMG信号も非常停止スイッチも反映させる事ができます。

なおA0信号のHとLの意味を反転させるにはconfig.hに以下を追加します。

> #define INVERT_CONTROL_PIN_MASK ((1<<CONTROL_RESET_BIT))

以上で回路が決まりました。次に基板を作っていくのですが、折角なのでこのCNCを用いて基板を切削してみようと思っています。その為にはスピンドルに基板切削用刃物を取付ける方法を考えねばなりません。
・・・という事で次に続きます。

旋盤とCNCフライス~その3~

ぽんさんに頂いた旋盤に続きCNCフライスも稼働させたいと思います。
このCNCはスピンドルの横に1Wのレーザーが取付けられていますが安全のため一旦取り外していずれ活用したいと思います。

ORIGINALMIND製BLACKⅡ1520

コントローラーはORIGINALMIND製のTRIOが筐体の下に収まっています。
TRIOはORIGINALMIND社のWebページで見かけますが実物を見るのは初めてです。ステッピングモーターのドライバには昔欲しかったけど手に入らなかったサンケンのSLA7078が載っています。


基本的にTRIOはPCのパラレルポート(プリンターポート)から接続しますが、最近のPCにはパラレルポートはありません。そこで USBからパラレルに変換する為のCNCdrive製UC100も一緒に頂きました。
因みにCNCをコントロールする場合、USBからパラレルポートに変換するアダプタとして普通に売られている物ではうまく動きません。USBは大量のデーターを送るには優れていますがリアルタイム性は今一つなのでモーター駆動パルスのタイミングが間に合わないのです。しかしこのUC100というインターフェースは内部にDSPを備えておりタイミング精度が必要な処理は内部で行ってしまうそうです。但しMach専用でLinxCNCは対象外です。

Machは基板切削CNCを作成した当初、お試し版( NCコードの行数制限あり )を使用しましたがそれ以降使っていません。
最終的にどうするか未定ですが、まずは使い慣れたLinuxCNCで(古いPCのパラレルポートで)動作を確認してみる事にします。

・・・と簡単に考えていたらハマりました。原因はTRIOに入れるイネーブル信号という物。当初マニュアル無しで動かそうとしていたのでORIGINALMIND社のピンアサイン表にあったM-ENBという信号がイネーブル信号であろうという事までは検討がついたのですが、単にHかLを入れてやればいいものだろうと思っていました。ところが全く動作しないので色々調べてみるとH/Lを繰り返す矩形波を入れ続ける必要があったのです。HかLだとPCの電源投入直後にたまたまそのレベルが出て不用意な動作をしてしまう危険があるので「たまたま」では出てこない信号を入れてやる事がPC側が準備できた証という訳です。
なおこの信号はチャージポンプと言うそうです。 LinuxCNCのマニュアルにもチャージポンプの事が書かれていましたが関係ないものかと思っていました(だってチャージポンプっていったらデバイス内で電圧を2倍とかに上げてFLASHの書込み電圧などを作るやつを思い浮かべますもん。それがLinuxCNCで要る理由は思い浮かびませんが。)
という事でLinuxCNCから「チャージポンプ」信号を出してTRIOのM-ENB入力(17pin)に入れてやる事で動作し始めました。

後日ぽんさんにTRIOのマニュアルを見せて頂き、TRIOは5~10KHzの信号をイネーブルと判断するという事が判りました(実際にLinuxCNCから何KHzが出ているのかは確かめていませんが)。
また基板上のジャンパー1をオープンにする事で単にLを入れるとイネーブルになる方式にも変更できる様です。

ここまででステッピングモーターは動作する様になったのですが、スピンドルを駆動するプーリーベルトが切れてしまいました。

とりあえずハンズマンで買ってきたOリング( 若干太いのが気になりますが )で代用します。

モーター側は良いのですが、Oリングが太いのでスピンドル軸側のプーリー溝には完全には嵌っていません。

ちょっといい加減なところもありますが動作し始めたので適当なデータで木を削ってみます。

切り口がササクレましたが削れています。ササクレは条件を詰めれば良くなると思います。

まずは最低限の動作が確認できました。

この後ですが・・・現在LinuxCNCを動かしているマシンはレーザー加工機と基板切削CNCを受け持っており、新しいCNCを設置したい場所とは部屋の反対側になってケーブルが届きません。基板切削CNCを撤去して代りに今回のBlackⅡ1520を置くというのもアリかと思いますが、まだ基板を削れる状態にはなっていないのです(スピンドルが基板切削用刃物のサイズに合っていないのをどうするか・・)。
コントローラもLinuxCNCで行くか、Machにするか、またはGrblにしてしまうか思案中です。

基板切削CNC不調

フライトシミュレータのモーション化を進めていますが、次の作業としてラダーペダルフライトヨークを座席と一体にになる様に固定したいところです。この作業には鉄を切ったり貼ったりする予定なのですが先週末は天気が悪くて外での作業が出来ませんでした。

仕方ないので現在ブレッドボードのままであるコントロール回路の基板作成を始めたのです。いつもの様にKi-cadで図面を描き、ガーバーデータを作成してgynostemmaで切削データを作成しました。そして基板切削CNCをスタートさせてしばらくしたところでガタガタという音がし始めました。最初は送りねじの油切れかなとか思っていたらそのうちX軸が回らなくなり、同じところばかり削り始めたので非常停止ボタンを押して止めました。

どうやらX軸のドライバ基板とステッピングモーターをつなぐナイロンコネクタ付近が接触不良みたいです。このあたりをグリグリやるとX軸が回ったり止まったりします。結局配線中の1本が切れかかっているのを見つけたので半田で付け直しました。

そして再スタートしたら今度はY軸がガタガタと言って回らなくなりました。これもコネクタ回りの配線が切れかかっており、半田で付け直しました。

これで一応動作する様になったのですがコネクタ回りをしつこくグリグリやってみるともう一か所怪しいところがあり、これも半田で付け直しました。

ナイロンコネクタは電極をカシメて止めますが、このCNCを作った時はまだカシメ工具を持っておらず、適当な事をした記憶があります。それがいま一気に噴出したのでしょうか?
もしかすると今まで何回か切削を失敗した事があるのもこれが原因だったのかもしれません。

CNC配線

ナイロンコネクタの切れたところを半田で修理

 

このドライバ基板、今では考えられませんが当時市販のステッピングモータドライバが手に入らなかったのでPICマイコンとMOSFETで作りました。ユニポーラのモーターを3個駆動するのでMOSFETを12個並べており配線もぐちゃぐちゃです。色々ぶら下がっており、そりゃ配線切れも起こすってもんです。

CNC制御

CNC制御基板

 

以上の修理で今のところ普通に動作する様になったのですが、いつまた再発するか分かりません。コネクタの配線を全部やり直せばいいのですが、それよりもArduino+CNCシールドに変えようかと検討しています。

ちょっと前にレーザー加工機をArduino制御に変えようと思ってCNCシールドは購入していましたが、非常停止スイッチ、水流センサー、上蓋開閉センサー等の接続を考えていたら面倒になってそのままにしています。なのでこのCNCシールドを流用しようかと考えています。。。

CNC

まずは修理完了

ぼちぼちとやります。

 

Grbl,CNCシールドとか水流センサーとか

だいぶ遅くなってしまいましたが、あけましておめでとうございます。
本年もぼちぼちとやっていきたいと思います。

ぼちぼちと言いつつ早速ですがCNCシールドの続きです。正月休みに帰省した際、日本橋のシリコンハウスに行く事ができたので4pin、2pinのハウジングを購入してきました。これでモーターやらリミットスイッチやらを接続しようと思います。
4pin,2pin

で、接続方法を調べているのですが、リミットスイッチや非常停止信号は今までの接続とGrblの標準が異なる様なので、とりあえずGrblの設定にて論理を反転したりしてやってみようと思います。ところで現在LinuxCNCで使っている制御回路は次のようになっています。色々継ぎ足したので特に非常停止信号周りはややこしくなってしまいました。

レーザーコントロール回路

そういえば水流センサーを取り付けた話はブログで報告していませんでした。のんさやさんのレーザー管破損記事も見ていたのでいつか付けねばと思っていたところ、昨年のMFTの後に秋葉原でセンサーを見つけたので購入して取り付けておりました。

水流センサー

水流センサー
ホースと接続する金具はホームセンター「ハンズマン」で購入。

水が流れるとセンサーから流量に応じたON/OFF信号が出ます。ウチの水ポンプの場合1秒あたり25から35発くらい出ていました。それを90円マイコンのPIC12F629で検出し、10発/秒以上なら水流ありの判定としました。水流が無い時は2pinがH,3pinがL、水流ありならその逆を出します。そして2pinから2SC1815を通してレーザーを強制OFFにしていますが、これだともし2SC1815が故障したらレーザーをOFFにできないのであんまりよい回路ではないと思いますが、簡単に後付するためこうなってしまいました。

WaterFlowSensowI/F

水流センサーインターフェース
後付けなので宙ぶらりんです。

このあたりの回路をCNCシールドに載っけるのが結構面倒です。とりあえずはLinuxCNCで動いているので、やっぱり「ぼちぼち」になりそうです。

参考までにPIC12F629のプログラムをここにアップしておきます。
(MPLAB IDE 8でコンパイルしています)

Grbl,CNCシールド

レーザー加工機ではこれまでLinuxCNCを使ってきました。
PCと加工機の間はプリンターケーブルでつないでいます。

LaserCutterController

こんな感じ・・・

 

このあたり、最近はGrblというのが流行りの様です。これだとArduino経由で接続するためプリンターポートが無いノートパソコンでも制御できます。
先日見せていただいたぽんさんのレーザー加工機もGrblを使われており、気になっていました。
またこちらのサイト「
自作CNCマシン・レーザーカッターについて」も大変参考になります。

最近Grblにはレーザー加工機用のモードが追加されたそうです。このモードはヘッドのスピードが落ちた時にレーザーを弱めてくれるとの事で、今まで直角の曲がり角とかは焼き過ぎっぽかったのが解消されるかもしれません。

AliExpressにはArduino UNOとCNCシールドがセットで¥1009-で売られていました。早速購入し、すでに到着しております。
CNCシールド

なんか、ステッピングモータードライバのヒートシンクが3つしか入っていないです。
まあ当面ふたつしか使わないですが。

ついでに2.54mmピッチの3pinコネクターも買いました。ラジコンサーボとかで使うアレです。
サーボは3pinでよいのですが、よく考えるとステッピングモーターは4ピン、センサー類は2ピンのハウジングが必要です。一緒に発注しておけば良かったです。これらを正月休み中に部品店に買いに行ければいいのですが…

2.54mmピッチコネクタ

2.54mmピッチコネクタ

・・・という訳で、ぼちぼちやっていきます。

FRISKサイズのUSBジョイスティック

OpenStickLiteが使える様になったので、Laser加工機用に小型のジョイスティックを製作しました。

これまでLaser加工機のジョグ制御には、下の様なジョイスティックを使用していました。見覚えがある方もいらっしゃるかもしれませんが、MakerFaireではラジコンシミュレータのコントローラに使用しているものです。
今回、OpenStickLiteを使って場所を取らない小型のものを作ろうと思います。

LaserCutterController

これまでのLaser加工機のコントローラ。
ちょっと大きくて邪魔になる。

 

X-Y軸入力のスティックはジャンクのゲームコントローラーから外したものです。HardOFFで108円で買ってきたコントローラをバラしてストックしています。
これはX-Yのアナログ制御に加えスティック自体を押し込む事でボタンをON/OFFできます。今回入力デバイスはこれ一つだけで、
X-Y軸とボタン1個だけにしました。

JoysticksFromPS

PlayStation用コントローラから外したジョイスティック

 

簡単に回路を描いて・・・

LaserStickSchematic

Laser制御用ジョイスティック回路図

 

基板切削CNCで削って・・・ 

LaserStickPCB

LaserStick基板
(実は一部パターンをミスっており、この後手配線で修正しました)

 

FRISKのケースに入れました。
FRISKはケースサイズが変わるという話ですが熊本ではまだ従来サイズしか見かけません。今回使用したのも従来サイズです。

LaserStick2

フリスクケースに収納。

 

中身はこんな感じです。
PIC18F14K50はフリスクケースにピッタリ。
部品がとっても少ないです。

LaserStick3

水晶発振子周りのスペースが厳しくなってしまったので、水晶を少し浮かして取付け、更にショート防止のためカプトンテープで保護しました。

LaserStick4

斜めからみたところ

 

コンフィグはこれを書き込みました。

LaserStick Configuration

今回のOpenStickConfigLiteの設定。
入力信号はX-Y軸とボタン1個だけ。

 

またLaser加工機に取付ける為、3Dプリンタでホルダーを製作しました。

LaserStick with Holder

ホルダーと小型ジョイスティック

そして加工機に取り付け!!

LaserStick6

ホルダーと共に加工機に取付けた図。

PIC18F14K50採用で小型機器が作り易くなりました。
SOP版を使うともっと小型化できそうです。

 

動画にしてみました。 2016-10-25

 

皮にレーザーマーキング~その2~

前回はくまモンを試し描きしたところまででした。
すこし大きすぎて皮の端切れからはみ出したので今回は少し小さくしてみます。

まず少し小さめのくまモンをPNG型式で作成します。背中も含めました。

そしてレーザーでマーキング。方法はこのあたりに書いた通りです。

少しですが加工中の動画を撮ってみました。

リングをつけてカシメで止めてキーホールダーにしてみました。
(この金具はカシメっていうんですかね。皮革加工は初めてなのでわかりませんが店ではそういう名札が付いていました。なんかそのままのネーミングです。因みにこれをカシメる道具は持ってないので万力で挟みました)

KumamnoKeyholder

くまモンキーホールダー
輪郭はハサミで適当に切ったのでガタついてしまいました。

暫く使用した後撮影したので既に剥げています。レーザーがスキャンした方向にスジ状に剥げているのでもう少し密度を上げてマーキングすると良いかもしれません。因みにこの時は144dpiの設定でした。

このキーホールダーは家の鍵に付けて使用しています。

Laser加工機製作 ~その14 LinxCNCでレーザーラスター加工 まとめ~

前回まででLinxCNCによるレーザーラスター加工が可能になりましたが課題もあります。

  1. 中間階調が出ない。
    今の所ONとOFFのみで写真等は綺麗に描画できません。
    細かい点の密度で階調を表現する様にgmaskファイルを生成すれば出るかもしれません。あるいはPWMでレーザーパワーを調整する様にHALを書き換えるとか・・・
    いずれ試したいと思います。
  2. TouchOffボタンにより座標系原点を機械原点と異なる値にすると正常動作しない。
    HAL内でX軸の位置を取得している「axis.0.joint-pos-fb」は機械座標での位置を返す様です。TouchOffボタンでワーク座標系を機械原点と異なる値にすると*.gmaskに書かれたX位置と一致せず、正しい位置でレーザーが出ません。 何か方法がありそうな気がしてマニュアルを読んでいるのですが・・・わかったら報告します。

そんなこんなで色々とありますが最低限の動作はした、という感じです。

なおLinuxCNC自体についてはhttp://linuxcnc.org/が、
またドキュメントの一部を日本語化されているシマリス技研さんのサイトも大変参考になりました。

 

Laser加工機製作 ~その13 LinxCNCでレーザーラスター加工 Graster~

ここ何回かRastering With a Laserに沿ってLinuxCNCによるラスター加工について書いてきました。今回のGrastarをインストールする事で任意の画像データを変換しレーザー加工機で出力するまでの流れが完結します

Grasterの動作

Grasterは画像データをLinuxCNCに喰わせる形に変換するプログラムで、Rubyで書かれています。 例えばKumamon.pngという画像ファイルをGrasterで処理すると、次の3つのファイルが生成されます。

  • Kumamon.png.raster.ngc ラスター描画時にレーザーヘッドの移動を制御するNCコードです。
  • Kumamon.png.raster.gmask ラスター描画時にレーザーのON/OFFを制御するデータです。上記NCコード実行時に読み込まれます。
  • Kumamon.png.cut.ngc 外形カット用NCコードです。

まずはRuby関係のツールをインストール
Grasterを動作させる為、まずはRubyとその関連ファイルをインストールします。ほいほい堂のUbuntu上ではapt-getにより以下のツールをインストールしました。

sudo apt-get install ruby
sudo apt-get install imagemagick
sudo apt-get install librmagick-ruby1.8
sudo apt-get install rubygems1.8

前回の投稿でダウンロードしたGrasterファイル
Graster自体は前回の投稿に書いた通り、下記コマンドで入手します。 ※前回の投稿は当初リンク切れのアドレスを載せていたので後日修正しています。

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

Grasterの動作確認と修正
ダウンロードしたGrasterを解凍するとgraster-masterディレクトリ下にbin/grasterというファイルがあります。これが実行すべきコマンドファイルですが、私の環境では次のエラー出ました。

$ ./bin/graster
/usr/bin/env: ruby -rubygems: そのようなファイルやディレクトリはありません

どうやらbin/grasterファイルの先頭行「#!/usr/bin/env ruby -rubygems」で引っかかっている様です。  /usr/bin/envでrubyへのパスを指定した場合、引数があると環境によってはエラーになるそうです。そこで次の様にrubyへのパスを直接指定してエラー回避しました。

$ diff graster.ORG graster
1c1
< #!/usr/bin/env ruby -rubygems
---
> #!/usr/bin/ruby -rubygems

これでとりあえずはエラー無く変換ができる様になったのですが、実際に加工機で描画してみると正しい場所でレーザーが出力されません。またレーザーヘッドの動作範囲が妙に狭い様です。 原因は次の通りと思われます。

  • Grasterはインチ単位の動作を前提に書かれている。 私の加工機はLinuxCNCの設定で、ミリ単位を基本にしています。本来インチで書かれたNCコードをミリと解釈しているためレーザーヘッドの動作範囲が狭くなっています。 また、xxx.raster.gmaskファイルにはX軸が所定の箇所に達したら次の動作(レーザーをON/OFFしたり)に移るという動作が書かれていますが、これもインチで書かれています。 これに対し加工機がhalに知らせるX軸のポジションがミリなので、ここも上手く行きません。
  • xxx.raster.gmask中の記述が往復描画と片道描画が混乱している。 ラスタースキャンではレーザーヘッドが往復する際に右向きと左向き両方で描画する方法と、片方向のみ描画する方法があります。速度と精度のトレードオフなのですが、生成されたgmaskはこの両方の方式が混ざって記載されている様で正しく制御できていませんでした。

以上2点の対策として次の方針で変更しました。

  • 単位はミリで出力する。 あまりややこしく考えず、座標を出力するデータ全てに25.4を掛けるという方法で修正しました。 よって出力はミリ単位になっていますがオプション入力での数値はインチのままです。
  • 片方向描画に統一したgmaskファイルを生成する。 とにかく片方向描画が正しく出来るファイルを生成する様に変更します。

これらを変更したところ、それっぽく動作する様になったのですが、描画の最後の方だけレーザーが出ないという問題が発生しました。 動作の最後の方になるとなぜかstreamerからデータが出てこなくなります(LinuxCNCのバグではないかと思っています)。結局原因は判っていないのですが、streamerのバッファにデータがたっぷりあればこの現象が発生しない様なので、gmaskファイル生成時にデータを余分に出す事で逃げています(全フィールド0の行を400行ほど余分に出力しています)。 本来LinuxCNCの最新バージョンでどうなるかを試すべきですが・・・いずれやってみます。

Graster修正結果
最終的に変更したのは次の内容です(それと上に掲載したbin/grasterもです)。

$ diff lib/graster.rb.ORG lib/graster.rb
177c177,178
<     @image.size[1].times {|y| @tiled_rows << tiled_row_spans(y, (forward = !forward)) }
---
>     #@image.size[1].times {|y| @tiled_rows << tiled_row_spans(y, (forward = !forward)) }
>     @image.size[1].times {|y| @tiled_rows << tiled_row_spans(y, (forward)) }
219a221
>     gmask.epilogue
$ diff lib/graster/gmask_file.rb.ORG lib/graster/gmask_file.rb
13,15c13,15
<         self << "0 0 0 %0.3f\n" % x1 if @begin_row
<         self << "0 0 1 %0.3f\n" % x1
<         self << "0 1 1 %0.3f\n" % x2
---
>         self << "0 0 0 %0.3f\n" % (x1*25.4) if @begin_row
>         self << "0 0 1 %0.3f\n" % (x1*25.4)
>         self << "0 1 1 %0.3f\n" % (x2*25.4)
17,19c17,19
<         self << "0 0 1 %0.3f\n" % x1 if @begin_row
<         self << "0 0 0 %0.3f\n" % x1
<         self << "0 1 0 %0.3f\n" % x2
---
>         self << "0 0 1 %0.3f\n" % (x1*25.4) if @begin_row
>         self << "0 0 0 %0.3f\n" % (x1*25.4)
>         self << "0 1 0 %0.3f\n" % (x2*25.4)
22a23,29
>
>     def epilogue
>       (0..400).each do |x|
>         self << "0 0 0 0\n"
>       end
>     end
>
$ diff lib/graster/gcode_file.rb.ORG lib/graster/gcode_file.rb
35c35
<           "#{k.to_s.upcase}%0.3f" % v
---
>           "#{k.to_s.upcase}%0.3f" % (v*25.4)

修正版一式
修正版一式をアップしておきます。

使用方法
次の様に使用します。 各種パラメーターはカレントディレクトリのgraster.ymlに書いておくとデフォルトとして使用されます。下の例では画像のドットを300dpiとして描画する様に指定しています。実行後、上に書いた3本のファイルが出来ています。

%graster –dpi 300,300 Kumamon.png

変換後のファイルもアップしておきます。  

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