Browse Source

Small FREQUENCY_LIMIT changes

pull/1/head
Erik vd Zalm 12 years ago
parent
commit
b98fb17fe9
  1. 127
      Marlin/createTemperatureLookup.py
  2. 82
      Marlin/planner.cpp

127
Marlin/createTemperatureLookup.py

@ -1,127 +0,0 @@
#!/usr/bin/python
#
# Creates a C code lookup table for doing ADC to temperature conversion
# on a microcontroller
# based on: http://hydraraptor.blogspot.com/2007/10/measuring-temperature-easy-way.html
"""Thermistor Value Lookup Table Generator
Generates lookup to temperature values for use in a microcontroller in C format based on:
http://hydraraptor.blogspot.com/2007/10/measuring-temperature-easy-way.html
The main use is for Arduino programs that read data from the circuit board described here:
http://make.rrrf.org/ts-1.0
Usage: python createTemperatureLookup.py [options]
Options:
-h, --help show this help
--r0=... thermistor rating where # is the ohm rating of the thermistor at t0 (eg: 10K = 10000)
--t0=... thermistor temp rating where # is the temperature in Celsuis to get r0 (from your datasheet)
--beta=... thermistor beta rating. see http://reprap.org/bin/view/Main/MeasuringThermistorBeta
--r1=... R1 rating where # is the ohm rating of R1 (eg: 10K = 10000)
--r2=... R2 rating where # is the ohm rating of R2 (eg: 10K = 10000)
--num-temps=... the number of temperature points to calculate (default: 20)
--max-adc=... the max ADC reading to use. if you use R1, it limits the top value for the thermistor circuit, and thus the possible range of ADC values
"""
from math import *
import sys
import getopt
class Thermistor:
"Class to do the thermistor maths"
def __init__(self, r0, t0, beta, r1, r2):
self.r0 = r0 # stated resistance, e.g. 10K
self.t0 = t0 + 273.15 # temperature at stated resistance, e.g. 25C
self.beta = beta # stated beta, e.g. 3500
self.vadc = 5.0 # ADC reference
self.vcc = 5.0 # supply voltage to potential divider
self.k = r0 * exp(-beta / self.t0) # constant part of calculation
if r1 > 0:
self.vs = r1 * self.vcc / (r1 + r2) # effective bias voltage
self.rs = r1 * r2 / (r1 + r2) # effective bias impedance
else:
self.vs = self.vcc # effective bias voltage
self.rs = r2 # effective bias impedance
def temp(self,adc):
"Convert ADC reading into a temperature in Celcius"
v = adc * self.vadc / 1024 # convert the 10 bit ADC value to a voltage
r = self.rs * v / (self.vs - v) # resistance of thermistor
return (self.beta / log(r / self.k)) - 273.15 # temperature
def setting(self, t):
"Convert a temperature into a ADC value"
r = self.r0 * exp(self.beta * (1 / (t + 273.15) - 1 / self.t0)) # resistance of the thermistor
v = self.vs * r / (self.rs + r) # the voltage at the potential divider
return round(v / self.vadc * 1024) # the ADC reading
def main(argv):
r0 = 10000;
t0 = 25;
beta = 3947;
r1 = 680;
r2 = 1600;
num_temps = int(20);
try:
opts, args = getopt.getopt(argv, "h", ["help", "r0=", "t0=", "beta=", "r1=", "r2="])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt == "--r0":
r0 = int(arg)
elif opt == "--t0":
t0 = int(arg)
elif opt == "--beta":
beta = int(arg)
elif opt == "--r1":
r1 = int(arg)
elif opt == "--r2":
r2 = int(arg)
if r1:
max_adc = int(1023 * r1 / (r1 + r2));
else:
max_adc = 1023
increment = int(max_adc/(num_temps-1));
t = Thermistor(r0, t0, beta, r1, r2)
adcs = range(1, max_adc, increment);
# adcs = [1, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110, 130, 150, 190, 220, 250, 300]
first = 1
print "// Thermistor lookup table for RepRap Temperature Sensor Boards (http://make.rrrf.org/ts)"
print "// Made with createTemperatureLookup.py (http://svn.reprap.org/trunk/reprap/firmware/Arduino/utilities/createTemperatureLookup.py)"
print "// ./createTemperatureLookup.py --r0=%s --t0=%s --r1=%s --r2=%s --beta=%s --max-adc=%s" % (r0, t0, r1, r2, beta, max_adc)
print "// r0: %s" % (r0)
print "// t0: %s" % (t0)
print "// r1: %s" % (r1)
print "// r2: %s" % (r2)
print "// beta: %s" % (beta)
print "// max adc: %s" % (max_adc)
print "#define NUMTEMPS %s" % (len(adcs))
print "short temptable[NUMTEMPS][2] = {"
counter = 0
for adc in adcs:
counter = counter +1
if counter == len(adcs):
print " {%s, %s}" % (adc, int(t.temp(adc)))
else:
print " {%s, %s}," % (adc, int(t.temp(adc)))
print "};"
def usage():
print __doc__
if __name__ == "__main__":
main(sys.argv[1:])

82
Marlin/planner.cpp

@ -103,12 +103,11 @@ volatile unsigned char block_buffer_tail; // Index of the block to pro
bool allow_cold_extrude=false;
#endif
#ifdef XY_FREQUENCY_LIMIT
#define MAX_FREQ_TIME (1000000.0/XY_FREQUENCY_LIMIT)
// Used for the frequency limit
static unsigned char old_direction_bits = 0; // Old direction bits. Used for speed calculations
static long x_segment_time[3]={
0,0,0}; // Segment times (in us). Used for speed calculations
static long y_segment_time[3]={
0,0,0};
static long x_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; // Segment times (in us). Used for speed calculations
static long y_segment_time[3]={MAX_FREQ_TIME + 1,0,0};
#endif
// Returns the index of the next block in the ring buffer
@ -435,7 +434,7 @@ void getHighESpeed()
}
#endif
void check_axes_activity()
void check_axes_activity()
{
unsigned char x_active = 0;
unsigned char y_active = 0;
@ -445,11 +444,11 @@ void check_axes_activity()
unsigned char tail_fan_speed = 0;
block_t *block;
if(block_buffer_tail != block_buffer_head)
if(block_buffer_tail != block_buffer_head)
{
uint8_t block_index = block_buffer_tail;
tail_fan_speed = block_buffer[block_index].fan_speed;
while(block_index != block_buffer_head)
while(block_index != block_buffer_head)
{
block = &block_buffer[block_index];
if(block->steps_x != 0) x_active++;
@ -460,7 +459,7 @@ void check_axes_activity()
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
}
}
else
else
{
#if FAN_PIN > -1
if (FanSpeed != 0){
@ -471,19 +470,19 @@ void check_axes_activity()
if((DISABLE_X) && (x_active == 0)) disable_x();
if((DISABLE_Y) && (y_active == 0)) disable_y();
if((DISABLE_Z) && (z_active == 0)) disable_z();
if((DISABLE_E) && (e_active == 0))
if((DISABLE_E) && (e_active == 0))
{
disable_e0();
disable_e1();
disable_e2();
}
#if FAN_PIN > -1
if((FanSpeed == 0) && (fan_speed ==0))
if((FanSpeed == 0) && (fan_speed ==0))
{
analogWrite(FAN_PIN, 0);
}
if (FanSpeed != 0 && tail_fan_speed !=0)
if (FanSpeed != 0 && tail_fan_speed !=0)
{
analogWrite(FAN_PIN,tail_fan_speed);
}
@ -505,7 +504,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
// If the buffer is full: good! That means we are well ahead of the robot.
// Rest here until there is room in the buffer.
while(block_buffer_tail == next_buffer_head)
while(block_buffer_tail == next_buffer_head)
{
manage_heater();
manage_inactivity();
@ -522,7 +521,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
target[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
#ifdef PREVENT_DANGEROUS_EXTRUDE
if(target[E_AXIS]!=position[E_AXIS])
if(target[E_AXIS]!=position[E_AXIS])
{
if(degHotend(active_extruder)<EXTRUDE_MINTEMP && !allow_cold_extrude)
{
@ -530,7 +529,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP);
}
#ifdef PREVENT_LENGTHY_EXTRUDE
if(labs(target[E_AXIS]-position[E_AXIS])>axis_steps_per_unit[E_AXIS]*EXTRUDE_MAXLENGTH)
{
@ -538,7 +537,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP);
}
#endif
#endif
}
#endif
@ -558,7 +557,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e)));
// Bail if this is a zero-length block
if (block->step_event_count <= dropsegments)
if (block->step_event_count <= dropsegments)
{
return;
}
@ -567,19 +566,19 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
// Compute direction bits for this block
block->direction_bits = 0;
if (target[X_AXIS] < position[X_AXIS])
if (target[X_AXIS] < position[X_AXIS])
{
block->direction_bits |= (1<<X_AXIS);
}
if (target[Y_AXIS] < position[Y_AXIS])
if (target[Y_AXIS] < position[Y_AXIS])
{
block->direction_bits |= (1<<Y_AXIS);
}
if (target[Z_AXIS] < position[Z_AXIS])
if (target[Z_AXIS] < position[Z_AXIS])
{
block->direction_bits |= (1<<Z_AXIS);
}
if (target[E_AXIS] < position[E_AXIS])
if (target[E_AXIS] < position[E_AXIS])
{
block->direction_bits |= (1<<E_AXIS);
}
@ -594,18 +593,18 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
#endif
// Enable all
if(block->steps_e != 0)
if(block->steps_e != 0)
{
enable_e0();
enable_e1();
enable_e2();
}
if (block->steps_e == 0)
if (block->steps_e == 0)
{
if(feed_rate<mintravelfeedrate) feed_rate=mintravelfeedrate;
}
else
else
{
if(feed_rate<minimumfeedrate) feed_rate=minimumfeedrate;
}
@ -615,11 +614,11 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS];
delta_mm[E_AXIS] = ((target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS])*extrudemultiply/100.0;
if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments )
if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments )
{
block->millimeters = fabs(delta_mm[E_AXIS]);
}
else
else
{
block->millimeters = sqrt(square(delta_mm[X_AXIS]) + square(delta_mm[Y_AXIS]) + square(delta_mm[Z_AXIS]));
}
@ -632,18 +631,21 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
// slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill
#ifdef OLD_SLOWDOWN
if(moves_queued < (BLOCK_BUFFER_SIZE * 0.5) && moves_queued > 1)
if(moves_queued < (BLOCK_BUFFER_SIZE * 0.5) && moves_queued > 1)
feed_rate = feed_rate*moves_queued / (BLOCK_BUFFER_SIZE * 0.5);
#endif
#ifdef SLOWDOWN
// segment time im micro seconds
unsigned long segment_time = lround(1000000.0/inverse_second);
if ((moves_queued > 1) && (moves_queued < (BLOCK_BUFFER_SIZE * 0.5)))
if ((moves_queued > 1) && (moves_queued < (BLOCK_BUFFER_SIZE * 0.5)))
{
if (segment_time < minsegmenttime)
if (segment_time < minsegmenttime)
{ // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more.
inverse_second=1000000.0/(segment_time+lround(2*(minsegmenttime-segment_time)/moves_queued));
#ifdef XY_FREQUENCY_LIMIT
segment_time = lround(1000000.0/inverse_second);
#endif
}
}
#endif
@ -656,7 +658,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
// Calculate and limit speed in mm/sec for each axis
float current_speed[4];
float speed_factor = 1.0; //factor <=1 do decrease speed
for(int i=0; i < 4; i++)
for(int i=0; i < 4; i++)
{
current_speed[i] = delta_mm[i] * inverse_second;
if(fabs(current_speed[i]) > max_feedrate[i])
@ -666,26 +668,26 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
// Max segement time in us.
#ifdef XY_FREQUENCY_LIMIT
#define MAX_FREQ_TIME (1000000.0/XY_FREQUENCY_LIMIT)
// Check and limit the xy direction change frequency
unsigned char direction_change = block->direction_bits ^ old_direction_bits;
old_direction_bits = block->direction_bits;
if((direction_change & (1<<X_AXIS)) == 0)
segment_time = lround((float)segment_time / speed_factor);
if((direction_change & (1<<X_AXIS)) == 0)
{
x_segment_time[0] += segment_time;
}
else
else
{
x_segment_time[2] = x_segment_time[1];
x_segment_time[1] = x_segment_time[0];
x_segment_time[0] = segment_time;
}
if((direction_change & (1<<Y_AXIS)) == 0)
if((direction_change & (1<<Y_AXIS)) == 0)
{
y_segment_time[0] += segment_time;
}
else
else
{
y_segment_time[2] = y_segment_time[1];
y_segment_time[1] = y_segment_time[0];
@ -694,14 +696,14 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
long max_x_segment_time = max(x_segment_time[0], max(x_segment_time[1], x_segment_time[2]));
long max_y_segment_time = max(y_segment_time[0], max(y_segment_time[1], y_segment_time[2]));
long min_xy_segment_time =min(max_x_segment_time, max_y_segment_time);
if(min_xy_segment_time < MAX_FREQ_TIME)
if(min_xy_segment_time < MAX_FREQ_TIME)
speed_factor = min(speed_factor, speed_factor * (float)min_xy_segment_time / (float)MAX_FREQ_TIME);
#endif
// Correct the speed
if( speed_factor < 1.0)
if( speed_factor < 1.0)
{
for(unsigned char i=0; i < 4; i++)
for(unsigned char i=0; i < 4; i++)
{
current_speed[i] *= speed_factor;
}
@ -711,11 +713,11 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
// Compute and limit the acceleration rate for the trapezoid generator.
float steps_per_mm = block->step_event_count/block->millimeters;
if(block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0)
if(block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0)
{
block->acceleration_st = ceil(retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
}
else
else
{
block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
// Limit acceleration per axis

Loading…
Cancel
Save