Machine Design¶
Objectives of the week
- Group assignment
- Actuate and automate your machine Document the group project and your individual
What I did
- I played a little bit with mods, tested the machine, and made a video!
What I learned
- The elegance of mods
- How to use a video editor
If I had the time to go further...
- We would have a better working machine
Files and resources¶
- You can find a complete documentation and all the resources on the group page
Step 1: organizing the work¶
As for the mechanical design, we used Gitlab to share the work. Axel took the main part, i.e. integrating the 4xiDraw and the syrunge pump. My job was to adapt mods and to allow to use it as interface.
Step 2: playing with mods¶
This week was the occasion for me to discover mods a little bit further. Thanks to Axel’s help, we used a modified version of the program machines->G-code->mill 2D svg/png
.
More precisely, we modified only one module: the path to G-cade
module.
Basically, Axel modified the lines to control the servo (changed the Z
commands toM3S
commands), and to enable and disable the Coolant (M8
and M9
commands). Indeed, Axel used the coolant command of the CNC shield as input signal for a custom board controlling the syringe pump. This is documented on the group page and on Axel’s page.
Since we used less parameters than in the basic mods module, I made a little bit of aesthetics, and modified the parameters widgets and the default values of the module. This also allowed me to code a little bit of javascript for the first time. Here is the final modified javascript
//
// path to G-code
//
// Neil Gershenfeld
// (c) Massachusetts Institute of Technology 2018
//
// Updated: Steven Chew
// Date: Feb 20 2019
// Comments: Added option to output in inch or mm
//
// Updated: Axel Cornu & Gilles Decroly 20/05/2019 - adapted for syringe machine
//
// This work may be reproduced, modified, distributed, performed, and
// displayed for any purpose, but must acknowledge the mods
// project. Copyright is retained and must be preserved. The work is
// provided as is; no warranty is provided, and users accept all
// liability.
//
// closure
//
(function(){
//
// module globals
//
var mod = {}
//
// name
//
var name = 'Syringe path to G-code'
//
// initialization
//
var init = function() {
mod.cutspeed.value = '1500'
//mod.plungespeed.value = '1500'
//mod.jogspeed.value = '1500'
mod.jogheight.value = '200'
//mod.spindlespeed.value = '10000'
//mod.tool.value = '1'
//mod.coolanton.checked = false
}
//
// inputs
//
var inputs = {
path:{type:'',
event:function(evt){
mod.name = evt.detail.name
mod.path = evt.detail.path
mod.dpi = evt.detail.dpi
mod.width = evt.detail.width
mod.height = evt.detail.height
make_path()
}}}
//
// outputs
//
var outputs = {
file:{type:'',
event:function(str){
obj = {}
obj.name = mod.name+".nc"
obj.contents = str
mods.output(mod,'file',obj)
}}}
//
// interface
//
var interface = function(div){
mod.div = div
//
// cut speed
//
div.appendChild(document.createTextNode('syringe speed: '))
var input = document.createElement('input')
input.type = 'text'
input.size = 6
div.appendChild(input)
mod.cutspeed = input
div.appendChild(document.createTextNode(' (mm/s)'))
div.appendChild(document.createElement('br'))
//
// jog height
//
div.appendChild(document.createTextNode('jog height: '))
var input = document.createElement('input')
input.type = 'text'
input.size = 6
div.appendChild(input)
mod.jogheight = input
div.appendChild(document.createTextNode(' (mm)'))
div.appendChild(document.createElement('br'))
//
// Inch or mm
//
div.appendChild(document.createTextNode('format:'))
var input = document.createElement('input')
input.type = 'radio'
input.name = mod.div.id+'format'
input.id = mod.div.id+'formatInch'
div.appendChild(input)
mod.formatInch = input
div.appendChild(document.createTextNode('inch'))
var input = document.createElement('input')
input.type = 'radio'
input.name = mod.div.id+'format'
input.id = mod.div.id+'formatMm'
input.checked = true
div.appendChild(input)
mod.formatMm = input
div.appendChild(document.createTextNode('mm'))
}
//
// local functions
//
function make_path() {
var dx = 25.4*mod.width/mod.dpi
var cut_speed = parseFloat(mod.cutspeed.value)
//var plunge_speed = parseFloat(mod.plungespeed.value)
//var jog_speed = parseFloat(mod.jogspeed.value)
var jog_height = parseFloat(mod.jogheight.value)
var nx = mod.width
var scale = dx/(nx-1)
var in_mm_scale = 1
if (mod.formatInch.checked) {
dx /= 25.4
scale /= 25.4
cut_speed /= 25.4
//plunge_speed /= 25.4
//jog_speed /= 25.4
jog_height /= 25.4
}
//var spindle_speed = parseFloat(mod.spindlespeed.value)
//var tool = parseInt(mod.tool.value)
str = "%\n" // tape start
str += "G17\n" // xy plane
if (mod.formatInch.checked)
str += "G20\n" // inches
if (mod.formatMm.checked)
str += "G21\n" // mm
str += "G54\n" // coordinate system 1
str += "G80\n" // cancel canned cycles
str += "G90\n" // absolute coordinates
str += "G94\n" // feed/minute units
str += "F"+cut_speed.toFixed(4)+"\n" // feed rate
//
// follow segments
//
for (var seg = 0; seg < mod.path.length; ++seg) {
//
// move up to starting point
//
x = scale*mod.path[seg][0][0]
y = scale*mod.path[seg][0][1]
str += "M3 S"+jog_height.toFixed(4)+"\n"
str += "G00X"+x.toFixed(4)+"Y"+y.toFixed(4)+"M3 S"+jog_height.toFixed(4)+"\n"
str += "M09\n"// S"+jog_height.toFixed(4)+"\n"
str += "G00X"+x.toFixed(4)+"Y"+y.toFixed(4)+"M09 M3 S"+jog_height.toFixed(4)+"\n"
//
// move down
//
z = scale*mod.path[seg][0][2]
str += "G01 M3 S"+z.toFixed(4)+"\n"
str += "M8 M3 S"+z.toFixed(4)+"\n"
str += "F"+cut_speed.toFixed(4)+"\n" //restore xy feed rate
for (var pt = 1; pt < mod.path[seg].length; ++pt) {
//
// move to next point
//
x = scale*mod.path[seg][pt][0]
y = scale*mod.path[seg][pt][1]
z = scale*mod.path[seg][pt][2]
str += "G01X"+x.toFixed(4)+"Y"+y.toFixed(4)+"M08 M3 S"+z.toFixed(4)+"\n"
}
}
//
// finish
//
str += "M09\n"
str += "M3 S"+jog_height.toFixed(4)+"\n" // move up before stopping spindle
str += "G01 X0Y0\n" //go back to origin
str += "M30\n" // program end and reset
str += "%\n" // tape end
//
// output file
//
outputs.file.event(str)
}
//
// return values
//
return ({
mod:mod,
name:name,
init:init,
inputs:inputs,
outputs:outputs,
interface:interface
})
}())
Step 3: testing the machine and making a video¶
We could finally test the machine, and it worked! The physics is not perfectly mastered, but the machine is modular and allow multiple types of use, and was not the limitation in our case! Additionally to the specification, we could imagine to use the machine to make soft robots as the octobot.
Axel, again, has a lot of good material to take quality pictures and video. We could take a lot of rush of the machine working, and I was charged to make the video. Greta focused on making the doc.
To make the video (I had never done this before), I tested quickly three programs: Windows movie maker, Avidemux, and Shotcut. Very quickly, the third solution showed to be the best: the easier to use and offering a lot of possibilities! I played a little bit with it and its easy interface, and used some filter, as to add text, to modify the speed, and to add pictures. The final video can be found at the top of this page!