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:
parent
4a527a46ce
commit
af99ab1645
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
|
@ -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()
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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,))
|
||||
|
|
Loading…
Reference in New Issue