diff --git a/LICENSE b/LICENSE
index e69de29..fca19f4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Patrick Knöbel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README-BUILD.md b/README-BUILD.md
new file mode 100644
index 0000000..ddb4034
--- /dev/null
+++ b/README-BUILD.md
@@ -0,0 +1,12 @@
+To build the program (with changes to the source):
+
+- install version 1.8 (aka 8.0) of the `JDK`, (openJDK variants such as [Azul's Zulu JDK](https://www.azul.com/downloads/?package=jdk&show-old-builds=true#zulu) may have better support for modern systems).
+
+- copy or hardlink `nrjavaserial-3.9.3.jar` and `jssc.jar` to the directory `./dist/lib/`
+
+- run `ant` from the top level directory of the repo to build the changes, with a command of the form
+ ```
+ ant -Dplatforms.JDK_1.8.home=/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home -Dnb.internal.action.name=build jar
+ ```
+
+this will produce the output jar files in the dist directory.
diff --git a/README.md b/README.md
index 71c8c13..48b160a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,28 @@
-cncgcodecontroller
+CNC-GCode-Controller
==================
+If you use a reprap Controller (like Marlin ...) for a CNC machine then this is your Program ;-)
-CNC-GCode-Controller
+### Features:
+* Communication with the Controller over com port
+* Basic movements with preview
+* Loading cnc files
+* Preview of cnc file
+* Autoleveling (at this point only for Marlin firmware because of hit endstop message)
+ * for GRPL you neet to set $10=2 for this to work!
+* Optimise G0 movements
+* Most commonly used Gcodes are translated for a Reprap Controller (Tested with Marlin)
+* Backlash correction
+* Artsupport
+
+### Tutorial Videos:
+ * [en] https://youtu.be/xxbBipRvp5I
+ * [de] https://youtu.be/hYSPs9B2VUM
+
+### Infos:
+ http://reprap.org/wiki/CNC_Gcode_controller
+
+
+
+
+
+
diff --git a/src/cnc/gcode/controller/CNCCommand.java b/src/cnc/gcode/controller/CNCCommand.java
index abe731a..c2fc00b 100644
--- a/src/cnc/gcode/controller/CNCCommand.java
+++ b/src/cnc/gcode/controller/CNCCommand.java
@@ -81,17 +81,28 @@ public class Move
private final double[] s;
private final double[] e;
private double a;
+ private double spindle;
private final Type t;
private final boolean xyz;
- public Move(double[] s, double[] e, double a, Type t, boolean xyz) {
+ public Move(double[] s, double[] e, double a, Type t, boolean xyz, double spindle) {
this.s = s;
this.e = e;
this.t = t;
this.a = a;
this.xyz=xyz;
+ this.spindle=spindle;
}
+ public Move(double[] s, double[] e, double a, Type t, boolean xyz) {
+ this.s = s;
+ this.e = e;
+ this.t = t;
+ this.a = a;
+ this.xyz=xyz;
+ this.spindle = Double.NaN;
+ }
+
public void scalexy(double[] scale){
for(int i=0;i<2;i++){
s[i]=s[i]*scale[i];
@@ -121,6 +132,10 @@ public double getA(){
return a;
}
+ public double getSpindle(){
+ return spindle;
+ }
+
public double getDistanceXY()
{
double dx = s[0]- e[0];
@@ -652,13 +667,17 @@ public State calcCommand(Calchelper c)
if(move.a!=0){
used=true;
}
+ if(Double.isNaN(move.spindle) == false){
+ message += "Spindle speed set";
+ used=true;
+ }
if(used == false)
{
if(state == State.NORMAL)
{
state = State.WARNING;
}
- message += "Command without any movment! ";
+ message += "Command without any movment!";
}
if(move.s[2] != move.e[2] && Double.isNaN(move.e[2]) == false)
@@ -710,7 +729,11 @@ public Move[] getMoves()
case G1:
case HOMING:
case SETPOS:
- moves.add(new Move(Arrays.copyOfRange(cin.axes, 0, 3), Arrays.copyOfRange(cout.axes, 0, 3),p.contains('A')?p.get('A').value:0.0, type,xyzmove));
+ if(p.contains('S')){
+ moves.add(new Move(Arrays.copyOfRange(cin.axes, 0, 3), Arrays.copyOfRange(cout.axes, 0, 3),p.contains('A')?p.get('A').value:0.0, type,xyzmove, p.get('S').value));
+ } else {
+ moves.add(new Move(Arrays.copyOfRange(cin.axes, 0, 3), Arrays.copyOfRange(cout.axes, 0, 3),p.contains('A')?p.get('A').value:0.0, type,xyzmove));
+ }
break;
case ARC:
@@ -933,6 +956,12 @@ String[] execute(Transform t, boolean autoleveling, boolean noshort) {
cmd += " " + 'A' + Tools.dtostr(move.a);
doMove = true;
}
+
+ if(Double.isNaN(move.spindle)==false){
+ cmd += " " + 'S' + Tools.dtostr(move.spindle);
+ doMove = true;
+ }
+
if(doMove == false && !Double.isNaN(cin.axes[3]) && !Double.isNaN(cout.axes[3]) && cin.axes[3] == cout.axes[3])
{
continue;
diff --git a/src/cnc/gcode/controller/DatabaseV2.java b/src/cnc/gcode/controller/DatabaseV2.java
index d4c86c1..d976eed 100644
--- a/src/cnc/gcode/controller/DatabaseV2.java
+++ b/src/cnc/gcode/controller/DatabaseV2.java
@@ -74,6 +74,7 @@ public enum DatabaseV2 {
//Communication Type
COMTYPE(Communication.MARLIN.toString()),
+ CSTREAMAHEAD(EOnOff.OFF.name()),
//Color Settings:
CBACKGROUND(""+Color.WHITE.getRGB()),
@@ -86,7 +87,7 @@ public enum DatabaseV2 {
ARTSETTINGS((new ArtSettings()).toString()),
;
- enum EHoming{
+ public enum EHoming{
//Homing Point 0= upper left; 1= upper right; 2= lower left; 3= lower right;
UPPER_LEFT,
UPPER_RIGHT,
@@ -107,7 +108,7 @@ public void set(){
}
}
- enum EOnOff{
+ public enum EOnOff{
ON,
OFF;
diff --git a/src/cnc/gcode/controller/JPanelAutoLevel.java b/src/cnc/gcode/controller/JPanelAutoLevel.java
index 3d61694..07e77cd 100644
--- a/src/cnc/gcode/controller/JPanelAutoLevel.java
+++ b/src/cnc/gcode/controller/JPanelAutoLevel.java
@@ -891,7 +891,7 @@ protected String doInBackground() throws Exception {
if(pos == false)
{
- throw new MyException("Timeout: No position report!");
+ throw new MyException("Timeout: No position report!\nFor GRPL you neet to set $10=2 for this to work!");
}
double thitValue = hitvalue;
diff --git a/src/cnc/gcode/controller/JPanelSettings.form b/src/cnc/gcode/controller/JPanelSettings.form
index d5e1885..1141b3a 100644
--- a/src/cnc/gcode/controller/JPanelSettings.form
+++ b/src/cnc/gcode/controller/JPanelSettings.form
@@ -18,10 +18,6 @@
-
-
-
-
@@ -68,6 +64,7 @@
+
@@ -82,6 +79,7 @@
+
@@ -89,6 +87,10 @@
+
+
+
+
@@ -169,9 +171,12 @@
-
+
-
+
+
+
+
@@ -290,6 +295,12 @@
+
+
+
+
+
+
@@ -636,6 +647,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cnc/gcode/controller/JPanelSettings.java b/src/cnc/gcode/controller/JPanelSettings.java
index df1c067..5a84bcd 100644
--- a/src/cnc/gcode/controller/JPanelSettings.java
+++ b/src/cnc/gcode/controller/JPanelSettings.java
@@ -72,6 +72,7 @@ public void updateGUI(boolean serial, boolean isworking)
}
jLSmodal.setText(Tools.convertToMultiline("Allow G1: "+DatabaseV2.EOnOff.get(DatabaseV2.G1MODAL).name()+"\nAllow G0: "+DatabaseV2.EOnOff.get(DatabaseV2.G0MODAL).name()));
jLSComType.setText(DatabaseV2.COMTYPE.get());
+ jLSCStreamAhead.setText(DatabaseV2.CSTREAMAHEAD.get());
jLSCBack.setBackground(new Color(Integer.parseInt(DatabaseV2.CBACKGROUND.get())));
jLSCGrid.setBackground(new Color(Integer.parseInt(DatabaseV2.CGRID.get())));
jLSCGridDis.setText(DatabaseV2.CGRIDDISTANCE.getsaved()>0?""+DatabaseV2.CGRIDDISTANCE.get():"OFF");
@@ -149,6 +150,9 @@ private void initComponents() {
jLabel44 = new javax.swing.JLabel();
jBSComType = new javax.swing.JButton();
jLSComType = new javax.swing.JLabel();
+ jLabel51 = new javax.swing.JLabel();
+ jBSCStreamAhead = new javax.swing.JButton();
+ jLSCStreamAhead = new javax.swing.JLabel();
jLabel46 = new javax.swing.JLabel();
jBSCBack = new javax.swing.JButton();
jLSCBack = new javax.swing.JLabel();
@@ -357,6 +361,17 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
jLSComType.setText("Settings Text");
+ jLabel51.setText("Stream ahead");
+
+ jBSCStreamAhead.setText("Change");
+ jBSCStreamAhead.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ jBSettingsActionPerformed(evt);
+ }
+ });
+
+ jLSCStreamAhead.setText("Settings Text");
+
jLabel46.setText("Background color:");
jBSCBack.setText("Change");
@@ -451,9 +466,6 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGap(10, 10, 10)
- .addComponent(jLabel43))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -498,7 +510,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
.addComponent(jBSCGridDis)
.addComponent(jBSCG0)
.addComponent(jBSCG1)
- .addComponent(jBSCNCAFeedrate)))
+ .addComponent(jBSCNCAFeedrate)
+ .addComponent(jBSCStreamAhead)))
.addComponent(jLabel44)
.addGroup(layout.createSequentialGroup()
.addComponent(jBexport)
@@ -509,11 +522,15 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
.addComponent(jLabel50)
.addComponent(jLabel47)
.addComponent(jLabel48)
- .addComponent(jLabel45))
+ .addComponent(jLabel45)
+ .addComponent(jLabel51))
.addGap(50, 50, 50)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLSCNCAFeedrate)
.addComponent(jLSCNCG0Feedrate)))
+ .addGroup(layout.createSequentialGroup()
+ .addGap(10, 10, 10)
+ .addComponent(jLabel43))
.addGroup(layout.createSequentialGroup()
.addGap(312, 312, 312)
.addComponent(jLSCG1))
@@ -576,7 +593,9 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
.addComponent(jLSHomeing))
.addGroup(layout.createSequentialGroup()
.addGap(312, 312, 312)
- .addComponent(jLSCBack)))
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jLSCStreamAhead)
+ .addComponent(jLSCBack))))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
@@ -673,6 +692,11 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
.addComponent(jBSComType)
.addComponent(jLSComType))
.addGap(18, 18, 18)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel51)
+ .addComponent(jBSCStreamAhead)
+ .addComponent(jLSCStreamAhead))
+ .addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel46)
.addComponent(jBSCBack)
@@ -953,6 +977,16 @@ private void jBSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI
DatabaseV2.COMTYPE.set(Communication.values()[options].toString());
}
}
+
+ //CStreamAhead
+ if(evt.getSource() == jBSCStreamAhead)
+ {
+ JSettingsDialog.SEnum setting= new JSettingsDialog.SEnum<>("Stream 3 commands ahead:",DatabaseV2.EOnOff.get(DatabaseV2.G1MODAL));
+ if(JSettingsDialog.showSettingsDialog("Stream ahead:",new JSettingsDialog.Setting[]{setting}))
+ {
+ setting.getValue().set(DatabaseV2.CSTREAMAHEAD);
+ }
+ }
//Colors
if(evt.getSource() == jBSCBack)
@@ -1080,6 +1114,7 @@ public String getDescription()
private javax.swing.JButton jBSCNCStart;
private javax.swing.JButton jBSCNCToolChange;
private javax.swing.JButton jBSCNCToolSize;
+ private javax.swing.JButton jBSCStreamAhead;
private javax.swing.JButton jBSComType;
private javax.swing.JButton jBSFastFeedrate;
private javax.swing.JButton jBSHoming;
@@ -1104,6 +1139,7 @@ public String getDescription()
private javax.swing.JLabel jLSCNCStart;
private javax.swing.JLabel jLSCNCToolChange;
private javax.swing.JLabel jLSCNCToolSize;
+ private javax.swing.JLabel jLSCStreamAhead;
private javax.swing.JLabel jLSComType;
private javax.swing.JLabel jLSFastFeedrate;
private javax.swing.JLabel jLSHomeing;
@@ -1132,6 +1168,7 @@ public String getDescription()
private javax.swing.JLabel jLabel48;
private javax.swing.JLabel jLabel49;
private javax.swing.JLabel jLabel50;
+ private javax.swing.JLabel jLabel51;
// End of variables declaration//GEN-END:variables
@Override
diff --git a/src/cnc/gcode/controller/MainForm.form b/src/cnc/gcode/controller/MainForm.form
index fb0300c..8ca0bd8 100644
--- a/src/cnc/gcode/controller/MainForm.form
+++ b/src/cnc/gcode/controller/MainForm.form
@@ -155,7 +155,11 @@
+
+
+
+
diff --git a/src/cnc/gcode/controller/MainForm.java b/src/cnc/gcode/controller/MainForm.java
index 7078c08..08de276 100644
--- a/src/cnc/gcode/controller/MainForm.java
+++ b/src/cnc/gcode/controller/MainForm.java
@@ -64,51 +64,7 @@ public void fired() {
//Show Comports/Speeds avilable (Can take secounds to load!)
- (new Thread(new Runnable() {
- @Override
- public void run() {
- final ArrayList ports = Communication.getPortsNames();
- if(ports.isEmpty())
- {
- ports.add("No serial port found!");
- }
-
- final ArrayList speeds= Communication.getPortsSpeeds();
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- jCBPort.setModel(new DefaultComboBoxModel(ports.toArray(new String[0])));
- jCBSpeed.setModel(new DefaultComboBoxModel(speeds.toArray(new Integer[0])));
-
- int index = 0;
- //Load last Comport
- for (String port:ports)
- {
- if(port.equals(DatabaseV2.PORT.get()))
- {
- jCBPort.setSelectedIndex(index);
- break;
- }
- index++;
- }
-
- //Load last Speed
- index = 0;
- for (Integer speed:speeds)
- {
- if(speed.toString().equals(DatabaseV2.SPEED.get()))
- {
- jCBSpeed.setSelectedIndex(index);
- break;
- }
- index++;
- }
-
- jLStatus.setText(Communication.getStatus());
- }
- });
- }
- })).start();
+ updateComportList();
Communication.addChangedEvent(new IEvent() {
@Override
@@ -210,6 +166,13 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
jLStatus.setText("Loading...");
+ jCBPort.setToolTipText("Right Click to Refresh");
+ jCBPort.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ jCBPortMouseClicked(evt);
+ }
+ });
+
jLabel6.setText("@");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
@@ -271,7 +234,65 @@ private void jBConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIR
DatabaseV2.PORT.set((String)jCBPort.getModel().getSelectedItem());
DatabaseV2.SPEED.set(((Integer)jCBSpeed.getSelectedItem()).toString());
}//GEN-LAST:event_jBConnectActionPerformed
+
+ private void jCBPortMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jCBPortMouseClicked
+ if(SwingUtilities.isRightMouseButton(evt)){
+ jCBPort.setModel(new DefaultComboBoxModel());
+ jCBSpeed.setModel(new DefaultComboBoxModel());
+ updateComportList();
+ }
+ }//GEN-LAST:event_jCBPortMouseClicked
+
+ private void updateComportList(){
+ (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ final ArrayList ports = Communication.getPortsNames();
+ if(ports.isEmpty())
+ {
+ ports.add("No serial port found!");
+ }
+
+ final ArrayList speeds= Communication.getPortsSpeeds();
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ jCBPort.setModel(new DefaultComboBoxModel(ports.toArray(new String[0])));
+ jCBSpeed.setModel(new DefaultComboBoxModel(speeds.toArray(new Integer[0])));
+
+ int index = 0;
+ //Load last Comport
+ for (String port:ports)
+ {
+ if(port.equals(DatabaseV2.PORT.get()))
+ {
+ jCBPort.setSelectedIndex(index);
+ break;
+ }
+ index++;
+ }
+
+ //Load last Speed
+ index = 0;
+ for (Integer speed:speeds)
+ {
+ if(speed.toString().equals(DatabaseV2.SPEED.get()))
+ {
+ jCBSpeed.setSelectedIndex(index);
+ break;
+ }
+ index++;
+ }
+
+ jLStatus.setText(Communication.getStatus());
+ }
+ });
+ }
+ })).start();
+
+ }
+
// Variables declaration - do not modify//GEN-BEGIN:variables
diff --git a/src/cnc/gcode/controller/communication/ComCoreJSSC.java b/src/cnc/gcode/controller/communication/ComCoreJSSC.java
index 4accf2c..536d230 100644
--- a/src/cnc/gcode/controller/communication/ComCoreJSSC.java
+++ b/src/cnc/gcode/controller/communication/ComCoreJSSC.java
@@ -4,9 +4,6 @@
*/
package cnc.gcode.controller.communication;
-import gnu.io.NRSerialPort;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Timer;
diff --git a/src/cnc/gcode/controller/communication/Communication.java b/src/cnc/gcode/controller/communication/Communication.java
index 47f134e..c8c73e3 100644
--- a/src/cnc/gcode/controller/communication/Communication.java
+++ b/src/cnc/gcode/controller/communication/Communication.java
@@ -10,8 +10,6 @@
import cnc.gcode.controller.MyException;
import cnc.gcode.controller.ObjectProxy;
import cnc.gcode.controller.Tools;
-import java.lang.reflect.InvocationTargetException;
-import java.text.ParseException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.logging.Level;
@@ -163,7 +161,7 @@ protected void internal_receive(String line) throws MyException{
}
@Override
protected boolean internal_isbusy(){
- return cmdHistroy.size() > receiveCount;
+ return cmdHistroy.size() > (receiveCount +(DatabaseV2.EOnOff.get(DatabaseV2.CSTREAMAHEAD)==DatabaseV2.EOnOff.ON?3:0));
}
@Override
protected boolean internal_isConnected(){
@@ -309,7 +307,7 @@ protected void internal_receive(String line) throws MyException{
}
@Override
protected boolean internal_isbusy(){
- return sendcount > resivecount;
+ return sendcount > (resivecount+(DatabaseV2.EOnOff.get(DatabaseV2.CSTREAMAHEAD)==DatabaseV2.EOnOff.ON?3:0));
}
@Override
protected boolean internal_isConnected(){
@@ -463,7 +461,7 @@ else if(!initThread.isAlive())
}
@Override
protected boolean internal_isbusy(){
- return resivecount ==0 || sendcount > resivecount;
+ return resivecount ==0 || sendcount > (resivecount+(DatabaseV2.EOnOff.get(DatabaseV2.CSTREAMAHEAD)==DatabaseV2.EOnOff.ON?3:0));
}
@Override
protected boolean internal_isConnected(){
@@ -491,7 +489,7 @@ protected Double[] internal_LocationString(String line){
{
Double[] dpos=new Double[3];
for(int i=0;i<3;i++)
- dpos[i]=Tools.strtod(line.split(":")[2].split(",")[i]);
+ dpos[i]=Tools.strtod(line.split("WPos:")[1].split(",")[i]);
return dpos;
}