├── package.json ├── README.md ├── GCODE └── module.js └── print.js /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Printer", 3 | "description": "The app we use to pass GCODE to our RepRap 3D printer", 4 | "version": "0.0.4", 5 | "private": true, 6 | "dependencies": { 7 | "express": "3.x", 8 | "serialport" : "1.1.0", 9 | "optimist" : "0.6.0" 10 | } 11 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Node.js 3D Printer App 2 | #####This is the Node.js app we use at Redweb to print out objects described in GCODE. 3 | 4 | ###Usage 5 | The app is pretty simple, just execute it and leave it running until completion. There is no point in the applications execution that will require user intervention. 6 | 7 | In order to start the program you need to pass both the serial port you will be connecting to your printer on and the path (either relative or absolute) to the GCODE for the thing your printing. 8 | 9 | ``` 10 | node print.js --port "/dev/tty-blah-blah" --file "printFiles/helloWorld.gcode" 11 | ``` 12 | 13 | The app should work for any device that uses a serial port for communication and is expecting GCODE. Here at Redweb, We have a MKII RepRap Mendel variant. 14 | 15 | ###Initial Setup 16 | This app uses a few modules, [Voodootikigod's Serialport library](https://github.com/voodootikigod/node-serialport) for communicating with the printer and ["Substack's optimist"](https://github.com/substack/node-optimist) for argument parsing. 17 | 18 | ``` 19 | npm install 20 | ``` 21 | 22 | in the directory with the package.json file will install the modules needed for the app, then you're ready to go. 23 | 24 | ###Possible Arguments 25 | 26 | Manadatory 27 | + --file "PATH/TO/PRINTFILE" 28 | + --port "SERIAL PORT FOR PRINTER CONNECTION. USUALLY /dev/tty.something" 29 | + --baudrate 19200 etc. - The baudrate for the serial port connection 30 | 31 | Optional 32 | + --speed 1.0 - This is a multiplier that will modify the travel rate of the printhead. This is something we need for our printer. -------------------------------------------------------------------------------- /GCODE/module.js: -------------------------------------------------------------------------------- 1 | var settings = { 2 | extrusionMultiplier : 20, 3 | heightMulitplier : 1, 4 | speedMultiplier : 1 5 | } 6 | 7 | function deconstruct(code){ 8 | 9 | var printData; 10 | 11 | printData = code.split('\n'); 12 | 13 | var newData = []; 14 | 15 | var cS = 0; 16 | 17 | while(cS < printData.length){ 18 | 19 | var thisLine = printData[cS].split(";")[0].split(' '); 20 | 21 | if(thisLine.length > 1){ 22 | var lL = 1; 23 | 24 | var printObject = {}; 25 | printObject.commandCode = thisLine[0]; 26 | printObject.other = [] 27 | 28 | 29 | while(lL < thisLine.length){ 30 | 31 | if(thisLine[lL].indexOf('E') != -1){ 32 | var tempChunk = parseFloat(thisLine[lL].slice(thisLine[lL].indexOf('E')).split('E')[1], 10); 33 | 34 | if(tempChunk < 4){ 35 | tempChunk = 4; 36 | } 37 | printObject.extrusion = tempChunk; 38 | 39 | } else if(thisLine[lL].indexOf('X') != -1){ 40 | var xChunk = parseFloat(thisLine[lL].slice(thisLine[lL].indexOf('X')).split('X')[1], 10); 41 | 42 | printObject.x = xChunk; 43 | } else if(thisLine[lL].indexOf('Y') != -1){ 44 | var yChunk = parseFloat(thisLine[lL].slice(thisLine[lL].indexOf('Y')).split('Y')[1], 10); 45 | 46 | printObject.y = yChunk; 47 | } else if(thisLine[lL].indexOf('Z') != -1){ 48 | var zChunk = parseFloat(thisLine[lL].slice(thisLine[lL].indexOf('Z')).split('Z')[1], 10); 49 | 50 | printObject.z = zChunk; 51 | } else if(thisLine[lL].indexOf('F') != -1){ 52 | var fChunk = parseFloat(thisLine[lL].slice(thisLine[lL].indexOf('F')).split('F')[1], 10); 53 | 54 | printObject.feed = fChunk; 55 | } else { 56 | 57 | if(thisLine[lL] !== " " && thisLine[lL] !== ""){ 58 | printObject.other.push(thisLine[lL]); 59 | } 60 | 61 | } 62 | 63 | lL += 1; 64 | } 65 | 66 | newData.push(printObject); 67 | 68 | } 69 | 70 | cS += 1; 71 | 72 | } 73 | 74 | return newData; 75 | 76 | } 77 | 78 | function reconstruct(command){ 79 | 80 | var commands = []; 81 | 82 | if(command === undefined){ 83 | return; 84 | } 85 | 86 | commands.push(command.commandCode); 87 | 88 | if(command.x){ 89 | commands.push("X" + command.x); 90 | } 91 | 92 | if(command.y){ 93 | commands.push("Y" + command.y); 94 | } 95 | 96 | if(command.z){ 97 | commands.push("Z" + command.z * settings.heightMulitplier); 98 | } 99 | 100 | if(command.feed){ 101 | commands.push("F" + command.feed * settings.speedMultiplier); 102 | } 103 | 104 | if(command.extrusion){ 105 | 106 | if(command.extrusion > 0){ 107 | commands.push("E" + command.extrusion * settings.extrusionMultiplier) 108 | } else { 109 | commands.push("E5"); 110 | } 111 | } 112 | 113 | if(command.other){ 114 | commands.push(command.other.join(" ")); 115 | } 116 | 117 | commands = commands.join(' '); 118 | 119 | return commands; 120 | 121 | } 122 | 123 | 124 | module.exports.settings = settings; 125 | module.exports.deconstruct = deconstruct; 126 | module.exports.reconstruct = reconstruct; -------------------------------------------------------------------------------- /print.js: -------------------------------------------------------------------------------- 1 | var serialport = require("serialport"), 2 | fs = require('fs'), 3 | argv = require('optimist').argv, 4 | GCODE = require('./GCODE/module.js'); 5 | 6 | var printCommands = [], 7 | printPosition = 0; 8 | 9 | var settings = { 10 | printFile : undefined, 11 | serialPort : undefined, 12 | baudrate : undefined, 13 | printing : false, 14 | paused : false 15 | } 16 | 17 | //=========================================================== 18 | // Self executing function - Will run before the file load 19 | // Usage: node [options] print.js --port [SERIAL PORT] --file [FILE PATH] --speed [SPEED MULTIPLIER] 20 | //=========================================================== 21 | 22 | var handleArguments = (function(){ 23 | 24 | if (argv.port){ 25 | settings.serialPort = argv.port; 26 | } else { 27 | console.log("No serial port passed. Exiting"); 28 | process.exit(1); 29 | } 30 | 31 | if(argv.baudrate){ 32 | console.log(argv.baudrate); 33 | settings.baudrate = argv.baudrate; 34 | } else { 35 | console.log("No Baudrate passed for serial port. Exiting"); 36 | process.exit(1); 37 | } 38 | 39 | if(argv.file){ 40 | settings.printFile = argv.file; 41 | console.log(settings.printFile); 42 | } else { 43 | console.log("No print file passed. Exiting"); 44 | console.log(argv.file); 45 | process.exit(1); 46 | } 47 | 48 | //Optional :: The multiplying factor that affects the travelling speed of the printhead 49 | if(argv.speed){ 50 | console.log("Speed multiplying factor:" + argv.speed); 51 | GCODE.settings.speedMultiplier = argv.speed; 52 | } 53 | 54 | })(); 55 | 56 | fs.readFile(settings.printFile, 'utf8', function (err,data) { 57 | 58 | if (err) { 59 | return console.log(err); 60 | } 61 | 62 | printCommands = GCODE.deconstruct(data); 63 | 64 | }); 65 | 66 | var SerialPort = serialport.SerialPort; 67 | var sp = new SerialPort(settings.serialPort, { 68 | parser: serialport.parsers.readline("\n"), 69 | baudrate : settings.baudrate 70 | }); 71 | 72 | sp.on("open", function () { 73 | console.log("Serial Port " + settings.serialPort + " is open."); 74 | 75 | printPosition = 0; 76 | 77 | sp.on('data', function(data) { 78 | 79 | if(data.indexOf("ok") != -1 || data == "start\r"){ 80 | 81 | setTimeout(function(){ 82 | if(settings.paused !== true){ 83 | printerCommand(GCODE.reconstruct(printCommands[printPosition])); 84 | } 85 | },50); 86 | 87 | } else { 88 | console.log("Nope") 89 | } 90 | 91 | }); 92 | 93 | }); 94 | 95 | 96 | function printerCommand(comm){ 97 | 98 | if(comm !== undefined && comm.indexOf(" ") === comm.length - 1){ 99 | console.log(comm.slice(comm.length - 1, comm.length)); 100 | comm = comm.substring(0, comm.length - 1); 101 | 102 | } 103 | 104 | console.log((printPosition + 1) + " / " + printCommands.length + ": " + comm); 105 | 106 | sp.write(comm + "\n", function(err, results) { 107 | 108 | if(err){ 109 | console.log(">>>ERR"); 110 | console.log(err); 111 | console.log("<<<"); 112 | } 113 | 114 | if(comm !== "M105"){ 115 | printPosition += 1; 116 | } 117 | 118 | }); 119 | 120 | } 121 | 122 | process.on('exit', function() { 123 | console.log("Issuing Stop Command"); 124 | printerCommand("M112"); 125 | 126 | }); --------------------------------------------------------------------------------