C#程式控制Mach3運動卡的方法(二)
 
 
  上回寫的程式版本是透過USB HID介面直接控制Mach3, 這次版本是透過Mach3橋接, 用它提供的API做控制, 好處是幾乎所有Mach3功能皆可實作, 壞處是Mach3必須先執行, 這樣做有甚麼好處呢? 主要是二次開發用, 會自已寫程式的人(C# , C++, VB)可加入演算法提升CNC的功能, 例如可在CNC加入OpenCV做影像辨識或做3D工件掃描建模功能, 或者加入類神經網路做深度學習….等等, 下次有機會我們再詳細討論這部份. 本章重點是簡單介紹開發步驟, 以C#程式語言為例(其實任何語言皆可, 只是呼叫方式略有不同而已)如下:
 
 
  (1)正常機碼必須有下列註冊檔, 否則程式無法呼叫API(有個補救方法, 下載Mach3Registry.reg, 執行可產生).
 
 
  xxxxxxxxxx : 每套機碼不一樣.  [HKEY_CLASSES_ROOT\CLSID\{xxxxxxxxxxx}]  @="Mach4.Document"
 
 
  [HKEY_CLASSES_ROOT\CLSID\{ xxxxxxxxxxx]  @="ole32.dll"
 
 
  [HKEY_CLASSES_ROOT\CLSID\{ xxxxxxxxxxx }\LocalServer32]  @="C:\\Mach3\\Mach3.exe"
 
 
  [HKEY_CLASSES_ROOT\CLSID\{ xxxxxxxxxxx }\ProgID]  @="Mach4.Document"
 
 
  [HKEY_CLASSES_ROOT\Mach4.Document]  @="Mach4.Document"
 
 
  [HKEY_CLASSES_ROOT\Mach4.Document\CLSID]  @="{ xxxxxxxxxxx }"
 
 
  (2)在C# /專案/加入參考/ 將Mach3.exe 加入參考,
 
 
  並在程式前面加入
 
 
  using System.Runtime.InteropServices;
 
 
  using Mach4;
 
 
  (3)主要操作就是這項, 一旦取得Mach3的handle(mInst), 就可長驅直入使用其提供的所有功能(功能可參考Mach3 Version3.x Macro Programmers Reference Manual.pdf) .
 
 
  IMyScriptObject mInst = null;
 
 
  try
 
 
  {
 
 
  Mach4 mach = (Mach4.IMach4)
 
 
  Marshal.GetActiveObject("Mach4.Document");
 
 
  mInst = (Mach4.IMyScriptObject)
 
 
  mach.GetScriptDispatch();
 
 
  }
 
 
  catch
 
 
  {
 
 
  }
 
 
  (4)程式有點長, 為避免洗版, 只好摘錄部分程式如下(有疑問或有興趣找我研發的也歡迎私訊我!):
 
 
  //---------------------------------------------------------------------
 
 
  //Mach3 Control Process
 
 
  //---------------------------------------------------------------------
 
 
  private IMyScriptObject GetMachInstance()
 
 
  {
 
 
  IMyScriptObject mInst = null;
 
 
  try
 
 
  {
 
 
  IMach4 mach = (Mach4.IMach4)
 
 
  Marshal.GetActiveObject("Mach4.Document");
 
 
  mInst = (Mach4.IMyScriptObject)
 
 
  mach.GetScriptDispatch();
 
 
  }
 
 
  catch
 
 
  {
 
 
  }
 
 
  return mInst;
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private bool DoEmButton(short number)
 
 
  {
 
 
  if(_mInst != null)
 
 
  {
 
 
  _mInst . DoOEMButton(number);
 
 
  return true;
 
 
  }
 
 
  return false;
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void DoGCode(string code)
 
 
  {
 
 
  if(_mInst != null)
 
 
  _mInst.Code(code);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void sendMDI()
 
 
  {
 
 
  if(textBoxMDI.Text.Trim() != null)
 
 
  {
 
 
  DoGCode(textBoxMDI.Text.Trim());
 
 
  }
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private double[] UpdateDRO()
 
 
  {
 
 
  double[] dro = new double[3];
 
 
  if(_mInst != null)
 
 
  {
 
 
  dro[0] = _mInst.GetOEMDRO(800);
 
 
  dro[1] = _mInst.GetOEMDRO(801);
 
 
  dro[2] = _mInst.GetOEMDRO(802);
 
 
  }
 
 
  return dro;
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  //dir = 0 to + direction, dir = 1 to - direction
 
 
  private void xJogStart(DirectionType dir)
 
 
  {
 
 
  if(_mInst != null)
 
 
  _mInst.JogOn((short)AxisType.X, (short)dir);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void xJogStop()
 
 
  {
 
 
  if(_mInst != null)
 
 
  _mInst.JogOff((short)AxisType.X);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void yJogStart(DirectionType dir)
 
 
  {
 
 
  if(_mInst != null)
 
 
  _mInst.JogOn((short)AxisType.Y, (short)dir);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void yJogStop()
 
 
  {
 
 
  if(_mInst != null)
 
 
  _mInst.JogOff((short)AxisType.Y);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void zJogStart(DirectionType dir)
 
 
  {
 
 
  if(_mInst != null)
 
 
  _mInst.JogOn((short)AxisType.Z, (short)dir);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void zJogStop()
 
 
  {
 
 
  if(_mInst != null)
 
 
  _mInst.JogOff((short)AxisType.Z);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonStart_Click(object sender, EventArgs e)
 
 
  {
 
 
  DoEmButton(1000); //start
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonFeedhold_Click(object sender, EventArgs e)
 
 
  {
 
 
  DoEmButton(1001); //Feedhold
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonStop_Click(object sender, EventArgs e)
 
 
  {
 
 
  DoEmButton(1003); //Stop
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonMDI_Click(object sender, EventArgs e)
 
 
  {
 
 
  if(_mInst != null && textBoxMDI.Text.Trim() != null)
 
 
  _mInst.Code(textBoxMDI.Text.Trim()); //senMDI
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void timerUpdateDRO_Tick(object sender, EventArgs e)
 
 
  {
 
 
  double[] dro = UpdateDRO();
 
 
  textBoxX.Text = dro[0].ToString("#0.0000");
 
 
  textBoxY.Text = dro[1].ToString("#0.0000");
 
 
  textBoxZ.Text = dro[2].ToString("#0.0000");
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonPX_MouseDown(object sender, MouseEventArgs e)
 
 
  {
 
 
  xJogStart(DirectionType.Positive);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonPX_MouseUp(object sender, MouseEventArgs e)
 
 
  {
 
 
  xJogStop();
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonNX_MouseDown(object sender,
 
 
  MouseEventArgs e)
 
 
  {
 
 
  xJogStart(DirectionType.Negtive);
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  private void buttonNX_MouseUp(object sender,
 
 
  MouseEventArgs e)
 
 
  {
 
 
  xJogStop();
 
 
  }
 
 
  //---------------------------------------------------------------------
 
 
  p.s. 一手操作一手攝影, 非專業攝影, 影片有些抖動請見諒!
 
														 
								 
										
					
						 辛育全
						辛育全
						2019-04-30 12:37:03
					
					
				 
				
					
						 Steve Wu
						Steve Wu
						2019-04-30 13:01:22
					
					
				 
				
					
						 張益晟
						張益晟
						2019-04-30 18:27:16
					
					
				 
				
					
						 Chihfu Huang
						Chihfu Huang
						2019-04-30 19:13:38
					
					
				 
				
					
						 沈宗麟
						沈宗麟
						2019-04-30 21:32:50
					
					
				 
				
					
						 徐豪宏
						徐豪宏
						2019-05-01 00:33:13
					
					
				 
				
					
						 Yu Tseng
						Yu Tseng
						2019-05-01 10:28:23
					
					
				 
				
					
						 林志強
						林志強
						2019-05-01 17:14:23
					
					
				 
				
					
						 吳治彥
						吳治彥
						2019-05-04 22:53:05
					
					
				 
				
					
						 石小川
						石小川
						2019-05-05 16:23:49
					
					
						
 
  謝謝! 感謝以上兄弟們熱烈回應!
 
 
 
  我是有些野人獻曝, 班門弄斧之感, 所幸大家善良. 在本社團內臥虎藏龍, 有經驗的CNC實務高手很多, 不結合一起做出好產品實在可惜, 畢竟要會玩也要會養家糊口, 哈哈哈! 想借此版拋磚引玉一下, 是否可腦力激盪, 集思廣益一下, 大家提出CNC專案或其他智慧機器由有興趣有能力的成員加入一起完成,  至於專案成立, 負責出資, 材料, 利潤分紅等細節我再想想, 會尊重此版規定, 跟管理員商討是公開或私訊方式. 以上是我初步構想, 看是否有正反意見皆可提出!