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

DIY CNC Machine.Taipei 造訪社團 » 控制

原文網址 Shelandy Ting
2020-03-04 15:02:47

某空間有人留下小型CNC雕刻機,但是沒有控制器,想用最少的金錢讓他動起來。聽說用印表機埠的控制會比用usb好。我可以找到一個有parallel port 的舊電腦(或是arduino 樹莓派之類的單板機)來接控制卡。請問
*是去對岸買parallel port 的GRBL控制卡:CNC(X/Y/spindel +x/y/z 限位 ) 接 控制卡 接 電腦 印表機埠 這樣就硬體可以動了嗎?(還是有其他要接的硬體?)
*採購卡時有沒有啥要注意的地方(早期某個設計有雷,或是某個卡便宜又大碗...
*有沒有人閒置控制卡要出清的?


原文網址 石小川
2020-02-14 08:56:23

好久沒在這裡發表文章了,容我在此分享一下Python TCP/IP遠程監控機台程式實作。

網路發達後要做到機器設備遠端監控已非遙不可及了,網路通信在無人工廠的監控設備上會越來越重要。 圖中展示的系統是TCP/IP通訊協定的主從(Server-Client)式架構,TServer伺服端程式負責現場機器設備運作及回傳Sensor數據和即時影像給TClient用戶端處理。
為了方便教學緣故,已將網路封包加密演算法及帳號管理拿掉,通信程式精簡許多,比較容易理解,伺服端是以C#實作,用戶端會以C#及Python各實作一個版本。建議伺服端以C++或C#為主,而用戶端可用Python設計遠端控制APP,將來回傳的遙測大數據可很容易的用Python模組分析。

熟悉遠端操控軟硬體對將來有志設計無人工廠機器設備的朋友幫助很大,習得一技之長絕對增加競爭力。2月分我將開此TCP/IP主從式通信實作課程,因為現在病毒肆虐,採遠距教學方式較適合,沒有機器設備的同學我會提供兩台三軸機台做遠距連線操控練習,可在家寫Python程式做遠端連線操控,詳細辦法及日期我再擇期公布,歡迎有興趣的朋友來報名上課。

林志強
2020-02-14 09:16:55


原文網址 張博翔
2019-12-08 19:18:33

以前使用的脈波信號控制器,5相步進馬達控制器 TR515B。


原文網址 李派克
2019-11-28 17:23:12

覺得市面上的控制器都不是你想要的嗎?

作自己的吧!

David Chuang
2019-11-28 20:24:12

? 看不懂?用電腦主機當控制器?


原文網址 李派克
2019-11-22 18:59:33

來改改modbus控制主軸好了⋯⋯

任宏彥
2019-11-22 20:13:02

好玩有趣的協定

任宏彥
2019-11-22 20:13:51

搞懂它 用pc控不是問題

李派克
2019-11-22 20:14:31

我用modbus很多年了啦~~只是要去組自己的變頻器用的又很懶。。

李派克
2019-11-22 20:17:33

只是最近手上多一個模組想説拿來用⋯⋯


原文網址 陳俊成
2019-10-26 09:59:49

TTL控制

林志強
2019-10-26 10:34:24

林志強
2019-10-27 19:46:37

鬼哥太強啦

陳俊成
2019-10-27 19:47:44

還有很多地方要設定

Genghis Wen
2019-11-22 20:45:18

星雲的?


原文網址 石小川
2019-10-18 22:50:16

光騰書齋十一月份第一梯次課程表

課程: Python 軸控班

課程三小時內容:

*CNC 軸控平台基本知識

*Python 軸控軟體開發平台建立

*Python呼叫動態連結庫(DLL)控制步進馬達 及 I/O Port

*剖析motion.py程式如何控制CNC雷射機台

此次開課目的是想引導有Python基礎的朋友進入CNC有趣的領域,學習後學員可自行用Python控制運動卡, 開發相關應用程式或CNC,學員學習後對軟硬體方面有問題也可用Messenger或Email 聯繫我, 可線上指導。

日期: 2019/11/2(星期六)

A班. 早上 9:00 – 12:00 (適合無CNC硬體基礎者)

B班. 下午 2:00 – 5:00 (適合有CNC硬體基礎者)

日期: 2019/11/3(星期日)

C班. 早上 9:00 – 12:00 (適合無CNC硬體基礎者)

D班. 下午 2:00 – 5:00 (適合有CNC硬體基礎者)

註1 . 每班會招收6 – 8人, 滿6人即開課, Python 軸控班只招收三個 月,名額有限請見諒!

註2. 先統計班級人數, 確定要來上課的朋友請連結光騰臉書報名, 看您選哪一班次(A/B/C/D),並在下面留言A/B/C/D, 我會主動用Messenger連路您, 人數夠了再通知匯款並傳Quantum講義給您(NT$3500)。

上課地點: 基隆

報名連結 >>> 光騰臉書 : https://www.facebook.com/qmlab/


原文網址 石小川
2019-10-03 19:28:13

使用Python語言做自動控制的方法 - I 軟體篇

[語法簡單明瞭]

Python語法簡單易學,最重要的是還有大量功能強大的免費模組可下載,其強大的應用層面已經發展到令人不可忽視的重要地位,甚至NASA也拿來當作航太人機介面的控制語言。早期接的專案我都是用Assembly、C、C++、C#等設計自動控制系統,這幾年我很多是改用Python來撰寫,好處是取得系統傳回的資料後,可很容易且快速的結合各種海量模組演算法發展出很專業的人工智慧機器。

[Python是跨平台語言]

Python本身沒有支援特定硬體控制的功能,也正因為如此它才能夠跨平台,但這不是原罪,相反的卻是它的優點,換句話說,在x86、Arm、Arduino、PC、手機或平板等不同的作業系統環境下,相同的程式皆可以很容易互相移植過去正常執行,這 print('免費資源 + 免費的模組 + 簡單易學') 根本是一場世界革命,能不紅嗎!

綜合以上講了一大堆,無非就是要說服工程師們是該改變自已接受世界脈動的時候了,我也不例外,以此共勉之!

[軟體開發]

接下來進入主題談論如何用Python開發一個多軸的CNC平台,會舉這個CNC專題當作例子是因為在我眼裡,CNC其實就是一個機器人,我的經驗是~只要搞懂CNC軟硬體知識後,無論是自駕車、四軸無人機或是工具機皆是囊中物,至於想要用它做些甚麼,端看你無限的想像力而定!

因為Python沒有直接存取硬體的介面,我的方法是用Python當作主程式,將底層存取硬體的API程式(動態連結程式庫 DLL)封裝成Python可調用的格式即可,如此一來多年使用C++/C#寫的程式庫都可引用了。因為程式很長, 為免洗板我簡略敘說過程如下:

(A). 封裝DLL程式庫成PyCNC.py 模組,其中 class __IMC_Pkg()就是封裝成類別的名稱, 將來Python與機器溝通的介面就是依靠這項。

#---------------------------------------------------------------------------

# 這是被呼叫的模組 : PyCNC.py

#---------------------------------------------------------------------------

# 需引用ctypes

import ctypes

import ctypes.wintypes

#------------------------------------------------------------------------------

class __IMC_Pkg():

def __init__(self):

self.ptr = ctypes.WinDLL('IMC_Pkg.dll') # _stdcall

#---------------------------------------------------------------------------

def Open(self, netcardId, imcId):

self.ptr.PKG_IMC_Open.argtypes = (ctypes.c_int, ctypes.c_int)

self.ptr.PKG_IMC_Open.restype = ctypes.POINTER(ctypes.c_voidp)

return self.ptr.PKG_IMC_Open(netcardId, imcId) #---------------------------------------------------------------------------

def Close(self, handle):

self.ptr.PKG_IMC_Close.argtypes = (ctypes.POINTER(ctypes.c_voidp), )

self.ptr.PKG_IMC_Close.restype = ctypes.c_int

return self.ptr.PKG_IMC_Close(handle)

#---------------------------------------------------------------------------

def MoveAbs(self, handle, pos, startvel, tgvel, wait, axis):

self.ptr.PKG_IMC_MoveAbs.argtypes = (ctypes.POINTER(ctypes.c_voidp), ctypes.c_int, ctypes.c_double, ctypes.c_double, ctypes.c_int, ctypes.c_int) self.ptr.PKG_IMC_MoveAbs.restype = ctypes.c_int

return self.ptr.PKG_IMC_MoveAbs(handle, pos, startvel, tgvel, wait, axis)

#---------------------------------------------------------------------------

def MoveAbs_P(self, handle, pos, startvel, tgvel, wait, axis): # P 輔助座標

self.ptr.PKG_IMC_MoveAbs_P.argtypes = (ctypes.POINTER(ctypes.c_voidp), ctypes.c_int, ctypes.c_double, ctypes.c_double, ctypes.c_int, ctypes.c_int) self.ptr.PKG_IMC_MoveAbs_P.restype = ctypes.c_int

return self.ptr.PKG_IMC_MoveAbs_P(handle, pos, startvel, tgvel, wait, axis)

.

.

(B). 主程式motion.py 要引用也很簡單, 只要加上PyCNC.py模組,就可以調用IMC_Pkg所有的功能

#---------------------------------------------------------------------------

# 這是主程式 : motion.py

#---------------------------------------------------------------------------

from CNC import PyCNC

IMC_Pkg = PyCNC.__IMC_Pkg()

#---------------------------------------------------------------------------

if(self.gHandle != None):

IMC_Pkg.Close(self.gHandle)

self.gHandle = IMC_Pkg.Open(netcardId, imcId)

if(self.gHandle != None): #//if(IsOpen())

if(IMC_Pkg.InitCfg(self.gHandle) != 0):

self.nAxis = IMC_Pkg.GetNaxis(self.gHandle) # 取得設備支援軸數

p, self.Position = self.GetPosition(3)

(C). 建議開發環境安裝Anaconda開發包, 在設計Python程式時可少走很多冤枉路,為了相容以前DLL程式庫,我是下載Anaconda3 - 32bit - Python3.7.3版本。

p.s. (1). IMC3xx/IMC4xx系列運動控制卡所有函數(IMC_Pkg.dll)我都有封裝成PyCNC.py以方便Python呼叫,有興趣的朋友可加入我臉書討論。

((2). 圖-1. 八軸運動+I/O+AD/DA控制卡應用圖例

圖-2. motion.py 主程式的視窗介面

影片-1. 使用motion.py 展示CNC軸控,也順便Demo飛行搖桿控制3軸及發射雷射

影片-2. 電腦執行motion.py情形

影片-3. 使用motion.py 執行G-Code,用雷射雕刻一個正圓

(3). 下回有機會再補上 : "使用Python語言做自動控制的方法 - I I 硬體篇"及 "使用Python語言做自動控制的方法 - I I I 通信篇" (UART、USB、TCP/IP)兩篇才算完整,並且教導大家如何組裝一台三軸運動控制平台的知識(機械結構及控制電路的接法),對於想創業設計自已機器的朋友不要錯過了。在臉書不適合長篇大論所以只能簡單敘述,總感覺見樹不見林,當然我也有開相關的指導課程,有興趣的朋友可上我臉書或私訊我。

Wei-Hsiung Huang
2019-10-03 19:48:42

Nice..

便宜十塊錢
2019-10-03 19:49:49

Python好用+1
我幫公司做一個簡易Web資訊看板
用一台PLC+乙太模組做收集各產線資訊
(我很懶得拓樸一大堆通訊線,跑RS485 To Zigbee)
由乙太模組把資訊先推到ModbusTCP層
再由Python讀ModbusTCP把讀到的值推到前端Web上
簡易的產能看板
跨平台真的好用

吳小東
2019-10-03 22:16:58

深深認同

石小川
2019-10-03 23:30:37

good job! 這是很好的應用, 以前接工廠資料收集器專案, 通信用RS232, 十台一大捆線, 現在看太不可思議了, 哈哈^^

便宜十塊錢
2019-10-03 23:57:01

石小川 我收集的PLC有做類心跳封包,只對有開機的機台通訊,不然Timeout會拖慢速度,越多台沒開越慢,所有的數值都在各機台PLC處理好,再收集
另外還有外加自動紀錄(5天)+控制各站自動歸零(各站開機時規零)

便宜十塊錢
2019-10-04 00:08:16

這個是第一個有線通訊(4台)
現在在做的無線(9台)快好了
規劃排點位跟處理問題較麻煩 ?

石小川
2019-10-04 12:12:53

感謝分享, 在關燈無人工廠掘起後, 機台間的通信越來越重要了, 大大的技術應該很有潛力, 我還停留在十幾年前TCP/IP抓封包技術, 有機會再請教您^^


原文網址 李派克
2019-10-01 14:17:19

我的數位小車⋯⋯

螢目先膠帶貼一貼...有空再來畫盒子貼...

目前這個主軸的servo 用VFD的控制方法。等我有空再把A軸的function也接進去。這樣應該可以作點有趣的事。。


原文網址 石小川
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

感謝大大分享