• #maker+t=market
  • 3D列印服務
  • COSPLAY 3D 建模
  • 1
  • 2
  • 3

DIY CNC Machine.Taipei 造訪社團 » 參考

原文網址 李派克
2019-11-27 23:17:52

epoxy的話,大家可以參考一下這個人的做品

David Chuang
2019-11-28 17:30:19

我就是看他的


原文網址 Yu Tseng
2019-11-06 15:31:06

https://www.youtube.com/watch?v=eC2Po2yJz74&feature=youtu.be

一個印尼人做的. 不會轉發, 就貼上連結, 大家參考.

話說, 有人有興趣搞一個嗎?

Daniel Lee
2019-11-06 19:18:04

好厲害!

林志強
2019-11-06 19:44:38

林志強
2019-11-06 19:44:44

漂亮

黃培恩
2019-11-06 20:18:51

阿强老板+1

黃培恩
2019-11-06 20:19:02


原文網址 石小川
2019-09-15 18:13:06

使用飛行搖桿控制CNC C#版程式範例

這個羅技飛行搖桿本來是用在一個從頭城出發要去一個遙遠地方的大台UAV,看到挑戰國內法令的罰款可能會罰到脫褲子, 所以只能收手不玩了, 天空不能玩了, 就換地上及海上囉, 於是把程式移植到CNC, 運作起來還蠻順手的, 像是 夾娃娃機, 其實不管是CNC軸控、太空船、飛機或機器人, Joystick程式是一樣的。

以前玩Apple-II時曾經用6502組合語言改寫地球保衛戰的電玩, 大意是太空衛星發射雷射光射向入侵地球的飛碟, 但不可以射到底下建築物否則扣分, 這個CNC Demo頗有幾分神似呢, 特別是雷射扳機打開發射時, 感覺還蠻爽的^^

下面是控制搖桿程式庫TJoystick, 分享給有興趣的好友參考一下, 可很容易地加入自已的機台:

因為主程式很長, 所以只列出TJoystick程式庫, 主程式就不po了, 有興趣再私下討論了。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using SharpDX;

using SharpDX.DirectInput;

namespace TJoystick

{

public enum JoyDirectionType

{

Center,

zUp,

zDown,

Up,

Right,

Down,

Left

}

//-------------------------------------------------------------------------

public class Joystick

{

SharpDX.DirectInput.DirectInput dirInput;

SharpDX.DirectInput.DeviceType typeJoystick;

IList<DeviceInstance> Devices;

SharpDX.DirectInput.Joystick curJoystick;

bool bJoystick;

int X, Y;

int RZ;

int Slider;

int POV;

int[] Buttons;

//-----------------------------------------------------------------------

public Joystick()

{

bJoystick = false;

X = 0;

Y = 0;

RZ = 0;

Slider = 0;

POV = -1; //中心點 = -1

Buttons = new int[7];

for(int i=0;i <7; i++)

Buttons[i] = 0;

}

//-----------------------------------------------------------------------

public SharpDX.DirectInput.DeviceInstance FindDevice()

{

SharpDX.DirectInput.DeviceInstance deviceInstance = new DeviceInstance();

deviceInstance.ProductName = "";

deviceInstance.InstanceName = "";

deviceInstance.InstanceGuid = Guid.Empty;

dirInput = new SharpDX.DirectInput.DirectInput();

typeJoystick = SharpDX.DirectInput.DeviceType.Joystick;

Devices = dirInput.GetDevices();

foreach (var device in Devices)

{

if (typeJoystick == device.Type)

{

deviceInstance.ProductName = device.ProductName;

deviceInstance.InstanceName = device.InstanceName;

deviceInstance.InstanceGuid = device.InstanceGuid;

break;

}

}

return deviceInstance;

} //public SharpDX.DirectInput.DeviceInstance Open()

//-----------------------------------------------------------------------

public bool Connect(SharpDX.DirectInput.DeviceInstance deviceInstance)

{

bJoystick = false;

if(deviceInstance.InstanceGuid != Guid.Empty)

{

bJoystick = true;

curJoystick = new SharpDX.DirectInput.Joystick(dirInput, deviceInstance.InstanceGuid);

// Set BufferSize in order to use buffered data.

//curJoystick.Properties.BufferSize = 128;

curJoystick.Acquire();

//curJoystick.Poll();

//curJoystick.GetCurrentState();

//Thread t1 = new Thread(PollThreadFunction);

//t1.IsBackground = true;

//t1.Start();

}

return bJoystick;

}

//-----------------------------------------------------------------------

public bool IsGetJoystick()

{

return bJoystick;

}

//-----------------------------------------------------------------------

public int[] GetJoystickData()

{

int[] data = new int[12];

data[0] = X;

data[1] = Y;

data[2] = RZ;

data[3] = Slider;

data[4] = POV;

for(int i=0; i<7; i++)

data[5 + i] = Buttons[i];

return data;

}

//-----------------------------------------------------------------------

public double NormalizationScale(double a, double b, int mindata, int maxdata)

{

double k=(b-a)/(maxdata - mindata);

return k;

}

//-----------------------------------------------------------------------

public double NormalizationData(double data, double a, double b, int mindata, int maxdata)

{

double k=(b-a)/(maxdata - mindata);

double normdata = a + k * (data - mindata);

if(normdata > b)

normdata = b;

else

if(normdata < a)

normdata = a;

return normdata;

}

//-----------------------------------------------------------------------

public double[] Signal_XY()

{

double[] data = new double[2];

data[0] = X;

data[1] = Y;

data[0] = NormalizationData(data[0], -128, 127, 69, 164);

data[1] = NormalizationData(data[1], -128, 127, 71, 201);

return data;

}

//-----------------------------------------------------------------------

public double Signal_RZ()

{

double rz = NormalizationData(RZ, -128, 127, 80, 216);

return rz;

}

//-----------------------------------------------------------------------

public double Signal_Slider()

{

double slider = NormalizationData(Slider, 0, 10, 45, 180);

return slider;

}

//-----------------------------------------------------------------------

public int[] Signal_POV()

{

int[] data = new int[2];

if(POV == -1) //Center

{

data[0] = -1;

data[1] = 0;

}

else

if(POV == 0) //Up

{

data[0] = 0;

data[1] = 0;

}

else

if(POV == 35) //Right

{

data[0] = 1;

data[1] = 0;

}

else

if(POV == 70) //Down

{

data[0] = 2;

data[1] = 0;

}

else

if(POV == 105) //Down

{

data[0] = 3;

data[1] = 0;

}

return data;

}

//-----------------------------------------------------------------------

public bool Signal_Button0()

{

if(Buttons[0] == 1)

return true;

return false;

}

//-----------------------------------------------------------------------

public void Poll()

{

try

{

//curJoystick.Acquire();

// poll the joystick

curJoystick.Poll();

// update the joystick state field

var joys = curJoystick.GetCurrentState();

X = joys.X >> 8; // X/256

Y = joys.Y >> 8; // Y/256

RZ = joys.RotationZ >> 8;

Slider = joys.Sliders[0] >> 8;

POV = joys.PointOfViewControllers[0] >> 8;

for(int i=0; i<7; i++)

Buttons[i] = Convert.ToInt32(joys.Buttons[i]);

}

catch (SystemException)

{

}

} //public void Poll()

//-----------------------------------------------------------------------

public void PollThreadFunction()

{

while(true)

{

Poll();

} //while(true)

} //public void JoystickThreadFunction()

} //public class TJoystick

} //namespace TJoystick

黃俊凱
2019-09-15 19:02:51

水喔,這個蠻實用

廖元佑
2019-09-15 19:39:01

感謝分享

Don Si
2019-09-16 13:25:58

感謝大大分享


原文網址 李派克
2019-09-02 17:19:02

# 更新 -- 補上 AMD RYZEN 3700 的不專業測試在最下面,也感謝Bise Chen 大大。

感謝各位前輩幫忙出的點子

感恩 朱興耀 大大的幫忙,讓我可以實驗一下我下一台電腦需要的方向

昨天測試的結果整理一下紀要:

1我的爛圖在fusion360上用朱大哥的機子32 CORE跑的結果,飛快,主要的原因cpu的時脈夠高,又可以多工處理。基本上,可以同時算七八個cam路徑

2. 我的i7因為是NB,四核就算全跑也只能跑一次一個cam路徑,但ram 16g 看來還是有餘

3. mac mini的i7 試的結果跟我的i7 的windows10 版本差不多速度

4.感謝另一位不露名的好友,支援我一台12 core的電腦,大概可以一次跑4個cam路徑, ram的話也是有餘,

綜合以上的結論,fusion360在cam(render的改天再試)的部份看來:

a. core數越多越好,可以同步運算

b. 時脈看來也是越高越好,每個路徑算時可以再更快

c. GPU在這邊用cam的部份應該沒什麼大幫助,可能在render圖上才會有感覺

d. RAM 反倒是夠就好,在這邊應該沒什麼主要因素,如果有影響應該主要還是ram的時脈

e. AMD 的cpu 因為我沒機子,所以沒得測,但估計在這邊主要運算還是無理數浮點運算,看來AMD討不太到便宜,應該有呼應到AMD的cpu有許多前輩說在這邊不好用的說法

Finally, 看起來多核多工處理還是最重要的,如果有需要潤圖才需要gpu數高的顯卡,但不知道fusion360有沒有辦法徹底去使用AMD(ATI)的引擎或是nV 的cuda..

再次感謝前輩們的幫忙,這個是大家幫忙的,所以把這些測的感受公佈讓大家知道,也不知道正不正確,反正多少有點參考價值。總之,有這個社團可以發問跟解惑真好!!!

以上!再次誠摯謝謝大家!

# 補上AMD3700的不專業測試

同一個圖,如果單比CAM一個路徑,看起來跟i7 跑一個路徑差不多,但這顆cpu的好處是多核的多工,感覺一次跑五個路徑真的好爽。{感謝@Bise Chen 提供機器讓我試一下}。

# AMD最近真的也是好物出一堆

# 如果我沒買AMD最大的理由應該是我想跑黑蘋果吧

Che Min Lin
2019-09-02 17:24:41

32核是Ryzen Threadripper 2990WX嗎?

朱興耀
2019-09-02 17:25:17

我只是剛好有在做動畫__有一台老機器<<真的還不夠用

朱興耀
2019-09-02 17:31:39

寫的好棒受教了

李派克
2019-09-02 17:41:56

哈˜˜這些都要歸功於各位大大

David Chuang
2019-09-02 17:41:57

原來如此 @@ 受教了

李派克
2019-09-02 17:42:24

我也是大受教了...

李派克
2019-09-02 17:43:37

我對這顆也有點興趣,不知道有沒有大大買這顆的

許阿瑋
2019-09-02 17:47:39

看來要組真香機了~~~~~~~~

李嘉祥
2019-09-02 18:04:47

NB與PC真的有不少效能落差

尤宏耀
2019-09-02 18:31:16

若要組電腦要如何配置,可以來討論一下!

吳水豚
2019-09-02 18:49:37

fusion 360 用ryzen並不會比較差~多核同時運算的效率 三代AMD RYZEN 還是比較高...

李派克
2019-09-02 18:59:03

可能吧。這個我沒機子。沒辦法實測

Bise Chen
2019-09-02 19:05:58

李派克 之前二代跟現在的三代RYZEN是沒辦法相提並論。比方說二代用Adobe全家桶表現不太好,但三代RYZEN則可說問題都解決了。

因此以往有人說AMD不如INTEL 那個以前可以算數,現在可就不見得了。

同樣的效能下,你願意多花錢就買Intel,想省錢可以買AMD。

吳水豚
2019-09-02 19:14:32

沒關係啦~你就去買INTEL好了~~~~

李派克
2019-09-02 19:23:51

吳水豚 你有事嗎?

李派克
2019-09-02 19:24:08

Bise Chen
2019-09-02 20:42:10

其實也還好…差個5~6千而已…^_^

盧修圻
2019-09-02 20:53:52

Bise Chen 站在系統開發的角度來說,AMD和INTEL比還是差很遠,可靠度和一些毛病還是I社比較少,AMD CPU他們自己的產品還porting不出來要靠3rd party救,這兩家有預算還是用I吧! 要不是I社之前產能不足,大家替代料只好往RYZEN去,不然它那波應該沒賣這麼好

AMD的CPU,摸多一點才會覺得怎麼這麼鳥 @@

Bise Chen
2019-09-02 21:07:04

盧修圻 你高興就好...XD

李派克
2019-09-02 21:09:36

Bise Chen 這種東西個自去體會就好了˜大家不用再討論

吳水豚
2019-09-02 21:09:42

盧修圻 繪圖軟體上INTEL處理器因為BUG更新後有時會有一點點的卡頓現象,我有顧客是設計公司,效能上差異多少先不說,但是那減少的卡頓現象,對設計時候的手感差很多...不過有質疑的話你就買INTEL就好....要不然到時候疑神疑鬼,自己心情不好...之前輸入數值,會停一下才能打數字....後來換RYZEN這問題就處理掉了~

Bise Chen
2019-09-02 21:10:58

李派克
我這裡上個月初剛組好一組 R7-3700 你要不要試試看?
要的話我來裝 Fusion 360...XD

李派克
2019-09-02 21:12:18

李派克
2019-09-02 21:12:40

我只要連進去試一下 看是anydesk或是teamview都可以

Bise Chen
2019-09-02 21:12:43

李派克 我抓一下...

李派克
2019-09-02 21:14:13

感謝您。。我個人其實沒有偏好那家的cpu,我唯一一台桌機也是AMD的。。有點老了 2008年組的,當時為了我的相機2460w畫素裝的。。

李派克
2019-09-02 21:16:20

說真的,我認真在看2990 WX中...

盧修圻
2019-09-02 21:16:56

吳水豚 那都是要fine tune所以要是會不順也不用意外,當然是挑順手的東西用,我只是就我自已做開發的角度在看兩家的產品, CPU我抽屜很多,還是那個道理,自已家裡開麵店的人不想吃麵,一顆幾萬的CPU下班後也不會想再碰,我自已在用的電腦還是六年前組的鳥機 XD

哪個CP值高就用哪個囉

Bise Chen
2019-09-02 21:20:38

李派克 ..........Fusion360 怎麼抓?..@@
之前都可以抓,現在一堆問題好像是教育授權過期...@@

李派克
2019-09-02 21:22:17

我可以連進去幫你處理

吳水豚
2019-09-02 21:23:06

盧修圻 反正就核心數加上去時脈加上去...速度就出來了~卡頓問題我只是說國外AUTODESK討論區上面之前2018年的結論跟處理方式,我對我客人也是同樣處理,也是正面回應~不過新版的2020年版本似乎有改善INTEL的.

Bise Chen
2019-09-02 21:24:22

李派克 私訊給你~

吳水豚
2019-09-02 21:40:48

盧修圻 反正用AMD跟INTEL差異到頂都不大,他想用INTEL就用INTEL~

Clarence Lee
2019-09-03 11:25:33

李派克
2019-09-03 11:29:22

大哥是對的

李派克
2019-09-03 11:30:07

GPU 出現很少...

方明亮
2019-09-03 21:06:59

gpu 應該是負責給我們「看」且好不好看。

cpufpu 才是算

有誤請指正

便宜十塊錢
2019-09-09 21:21:44

如果是要多工運算,執行緒多寡有點影響,相對軟體也要有支援多執行緒運算,以上參考


原文網址 石小川
2019-08-14 13:40:17

淺談 G-Code 產生器

窮忙一陣子後今天終於可偷閒寫一下文章跟大家分享一下上回談的G-Code產生器了. 我用最簡單的CNC圓形切割來圖文解釋一下, 相信應該可以很快了解其中運作原理.

先解釋一下Entity名詞, Entity在CAD工程上是實體的意思, AutoCAD出圖後的元件我們稱為Entity, 如圓弧, 直線, 雲行線等皆是實體. 上回提過由DWG/DXF檔案 經過程式剖析分解後產生一連串Entity的資料, 如圖一, 是圓的Entity, 將它送入GCodeCircle(Entity) 函式就可很快地產生切圓的G-Code, 下面是GCodeCircle(Entity)程式範例:

//-------------------------------------------------------------------------

public string GCodeCircle(EntityRecord entityrecord)

{

string gCode = "";

Point3D center = new Point3D(entityrecord.Circle.Center.X, entityrecord.Circle.Center.Y, entityrecord.Circle.Center.Z);

double radius = entityrecord.Circle.Radius;

Point3D point = new Point3D(0, 0, 0);

point.X = center.X + radius;

point.Y = center.Y;

gCode += "G00 X" + (point.X - center.X).ToString("#0.0000") + " " + "Y"+ (point.Y - center.Y).ToString("#0.0000") + " " + "Z5.0000"+ "\n";

//此段是為了說明已經簡化許多參數

gCode += "G01" + " " + "Z-1.0000"+ " " + "F200"+ "\n";

gCode += "G02" + " " + "I-"+ radius.ToString("#0.0000");

return gCode;

}

圖二是產生的G-Code, 可直接送去機器做切割一個100mm的正圓.

另外之前有位朋友問我5軸聯動切向跟隨實作問題, 我列出部分程式碼給您參考一下, 基本上我大部分實作都是圓弧直線插補ArcLine()就可完成.

//---------------------------------------------------------------------------

//圓弧直線跟隨插補

//pos : Z軸直線運動位置

//axisNum = 3, 圓弧+直線運動軸數 X Y Z

public boolArcLine(int startx, int starty, int endx, int endy, int cx, intcy, int[] pos, int[] axis, int dir = 0, int axisNum = 3, double acc = 10, doubletgvel = 100, double endvel = 0, double feedRate = 1.0, int wait = 1, intfifo = (int)FIFO_SEL.SEL_PFIFO1, boolbAbs = true)

{

int st;

if(axisNum < 2 || axisNum > MAX_NAXIS)

return false;

//清空PFIFO

st = IMC_Pkg.PKG_IMC_PFIFOclear(gHandle, fifo);

if(st == 0)

return false;

//設置加速度和進給率

if(SetPFIFO(acc, feedRate, fifo) == false)

return false;

//映射軸

st = IMC_Pkg.PKG_IMC_AxisMap(gHandle, axis, axisNum, fifo);

if(st == 0)

return false;

double dx,dy;

dx = startx - cx;

dy = starty - cy;

double r1 = Math.Sqrt(dx * dx + dy * dy);

dx = endx - cx;

dy = endy - cy;

double r2 = Math.Sqrt(dx * dx + dy * dy);

//判斷, 如果起點到圓心距離r1 != 終點到圓心距離r2 表示圓弧軌跡不正確, 跳出不執行

if(r1 != r2)

return false;

//由當前位置移動到指定位置

if(bAbs) //絕對位置

st = IMC_Pkg.PKG_IMC_ArcLine_Pos(gHandle, endx, endy, cx, cy, dir, pos, axisNum - 2, tgvel, endvel, wait, fifo); //絕對位置

else

st = IMC_Pkg.PKG_IMC_ArcLine_Dist(gHandle, endx, endy, cx, cy, dir, pos, axisNum - 2, tgvel, endvel, wait, fifo); //相對位置

if(st == 0)

return false;

return true;

}

圖三是我執行雷射切割的機台, 雷射頭是5.5W藍光雷射, 下回再分享此G-Code雷射切割成果.

p.s. 在我的APP程式直接畫圖我是直接呼叫運動卡驅動CNC, 沒有經過G-Code產生器這道手續, 加快CNC處理速度, 除非是匯入DWG/DXF檔案才會呼叫G-Code 產生器。

黃小法
2019-08-14 14:25:41

這個有開源?

Jade Yang
2019-08-14 15:07:20

無私 , 給你讚。字串相加可改用 $”{}”你以後看才不會累


原文網址 石小川
2019-07-11 17:28:35

DWG/DXF to CNC 工程 I - DWG/DXF圖檔解析篇

對於想用CNC製作一些零組件的朋友來說,要學會AutoCAD、SolidWork、uG、Fusion360、ARTCAM、PowerMill、 MasterCAM、Mach3等,我相信會嚇跑一票人的熱血。其實CAD/CAM套裝軟體很強但有很多功能幾百年也用不到,只是浪費錢而已,在接工廠自動控制客製化軟體方面絕大部分作動都很單純,我這裡是將所有功能精簡成 : /檔案/機器/刀具/G-Code sender,只要讀檔或在螢幕寫字、繪圖後自動產生G-Code直接送至CNC銑床或雷射加工,盡量能由機器代勞的就盡量隱藏在程式裏面,操作介面就只有一個螢幕面板Panel。

要做到這點須先解析DWG檔案結構,後續追加功能才有辦法走下去,AutoCAD DWG檔案簡直就是一個複雜的巨型圖層資料庫而且每兩年改版一次,建議還是用DXF圖檔相容性較高,有機會再談談DXF檔結構。這裡先分享一下DWG解析方法給有興趣研發的好友參考一 下。

基本上程式要解析其中的資料結構如下,有點長刪減一些函數但原理不變。

讀取DWG檔後打開資料庫取實體EntityName的字串名稱(約50個標籤名稱)一層層解析後繪圖即可原圖重現,看你要加圖、刪圖或送去產生G-Code等,另外如果用不著的功能就略過,沒必要全部實作,有興趣可一起討論,下回再討論G-Code產生器。

//-------------------------------------------------------------------

public void Draw(List<CadParse> cadparselist)

{

foreach(CadParse cadParse in cadparselist)

{

switch(cadParse.EntityName)

{

case "AcDbAlignedDimension":

break;

case "AcDbArc":

break;

case "AcDbArcDimension":

break;

case "AcDbBlockReference":

break;

case "AcDbBody":

break;

case "AcDbCircle":

DrawCircle(cadParse);

break;

case "AcDbPoint":

break;

case "AcDbDiametricDimension":

break;

case "AcDbViewport":

break;

case "AcDbEllipse":

DrawEllipse (cadParse);

break;

case "AcDbFace":

break;

case "AcDbHatch":

break;

case "AcDbLeader":

break;

case "AcDbLine":

DrawLine(cadParse);

break;

case "AcDb2LineAngularDimension":

break;

case "AcDbMInsertBlock":

break;

case "AcDbMline":

break;

case "AcDbMText":

break;

case "AcDbOle2Frame":

break;

case "AcDbOrdinateDimension":

break;

case "AcDb3PointAngularDimension":

break;

case "AcDbPolyFaceMesh":

break;

case "AcDbPolygonMesh":

break;

case "AcDbPolyline":

DrawPolyLine(cadParse);

break;

case "AcDb2dPolyline":

break;

case "AcDb3dPolyline":

break;

case "AcDbProxyEntity":

break;

case "AcDbRadialDimension":

break;

case "AcDbRasterImage":

break;

case "AcDbRay":

break;

case "AcDbRegion":

break;

case "AcDbRotatedDimension":

break;

case "AcDbShape":

break;

case "AcDbSolid":

break;

case "AcDb3dSolid":

break;

case "AcDbSpline":

break;

case "AcDbTable":

break;

case "AcDbTrace":

break;

case "AcDbWipeout":

break;

case "AcDbXline":

break;

case "AcDbPdfReference":

break;

case "AcDbDwfReference":

break;

case "AcDbDgnReference":

break;

} //end switch(cadParse.EntityName)

} //end foreach(CadParse cadParse in _cadParseList)

} //end public void Draw()


原文網址 石小川
2019-05-10 16:49:04

介紹一款CNC運動控制卡給喜歡自已寫控制程式的人參考

通常我不在社團內介紹商品以免有廣告之嫌, 不過這個運動卡我用過好幾個專案, 可控制自由度高, 一年了也沒出問題, 所以決定分享給社團好友參考.

如圖所示 IMC3xx2E 運動卡簡介: 我用的的是八軸及六軸聯動運動卡, 介面是採用RJ45網路線傳輸控制碼到機台, 以八軸卡來說內有80個輸入/ 48個輸出, 足夠一般機器使用, 在PC也是用ethernet 與運動卡通訊, 好處是防雜訊比USB好很多, 而且網路線可拉很長很長, 只要你網路可通的話!

我的重點是廠商有提共完整的API函數庫(VB, VC++, VC#, QT)讓你控制CNC所有功能, 包括網卡搜尋, 八軸運動, I/O狀態, 圓弧直線插補, 族繁不及備載, 該有的應該都有了, 端看你要如何應用, 我打算用跑Linux 的ARM板做脫機, 我這裡有一些相關pdf資料, 如果有興趣的人可mail我.

程式控制很簡單, 以C#為例:

(1)專案加入IMC_PKG.cs

(2)程式前面加上 using imcpkg;

//---------------------------------------------------------------------

//單軸連續移動(continue)

private void MachineMove(int axis, bool bDirection)

{

double acc = 10;

double startvel = 100;

double tgvel = 100;

IMC_Pkg.PKG_IMC_SetAccel(Global.gHandle,

acc, acc, axis);

if(bDirection)

IMC_Pkg.PKG_IMC_MoveVel(Global.gHandle,

startvel, tgvel, axis);

else

IMC_Pkg.PKG_IMC_MoveVel(Global.gHandle,

-startvel, -tgvel, axis);

}

//---------------------------------------------------------------------

//單軸移動至指定位置(step)

private void MachineMove(float pos, int axis)

{

double acc = 10;

double startvel = 100;

double tgvel = 100;

int pulse_per_mm = 5120; //steps_per=pulse/mm

int dist = (int)(pos * pulse_per_mm);

IMC_Pkg.PKG_IMC_SetAccel(Global.gHandle,

acc, acc, axis);

IMC_Pkg.PKG_IMC_MoveDist(Global.gHandle,

dist, startvel, tgvel, 0, axis);

}

//---------------------------------------------------------------------

David Chuang
2019-05-10 16:58:12

我有興趣

Allen Chang
2019-05-10 16:58:29

宜震陳
2019-05-10 17:00:32

? ?

蔣益民
2019-05-10 17:17:22

您可以將檔案分享到社團的檔案區

石小川
2019-05-10 17:28:31

ok! 已分享乙太網運動卡兩個檔案至社團檔案區, 有需要的可參考看, 軟硬體有問題可互相討論!

Don Si
2019-05-10 17:41:53

感謝分享

黃小法
2019-05-10 18:01:49

不好意思,小弟愚拙,這個該怎麼應用到CNC上??介面要自己搞??

Cheng Chris
2019-05-10 18:49:02

請教一下如果是大機台的那種可以嗎

辛育全
2019-05-10 19:33:52

哥價格落在哪?

盧人菖
2019-05-10 22:02:48

林錫義
2019-05-10 22:54:33

可以控制伺服馬達?

陳竑吾
2019-05-11 01:07:41

謝謝推薦!很實用的資訊

吳忠哲
2019-05-11 11:17:22

用這個來做CNC的話,可以享受自己搞一個Mach3的樂趣是嗎?


原文網址 石小川
2019-04-30 12:34:34

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
2019-04-30 13:01:22

張益晟
2019-04-30 18:27:16

?

Chihfu Huang
2019-04-30 19:13:38

沈宗麟
2019-04-30 21:32:50

厲害

徐豪宏
2019-05-01 00:33:13

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專案或其他智慧機器由有興趣有能力的成員加入一起完成, 至於專案成立, 負責出資, 材料, 利潤分紅等細節我再想想, 會尊重此版規定, 跟管理員商討是公開或私訊方式. 以上是我初步構想, 看是否有正反意見皆可提出!


原文網址 陳啟耀
2019-04-12 09:27:56

請問各位如果想要組一台300*400mm的Cnc
需求主要木工,次要軟金屬(銅.鋁)
可能考慮滾珠螺桿加直線滑軌水冷主軸,大概都是想買大陸的。

預算約莫2、3萬台幣有沒有辦法。

各位有推薦的機架嗎
以及推薦的四軸控制卡嗎
想參考各位的配置。感謝。

或是有人要賣二手的給我也是可以 ?


原文網址 石小川
2018-10-13 12:53:47

用C++/C# 程式直接控制USB Mach3 CNC運動控制卡簡介

分享給想要了解Mach3及USB控制卡如何通訊的朋友參考.

Mach3 USB程式是以HID裝置類型通訊協定作為溝通管道, 因為現在Windows 作業系統都有內建支援HID裝置的驅動程式, 所以焦點只要設計PC應用程式即可, 省掉很多麻煩事情.

如果用抓封包工具程式(Wireshark 或 Bus Hound)觀察Mach3 USB封包可得知, HID報告描述元(Report)的每次輸入/輸出資料交易是以61個位元組(Byte)為單位送出或接收, 只要解析這些位元組即可直接控制USB Mach3 CNC運動控制卡, 不須Mach3介入, 這樣做的好處是可以自已設計一些人工智慧演算法(例如影像辨識)去直接控制CNC機台做自動光學檢測(AOI), 或改裝CNC成機器手等. 當然有些非Mach3 CNC控制卡廠商有推出API開發包, 應用程式直接呼叫API就更方便了, 這樣就不需要了解煩人的底層封包問題, 不過這篇是要分享給想設計類似Mach3程式或製作USB Mach3 CNC運動控制卡的人參考, 由於資料太多, 不想洗板, 我就列出部分範例提供參考.

我的CNC機器裝置配備是USB Mach3 CNC六軸連動控制卡, 螺桿Pitch=5mm, 步進驅動128細分.

解析後的封包資料如下:
基本上Reset , M code, G Code都要解碼.

(A)繼電器控制
M204/M205碼我是規劃成繼電器控制警示燈
M204 Code(Output 7 ON) :
public string[] Output = { "02 06 58 00 09 20 00 00 f0 f7 19 00 97 b1 9d 06 44 f8 19 00 00 01 00 00 9c b4 9e 06 00 00 00 00 1c f8 19 00 0c f8 19 00 10 80 9d 06 44 f8 19 00 00 01 00 00 9c b4 9e 06 1c f8 19 00 00" };

M205 Code(Output 7 OFF) :
public string[] Output = { "02 06 58 00 09 00 00 00 f0 f7 19 00 97 b1 9d 06 44 f8 19 00 00 01 00 00 9c b4 9e 06 00 00 00 00 1c f8 19 00 0c f8 19 00 10 80 9d 06 44 f8 19 00 00 01 00 00 9c b4 9e 06 1c f8 19 00 00" };

p.s. 標註的02 06 58 是M控制碼, 09 20/09 00 是On/Off作動參數.

(B)步進馬達控制
G0 Xn Code :
public string[][] G0X = {
//G0 X0
new string[]
{"02 0e 55 e6 ff 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 06 df 59 77 34 ef 55 77 f8 5b 38 a0 00 00 00 00 00 c0 2c 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00",
"02 0e 55 b4 ff 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 06 df 59 77 34 ef 55 77 f8 5b 38 a0 00 00 00 00 00 c0 2c 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00",
.
.
};

p.s. 標註的02 0e 55 是G0控制碼, e6 ff/b4 ff 是馬達脈衝參數.

另外值得一提的是Mach3步進馬達的脈衝控制是以圖中(G0 X5)所示的方式控制, 只要遵照斜率及內插數值就可組合出想要馬達移動的距離及速度了, 如果是六軸連動當然更複雜了!

沒圖沒真相, 最後簡單的寫了一個小程式Demo一下, 有興趣的朋友可參考一下囉!

林志強
2018-10-13 13:00:25

好強啊

Brian Kuo
2018-10-13 13:23:48

您是解析USB HID 的byte array來進行驅動控制板,印象中Mach3 軟體有提供API可以直接控制。可能會更方便哦,之前有下載但一直沒時間玩。。。

感謝您的分享哦~ 謝謝您

蘇炳文
2018-10-13 13:37:38

感謝分享,以前都用wireshark抓Ethernet封包觀看Internet的protocol,現在才知道也可以抓USB封包,太好用了。

Kenny Plus
2018-10-13 15:01:18

大大好強

Suadia Wu
2018-10-13 17:53:26

大大開個手把手的課啦~

廖元佑
2018-10-14 08:55:55

好厲害

李大熊
2018-11-03 00:13:00

連G Code都出來了 哈哈哈