extruder: Create a new class and python file to track the printer extruder

Create a new python file (extruder.py) to control the extruder heater
and stepper motors.  This separates the extruder control logic from
the cartesian robot code - making it easier to customize both the
kinematic control of the robot as well as the extruder.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2016-07-10 12:23:35 -04:00
parent 4a527a46ce
commit af99ab1645
8 changed files with 88 additions and 27 deletions

View File

@ -42,7 +42,7 @@ position_min: 0.1
position_endstop: 0.5
position_max: 200
[stepper_e]
[extruder]
# Pins: PC3, PC2
step_pin: ar19
dir_pin: ar18
@ -50,8 +50,6 @@ enable_pin: ar25
step_distance: .004242
max_velocity: 200000
max_accel: 3000
[heater_nozzle]
heater_pin: ar4
thermistor_pin: analog1
thermistor_type: EPCOS 100K B57560G104F

View File

@ -77,19 +77,19 @@ position_min: 0.1
position_endstop: 0.5
position_max: 200
# The stepper_e section is used to describe the stepper controlling
# the printer extruder. It has the same settings as the stepper_x
# section
[stepper_e]
# The extruder section is used to describe both the stepper
# controlling the printer extruder and the heater parameters for the
# nozzle. The stepper configuration has the same settings as the
# stepper_x section and the heater configuration has the same settings
# as the heater_bed section
[extruder]
step_pin: ar19
dir_pin: ar18
enable_pin: !ar25
step_distance: .004242
max_velocity: 200000
max_accel: 3000
# The heater_nozzle section describes the extruder and extruder heater
[heater_nozzle]
# The remaining variables describe the extruder heater
heater_pin: ar4
# PWM output pin controlling the heater
thermistor_pin: analog1
@ -118,8 +118,7 @@ max_temp: 210
# this value)
# The heater_bed section describes a heated bed (if present - omit
# section if not present). It has the same settings as the
# heater_nozzle section
# section if not present).
[heater_bed]
heater_pin: ar3
thermistor_pin: analog0

View File

@ -43,15 +43,13 @@ position_min: 0.1
position_endstop: 0.7
position_max: 200
[stepper_e]
[extruder]
step_pin: PC3
dir_pin: !PL6
enable_pin: !PA4
step_distance: .004242
max_velocity: 200000
max_accel: 3000
[heater_nozzle]
heater_pin: PH6
thermistor_pin: PF0
thermistor_type: EPCOS 100K B57560G104F

View File

@ -6,14 +6,14 @@
import logging
import stepper, homing
StepList = (0, 1, 2, 3)
StepList = (0, 1, 2)
class CartKinematics:
def __init__(self, printer, config):
steppers = ['stepper_x', 'stepper_y', 'stepper_z', 'stepper_e']
steppers = ['stepper_x', 'stepper_y', 'stepper_z']
self.steppers = [stepper.PrinterStepper(printer, config.getsection(n))
for n in steppers]
self.stepper_pos = [0, 0, 0, 0]
self.stepper_pos = [0, 0, 0]
def build_config(self):
for stepper in self.steppers:
stepper.build_config()
@ -31,9 +31,6 @@ class CartKinematics:
accel_factor = min([self.steppers[i].max_accel / abs(axes_d[i])
for i in StepList if axes_d[i]])
return velocity_factor * move_d, accel_factor * move_d
def get_max_e_speed(self):
s = self.steppers[3]
return s.max_velocity, s.max_accel
def home(self, toolhead, axis):
# Each axis is homed independently and in order
homing_state = homing.Homing(toolhead, self.steppers) # XXX

62
klippy/extruder.py Normal file
View File

@ -0,0 +1,62 @@
# Code for handling printer nozzle extruders
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import stepper, heater
class PrinterExtruder:
def __init__(self, printer, config):
cfg = config.getsection('extruder')
self.heater = heater.PrinterHeater(printer, cfg)
self.stepper = stepper.PrinterStepper(printer, cfg)
self.stepper_pos = 0
def build_config(self):
self.heater.build_config()
self.stepper.build_config()
def get_max_speed(self):
return self.stepper.max_velocity, self.stepper.max_accel
def motor_off(self, move_time):
self.stepper.motor_enable(move_time, 0)
def move(self, move_time, move):
inv_accel = 1. / move.accel
new_step_pos = int(move.pos[3]*self.stepper.inv_step_dist + 0.5)
steps = new_step_pos - self.stepper_pos
if not steps:
return
self.stepper_pos = new_step_pos
sdir = 0
if steps < 0:
sdir = 1
steps = -steps
clock_offset, clock_freq, so = self.stepper.prep_move(sdir, move_time)
step_dist = move.move_d / steps
step_offset = 0.5
# Acceleration steps
#t = sqrt(2*pos/accel + (start_v/accel)**2) - start_v/accel
accel_clock_offset = move.start_v * inv_accel * clock_freq
accel_sqrt_offset = accel_clock_offset**2
accel_multiplier = 2.0 * step_dist * inv_accel * clock_freq**2
accel_steps = move.accel_r * steps
step_offset = so.step_sqrt(
accel_steps, step_offset, clock_offset - accel_clock_offset
, accel_sqrt_offset, accel_multiplier)
clock_offset += move.accel_t * clock_freq
# Cruising steps
#t = pos/cruise_v
cruise_multiplier = step_dist * clock_freq / move.cruise_v
cruise_steps = move.cruise_r * steps
step_offset = so.step_factor(
cruise_steps, step_offset, clock_offset, cruise_multiplier)
clock_offset += move.cruise_t * clock_freq
# Deceleration steps
#t = cruise_v/accel - sqrt((cruise_v/accel)**2 - 2*pos/accel)
decel_clock_offset = move.cruise_v * inv_accel * clock_freq
decel_sqrt_offset = decel_clock_offset**2
decel_steps = move.decel_r * steps
so.step_sqrt(
decel_steps, step_offset, clock_offset + decel_clock_offset
, decel_sqrt_offset, -accel_multiplier)

View File

@ -35,7 +35,10 @@ class GCodeParser:
self.axis2pos = {'X': 0, 'Y': 1, 'Z': 2, 'E': 3}
def build_config(self):
self.toolhead = self.printer.objects['toolhead']
self.heater_nozzle = self.printer.objects.get('heater_nozzle')
self.heater_nozzle = None
extruder = self.printer.objects.get('extruder')
if extruder:
self.heater_nozzle = extruder.heater
self.heater_bed = self.printer.objects.get('heater_bed')
self.fan = self.printer.objects.get('fan')
self.build_handlers()

View File

@ -5,7 +5,7 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, optparse, ConfigParser, logging, time, threading
import gcode, toolhead, util, mcu, fan, heater, reactor
import gcode, toolhead, util, mcu, fan, heater, extruder, reactor
class ConfigWrapper:
def __init__(self, printer, section):
@ -52,9 +52,9 @@ class Printer:
if self.fileconfig.has_section('fan'):
self.objects['fan'] = fan.PrinterFan(
self, ConfigWrapper(self, 'fan'))
if self.fileconfig.has_section('heater_nozzle'):
self.objects['heater_nozzle'] = heater.PrinterHeater(
self, ConfigWrapper(self, 'heater_nozzle'))
if self.fileconfig.has_section('extruder'):
self.objects['extruder'] = extruder.PrinterExtruder(
self, ConfigWrapper(self, 'extruder'))
if self.fileconfig.has_section('heater_bed'):
self.objects['heater_bed'] = heater.PrinterHeater(
self, ConfigWrapper(self, 'heater_bed'))

View File

@ -61,6 +61,8 @@ class Move:
# Generate step times for the move
next_move_time = self.toolhead.get_next_move_time()
self.toolhead.kin.move(next_move_time, self)
if self.axes_d[3]:
self.toolhead.extruder.move(next_move_time, self)
self.toolhead.update_move_time(accel_t + cruise_t + decel_t)
# Class to track a list of pending move requests and to facilitate
@ -113,6 +115,7 @@ class ToolHead:
def __init__(self, printer, config):
self.printer = printer
self.reactor = printer.reactor
self.extruder = printer.objects.get('extruder')
self.kin = cartesian.CartKinematics(printer, config)
self.max_xy_speed, self.max_xy_accel = self.kin.get_max_xy_speed()
self.junction_deviation = config.getfloat('junction_deviation', 0.02)
@ -208,7 +211,7 @@ class ToolHead:
move.process(0., 0.)
def _move_only_e(self, newpos, axes_d, speed):
self.move_queue.flush()
kin_speed, kin_accel = self.kin.get_max_e_speed()
kin_speed, kin_accel = self.extruder.get_max_speed()
speed = min(speed, self.max_xy_speed, kin_speed)
accel = min(self.max_xy_accel, kin_accel)
move = Move(self, newpos, abs(axes_d[3]), axes_d, speed, accel)
@ -238,5 +241,6 @@ class ToolHead:
self.dwell(STALL_TIME)
last_move_time = self.get_last_move_time()
self.kin.motor_off(last_move_time)
self.extruder.motor_off(last_move_time)
self.dwell(STALL_TIME)
logging.debug('; Max time of %f' % (last_move_time,))