Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Grbl Boards #3

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
133 changes: 105 additions & 28 deletions host-python/chipshover/cs.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@
import base64
import datetime
import binascii
from enum import Enum


class FirmwareType(Enum):
Marlin = 0
Grbl = 1


def firmware_update(comport, fw_path=None):
Expand Down Expand Up @@ -155,9 +161,15 @@ class ChipShover:
#Default ChipShover table/firmware combo
STEPS_PER_MM = 1600

def __init__(self, comport):
def __init__(self, comport, firmware: FirmwareType = FirmwareType.Marlin):
"""Connect to ChipShover-Controller using given serial port."""
self.ser = serial.Serial(comport, rtscts=True)
self.firmwaretype = firmware
if self.firmwaretype == FirmwareType.Grbl:
self.ser = serial.Serial(comport, baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
self.ser.write(b"\r\n\r\n")
time.sleep(2)
else:
self.ser = serial.Serial(comport, rtscts=True)
self._com = comport

#Required for ChipShover-One + Archim2 USB serial
Expand All @@ -179,41 +191,69 @@ def __init__(self, comport):
self.wait_done()

#Check the "steps per unit" is valid
self.get_steps_grbl()


if self.firmwaretype == FirmwareType.Marlin:
self.set_fan(50)

self.call_stop_on_ctrlc = True

#TODO -
#signal.signal(signal.SIGINT, self.stop)

def get_steps_grbl(self):
self.ser.write(b"$$\n")
line = None
xsteps, ysteps, zsteps = None, None, None
while line != b'':
line = self.ser.readline()
if b'=' in line:
param, val = line.split(b'=')
val = float(val.split(b' ')[0])
if param == b'$100':
xsteps = val
elif param == b'$101':
ysteps = val
elif param == b'$102':
zsteps = val
if xsteps != ysteps != zsteps:
raise ValueError("XSTEPS/YSTEPS/ZSTEPS differs. Abort. %f %f %f" % (xsteps, ysteps, zsteps))

if xsteps < 100 or xsteps > 10E3:
raise ValueError("Sanity check in XSTEPS failed. %f" % xsteps)

self.STEPS_PER_MM = int(xsteps)


def get_steps_marlin(self):
self.ser.write(b"M503\n")
results = self.wait_done()
try:
splitres = results.split(b"Steps per unit:\necho: M92")[1].split(b"\n")[0]
splitres = splitres.split(b" ")
if splitres[1][0] != ord('X') or \
splitres[2][0] != ord('Y') or \
splitres[3][0] != ord('Z'):
splitres[2][0] != ord('Y') or \
splitres[3][0] != ord('Z'):
raise IOError("Communication problem attempting to read" + \
"M503 response. %s was splitres"%splitres)
"M503 response. %s was splitres" % splitres)
xsteps = float(splitres[1][1:])
ysteps = float(splitres[2][1:])
zsteps = float(splitres[3][1:])

if xsteps != ysteps != zsteps:
raise ValueError("XSTEPS/YSTEPS/ZSTEPS differs. Abort. %f %f %f"%(xsteps, ysteps, zsteps))
raise ValueError("XSTEPS/YSTEPS/ZSTEPS differs. Abort. %f %f %f" % (xsteps, ysteps, zsteps))

if xsteps < 100 or xsteps > 10E3:
raise ValueError("Sanity check in XSTEPS failed. %f"%xsteps)
raise ValueError("Sanity check in XSTEPS failed. %f" % xsteps)

self.STEPS_PER_MM = int(xsteps)

except:
print("Failed to read steps/mm, check communication is OK.")
print("Response to M503: %s"%results)
print("Response to M503: %s" % results)
raise


self.set_fan(50)

self.call_stop_on_ctrlc = True

#TODO -
#signal.signal(signal.SIGINT, self.stop)

def set_fan(self, fan_speed=100):
"""Sets cooling fan speed, range of 0 - 100"""

Expand Down Expand Up @@ -289,14 +329,31 @@ def move(self, x=None, y=None, z=None, debug=False):

if debug:
print(cmdstr)


self.ser.write(cmdstr)

self.ser.write(cmdstr)
self.wait_done()

self.wait_for_move()

def wait_for_move(self):
if self.firmwaretype == FirmwareType.Marlin:
self.wait_for_move_marlin()
elif self.firmwaretype == FirmwareType.Grbl:
self.wait_for_move_grbl()

def wait_for_move_grbl(self):
self.ser.flush()
self.ser.reset_input_buffer()
# wait for move to finish
self.ser.write(b"?\n")
while True:
line = self.ser.readline()
self.wait_done()
if line.startswith(b'<Idle'):
break
self.ser.write(b"?\n")

self.ser.flush()
self.ser.reset_input_buffer()

def wait_for_move_marlin(self):
"""Wait for current movement to be done"""

self.ser.flush()
Expand All @@ -305,8 +362,21 @@ def wait_for_move(self):
self.ser.write(b"M400\n")
self.wait_done()

def get_position_grbl(self, forcefinish=True):
if forcefinish:
self.wait_for_move_grbl()

self.ser.write(b'?\n')
status = self.ser.readline()
work_pos = status.split(b'WPos:')[1][:-3]
x_pos, y_pos, z_pos = work_pos.split(b',')
x_pos = float(x_pos)
y_pos = float(y_pos)
z_pos = float(z_pos)
self.wait_done()
return x_pos, y_pos, z_pos

def get_position(self, forcefinish=True):
def get_position_marlin(self, forcefinish=True):
"""Gets the X/Y/Z position of the table.

By default will wait for any movement to
Expand All @@ -317,7 +387,7 @@ def get_position(self, forcefinish=True):

if forcefinish:
#wait for move to finish
self.wait_for_move()
self.wait_for_move_marlin()

self.ser.write(b"M114\n")

Expand Down Expand Up @@ -389,8 +459,12 @@ def home(self, x=True, y=True, z=True):
self.ser.write(b"\n")

home_resp = self.wait_done()

self.z_home = self.get_position()[2]

if self.firmwaretype == FirmwareType.Marlin:
self.z_home = self.get_position_marlin()[2]

elif self.firmwaretype == FirmwareType.Grbl:
self.z_home = self.get_position_grbl()[2]

return home_resp

Expand Down Expand Up @@ -434,7 +508,10 @@ def sweep_x_y(self, x_start, x_end, y_start, y_end, step=0.1, x_step=None, y_ste
self.move(y=y)

if z_plunge:
old_z = self.get_position()[2]
if self.firmwaretype == FirmwareType.Marlin:
old_z = self.get_position_marlin()[2]
elif self.firmwaretype == FirmwareType.Grbl:
old_z = self.get_position_grbl()[2]
self.move(z = (old_z-z_plunge))

yield (x, y)
Expand Down Expand Up @@ -479,7 +556,7 @@ def wait_done(self, timeout=5, debug=False):
timeout_cnt = 0

#Done deal I guess
if resp == b'ok\n':
if resp == b'ok\r\n' or resp == b'ok\n':
break

time.sleep(0.25)
Expand Down