2014年12月24日 星期三

土砲 CNC:控制器和韌體 (Grbl)

接續前篇:土砲 CNC:電機部份
我們把馬達和電磨機裝好後, 接著就要控制它們了
由於原先 3D 印表機的主板有問題所以決定上網重買
找來找去都沒看到順眼的, 後來不知道哪天心血來潮換了個關鍵詞搜尋
結果找到這:

Arduino CNC Shield!真是屌爆了!(?)XD
真是佩服老外吃飽撐著時的娛樂XD 居然連這種都做 kit 出來
在大量生產的優勢下上圖這堆全部加起來只收一張小朋友
控制器, 馬達控制 IC, 與電腦的連線, 統統都準備好了
本來想說找不到順眼的就自己開板子, 看來不需要了
雖然是用 Arduino 但這不代表就一定要用 Arduino IDE
慣用 C 語言 (簡稱慣C) 是本實驗室的規矩, 上圖右拉出來的線就是燒錄器界面
USB 只當 USB Serial 使用



這板子採用 A4988 馬達控制器, 和 3D 印表機的相同, 可同時驅動四顆馬達
上圖標有 XYZA, XYZ 馬達都有獨立的 CLK 和 DIR 接腳
然後提供跳線可將 A 和 XYZ 任選進行並聯
以我的機器就是和 Y 軸接, 並接 A4988 的 CLK 和 DIR 接腳
意思就是 Y 和 A 兩馬達會有相同的旋轉方向, 且會同時移動
這設計很明顯就是要給雙馬達 Y 軸的用戶使用的
既然是 A4988 就有微步設定, 由於板子面積小, 擺設緊湊
所以微步設定 (MS0-2) 被放在 A4988 模組下方
替換不方便 (雖然這也不是會需要常更改的設定)
所以我把所有需要跳線的都直接從背面焊死

jumper 也是要花錢買的, 拿剪下的零件接腳焊上去就是了, 簡單又不用錢!

對 3D 印表機來說步進馬達牽引的列印頭重量不重, 不需要太多扭力
把 A4988 偏壓設在 0.37V 就足夠了, 所以也不需要大散熱片, 可是 CNC 就不一樣了
偏壓 0.37V 時用手用力抓是可以讓它掉步的, 設到 0.55V 才比較夠力
可是 0.55V 上去散熱片超燙, 感覺再用久一點就要冒煙了, 看起來很危險, 所以要調整

做機構時留下不少鋁板散件, 切四小塊放上去, 後面用散熱雙面膠和 A4988 黏好
然後......

用 Atom CPU 在用的散熱片疊上去, 由於疊上去後會蓋住馬達輸出接點
所以要先用電線將接點引出 (即上圖藍紫雙色電線)
這樣測試一下運作 30 分鐘溫度會到 57 度左右, 手摸上去還行
不過如果要更長時間運轉還是加個風扇比較好

接好後可以開始準備軟體, 循著 CNC Shield 的網頁過去, 就會看到更厲害的東西
這 CNC Shield 可不只是硬體解決方案, 連軟體都做好了
還在想要花多少時間才能做完, 結果都有了, 真是太棒了
這韌體是 Grbl , 2009 開始, 由開源社群發展
採用 C 語言設計, 相同功能函數放同一檔案並有相同的前置命名, 多檔案維護的源碼
完全符合本實驗室精神, 並應用許多 AVR 平台硬體功能, 計時器, 中斷等
其核心轉速計算程式在 2013 年中時有超過 120 個開源專案移植去使用
程式碼包含大量註解說明, 目前是 0.9 版, GPL 協議
後來似乎會改 MIT 協議, 真是慷慨到不行, 那我還寫啥? 用就對了!XD
由於直接裝上就能用, 馬上就發現它控制的方式很不一樣 (正確說是我門外漢沒見過世面XD)
引入轉速控制, 對此我翻了一下源碼, 記下一些心得

對於機械控制, 正常的情況我們會需要許多的感測器來了解當前的狀態
控制時依據感測器傳回訊息來進行操作, 所以會有前篇的 PID 方法
用在 CNC 就是我們可能會需要知道當前銑刀移動到哪
如果發現掉步 (missing steps) 就要多轉幾下補回去, 這樣才會精確
可是這種東西不便宜, 可能一軸量測設備的錢都可以買一台甚至多台 3D 印表機了
而且有感測器反饋還會讓程式變得更加複雜, 所以我們就要換個方法
不要感測器的 CNC, 解決掉步問題就是 "避免它掉步", 只要不發生, 我們就可以不理它
Grbl 透過多種策略自動調整轉速來避免掉步發生
假設移動銑刀走一段直線, 那麼 Grbl 會以這樣的速度控制:

X 軸是時間, Y 軸是速度, 中間的面積就是移動的距離
一開始逐漸加速, 抵達最大速度時維持定速, 快到目的地後開始減速
這樣的設計和馬達的力矩有關, 參考資料:Stepping Motion Profiles in Realtime
簡略敘述:
牛頓第二運動定律 F = m * a
馬達的力矩是有限的, 所以加速度也是受限的, 能產生的加速度和負載的質量有關
加上前篇 用 A4988 控制步進馬達 敘述, 馬達低速時力矩最大, 速度越快力矩最小
所以最高速度也是受限的, 如果快到連阻動力矩都克服不了時, 它就轉不動了
一旦操作馬達時超出這些限制, 它就會掉步, 然後又沒有感測器回報, 操作就會失敗
所以如果不依賴感測器, 就必須謹慎的管控這些速度和加速度, 這樣才可迴避掉步問題
步進馬達加速的形式還有別種選擇, 有興趣可 Google 搜尋 stepper speed profile

如果總是加上這些加速度限制, 理論上就可以正常的完成工作, 那是大多數的情況
源碼裡註解有提到, 當執行大量小幅度的線段時, 這種算法會惹上麻煩, 尤其曲線

上圖左下角有條曲線, 如果要讓機器畫出這種曲線, 通常它會被轉換成許多小線段
也就是紅色箭頭指處, 如果我們依照前面的加速度規則下去運算
每段線段的速度變化會變成藍色虛線指的地方, 也就是許多三角形
意思就是因為線段過短, 所以運轉時間也短, 它還來不及升到最高速就要開始減速了
這種曲線如果是從 G code 的曲線指令下的或許還有一些調整空間
但是有些模型轉換軟體會自動產生大量線段來趨近曲線
對 CNC 機器來說看到的就是一堆線段命令, 它沒法知道我們要做曲線
自然就是依照標準速度控制, 然後就會出現超龜速移動的現象
解決這問題 Grbl 用一種應該是數值方法的方式來計算
算法原文介紹:Improving Grbl: Cornering Algorithm
當兩條線段連在一起時, 規劃移動速度會如下圖

中間的 Vjunction 就是兩線段連結點的速度, 前一線段規劃速度時不會降到 0
而是降到一個計算過的值, 這個值和兩條線之間的夾角有關
如果這兩條線夾角接近 180 度, 那它就很可能是高密度曲線
就算不是, 這樣的夾角表示前進方向並沒有改變太多, 也不需要減速
如果這夾角是 90 度或更小, 表示它會進行大迴轉, 那就要確實減速
即使這線段是曲線的一部分也要這麼做, 算法如下:

Ventry 是第一條線的速度向量, Vexit 是第二條線的速度向量
這兩條線夾角為 θ, 綠色線 δ 為一常數, R 為圓的半徑
這個圓會接觸到兩向量且距離兩向量的接點距離為 δ
我們可以透過上圖右的算式求得 R 的長度
式子(1):基本 sin 函數, θ, δ, Ventry 邊組成的三角形來計算
式子(2)(3):把它左右搬移一下, 得到求 R 的算式
由於式子 (3) 可以用其下方的算式替換, 結果就是我們只要運用兩次開根號就求得解
雖然我們畫圖可以很清楚知道 θ 的角度, 但是 CNC 機器只收到該往哪裡移動
它並沒法知道夾角, 而求這夾角需要頭痛的 acos 來先找到 θ 值
對 AVR 這種 8-bit MCU 這會是運算負擔, Grbl 改用這來算可以大幅提昇效能
這段程式在 planner.c 中的 plan_buffer_line 函數

計算後求得 R, Vjunction = sqrt(a * R), a 是加速度值, 最大值由使用者設定
我很無聊的用 gnuplot 畫出 sqrt(R) 和線段夾角的曲線, 指令如下

gnuplot -e "set terminal png size 800,400" \
-e "set xrange [0:210]" \
-e "set yrange [0:50]" \
-e "set xtics 15" \
-e "set xlabel \"Vector Angle (degrees)\"" \
-e "set ylabel \"sqrt(R)\"" \
-e "set key left" \
-e "plot \
  sqrt((0.02*sin((x*pi/180)/2))/(1-sin((x*pi/180)/2))) title 'Deviation = 0.02', \
  sqrt((0.1*sin((x*pi/180)/2))/(1-sin((x*pi/180)/2))) title 'Deviation = 0.1', \
  sqrt((1*sin((x*pi/180)/2))/(1-sin((x*pi/180)/2))) title 'Deviation = 1'" > gplot.png

結果:


或是直接上 Google!XD
搜尋:sqrt((0.02*sin(x/2))/(1-sin(x/2)))


Deviation 即是 δ 值, 它是一使用者設定的常數, Grbl 預設為 0.02
3D 印表機預設為 0.1, 1 是我無聊亂選的誇張值XD
可以發現夾角越接近 180 度 (Google 那張圖則是 3.14), Vjunction 就會越大
當曲線轉向幅度不大時它就不會減速, 就可以消除曲線龜速移動的問題
而當夾角縮小時, Vjunction 會掉的很快, 差不多到 135 度時就幾乎是減速到 0 再重新加速

計算完成後會放到 block_buffer 中
plan_buffer_line 會由 motion_control.c 裡的 mc_line 來呼叫
mc_line 會持續填充線段, 直到緩衝區滿了才開始做事情
然後呼叫 stepper.c 中的 st_prep_buffer 把計算過的速度資料存入步進馬達控制的緩衝區
接著就由 timer 中斷不斷的移動馬達, 採用 Bresenham 演算法, 中斷函數也在 stepper.c 中
算法可參考前篇:實作 Bresenham 直線演算法
有點不同的是 Grbl 有 AMASS, 提高取樣頻率但走的步數相同, 目前不太懂其優點
Grbl 把這些線段資料以 block 命名, 而算完後進入步進馬達則是用 segment 命名
上面這些算完只有包含線段的起始速度和終止速度, 並不包含中間的速度控制
進入 st_prep_buffer 這函數後會根據起始速度和終止速度決定加速時間
這裡有一些乘除的算式, 變數名為 intersect_distance, 這裡我不太知道它怎算的
從變數名稱看來應該是求從起始速度加速以及從結束速度加速在中途的交點

Vs 為起始速度, Ve 為結束速度, X 軸為時間, Vi 為交叉點速度, 面積為距離
d1 是 Vs 加速到 Vi 走的距離, d2 是 Vi 減速到 Ve 走的距離, D 為總距離
根據 等加速度直線公式 假設加速度固定
應該可以寫出上圖右側的算式, 然後左右搬移後可以求得 d1 的距離
結果...我算出來的和程式裡的差一個運算符, 上圖右下有個紅色的減號, 程式裡是寫加號
我不太知道哪裡出錯了, 不過我相信應該是我錯的XD 這韌體已經佈署在很多機器上了
加上我數學不好, 不需要去質疑它的正確性XD
這裡算完後就可以決定這線段的速度變化曲線
有可能是梯形 (加速後恆定再減速, 即最上面第一張 v-t 圖)
也可能是三角形, 或是恆遞增, 恆遞減...等, 紀錄下後就可以讓步進馬達去運行

上面這些算式都是用來計算移動速度, 並不會動到移動的步數, 該走的步數當然是要確實走完
大致上就這樣, 這韌體還有許多細節, 像是兩端點偵測, 還有一些其他 G code 的功能
那些我目前先跳過, 目前走線方式我比較有興趣
了解移動細節後我們就可以設定原始碼以符合本機設定, 預設值會丟在 defaults.h
我只改這幾項

#ifdef DEFAULTS_GENERIC
  // Grbl generic default settings. Should work across different machines.
  #define DEFAULT_X_STEPS_PER_MM 1280.0
  #define DEFAULT_Y_STEPS_PER_MM 1280.0
  #define DEFAULT_Z_STEPS_PER_MM 1280.0
  #define DEFAULT_X_MAX_RATE 450.0 // mm/min
  #define DEFAULT_Y_MAX_RATE 450.0 // mm/min
  #define DEFAULT_Z_MAX_RATE 450.0 // mm/min
  #define DEFAULT_X_MAX_TRAVEL 200.0 // mm
  #define DEFAULT_Y_MAX_TRAVEL 270.0 // mm
  #define DEFAULT_Z_MAX_TRAVEL 170.0 // mm

DEFAULT_X_STEPS_PER_MM 1280.0
我的馬達加上 M8 螺桿, A4988 設 8 微步, 轉一圈 = 8 * 200 = 1600 微步
M8 的 pitch = 1.25mm, 所以每走 1mm 需要轉 1600 / 1.25 = 1280 微步

DEFAULT_X_MAX_RATE 450.0
這個要用量測的, 沒有馬達規格, 就手動下 G code, 用 feedrate 參數
下到空轉為止然後再減一點, 差不多就好XD

DEFAULT_X_MAX_TRAVEL 200.0
這是最大行程, 前篇有量測過, 直接輸入


改到這裡, 如果用戶手邊有現成商業軟體, 像是 Mach3, MasterCAM 之類的或許可以試試看
本實驗室主力桌機已裝 ubuntu, 沒有 Windows 軟體可用, 所以動手拼一個!
下回→ 土砲 CNC:控制界面軟體

15 則留言:

  1. 下班要回時刪了^^b 那就讓我自言自語一下
    printport 蠻擋路的, 新 PC 幾乎看不到了, 而且用這就等於是電腦版的 GPIO
    這樣最便宜的還要一張小朋友再多一點實在有點貴啊
    這個時代還是 USB 的才讚~XD

    回覆刪除
  2. 我另外的留言好像消失了?,我自己也有做一台雕刻機是用usb的

    lpt界面廣泛都說比較穩,加個擴充卡就好了
    而且用mach3比較趨近數值操控,操作比較便利,我覺得很值得投資
    尤其是自動對刀功能,真的愛不釋手

    回覆刪除
    回覆
    1. 你那台真是有夠貴重, 馬達三顆 16 公斤喔臥槽XD
      lpt 的程式我寫過, 它如果不內建到驅動而只在一般應用程式存取, 會有非常嚴重的時間延遲問題
      不像 uart 或 USB serial 那麼簡單好用, 驅動都不用裝, 換作業系統不用擔心不會動
      而且我已經不買大台桌機了, 沒打電動需求, 都買迷你電腦, 連擴充槽都沒有XD
      我已經停止更新 Windows 了, 除了舊有軟體非必要不再新增, 所以我還是用自己拼出來的軟體吧

      刪除
  3. 我只是希望讓它能往我想要的想法發展,有些忙的沒時間更新,等完成體再來更新
    MACH3裝上去就含驅動了,只是要設定一下,假設要買USB卡的話別考慮E-CUT卡就好了
    用你可用適合的資源就行了,沒有絕對要哪種,符合需求比較重要:D
    你有空可以去逛逛這裡,很多資訊:http://www.diychina.org

    回覆刪除
  4. 想請問一下,你的刀具馬達跟Z軸馬達是插在同一邊嗎?
    還在插在SPNdirg上

    回覆刪除
    回覆
    1. 看不太懂?
      主軸和 Z 軸馬達是固定在同一塊鋁板上
      主軸在鋁板正面, Z 軸馬達固定在背面
      前篇 土砲 CNC:電機部份 (http://wukcsoft.blogspot.com/2014/12/cnc-motor.html) 有圖

      刪除
  5. 所以主軸沒有接到cnc shield上嗎???

    回覆刪除
    回覆
    1. 沒有, 主軸是由另一台獨立的 PID 控制器來控制的

      刪除
  6. 不好意思打擾了,想請問你,關於做龍門雙軸的部分,兩顆馬達吃同樣的訊號,在你的運轉經驗上,會不會出現兩邊沒有完全同步或是機械問題造成該軸的誤差,因為我現在想把我的單軸驅動的龍門改成跟你一樣是雙軸的,不要求精度,只求盡量穩定不要龍門動到卡住,想問問你的經驗,謝謝

    回覆刪除
    回覆
    1. 我的雙軸到目前為止是沒遇過不同步的問題
      只要雙軸用一樣型號的馬達, 吃相同信號且相同偏壓設定的 A4988 (每顆馬達配一片控制板)
      搭配相同品質的聯軸器和滑塊, 以及一樣的螺桿和兩端擋板, 這樣不會有問題的
      但只要有一項不同, 它就可能會有問題!

      刪除
  7. 不好意思 想請問那個A馬達是做什麼用的?

    回覆刪除
    回覆
    1. 請參考文章最上面第二段

      > 然後提供跳線可將 A 和 XYZ 任選進行並聯
      > 以我的機器就是和 Y 軸接, 並接 A4988 的 CLK 和 DIR 接腳
      > 意思就是 Y 和 A 兩馬達會有相同的旋轉方向, 且會同時移動
      > 這設計很明顯就是要給雙馬達 Y 軸的用戶使用的

      刪除
  8. 你好 想問一下 目前看到的控制板上用的是Arduino Nano (網址https://www.ruten.com.tw/item/show?21511596464341) 使用方式(刷韌體,serial)跟UNO一樣嗎 沒有接觸過不太懂 若有資源關鍵字還請分享 謝謝

    回覆刪除
    回覆
    1. 和 UNO 有些不同, 而且這是對岸特製版, 不確定是否和原廠的 Nano 一樣
      刷韌體的方式相同, 都是用燒錄器, 不是用 Arduino IDE
      燒錄後韌體和 PC 通訊上可能不太相同, 如果你懂源碼應該小修改就能動
      但是看你問的問題......我建議你還是買 UNO 比較好XD

      刪除

注意:只有此網誌的成員可以留言。