diff --git a/GCodeFiles/log.gcode b/GCodeFiles/log.gcode index 82b3827..9fb1ea0 100755 --- a/GCodeFiles/log.gcode +++ b/GCodeFiles/log.gcode @@ -2,11 +2,11 @@ G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t176148132360 f1000 G90 G1 x-50 y300 z0 a131.25 b-90.00 c0.00 e0.00 t176148136260 f1000 G90 G1 x-128.5 y410 z-11 a134.11 b-90.00 c9.74 e-57.30 t176148145060 f1000 G90 G1 x-128.5 y410 z-11 a134.11 b-90.00 c9.74 e62.45 t176148148860 f1000 -G90 G1 x-128.5 y410 z35 a134.11 b-90.00 c9.74 e62.45 t176148149240 f1000 +G90 G1 x-128.5 y410 z35 a134.11 b-90.00 c9.74 e62.45 t176148149240 f1000;! G90 G1 x-128.5 y410 z35 a163.90 b-90.00 c9.74 e62.45 t176148149980 f1000 G90 G1 x-128.5 y410 z35 a84.84 b-90.00 c9.74 e62.45 t176148150690 f1000 G90 G1 x-128.5 y410 z-21 a84.84 b-88.85 c9.74 e62.45 t176148152270 f1000 -G90 G1 x-128.5 y410 z-21 a84.84 b-88.85 c9.74 e-59.59 t176148152820 f1000;! +G90 G1 x-128.5 y410 z-21 a84.84 b-88.85 c9.74 e-59.59 t176148152820 f1000 G90 G1 x-128.5 y410 z65 a84.84 b-88.85 c9.74 e-59.59 t176148159940 f1000 G90 G1 x-47 y410 z65 a84.84 b-88.85 c9.74 e-59.59 t176148160630 f1000 G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e-59.59 t176148160830 f1000 @@ -26,3 +26,10 @@ G90 G1 x-37 y369 z87.5 a90.00 b-90.00 c193.09 e-100.85 t176148250020 f1000 G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e-100.85 t176148250630 f1000 G90 G1 x0 y614 z0 a-90.00 b90.00 c0.00 e0.00 t176242679300 f1000 G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t176244052830 f1000 +G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t177350160280 f1000 +G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t177350160530 f1000 +G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t177350160920 f1000 +G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t177350161950 f1000 +G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t177350162310 f1000 +G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t177350162470 f1000 +G90 G1 x0 y300 z0 a90.00 b-90.00 c0.00 e0.00 t177350162630 f1000 diff --git a/robot/TelnetSenderGRBL.js b/robot/TelnetSenderGRBL.js index 09256ee..5500467 100755 --- a/robot/TelnetSenderGRBL.js +++ b/robot/TelnetSenderGRBL.js @@ -34,12 +34,7 @@ module.exports = class TelnetSenderGRBL{ }) .on('error', reject); }).then( connection => { - connection.on('data', data => { - //console.log("data from " + urlGRBL + " is: " + data); - //if(this.receiver && this.receiver != null){ - // this.receiver.send(buffer); - // } - }); + connection.on('data', data => {}); }, error => { console.log("Telnet Connection Error on " + urlGRBL + ": " + error.toString()); this.tSocket = null; diff --git a/robot/WSSenderGrbl.js b/robot/WSSenderGrbl.js new file mode 100755 index 0000000..18a2298 --- /dev/null +++ b/robot/WSSenderGrbl.js @@ -0,0 +1,189 @@ +const net = require("net"); +const { resolve } = require("path"); +const FluidNCClient = require("./fluidnc/FluidNCClient"); + + + + +module.exports = class TelnetSenderGRBL{ + + /* urlGRBL: URL für den GCode Empfänger (MicroController, GRBL) + * xAxisGrbl: Welche Achse soll ausgelesen werden? Welche Achse ist die GRBL-X-Achse + * yAxisGrbl: ... + * zAxisGrbl: ... + */ + constructor(urlGRBL = "grblesp.local", maxSpeedF = 5000, xAxisGrbl = "x", yAxisGrbl = "y", zAxisGrbl = "z", aAxisGrbl = null, bAxisGrbl = null, cAxisGrbl = null, eAxisGrbl = null){ + + var socket = null; + this.tSocket = null; + this.receiver = null; + + this.urlGRBLstr = urlGRBL; + this.xAxisGrbl = xAxisGrbl; + this.yAxisGrbl = yAxisGrbl; + this.zAxisGrbl = zAxisGrbl; + this.aAxisGrbl = aAxisGrbl; + this.bAxisGrbl = bAxisGrbl; + this.cAxisGrbl = cAxisGrbl; + this.eAxisGrbl = eAxisGrbl; + + var fluidConfig = { host: urlGRBL, port: 80, reconnectDelay: 30000} + + // Create FluidNC WebSocket client + const fluid = new FluidNCClient(fluidConfig); + } + + + + moveTo(mOld, mNew){ + + // The Hand-Turn is not 1:1 to the Hand-Lift ° + var factorTurnLift = 1.2; + + // The Hand-Open is not 1:1 to the Hand-Turn + var factorOpenTurn = 1.92; + + // Hand-Open in mm + var handOpenInMM = 1.0 + + var data = "G1" + + if(this.xAxisGrbl == "x"){ + data += " x" + (mNew.x).toFixed(2).toString(); + } + if(this.xAxisGrbl == "y"){ + data += " x" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); + } + if(this.xAxisGrbl == "z"){ + data += " x" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); + } + if(this.xAxisGrbl == "a"){ + // This is the case for the Ellbow, when the Motor is connected to the X-Port of the FluidNC + data += " x" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); + } + if(this.xAxisGrbl == "b"){ + data += " x" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); + } + if(this.xAxisGrbl == "c"){ + // Runs correctly, substracts the "b" axis, uses the "c" axis to send to the x-Motor wich is in this case the hand-twist + data += " x" + ((-1)*mNew.b * 180 / Math.PI + (mNew.c * 180 / Math.PI) ).toFixed(2).toString(); + } + if(this.xAxisGrbl == "e"){ + //This is the case for the Hand, when the Open-Close Motor is connected to the X-Port of FluidNC + var handUpDown = mNew.b * 180 * factorTurnLift / Math.PI ; + var handTurn = mNew.c*180/Math.PI ; + data += " x" + ((-1.0*(-1.0*(handUpDown) + handTurn) + mNew.e*handOpenInMM)).toFixed(2).toString(); + } + + + + if(this.yAxisGrbl == "x"){ + data += " y" + (mNew.x ).toFixed(2).toString(); + } + if(this.yAxisGrbl == "y"){ + data += " y" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); + } + if(this.yAxisGrbl == "z"){ + data += " y" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); + } + if(this.yAxisGrbl == "a"){ + data += " y" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); + } + if(this.yAxisGrbl == "b"){ + data += " y" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); + } + if(this.yAxisGrbl == "c"){ + // This is the case if the hand-rotation-turner is connected to the FluidNC-Y + var handUpDown = (mNew.b * 180 / Math.PI ) * factorTurnLift; + var handTurn = ( mNew.c*180/Math.PI ) ; + data += " y" + (-1.0*(handUpDown) + handTurn).toFixed(2).toString(); + } + if(this.yAxisGrbl == "e"){ + data += " y" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); + } + + + if(this.zAxisGrbl == "x"){ + data += " z" + (mNew.x).toFixed(2).toString(); + } + if(this.zAxisGrbl == "y"){ + data += " z" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); + } + if(this.zAxisGrbl == "z"){ + data += " z" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); + } + if(this.zAxisGrbl == "a"){ + data += " z" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); + } + if(this.zAxisGrbl == "b"){ + // This is the case of the Hand, when the Up-Down-Motor is connected to the FluidNC-Z + data += " z" + ( mNew.b * 180 / Math.PI ).toFixed(2).toString(); + } + if(this.zAxisGrbl == "c"){ + data += " z" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); + } + if(this.zAxisGrbl == "e"){ + + data += " z" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); + } + + + + if(this.aAxisGrbl == "x"){ + data += " a" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); + } + if(this.aAxisGrbl == "y"){ + data += " a" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); + } + if(this.aAxisGrbl == "z"){ + data += " a" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); + } + if(this.aAxisGrbl == "a"){ + data += " a" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); + } + if(this.aAxisGrbl == "b"){ + data += " a" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); + } + if(this.aAxisGrbl == "c"){ + data += " a" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); + } + if(this.aAxisGrbl == "e"){ + // ToDo Mai 2024 + data += " a" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); + } + + + + + if(this.bAxisGrbl == "x"){ + data += " b" + (mNew.x).toFixed(2).toString(); + } + if(this.bAxisGrbl == "y"){ + data += " b" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); + } + if(this.bAxisGrbl == "z"){ + data += " b" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); + } + if(this.bAxisGrbl == "a"){ + data += " b" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); + } + if(this.bAxisGrbl == "b"){ + data += " b" + (mNew.b * 180 / Math.PI).toFixed(2).toString(); + } + if(this.bAxisGrbl == "c"){ + data += " b" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); + } + if(this.bAxisGrbl == "e"){ + data += " b" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); + } + + data += " f"+(maxSpeedF.toFixed(2).toString()) + + + console.log("" + this.urlGRBLstr + " receives: " + data.toString("utf-8")) + + if(this.tSocket && data.toString("utf-8").length > 3){ + this.tSocket.write( data.toString("utf-8") + "\r\n"); + } + } +} \ No newline at end of file diff --git a/robot/fluidnc/FluidNCClient.js b/robot/fluidnc/FluidNCClient.js new file mode 100755 index 0000000..b08277b --- /dev/null +++ b/robot/fluidnc/FluidNCClient.js @@ -0,0 +1,60 @@ +const WebSocket = require("ws"); +const EventEmitter = require("events"); + +class FluidNCClient extends EventEmitter { + constructor(cfg) { + super(); + + this.host = cfg.host; + this.port = cfg.port || 81; + + this.ws = null; + this.reconnectDelay = 2000; + + this.connect(); + } + + connect() { + const url = `ws://${this.host}:${this.port}`; + console.log("[FluidNC] Connecting to:", url); + + this.ws = new WebSocket(url); + + this.ws.on("open", () => { + console.log("[FluidNC] Connected (WS)"); + }); + + this.ws.on("message", (msg) => { + this.emit("message", msg.toString()); + }); + + this.ws.on("close", () => { + console.log("[FluidNC] Disconnected → retry"); + setTimeout(() => this.connect(), this.reconnectDelay); + }); + + this.ws.on("error", (err) => { + console.log("[FluidNC] WS Error:", err.message); + }); + } + + sendLine(cmd) { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + this.ws.send(cmd + "\n"); + } + } + + requestStatus() { + this.sendLine("?"); + } + + sendGcode(cmd) { + this.sendLine(cmd); + } + + onMessage(fn) { + this.on("message", fn); + } +} + +module.exports = FluidNCClient; \ No newline at end of file diff --git a/startRobot.js b/startRobot.js index f85be49..9b522c8 100755 --- a/startRobot.js +++ b/startRobot.js @@ -78,15 +78,17 @@ wss.on('connection', function connection(ws) var TenetSender = require('./robot/TelnetSenderGRBL.js') -/* -var telnetSender1 = null; //new TenetSender(urlGRBL = "fluidNcBase.local", maxSpeedF = 2300, xAxisGrbl = "x", yAxisGrbl = "y", zAxisGrbl = "z"); -var telnetSender2 = null; // new TenetSender(urlGRBL = "fluidNcEllbow.local", maxSpeedF = 5000, xAxisGrbl = "a", yAxisGrbl = null, zAxisGrbl = null); -var telnetSender3 = null; // new TenetSender(urlGRBL = "fluidNcHand.local", maxSpeedF = 5000, xAxisGrbl = "c", yAxisGrbl = "e", zAxisGrbl = "b"); -*/ -var telnetSender1 = new TenetSender(urlGRBL = "fluidNcBase.local", maxSpeedF = 2300, xAxisGrbl = "x", yAxisGrbl = "y", zAxisGrbl = "z"); -var telnetSender2 = new TenetSender(urlGRBL = "fluidNcEllbow.local", maxSpeedF = 5000, xAxisGrbl = "a", yAxisGrbl = null, zAxisGrbl = null); -var telnetSender3 = new TenetSender(urlGRBL = "fluidNcHand.local", maxSpeedF = 5000, xAxisGrbl = "c", yAxisGrbl = "e", zAxisGrbl = "b"); +const baseIP = process.env.GRBL_BASE_IP ?? "fluidNcBase.local"; +const elbowIP = process.env.GRBL_ELLBOW_IP ?? "fluidNcEllbow.local"; +const handIP = process.env.GRBL_HAND_IP ?? "fluidNcHand.local"; + +console.log(baseIP, elbowIP, handIP); + + +var telnetSender1 = new TenetSender(urlGRBL = baseIP, maxSpeedF = 2300, xAxisGrbl = "x", yAxisGrbl = "y", zAxisGrbl = "z"); +var telnetSender2 = new TenetSender(urlGRBL = elbowIP, maxSpeedF = 5000, xAxisGrbl = "a", yAxisGrbl = null, zAxisGrbl = null); +var telnetSender3 = new TenetSender(urlGRBL = handIP, maxSpeedF = 5000, xAxisGrbl = "c", yAxisGrbl = "e", zAxisGrbl = "b"); setTimeout(function() {