i have send source file of driver, hovever here is copy of the file based on grbl driver.
/*
This file is part of OpenPnP.
OpenPnP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenPnP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
*/
package org.openpnp.machine.reference.driver;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Action;
import org.openpnp.machine.reference.ReferenceDriver;
import org.openpnp.machine.reference.ReferenceHead;
import org.openpnp.model.Configuration;
import org.openpnp.model.Part;
import org.simpleframework.xml.Attribute;
import java.util.logging.*;
import javax.swing.Action;
import org.openpnp.gui.support.PropertySheetWizardAdapter;
import org.openpnp.gui.support.Wizard;
import org.openpnp.machine.reference.ReferenceActuator;
import org.openpnp.machine.reference.ReferenceHead;
import org.openpnp.machine.reference.ReferenceHeadMountable;
import org.openpnp.machine.reference.ReferenceNozzle;
import org.openpnp.machine.reference.driver.wizards.AbstractSerialPortDriverConfigurationWizard;
import org.openpnp.model.LengthUnit;
import org.openpnp.model.Location;
import org.openpnp.spi.PropertySheetHolder;
import org.simpleframework.xml.Attribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* TODO: Consider adding some type of heartbeat to the firmware.
*/
public class MojaDriver extends AbstractSerialPortDriver implements Runnable {
private static final Logger logger = LoggerFactory.getLogger( MojaDriver.class.getName() );
private static final double minimumRequiredVersion = 0.81;
@Attribute
private String portName;
@Attribute
private int baud;
@Attribute(required=false)
private int mm=0;
@Attribute(required=false)
private double delay=0;
@Attribute(required=false)
private int autoHeight=0;
@Attribute(required=false)
private int pickM=0x89;
private boolean vacuum;
private double x, y, z, c,f=0,ff=0;
private Thread readerThread;
private boolean disconnectRequested;
private Object commandLock = new Object();
private boolean connected;
private double connectedVersion;
private Queue<String> responseQueue = new ConcurrentLinkedQueue<String>();
@Override
public Location getAbsoluteLocation(ReferenceHeadMountable hm) {
return new Location(LengthUnit.Millimeters, x, y, z, c);
}
@Override
public Location getLocation(ReferenceHeadMountable hm) {
return new Location(LengthUnit.Millimeters, x, y, z, c).add(hm
.getHeadOffsets());
}
@Override
public void actuate(ReferenceActuator head, boolean on)
{ actuate(head,0,on); }
@Override
public void actuate(ReferenceActuator head, double on)
{ actuate(head,0,on!=0.0); }
@Override
public void actuate(ReferenceActuator head, int index, boolean on)
throws Exception {
actuate(head,index,on);
}
@Override
public void actuate(ReferenceActuator head, int index, double on)
throws Exception {
actuate(head,index,on);
}
@Override
public void actuate(ReferenceHead head, int index, boolean on)
throws Exception {
if (index == 0)
sendCommand(on ? "M7" : "M9");
if (index == 1)
sendCommand(on ? "M8" : "M9");
if (index == 2)
sendCommand(on ? "M10" : "M11");
if (index == 3)
sendCommand(on ? "M3" : "M5");
if (index == 4)
sendCommand(on ? "M4" : "M5");
dwell();
}
@Override
public void home(ReferenceHead head) throws Exception {
sendCommand("g28");
sendCommand("$H");
sendCommand("g21");
sendCommand("G92 X0 Y0 Z0 C0",700);
x = y = z= c = 0;
//head.updateDuringMoveTo(this.x, this.y, this.z, this.c);
}
private void moveTo_(ReferenceHead head, double x, double y, double z, double c, double feedRateMmPerMinute)
throws Exception {
if (Double.isNaN(x)||Double.isInfinite(x)) x = this.x;
if (Double.isNaN(y)||Double.isInfinite(y)) y = this.y;
if (Double.isNaN(z)||Double.isInfinite(z)) z = this.z;
if (Double.isNaN(c)||Double.isInfinite(c)) c = this.c;
if (Double.isNaN(f)||Double.isInfinite(f)) f = this.f;
if(f<0||f>99999) feedRateMmPerMinute=this.f;
if(x<-999.9||x>999.9) x=this.x;
if(y<-999.9||y>999.9) y=this.y;
if(z<-999.9||z>999.9) z=this.z;
if(c<-999.9||c>999.9) c=this.c;
StringBuffer sb = new StringBuffer();
if (x != this.x) {
sb.append(String.format("X%2.2f ", x));
}
if (y != this.y) {
sb.append(String.format("Y%2.2f ", y));
}
if (z != this.z) {
sb.append(String.format("Z%2.2f ", z));
}
if (c != this.c) {
// TODO see above bug note, and remove this when fixed.
sb.append(String.format("C%2.2f ", c));
}
if (sb.length() > 0) {
if(feedRateMmPerMinute!=0)
sb.append(String.format("F%2.2f", feedRateMmPerMinute));
if(feedRateMmPerMinute!=0)
sendCommand("G1 " + sb.toString());
else
sendCommand("G0 " + sb.toString());
// dwell();
}
this.x = x;
this.y = y;
this.z = z;
this.c = c;
/*
if(head!=null)
head.updateDuringMoveTo(this.x, this.y, this.z, this.c);
*/
//System.out.println("done moveTo("+head+","+this.x+","+this.y+","+this.z+","+this.c+")");
}
@Override
public void moveTo(ReferenceHeadMountable head, Location loc, double f) throws Exception {
moveTo(head,loc.getX(),loc.getY(),loc.getZ(),loc.getRotation(),f);
}
@Override
public void moveTo(ReferenceHeadMountable head, double x, double y, double z, double c, double f)
throws Exception {
moveTo(head,loc.x,y,z,c,f);
}
@Override
public void moveTo(ReferenceHead head, double x, double y, double z, double c, double f)
throws Exception {
// TODO: Due to a bug (of my creating) in Grbl, C movements are // included in the linear movements, and since they are much slower
// than X, Y movements they end up slowing the whole thing down.
// So, as a temporary hack, if there is a C move to be made we'll
//System.out.println("moveTo("+head+","+x+","+y+","+z+","+c+","+feedRateMmPerMinute+")");
if(f==-1) f=0;
if(f<0||f>99999) f=this.f;
if (Double.isNaN(x)||Double.isInfinite(x)) x = this.x;
if (Double.isNaN(y)||Double.isInfinite(y)) y = this.y;
if (Double.isNaN(z)||Double.isInfinite(z)) z = this.z;
if (Double.isNaN(c)||Double.isInfinite(c)) c = this.c;
if (Double.isNaN(f)||Double.isInfinite(f)) f = this.f;
if(x< -999.9||x>999.9) x=this.x;
if(y< -999.9||y>999.9) y=this.y;
if(z< -999.9||z>999.9) z=this.z;
if(c< -999.9||c>999.9) c=this.c;
if(f!=0)
this.f=f;
//System.out.println("MoveTo("+head+","+x+","+y+","+z+","+c+","+feedRateMmPerMinute+")");
if(!vacuum)
if(z<autoHeight&&this.z>autoHeight) // down
moveTo_(head,this.x,this.y,autoHeight,c,0);
else
if(z<autoHeight) ;
else f=0;
/*
if(z>autoHeight&&this.z<autoHeight) // up
moveTo(head,this.x,this.y,autoHeight+0.1,this.c,f),f=0;
if(z>autoHeight) f=0;
*/
// make it first.
// Also, since C is so slow in comparison, we just increase it
// by a factor of 10.
if (c != this.c )
if(f!=0)
if(Math.sqrt( (x-this.x)*(x-this.x)
+(y-this.y)*(y-this.y)
+(z-this.z)*(z-this.z)
)<=Math.sqrt(
(c-this.c)*(c-this.c)
)
)
moveTo_(head, this.x, this.y, this.z, c, f*10);
moveTo_(head, x, y, z, c, f);
//System.out.println("done moveTo("+head+","+this.x+","+this.y+","+this.z+","+this.c+")");
}
@Override
public void setEnabled(boolean enabled) throws Exception {
sendCommand("\030\030\030",1000);
sendCommand("\n",500);
sendCommand("\n",1000);
sendCommand("G92 X0 Y0 Z0 C0",700);
// sendCommand("$1000=" + (enabled ? "1" : "0"));
vacuum=false;
}
@Override
public void pick(ReferenceNozzle n) throws Exception {
pick(n,null);
}
@Override
public void pick(ReferenceHead head, Part part) throws Exception {
double dly; dly=0.3+delay; int m=(pickM>>4)&0xf;
vacuum=true;
if(mm!=0)
if(y>mm&&y<(mm+10)) {
moveTo(head, x, y-40, z, c, f );
sendCommand("M"+m);
moveTo(head, x, y, z-5.5, c, f );
sendCommand("G4P"+dly);
moveTo(head, x, y, z+5.5, c, f );
sendCommand("G4P0");
moveTo(head, x, y+40, z, c, f );
} else
sendCommand("M"+m);
else
sendCommand("M"+m);
dwell();
}
@Override
public void place(ReferenceNozzle head) throws Exception {
int m=pickM&0xf;
dwell();
sendCommand("M"+m); // inverted, should be M5
dwell();
vacuum=false;
}
public synchronized void connect()
throws Exception {
disconnect();
super.connect();
/**
* Connection process notes:
*
* On some platforms, as soon as we open the serial port it will reset
* Grbl and we'll start getting some data. On others, Grbl may already
* be running and we will get nothing on connect.
*/
List<String> responses;
synchronized (commandLock) {
// Start the reader thread with the commandLock held. This will
// keep the thread from quickly parsing any responses messages
// and notifying before we get a change to wait.
readerThread = new Thread(this);
readerThread.start();
// Wait up to 3 seconds for Grbl to say Hi
// If we get anything at this point it will have been the settings
// dump that is sent after reset.
responses = sendCommand(null, 3000);
}
processConnectionResponses(responses);
for (int i = 0; i < 5 && !connected; i++) {
responses = sendCommand("\030", 5000);
processConnectionResponses(responses);
}
if (!connected) {
throw new Error(
String.format("Unable to receive connection response from Grbl. Check your port and baud rate, and that you are running at least version %f of Grbl",
minimumRequiredVersion));
}
if (connectedVersion < minimumRequiredVersion) {
throw new Error(String.format("This driver requires Grbl version %.2f or higher. You are running version %.2f", minimumRequiredVersion, connectedVersion));
}
// We are connected to at least the minimum required version now
// So perform some setup
// Turn off the stepper drivers
setEnabled(false);
// Reset all axes to 0, in case the firmware was not reset on
// connect.
sendCommand("G92 X0 Y0 Z0 C0");
}
private void processConnectionResponses(List<String> responses) {
for (String response : responses) {
if(true) {
if (response.startsWith("$VERSION = ")) {
String[] versionComponents = response.split(" ");
connectedVersion = Double.parseDouble(versionComponents[2]);
connected = true;
logger.debug(String.format("Connected to Grbl Version: %.2f", connectedVersion));
}
} else {
connectedVersion = 0.9;
connected = true;
}
}
}
public synchronized void disconnect() {
disconnectRequested = true;
connected = false;
try {
if (readerThread != null && readerThread.isAlive()) {
readerThread.join();
}
}
catch (Exception e) {
logger.error("disconnect()", e);
}
super.close();
disconnectRequested = false;
}
private List<String> sendCommand(String command) throws Exception {
return sendCommand(command, -1);
}
private List<String> sendCommand(String command, long timeout) throws Exception {
synchronized (commandLock) {
if (command != null) {
logger.debug("sendCommand({}, {})", command, timeout);
//System.out.println("sendCommand("+command+","+timeout+")");
output.write(command.getBytes());
output.write("\n".getBytes());
}
if (timeout == -1) {
commandLock.wait();
}
else {
commandLock.wait(timeout);
}
}
List<String> responses = drainResponseQueue();
return responses;
}
public void run() {
while (!disconnectRequested) {
String line;
try {
line = readLine().trim();
}
catch (TimeoutException ex) {
continue;
}
catch (IOException e) {
logger.error("Read error", e);
return;
}
line = line.trim();
logger.debug("<< " + line);
responseQueue.offer(line);
if (line.equals("ok") || line.startsWith("error: ")
|| line.startsWith("$VERSION =")) {
// This is the end of processing for a command
//System.out.println("Line = " + line);
synchronized (commandLock) {
commandLock.notify();
}
}
}
}
@Override
public Wizard getConfigurationWizard() {
return new AbstractSerialPortDriverConfigurationWizard(this);
}
@Override
public PropertySheetHolder[] getChildPropertySheetHolders() {
// TODO Auto-generated method stub
return null;
}
@Override
public Action[] getPropertySheetHolderActions() {
// TODO Auto-generated method stub
return null;
}
@Override
public PropertySheet[] getPropertySheets() {
return new PropertySheet[] {
new PropertySheetWizardAdapter(getConfigurationWizard())
};
}
@Override
public String getPropertySheetHolderTitle() {
return getClass().getSimpleName();
}
/**
* Causes Grbl to block until all commands are complete.
* @throws Exception
*/
private void dwell() throws Exception {
sendCommand("G4 P0.01");
}
private List<String> drainResponseQueue() {
List<String> responses = new ArrayList<String>();
String response;
while ((response = responseQueue.poll()) != null) {
responses.add(response);
}
return responses;
}
}