A port of the Sprinter Firmware to the mbed.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
nullsub
Date:
Sun Jul 08 16:17:09 2012 +0000
Commit message:
Working

Changed in this revision

SerialBuffered.cpp Show annotated file Show diff for this revision Revisions of this file
SerialBuffered.h Show annotated file Show diff for this revision Revisions of this file
Sprinter.cpp Show annotated file Show diff for this revision Revisions of this file
Sprinter.h Show annotated file Show diff for this revision Revisions of this file
configuration.h Show annotated file Show diff for this revision Revisions of this file
export.bld Show annotated file Show diff for this revision Revisions of this file
pins.h Show annotated file Show diff for this revision Revisions of this file
thermistortables.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.cpp	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,80 @@
+
+#include "mbed.h"
+#include "SerialBuffered.h"
+
+SerialBuffered::SerialBuffered( size_t bufferSize, PinName tx, PinName rx ) : Serial(  tx,  rx ) {
+    m_buffSize = 0;
+    m_contentStart = 0;
+    m_contentEnd = 0;
+    m_timeout = 1.0;
+
+
+    attach( this, &SerialBuffered::handleInterrupt );
+
+    m_buff = (uint8_t *) malloc( bufferSize );
+    if ( m_buff == NULL ) {
+        //loggerSerial.printf("SerialBuffered - failed to alloc buffer size %d\r\n", (int) bufferSize );
+    } else {
+        m_buffSize = bufferSize;
+    }
+}
+
+
+SerialBuffered::~SerialBuffered() {
+    if ( m_buff )
+        free( m_buff );
+}
+
+void SerialBuffered::setTimeout( float seconds ) {
+    m_timeout = seconds;
+}
+
+size_t SerialBuffered::readBytes( uint8_t *bytes, size_t requested ) {
+    int i = 0;
+
+    for ( ; i < requested; ) {
+        int c = getc();
+        if ( c < 0 )
+            break;
+        bytes[i] = c;
+        i++;
+    }
+    return i;
+}
+
+int SerialBuffered::getc() {
+    m_timer.reset();
+    m_timer.start();
+    while ( m_contentStart == m_contentEnd ) {
+
+
+        wait_ms( 1 );
+        if ( m_timeout > 0 &&  m_timer.read() > m_timeout )
+            return EOF;
+    }
+
+    m_timer.stop();
+
+    uint8_t result = m_buff[m_contentStart++];
+    m_contentStart =  m_contentStart % m_buffSize;
+
+
+    return result;
+}
+
+int SerialBuffered::readable() {
+    return m_contentStart != m_contentEnd ;
+}
+
+void SerialBuffered::handleInterrupt() {
+
+    while ( Serial::readable()) {
+        if ( m_contentStart == (m_contentEnd +1) % m_buffSize) {
+            //loggerSerial.printf("SerialBuffered - buffer overrun, data lost!\r\n" );
+            Serial::getc();
+        } else {
+            m_buff[ m_contentEnd ++ ] = Serial::getc();
+            m_contentEnd = m_contentEnd % m_buffSize;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.h	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,38 @@
+#pragma once
+
+// This is a buffered serial reading class, using the serial interrupt introduced in mbed library version 18 on 17/11/09
+
+// In the simplest case, construct it with a buffer size at least equal to the largest message you
+// expect your program to receive in one go.
+
+class SerialBuffered : public Serial {
+public:
+    SerialBuffered( size_t bufferSize, PinName tx, PinName rx );
+    virtual ~SerialBuffered();
+
+    int getc();     // will block till the next character turns up, or return -1 if there is a timeout
+
+    int readable(); // returns 1 if there is a character available to read, 0 otherwise
+
+    void setTimeout( float seconds );    // maximum time in seconds that getc() should block
+    // while waiting for a character
+    // Pass -1 to disable the timeout.
+
+    size_t readBytes( uint8_t *bytes, size_t requested );    // read requested bytes into a buffer,
+    // return number actually read,
+    // which may be less than requested if there has been a timeout
+
+
+private:
+
+    void handleInterrupt();
+
+
+    uint8_t *m_buff;            // points at a circular buffer, containing data from m_contentStart, for m_contentSize bytes, wrapping when you get to the end
+    uint16_t  m_contentStart;   // index of first bytes of content
+    uint16_t  m_contentEnd;     // index of bytes after last byte of content
+    uint16_t m_buffSize;
+    float m_timeout;
+    Timer m_timer;
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sprinter.cpp	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,1467 @@
+//https://github.com/kliment/Sprinter/tree/master/Sprinter
+#include "mbed.h"
+#include "configuration.h"
+#include "pins.h"
+#include "Sprinter.h"
+
+#include "SerialBuffered.h"
+
+DigitalOut heat0_led(LED1);//x
+DigitalOut heat1_led(LED2);//y
+//DigitalOut led3(LED3);//z
+DigitalOut p_led(LED_PIN);//e
+
+DigitalOut p_fan(FAN_PIN);
+
+//DigitalOut p_x_enable(X_ENABLE_PIN);
+DigitalOut p_x_dir(X_DIR_PIN);
+DigitalOut p_x_step(X_STEP_PIN);
+//DigitalIn p_x_min(X_MIN_PIN);
+//DigitalIn p_x_max(X_MAX_PIN);
+
+//DigitalOut p_y_enable(Y_ENABLE_PIN);
+DigitalOut p_y_dir(Y_DIR_PIN);
+DigitalOut p_y_step(Y_STEP_PIN);
+//DigitalIn p_y_min(Y_MIN_PIN);
+//DigitalIn p_y_max(Y_MAX_PIN);
+
+//DigitalOut p_z_enable(Z_ENABLE_PIN);
+DigitalOut p_z_dir(Z_DIR_PIN);
+DigitalOut p_z_step(Z_STEP_PIN);
+//DigitalIn p_z_min(Z_MIN_PIN);
+//DigitalIn p_z_max(Z_MAX_PIN);
+
+//DigitalOut p_e_enable(E_ENABLE_PIN);
+DigitalOut p_e_dir(E_DIR_PIN);
+DigitalOut p_e_step(E_STEP_PIN);
+
+DigitalOut p_heater0(HEATER_0_PIN);
+DigitalOut p_heater1(HEATER_1_PIN);//heated-build-platform
+
+AnalogIn p_temp0(TEMP_0_PIN);
+AnalogIn p_temp1(TEMP_1_PIN);//heated-build-platform thermistor
+
+SerialBuffered pc( 4096, USBTX, USBRX);
+char print_buffer[100];
+
+Timer timer;
+
+void print_string(char * s) {
+    while (*s) {
+        pc.putc(*s);
+        s++;
+    }
+}
+
+void print_int(int var) {
+    sprintf(print_buffer,"%d",var);
+    print_string(print_buffer);
+}
+
+void print_long(long var) {
+    sprintf(print_buffer,"%ld", var);
+    print_string(print_buffer);
+}
+
+void print_float(float var) {
+    sprintf(print_buffer,"%f",var);
+    print_string(print_buffer);
+}
+
+int micros() {
+    static long long current_us = 0;
+    current_us += timer.read_us();
+    timer.reset();
+    return current_us;
+}
+
+int millis() {
+    return int(micros()/1000);
+}
+
+// look here for descriptions of gcodes: http://linuxcnc.org/handbook/gcode/g-code.html
+// http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
+
+//Stepper Movement Variables
+
+char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
+bool move_direction[NUM_AXIS];
+unsigned long axis_previous_micros[NUM_AXIS];
+unsigned long previous_micros = 0, previous_millis_heater, previous_millis_bed_heater;
+unsigned long move_steps_to_take[NUM_AXIS];
+#ifdef RAMP_ACCELERATION
+unsigned long axis_max_interval[NUM_AXIS];
+unsigned long axis_steps_per_sqr_second[NUM_AXIS];
+unsigned long axis_travel_steps_per_sqr_second[NUM_AXIS];
+unsigned long max_interval;
+unsigned long steps_per_sqr_second, plateau_steps;
+#endif
+bool acceleration_enabled = false, accelerating = false;
+unsigned long interval;
+float destination[NUM_AXIS] = {0.0, 0.0, 0.0, 0.0};
+float current_position[NUM_AXIS] = {0.0, 0.0, 0.0, 0.0};
+unsigned long steps_taken[NUM_AXIS];
+long axis_interval[NUM_AXIS]; // for speed delay
+bool home_all_axis = false;//true;
+int feedrate = 1500, next_feedrate, saved_feedrate;
+float time_for_move;
+long gcode_N, gcode_LastN;
+bool relative_mode = false;  //Determines Absolute or Relative Coordinates
+bool relative_mode_e = false;  //Determines Absolute or Relative E Codes while in Absolute Coordinates mode. E is always relative in Relative Coordinates mode.
+long timediff = 0;
+//experimental feedrate calc
+float d = 0;
+float axis_diff[NUM_AXIS] = {0, 0, 0, 0};
+#ifdef STEP_DELAY_RATIO
+long long_step_delay_ratio = STEP_DELAY_RATIO * 100;
+#endif
+
+// comm variables
+#define MAX_CMD_SIZE 96
+#define BUFSIZE 8
+char cmdbuffer[BUFSIZE][MAX_CMD_SIZE];
+bool fromsd[BUFSIZE];
+int bufindr = 0;
+int bufindw = 0;
+int buflen = 0;
+int i = 0;
+char serial_char;
+int serial_count = 0;
+bool comment_mode = false;
+char *strchr_pointer; // just a pointer to find chars in the cmd string like X, Y, Z, E, etc
+
+// Manage heater variables. For a thermistor or AD595 thermocouple, raw values refer to the
+// reading from the analog pin. For a MAX6675 thermocouple, the raw value is the temperature in 0.25
+// degree increments (i.e. 100=25 deg).
+
+int target_raw = 0;
+int target_temp = 0;
+int current_raw = 0;
+int target_bed_raw = 0;
+int current_bed_raw = 0;
+int tt = 0, bt = 0;
+#ifdef PIDTEMP
+int temp_iState = 0;
+int prev_temp = 0;
+int pTerm;
+int iTerm;
+int dTerm;
+//int output;
+int error;
+int heater_duty = 0;
+const int temp_iState_min = 256L * -PID_INTEGRAL_DRIVE_MAX / PID_IGAIN;
+const int temp_iState_max = 256L * PID_INTEGRAL_DRIVE_MAX / PID_IGAIN;
+#endif
+#ifndef HEATER_CURRENT
+#define HEATER_CURRENT 255
+#endif
+#ifdef SMOOTHING
+uint32_t nma = 0;
+#endif
+#ifdef WATCHPERIOD
+int watch_raw = -1000;
+unsigned long watchmillis = 0;
+#endif
+#ifdef MINTEMP
+int minttemp = temp2analogh(MINTEMP);
+#endif
+#ifdef MAXTEMP
+int maxttemp = temp2analogh(MAXTEMP);
+#endif
+
+//Inactivity shutdown variables
+unsigned long previous_millis_cmd = 0;
+unsigned long max_inactive_time = 0;
+unsigned long stepper_inactive_time = 0;
+
+void setup() {
+    pc.baud(BAUDRATE);
+    print_string("start\r\n");
+    for (int i = 0; i < BUFSIZE; i++) {
+        fromsd[i] = false;
+    }
+    //Initialize Enable Pins - steppers default to disabled.
+#if (X_ENABLE_PIN > -1)
+    if (!X_ENABLE_ON) p_x_enable = 1;
+#endif
+#if (Y_ENABLE_PIN > -1)
+    if (!Y_ENABLE_ON) p_y_enable = 1;
+#endif
+#if (Z_ENABLE_PIN > -1)
+    if (!Z_ENABLE_ON) p_z_enable = 1;
+#endif
+#if (E_ENABLE_PIN > -1)
+    if (!E_ENABLE_ON) p_e_enable = 1;
+#endif
+
+#if (HEATER_0_PIN > -1)
+    p_heater0 = 0; //WRITE(HEATER_0_PIN,LOW);
+    heat0_led = 0;
+#endif
+#if (HEATER_1_PIN > -1)
+    p_heater1 = 0; //WRITE(HEATER_1_PIN,LOW);
+    heat1_led = 0;
+#endif
+
+    //Initialize Alarm Pin
+#if (ALARM_PIN > -1)
+    p_alarm = 0; //WRITE(ALARM_PIN,LOW);
+#endif
+
+    //Initialize LED Pin
+#if (LED_PIN > -1)
+    p_led = 0; //WRITE(LED_PIN,LOW);
+#endif
+
+#ifdef RAMP_ACCELERATION
+    setup_acceleration();
+#endif
+}
+
+void loop() {
+    if (buflen<3)
+        get_command();
+
+    if (buflen) {
+        process_commands();
+        buflen = (buflen-1);
+        bufindr = (bufindr + 1)%BUFSIZE;
+    }
+    //check heater every n milliseconds
+    manage_heater();
+    manage_inactivity(1);
+}
+
+int main() {
+    timer.start();
+    setup();
+    while (1) {
+        loop();
+    }
+}
+
+inline void get_command() {
+    while ( pc.readable() != 0 && buflen < BUFSIZE) {
+        serial_char = pc.getc();
+        if (serial_char == '\n' || serial_char == '\r' || serial_char == ':' || serial_count >= (MAX_CMD_SIZE - 1) ) {
+            if (!serial_count) { //if empty line
+                comment_mode = false; // for new command
+                return;
+            }
+            cmdbuffer[bufindw][serial_count] = 0; //terminate string
+            fromsd[bufindw] = false;
+            if (strstr(cmdbuffer[bufindw], "N") != NULL) {
+                strchr_pointer = strchr(cmdbuffer[bufindw], 'N');
+                gcode_N = (strtol(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL, 10));
+                if (gcode_N != gcode_LastN+1 && (strstr(cmdbuffer[bufindw], "M110") == NULL) ) {
+                    print_string("Serial Error: Line Number is not Last Line Number+1, Last Line:");
+                    print_long(gcode_LastN);
+                    print_string("\r\n");
+                    //print_long(gcode_N);
+                    FlushSerialRequestResend();
+                    serial_count = 0;
+                    return;
+                }
+
+                if (strstr(cmdbuffer[bufindw], "*") != NULL) {
+                    int checksum = 0;
+                    int count = 0;
+                    while (cmdbuffer[bufindw][count] != '*') checksum = checksum^cmdbuffer[bufindw][count++];
+                    strchr_pointer = strchr(cmdbuffer[bufindw], '*');
+
+                    if ( (int)(strtod(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL)) != checksum) {
+                        print_string("Error: checksum mismatch, Last Line:");
+                        print_long(gcode_LastN);
+                        print_string("\r\n");
+                        FlushSerialRequestResend();
+                        serial_count = 0;
+                        return;
+                    }
+                    //if no errors, continue parsing
+                } else {
+                    print_string("Error: No Checksum with line number, Last Line:");
+                    print_long(gcode_LastN);
+                    print_string("\r\n");
+                    FlushSerialRequestResend();
+                    serial_count = 0;
+                    return;
+                }
+
+                gcode_LastN = gcode_N;
+                //if no errors, continue parsing
+            } else { // if we don't receive 'N' but still see '*'
+                if ((strstr(cmdbuffer[bufindw], "*") != NULL)) {
+                    print_string("Error: No Line Number with checksum, Last Line:");
+                    print_long(gcode_LastN);
+                    print_string("\r\n");
+                    serial_count = 0;
+                    return;
+                }
+            }
+            if ((strstr(cmdbuffer[bufindw], "G") != NULL)) {
+                strchr_pointer = strchr(cmdbuffer[bufindw], 'G');
+                switch ((int)((strtod(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL)))) {
+                    case 0:
+                    case 1:
+                        print_string("ok\r\n");
+                        break;
+                    default:
+                        break;
+                }
+
+            }
+            bufindw = (bufindw + 1)%BUFSIZE;
+            buflen += 1;
+
+            comment_mode = false; //for new command
+            serial_count = 0; //clear buffer
+        } else {
+            if (serial_char == ';') comment_mode = true;
+            if (!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char;
+        }
+    }
+}
+
+inline float code_value() {
+    return (strtod(&cmdbuffer[bufindr][strchr_pointer - cmdbuffer[bufindr] + 1], NULL));
+}
+inline long code_value_long() {
+    return (strtol(&cmdbuffer[bufindr][strchr_pointer - cmdbuffer[bufindr] + 1], NULL, 10));
+}
+inline bool code_seen(char code_string[]) {
+    return (strstr(cmdbuffer[bufindr], code_string) != NULL);    //Return True if the string was found
+}
+
+inline bool code_seen(char code) {
+    strchr_pointer = strchr(cmdbuffer[bufindr], code);
+    return (strchr_pointer != NULL);  //Return True if a character was found
+}
+
+inline void process_commands() {
+    unsigned long codenum; //throw away variable
+    //char *starpos = NULL;
+
+    if (code_seen('G')) {
+        switch ((int)code_value()) {
+            case 0: // G0 -> G1
+            case 1: // G1
+#if (defined DISABLE_CHECK_DURING_ACC) || (defined DISABLE_CHECK_DURING_MOVE) || (defined DISABLE_CHECK_DURING_TRAVEL)
+                manage_heater();
+#endif
+                get_coordinates(); // For X Y Z E F
+                prepare_move();
+                previous_millis_cmd = millis();
+                //ClearToSend();
+                return;
+                //break;
+            case 4: // G4 dwell
+                codenum = 0;
+                if (code_seen('P')) codenum = code_value(); // milliseconds to wait
+                if (code_seen('S')) codenum = code_value() * 1000; // seconds to wait
+                codenum += millis();  // keep track of when we started waiting
+                while (millis()  < codenum ) {
+                    manage_heater();
+                }
+                break;
+            case 28: //G28 Home all Axis one at a time
+                saved_feedrate = feedrate;
+                for (int i=0; i < NUM_AXIS; i++) {
+                    destination[i] = current_position[i];
+                }
+                feedrate = 0;
+
+                home_all_axis = !((code_seen(axis_codes[0])) || (code_seen(axis_codes[1])) || (code_seen(axis_codes[2])));
+
+                if ((home_all_axis) || (code_seen(axis_codes[0]))) {
+                    if ((X_MIN_PIN > -1 && X_HOME_DIR==-1) || (X_MAX_PIN > -1 && X_HOME_DIR==1)) {
+                        current_position[0] = -1.5 * X_MAX_LENGTH * X_HOME_DIR;
+                        destination[0] = 0;
+                        feedrate = homing_feedrate[0];
+                        prepare_move();
+
+                        current_position[0] = 5 * X_HOME_DIR;
+                        destination[0] = 0;
+                        prepare_move();
+
+                        current_position[0] = -10 * X_HOME_DIR;
+                        destination[0] = 0;
+                        prepare_move();
+
+                        current_position[0] = (X_HOME_DIR == -1) ? 0 : X_MAX_LENGTH;
+                        destination[0] = current_position[0];
+                        feedrate = 0;
+                    }
+                }
+
+                if ((home_all_axis) || (code_seen(axis_codes[1]))) {
+                    if ((Y_MIN_PIN > -1 && Y_HOME_DIR==-1) || (Y_MAX_PIN > -1 && Y_HOME_DIR==1)) {
+                        current_position[1] = -1.5 * Y_MAX_LENGTH * Y_HOME_DIR;
+                        destination[1] = 0;
+
+                        feedrate = homing_feedrate[1];
+                        prepare_move();
+
+                        current_position[1] = 5 * Y_HOME_DIR;
+                        destination[1] = 0;
+                        prepare_move();
+
+                        current_position[1] = -10 * Y_HOME_DIR;
+                        destination[1] = 0;
+                        prepare_move();
+
+                        current_position[1] = (Y_HOME_DIR == -1) ? 0 : Y_MAX_LENGTH;
+                        destination[1] = current_position[1];
+                        feedrate = 0;
+                    }
+                }
+
+                if ((home_all_axis) || (code_seen(axis_codes[2]))) {
+                    if ((Z_MIN_PIN > -1 && Z_HOME_DIR==-1) || (Z_MAX_PIN > -1 && Z_HOME_DIR==1)) {
+                        current_position[2] = -1.5 * Z_MAX_LENGTH * Z_HOME_DIR;
+                        destination[2] = 0;
+                        feedrate = homing_feedrate[2];
+                        prepare_move();
+
+                        current_position[2] = 2 * Z_HOME_DIR;
+                        destination[2] = 0;
+                        prepare_move();
+
+                        current_position[2] = -5 * Z_HOME_DIR;
+                        destination[2] = 0;
+                        prepare_move();
+
+                        current_position[2] = (Z_HOME_DIR == -1) ? 0 : Z_MAX_LENGTH;
+                        destination[2] = current_position[2];
+                        feedrate = 0;
+                    }
+                }
+                feedrate = saved_feedrate;
+                previous_millis_cmd = millis();
+                break;
+            case 90: // G90
+                relative_mode = false;
+                break;
+            case 91: // G91
+                relative_mode = true;
+                break;
+            case 92: // G92
+                for (int i=0; i < NUM_AXIS; i++) {
+                    if (code_seen(axis_codes[i])) current_position[i] = code_value();
+                }
+                break;
+        }
+    }
+
+    else if (code_seen('M')) {
+        switch ( (int)code_value() ) {
+            case 42: //M42 -Change pin status via gcode
+                print_string("not supported!\n");
+                /*  if (code_seen('S')) {
+                      int pin_status = code_value();
+                      if (code_seen('P') && pin_status >= 0 && pin_status <= 255) {
+                          int pin_number = code_value();
+                          for (int i = 0; i < sizeof(sensitive_pins); i++) {
+                              if (sensitive_pins[i] == pin_number) {
+                                  pin_number = -1;
+                                  break;
+                              }
+                          }
+
+                          if (pin_number > -1) {
+                              pinMode(pin_number, OUTPUT);
+                              digitalWrite(pin_number, pin_status);
+                              analogWrite(pin_number, pin_status);
+                          }
+                      }
+                  }*/
+                break;
+            case 104: // M104
+                if (code_seen('S')) target_raw = temp2analogh(target_temp = code_value());
+#ifdef WATCHPERIOD
+                if (target_raw > current_raw) {
+                    watchmillis = max(1,millis());
+                    watch_raw = current_raw;
+                } else {
+                    watchmillis = 0;
+                }
+#endif
+                break;
+            case 140: // M140 set bed temp
+#if TEMP_1_PIN > -1
+                if (code_seen('S')) target_bed_raw = temp2analogBed(code_value());
+#endif
+                break;
+            case 105: // M105
+#if (TEMP_0_PIN > -1)
+                tt = analog2temp(current_raw);
+#endif
+#if TEMP_1_PIN > -1
+                bt = analog2tempBed(current_bed_raw);
+#endif
+#if (TEMP_0_PIN > -1)
+                print_string("ok T:");
+                print_int(tt);
+#ifdef PIDTEMP
+                print_string(" @:");
+                print_int(heater_duty);
+                print_string("\r\n,");
+                print_int(iTerm);
+                print_string("\r\n");
+#endif
+#if TEMP_1_PIN > -1
+                print_string(" B:");
+                print_int(bt);
+#else
+#endif
+                print_string("\r\n");
+
+#else
+#error No temperature source available
+#endif
+                return;
+                //break;
+            case 109: { // M109 - Wait for extruder heater to reach target.
+                if (code_seen('S')) target_raw = temp2analogh(target_temp = code_value());
+#ifdef WATCHPERIOD
+                if (target_raw>current_raw) {
+                    watchmillis = max(1,millis());
+                    watch_raw = current_raw;
+                } else {
+                    watchmillis = 0;
+                }
+#endif
+                codenum = millis();
+
+                /* See if we are heating up or cooling down */
+                bool target_direction = (current_raw < target_raw);  // true if heating, false if cooling
+
+#ifdef TEMP_RESIDENCY_TIME
+                long residencyStart;
+                residencyStart = -1;
+                /* continue to loop until we have reached the target temp
+                   _and_ until TEMP_RESIDENCY_TIME hasn't passed since we reached it */
+                while ( (target_direction ? (current_raw < target_raw) : (current_raw > target_raw))
+                        || (residencyStart > -1 && (millis() - residencyStart) < TEMP_RESIDENCY_TIME*1000) ) {
+#else
+                while ( target_direction ? (current_raw < target_raw) : (current_raw > target_raw) ) {
+#endif
+                    if ( (millis() - codenum) > 1000 ) { //Print Temp Reading every 1 second while heating up/cooling down
+                        print_string("T:");
+                        print_float(analog2temp(current_raw) );
+                        print_string("\r\n");
+                        codenum = millis();
+                    }
+                    manage_heater();
+#ifdef TEMP_RESIDENCY_TIME
+                    /* start/restart the TEMP_RESIDENCY_TIME timer whenever we reach target temp for the first time
+                       or when current temp falls outside the hysteresis after target temp was reached */
+                    if (   (residencyStart == -1 &&  target_direction && current_raw >= target_raw)
+                            || (residencyStart == -1 && !target_direction && current_raw <= target_raw)
+                            || (residencyStart > -1 && labs(analog2temp(current_raw) - analog2temp(target_raw)) > TEMP_HYSTERESIS) ) {
+                        residencyStart = millis();
+                    }
+#endif
+                }
+            }
+            break;
+            case 190: // M190 - Wait bed for heater to reach target.
+#if TEMP_1_PIN > -1
+                if (code_seen('S')) target_bed_raw = temp2analogh(code_value());
+                codenum = millis();
+                while (current_bed_raw < target_bed_raw) {
+                    if ( (millis()-codenum) > 1000 ) { //Print Temp Reading every 1 second while heating up.
+                        tt=analog2temp(current_raw);
+                        print_string("T:");
+                        print_int(tt);
+                        print_string("\r\n B:");
+                        print_int(analog2temp(current_bed_raw));
+                        print_string("\r\n");
+                        codenum = millis();
+                    }
+                    manage_heater();
+                }
+#endif
+                break;
+#if FAN_PIN > -1
+            case 106: //M106 Fan On
+                if (code_seen('S')) {
+                    p_fan = 1; //WRITE(FAN_PIN, HIGH);
+                    // analogWrite(FAN_PIN, constrain(code_value(),0,255) );
+                } else {
+                    p_fan = 1; //WRITE(FAN_PIN, HIGH);
+                    //analogWrite(FAN_PIN, 255 );
+                }
+                break;
+            case 107: //M107 Fan Off
+                //analogWrite(FAN_PIN, 0);
+                p_fan = 0; //WRITE(FAN_PIN, LOW);
+                break;
+#endif
+#if (PS_ON_PIN > -1)
+            case 80: // M81 - ATX Power On
+                SET_OUTPUT(PS_ON_PIN); //GND
+                break;
+            case 81: // M81 - ATX Power Off
+                SET_INPUT(PS_ON_PIN); //Floating
+                break;
+#endif
+            case 82:
+                axis_relative_modes[3] = false;
+                break;
+            case 83:
+                axis_relative_modes[3] = true;
+                break;
+            case 84:
+                if (code_seen('S')) {
+                    stepper_inactive_time = code_value() * 1000;
+                } else {
+                    disable_x();
+                    disable_y();
+                    disable_z();
+                    disable_e();
+                }
+                break;
+            case 85: // M85
+                code_seen('S');
+                max_inactive_time = code_value() * 1000;
+                break;
+            case 92: // M92
+                for (int i=0; i < NUM_AXIS; i++) {
+                    if (code_seen(axis_codes[i])) axis_steps_per_unit[i] = code_value();
+                }
+
+#ifdef RAMP_ACCELERATION
+                setup_acceleration();
+#endif
+
+                break;
+            case 115: // M115
+                print_string("FIRMWARE_NAME:Sprinter FIRMWARE_URL:http%%3A/github.com/kliment/Sprinter/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Mendel EXTRUDER_COUNT:1 UUID:");
+                print_string(uuid);
+                print_string("\r\n");
+                break;
+            case 114: // M114
+                print_string("ok C: X:");
+                print_float(current_position[0]);
+                print_string(" Y:");
+                print_float(current_position[1]);
+                print_string(" Z:");
+                print_float(current_position[2]);
+                print_string(" E:");
+                print_float(current_position[3]);
+                print_string("\r\n");
+                return;
+            case 119: // M119
+#if (X_MIN_PIN > -1)
+                print_string("x_min:");
+                pc.printf((p_x_min.read()^X_ENDSTOP_INVERT)?"H \r\n":"L \r\n");
+#endif
+#if (X_MAX_PIN > -1)
+                print_string("x_max:");
+                pc.printf((p_x_max.read()^X_ENDSTOP_INVERT)?"H \r\n":"L \r\n");
+#endif
+#if (Y_MIN_PIN > -1)
+                print_string("y_min:");
+                pc.printf((p_y_min.read()^Y_ENDSTOP_INVERT)?"H \r\n":"L \r\n");
+#endif
+#if (Y_MAX_PIN > -1)
+                print_string("y_max:");
+                pc.printf((p_y_max.read()^Y_ENDSTOP_INVERT)?"H \r\n":"L \r\n");
+#endif
+#if (Z_MIN_PIN > -1)
+                print_string("z_min:");
+                pc.printf((p_z_min.read()^Z_ENDSTOP_INVERT)?"H \r\n":"L \r\n");
+#endif
+#if (Z_MAX_PIN > -1)
+                print_string("z_max:");
+                pc.printf((p_z_max.read()^Z_ENDSTOP_INVERT)?"H \r\n":"L \r\n");
+#endif
+                print_string("\r\n");
+                break;
+#ifdef RAMP_ACCELERATION
+                //TODO: update for all axis, use for loop
+            case 201: // M201
+                for (int i=0; i < NUM_AXIS; i++) {
+                    if (code_seen(axis_codes[i])) axis_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i];
+                }
+                break;
+            case 202: // M202
+                for (int i=0; i < NUM_AXIS; i++) {
+                    if (code_seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i];
+                }
+                break;
+#endif
+        }
+    }
+    else {
+        print_string("Unknown command:\r\n");
+        print_string(cmdbuffer[bufindr]);
+        print_string("\r\n");
+    }
+    ClearToSend();
+}
+
+void FlushSerialRequestResend() {
+    //char cmdbuffer[bufindr][100]="Resend:";
+    //while (pc.txIsBusy()); //FLUSH!//pc.flush();
+    wait_ms(200); //dont know
+    print_string("Resend:");
+    print_long(gcode_LastN + 1);
+    print_string("\r\n");
+    ClearToSend();
+}
+
+void ClearToSend() {
+    previous_millis_cmd = millis();
+    print_string("ok\r\n");
+    wait_ms(10); //ACHTUNG
+}
+
+inline void get_coordinates() {
+    for (int i=0; i < NUM_AXIS; i++) {
+        if (code_seen(axis_codes[i])) destination[i] = (float)code_value() + (axis_relative_modes[i] || relative_mode)*current_position[i];
+        else destination[i] = current_position[i];                                                       //Are these else lines really needed?
+    }
+    if (code_seen('F')) {
+        next_feedrate = code_value();
+        if (next_feedrate > 0.0) feedrate = next_feedrate;
+    }
+}
+
+void prepare_move() {
+    //Find direction
+    for (int i=0; i < NUM_AXIS; i++) {
+        if (destination[i] >= current_position[i]) move_direction[i] = 1;
+        else move_direction[i] = 0;
+    }
+
+    if (min_software_endstops) {
+        if (destination[0] < 0) destination[0] = 0.0;
+        if (destination[1] < 0) destination[1] = 0.0;
+        if (destination[2] < 0) destination[2] = 0.0;
+    }
+
+    if (max_software_endstops) {
+        if (destination[0] > X_MAX_LENGTH) destination[0] = X_MAX_LENGTH;
+        if (destination[1] > Y_MAX_LENGTH) destination[1] = Y_MAX_LENGTH;
+        if (destination[2] > Z_MAX_LENGTH) destination[2] = Z_MAX_LENGTH;
+    }
+
+    for (int i=0; i < NUM_AXIS; i++) {
+        axis_diff[i] = destination[i] - current_position[i];
+        move_steps_to_take[i] = abs(axis_diff[i]) * axis_steps_per_unit[i];
+    }
+    if (feedrate < 10)
+        feedrate = 10;
+
+    //Feedrate calc based on XYZ travel distance
+    float xy_d;
+    //Check for cases where only one axis is moving - handle those without float sqrt
+    if (abs(axis_diff[0]) > 0 && abs(axis_diff[1]) == 0 && abs(axis_diff[2])==0)
+        d=abs(axis_diff[0]);
+    else if (abs(axis_diff[0]) == 0 && abs(axis_diff[1]) > 0 && abs(axis_diff[2])==0)
+        d=abs(axis_diff[1]);
+    else if (abs(axis_diff[0]) == 0 && abs(axis_diff[1]) == 0 && abs(axis_diff[2])>0)
+        d=abs(axis_diff[2]);
+    //two or three XYZ axes moving
+    else if (abs(axis_diff[0]) > 0 || abs(axis_diff[1]) > 0) { //X or Y or both
+        xy_d = sqrt(axis_diff[0] * axis_diff[0] + axis_diff[1] * axis_diff[1]);
+        //check if Z involved - if so interpolate that too
+        d = (abs(axis_diff[2])>0)?sqrt(xy_d * xy_d + axis_diff[2] * axis_diff[2]):xy_d;
+    } else if (abs(axis_diff[3]) > 0)
+        d = abs(axis_diff[3]);
+    else { //zero length move
+#ifdef DEBUG_PREPARE_MOVE
+        log_message("_PREPARE_MOVE - No steps to take!");
+#endif
+        return;
+    }
+    time_for_move = (d / (feedrate / 60000000.0) );
+    //Check max feedrate for each axis is not violated, update time_for_move if necessary
+    for (int i = 0; i < NUM_AXIS; i++) {
+        if (move_steps_to_take[i] && abs(axis_diff[i]) / (time_for_move / 60000000.0) > max_feedrate[i]) {
+            time_for_move = time_for_move / max_feedrate[i] * (abs(axis_diff[i]) / (time_for_move / 60000000.0));
+        }
+    }
+    //Calculate the full speed stepper interval for each axis
+    for (int i=0; i < NUM_AXIS; i++) {
+        if (move_steps_to_take[i]) axis_interval[i] = time_for_move / move_steps_to_take[i] * 100;
+    }
+
+#ifdef DEBUG_PREPARE_MOVE
+    log_float("_PREPARE_MOVE - Move distance on the XY plane", xy_d);
+    log_float("_PREPARE_MOVE - Move distance on the XYZ space", d);
+    log_int("_PREPARE_MOVE - Commanded feedrate", feedrate);
+    log_float("_PREPARE_MOVE - Constant full speed move time", time_for_move);
+    log_float_array("_PREPARE_MOVE - Destination", destination, NUM_AXIS);
+    log_float_array("_PREPARE_MOVE - Current position", current_position, NUM_AXIS);
+    log_ulong_array("_PREPARE_MOVE - Steps to take", move_steps_to_take, NUM_AXIS);
+    log_long_array("_PREPARE_MOVE - Axes full speed intervals", axis_interval, NUM_AXIS);
+#endif
+
+    unsigned long move_steps[NUM_AXIS];
+    for (int i=0; i < NUM_AXIS; i++)
+        move_steps[i] = move_steps_to_take[i];
+    linear_move(move_steps); // make the move
+}
+
+int max(int a, int b) {
+    if (a > b)
+        return a;
+    return b;
+}
+
+inline void linear_move(unsigned long axis_steps_remaining[]) { // make linear move with preset speeds and destinations, see G0 and G1
+    //Determine direction of movement
+    if (destination[0] > current_position[0]) p_x_dir =!INVERT_X_DIR; //WRITE(X_DIR_PIN,!INVERT_X_DIR);
+    else  p_x_dir = INVERT_X_DIR; //WRITE(X_DIR_PIN,INVERT_X_DIR);
+    if (destination[1] > current_position[1]) p_y_dir =!INVERT_Y_DIR; // WRITE(Y_DIR_PIN,!INVERT_Y_DIR);
+    else p_y_dir = INVERT_Y_DIR; // WRITE(Y_DIR_PIN,INVERT_Y_DIR);
+    if (destination[2] > current_position[2])  p_z_dir =!INVERT_Z_DIR; //WRITE(Z_DIR_PIN,!INVERT_Z_DIR);
+    else  p_z_dir = INVERT_Z_DIR; //WRITE(Z_DIR_PIN,INVERT_Z_DIR);
+    if (destination[3] > current_position[3])  p_e_dir =!INVERT_E_DIR; //WRITE(E_DIR_PIN,!INVERT_E_DIR);
+    else  p_e_dir = INVERT_E_DIR; //WRITE(E_DIR_PIN,INVERT_E_DIR);
+
+#if (X_MIN_PIN > -1)
+    if (!move_direction[0]) if (p_x_min.read() != X_ENDSTOP_INVERT) axis_steps_remaining[0]=0;
+#endif
+#if (Y_MIN_PIN > -1)
+    if (!move_direction[1]) if (p_y_min.read() != Y_ENDSTOP_INVERT) axis_steps_remaining[1]=0;
+#endif
+#if (Z_MIN_PIN > -1)
+    if (!move_direction[2]) if (p_z_min.read() != Z_ENDSTOP_INVERT) axis_steps_remaining[2]=0;
+#endif
+#if (X_MAX_PIN > -1)
+    if (move_direction[0]) if (p_x_max.read() != X_ENDSTOP_INVERT) axis_steps_remaining[0]=0;
+#endif
+#if (Y_MAX_PIN > -1)
+    if (move_direction[1]) if (p_y_max.read() != Y_ENDSTOP_INVERT) axis_steps_remaining[1]=0;
+#endif
+# if(Z_MAX_PIN > -1)
+    if (move_direction[2]) if (p_z_max.read() != Z_ENDSTOP_INVERT) axis_steps_remaining[2]=0;
+#endif
+
+
+    //Only enable axis that are moving. If the axis doesn't need to move then it can stay disabled depending on configuration.
+    // TODO: maybe it's better to refactor into a generic enable(int axis) function, that will probably take more ram,
+    // but will reduce code size
+    if (axis_steps_remaining[0]) enable_x();
+    if (axis_steps_remaining[1]) enable_y();
+    if (axis_steps_remaining[2]) enable_z();
+    if (axis_steps_remaining[3]) enable_e();
+
+    //Define variables that are needed for the Bresenham algorithm. Please note that  Z is not currently included in the Bresenham algorithm.
+    unsigned long delta[] = {axis_steps_remaining[0], axis_steps_remaining[1], axis_steps_remaining[2], axis_steps_remaining[3]}; //TODO: implement a "for" to support N axes
+    long axis_error[NUM_AXIS];
+    int primary_axis;
+    if (delta[1] > delta[0] && delta[1] > delta[2] && delta[1] > delta[3]) primary_axis = 1;
+    else if (delta[0] >= delta[1] && delta[0] > delta[2] && delta[0] > delta[3]) primary_axis = 0;
+    else if (delta[2] >= delta[0] && delta[2] >= delta[1] && delta[2] > delta[3]) primary_axis = 2;
+    else primary_axis = 3;
+    unsigned long steps_remaining = delta[primary_axis];
+    unsigned long steps_to_take = steps_remaining;
+    for (int i=0; i < NUM_AXIS; i++) {
+        if (i != primary_axis) axis_error[i] = delta[primary_axis] / 2;
+        steps_taken[i]=0;
+    }
+    interval = axis_interval[primary_axis];
+    bool is_print_move = delta[3] > 0;
+#ifdef DEBUG_BRESENHAM
+    log_int("_BRESENHAM - Primary axis", primary_axis);
+    log_int("_BRESENHAM - Primary axis full speed interval", interval);
+    log_ulong_array("_BRESENHAM - Deltas", delta, NUM_AXIS);
+    log_long_array("_BRESENHAM - Errors", axis_error, NUM_AXIS);
+#endif
+
+    //If acceleration is enabled, do some Bresenham calculations depending on which axis will lead it.
+#ifdef RAMP_ACCELERATION
+    long max_speed_steps_per_second;
+    long min_speed_steps_per_second;
+    max_interval = axis_max_interval[primary_axis];
+#ifdef DEBUG_RAMP_ACCELERATION
+    log_ulong_array("_RAMP_ACCELERATION - Teoric step intervals at move start", axis_max_interval, NUM_AXIS);
+#endif
+    unsigned long new_axis_max_intervals[NUM_AXIS];
+    max_speed_steps_per_second = 100000000 / interval;
+    min_speed_steps_per_second = 100000000 / max_interval; //TODO: can this be deleted?
+    //Calculate start speeds based on moving axes max start speed constraints.
+    int slowest_start_axis = primary_axis;
+    unsigned long slowest_start_axis_max_interval = max_interval;
+    for (int i = 0; i < NUM_AXIS; i++)
+        if (axis_steps_remaining[i] >0 &&
+                i != primary_axis &&
+                axis_max_interval[i] * axis_steps_remaining[i]/ axis_steps_remaining[slowest_start_axis] > slowest_start_axis_max_interval) {
+            slowest_start_axis = i;
+            slowest_start_axis_max_interval = axis_max_interval[i];
+        }
+    for (int i = 0; i < NUM_AXIS; i++)
+        if (axis_steps_remaining[i] >0) {
+            // multiplying slowest_start_axis_max_interval by axis_steps_remaining[slowest_start_axis]
+            // could lead to overflows when we have long distance moves (say, 390625*390625 > sizeof(unsigned long))
+            float steps_remaining_ratio = (float) axis_steps_remaining[slowest_start_axis] / axis_steps_remaining[i];
+            new_axis_max_intervals[i] = slowest_start_axis_max_interval * steps_remaining_ratio;
+
+            if (i == primary_axis) {
+                max_interval = new_axis_max_intervals[i];
+                min_speed_steps_per_second = 100000000 / max_interval;
+            }
+        }
+    //Calculate slowest axis plateau time
+    float slowest_axis_plateau_time = 0;
+    for (int i=0; i < NUM_AXIS ; i++) {
+        if (axis_steps_remaining[i] > 0) {
+            if (is_print_move && axis_steps_remaining[i] > 0) slowest_axis_plateau_time = max(slowest_axis_plateau_time,
+                        (100000000.0 / axis_interval[i] - 100000000.0 / new_axis_max_intervals[i]) / (float) axis_steps_per_sqr_second[i]);
+            else if (axis_steps_remaining[i] > 0) slowest_axis_plateau_time = max(slowest_axis_plateau_time,
+                        (100000000.0 / axis_interval[i] - 100000000.0 / new_axis_max_intervals[i]) / (float) axis_travel_steps_per_sqr_second[i]);
+        }
+    }
+    //Now we can calculate the new primary axis acceleration, so that the slowest axis max acceleration is not violated
+    steps_per_sqr_second = (100000000.0 / axis_interval[primary_axis] - 100000000.0 / new_axis_max_intervals[primary_axis]) / slowest_axis_plateau_time;
+    plateau_steps = (long) ((steps_per_sqr_second / 2.0 * slowest_axis_plateau_time + min_speed_steps_per_second) * slowest_axis_plateau_time);
+#ifdef DEBUG_RAMP_ACCELERATION
+    log_int("_RAMP_ACCELERATION - Start speed limiting axis", slowest_start_axis);
+    log_ulong("_RAMP_ACCELERATION - Limiting axis start interval", slowest_start_axis_max_interval);
+    log_ulong_array("_RAMP_ACCELERATION - Actual step intervals at move start", new_axis_max_intervals, NUM_AXIS);
+#endif
+#endif
+
+    unsigned long steps_done = 0;
+#ifdef RAMP_ACCELERATION
+    plateau_steps *= 1.01; // This is to compensate we use discrete intervals
+    acceleration_enabled = true;
+    unsigned long full_interval = interval;
+    if (interval > max_interval) acceleration_enabled = false;
+    bool decelerating = false;
+#endif
+
+    unsigned long start_move_micros = micros();
+    for (int i = 0; i < NUM_AXIS; i++) {
+        axis_previous_micros[i] = start_move_micros * 100;
+    }
+
+#ifdef DISABLE_CHECK_DURING_TRAVEL
+    //If the move time is more than allowed in DISABLE_CHECK_DURING_TRAVEL, let's
+    // consider this a print move and perform heat management during it
+    if (time_for_move / 1000 > DISABLE_CHECK_DURING_TRAVEL) is_print_move = true;
+    //else, if the move is a retract, consider it as a travel move for the sake of this feature
+    else if (delta[3]>0 && delta[0] + delta[1] + delta[2] == 0) is_print_move = false;
+#ifdef DEBUG_DISABLE_CHECK_DURING_TRAVEL
+    log_bool("_DISABLE_CHECK_DURING_TRAVEL - is_print_move", is_print_move);
+#endif
+#endif
+
+#ifdef DEBUG_MOVE_TIME
+    unsigned long startmove = micros();
+#endif
+
+    //move until no more steps remain
+    while (axis_steps_remaining[0] + axis_steps_remaining[1] + axis_steps_remaining[2] + axis_steps_remaining[3] > 0) {
+#if defined RAMP_ACCELERATION && defined DISABLE_CHECK_DURING_ACC
+        if (!accelerating && !decelerating) {
+            //If more that HEATER_CHECK_INTERVAL ms have passed since previous heating check, adjust temp
+#ifdef DISABLE_CHECK_DURING_TRAVEL
+            if (is_print_move)
+#endif
+                manage_heater();
+        }
+#else
+#ifdef DISABLE_CHECK_DURING_MOVE
+        {} //Do nothing
+#else
+        //If more that HEATER_CHECK_INTERVAL ms have passed since previous heating check, adjust temp
+#ifdef DISABLE_CHECK_DURING_TRAVEL
+        if (is_print_move)
+#endif
+            manage_heater();
+#endif
+#endif
+#ifdef RAMP_ACCELERATION
+        //If acceleration is enabled on this move and we are in the acceleration segment, calculate the current interval
+        if (acceleration_enabled && steps_done == 0) {
+            interval = max_interval;
+        } else if (acceleration_enabled && steps_done <= plateau_steps) {
+            long current_speed = (long) ((((long) steps_per_sqr_second) / 100)
+                                         * ((micros() - start_move_micros)  / 100)/100 + (long) min_speed_steps_per_second);
+            interval = 100000000 / current_speed;
+            if (interval < full_interval) {
+                accelerating = false;
+                interval = full_interval;
+            }
+            if (steps_done >= steps_to_take / 2) {
+                plateau_steps = steps_done;
+                max_speed_steps_per_second = 100000000 / interval;
+                accelerating = false;
+            }
+        } else if (acceleration_enabled && steps_remaining <= plateau_steps) { //(interval > minInterval * 100) {
+            if (!accelerating) {
+                start_move_micros = micros();
+                accelerating = true;
+                decelerating = true;
+            }
+            long current_speed = (long) ((long) max_speed_steps_per_second - ((((long) steps_per_sqr_second) / 100)
+                                         * ((micros() - start_move_micros) / 100)/100));
+            interval = 100000000 / current_speed;
+            if (interval > max_interval)
+                interval = max_interval;
+        } else {
+            //Else, we are just use the full speed interval as current interval
+            interval = full_interval;
+            accelerating = false;
+        }
+#endif
+
+        //If there are x or y steps remaining, perform Bresenham algorithm
+        if (axis_steps_remaining[primary_axis]) {
+#if (X_MIN_PIN > -1)
+            if (!move_direction[0]) if (p_x_min.read() != X_ENDSTOP_INVERT) if (primary_axis==0) break;
+                    else if (axis_steps_remaining[0]) axis_steps_remaining[0]=0;
+#endif
+#if (Y_MIN_PIN > -1)
+            if (!move_direction[1]) if (p_y_min.read() != Y_ENDSTOP_INVERT) if (primary_axis==1) break;
+                    else if (axis_steps_remaining[1]) axis_steps_remaining[1]=0;
+#endif
+#if (X_MAX_PIN > -1)
+            if (move_direction[0]) if (p_x_max.read() != X_ENDSTOP_INVERT) if (primary_axis==0) break;
+                    else if (axis_steps_remaining[0]) axis_steps_remaining[0]=0;
+#endif
+#if (Y_MAX_PIN > -1)
+            if (move_direction[1]) if (p_y_max.read() != Y_ENDSTOP_INVERT) if (primary_axis==1) break;
+                    else if (axis_steps_remaining[1]) axis_steps_remaining[1]=0;
+#endif
+#if (Z_MIN_PIN > -1)
+            if (!move_direction[2]) if (p_z_min.read() != Z_ENDSTOP_INVERT) if (primary_axis==2) break;
+                    else if (axis_steps_remaining[2]) axis_steps_remaining[2]=0;
+#endif
+#if (Z_MAX_PIN > -1)
+            if (move_direction[2]) if (p_z_max.read() != Z_ENDSTOP_INVERT) if (primary_axis==2) break;
+                    else if (axis_steps_remaining[2]) axis_steps_remaining[2]=0;
+#endif
+            timediff = micros() * 100 - axis_previous_micros[primary_axis];
+            if (timediff<0) {//check for overflow
+                axis_previous_micros[primary_axis]=micros()*100;
+                timediff=interval/2; //approximation
+            }
+            while (((unsigned long)timediff) >= interval && axis_steps_remaining[primary_axis] > 0) {
+                steps_done++;
+                steps_remaining--;
+                axis_steps_remaining[primary_axis]--;
+                timediff -= interval;
+                do_step(primary_axis);
+                axis_previous_micros[primary_axis] += interval;
+                for (int i=0; i < NUM_AXIS; i++) if (i != primary_axis && axis_steps_remaining[i] > 0) {
+                        axis_error[i] = axis_error[i] - delta[i];
+                        if (axis_error[i] < 0) {
+                            do_step(i);
+                            axis_steps_remaining[i]--;
+                            axis_error[i] = axis_error[i] + delta[primary_axis];
+                        }
+                    }
+#ifdef STEP_DELAY_RATIO
+                if (timediff >= interval) delayMicroseconds(long_step_delay_ratio * interval / 10000);
+#endif
+#ifdef STEP_DELAY_MICROS
+                if (timediff >= interval) delayMicroseconds(STEP_DELAY_MICROS);
+#endif
+            }
+        }
+    }
+#ifdef DEBUG_MOVE_TIME
+    log_ulong("_MOVE_TIME - This move took", micros()-startmove);
+#endif
+
+    if (DISABLE_X) disable_x();
+    if (DISABLE_Y) disable_y();
+    if (DISABLE_Z) disable_z();
+    if (DISABLE_E) disable_e();
+
+    // Update current position partly based on direction, we probably can combine this with the direction code above...
+    for (int i=0; i < NUM_AXIS; i++) {
+        if (destination[i] > current_position[i]) current_position[i] = current_position[i] + steps_taken[i] /  axis_steps_per_unit[i];
+        else current_position[i] = current_position[i] - steps_taken[i] / axis_steps_per_unit[i];
+    }
+}
+
+void do_step(int axis) {
+    switch (axis) {
+        case 0:
+            p_x_step = 1; //WRITE(X_STEP_PIN, HIGH);
+            break;
+        case 1:
+            p_y_step = 1; //WRITE(Y_STEP_PIN, HIGH);
+            break;
+        case 2:
+            p_z_step = 1; //WRITE(Z_STEP_PIN, HIGH);
+            break;
+        case 3:
+            p_e_step = 1; //WRITE(E_STEP_PIN, HIGH);
+            break;
+    }
+    steps_taken[axis]+=1;
+    p_x_step = 0; //WRITE(X_STEP_PIN, LOW);
+    p_y_step = 0; //WRITE(Y_STEP_PIN, LOW);
+    p_z_step = 0; //WRITE(Z_STEP_PIN, LOW);
+    p_e_step = 0; //WRITE(E_STEP_PIN, LOW);
+}
+
+#define HEAT_INTERVAL 250
+
+#ifdef CONTROLLERFAN_PIN
+unsigned long lastMotor = 0; //Save the time for when a motor was turned on last
+unsigned long lastMotorCheck = 0;
+
+void controllerFan() {
+    if ((millis() - lastMotorCheck) >= 2500) { //Not a time critical function, so we only check every 2500ms
+        lastMotorCheck = millis();
+
+        if (!READ(X_ENABLE_PIN) || !READ(Y_ENABLE_PIN) || !READ(Z_ENABLE_PIN) || !READ(E_ENABLE_PIN)) { //If any of the drivers are enabled...
+            lastMotor = millis(); //... set time to NOW so the fan will turn on
+        }
+
+        if ((millis() - lastMotor) >= (CONTROLLERFAN_SEC*1000UL) || lastMotor == 0) { //If the last time any driver was enabled, is longer since than CONTROLLERSEC...
+            WRITE(CONTROLLERFAN_PIN, LOW); //... turn the fan off
+        } else {
+            WRITE(CONTROLLERFAN_PIN, HIGH); //... turn the fan on
+        }
+    }
+}
+#endif
+
+void manage_heater() {
+    if ((millis() - previous_millis_heater) < HEATER_CHECK_INTERVAL )
+        return;
+    previous_millis_heater = millis();
+#ifdef HEATER_USES_THERMISTOR
+    current_raw = (int) (p_temp0.read()*1023.0f) ; ///analogRead(TEMP_0_PIN);
+    //printf("temp0 = %f, temp1 = %f",p_temp0.read(), p_temp1.read());
+    //   printf("current_raw == %i\r\n", current_raw);
+
+#ifdef DEBUG_HEAT_MGMT
+    log_int("_HEAT_MGMT - analogRead(TEMP_0_PIN)", current_raw);
+    log_int("_HEAT_MGMT - NUMTEMPS", NUMTEMPS);
+#endif
+    // When using thermistor, when the heater is colder than targer temp, we get a higher analog reading than target,
+    // this switches it up so that the reading appears lower than target for the control logic.
+    current_raw = 1023 - current_raw;
+#endif
+#ifdef SMOOTHING
+    if (!nma) nma = SMOOTHFACTOR * current_raw;
+    nma = (nma + current_raw) - (nma / SMOOTHFACTOR);
+    current_raw = nma / SMOOTHFACTOR;
+#endif
+#ifdef WATCHPERIOD
+    if (watchmillis && millis() - watchmillis > WATCHPERIOD) {
+        if (watch_raw + 1 >= current_raw) {
+            target_temp = target_raw = 0;
+            WRITE(HEATER_0_PIN,LOW);
+            analogWrite(HEATER_0_PIN, 0);
+#if LED_PIN >- 1
+            p_led = 0;//WRITE(LED_PIN,LOW);
+#endif
+        } else {
+            watchmillis = 0;
+        }
+    }
+#endif
+#ifdef MINTEMP
+    if (current_raw <= minttemp)
+        target_temp = target_raw = 0;
+#endif
+#ifdef MAXTEMP
+    if (current_raw >= maxttemp) {
+        target_temp = target_raw = 0;
+#if (ALARM_PIN > -1)
+        WRITE(ALARM_PIN,HIGH);
+#endif
+    }
+#endif
+#if (TEMP_0_PIN > -1)
+#ifdef PIDTEMP
+    int current_temp = analog2temp(current_raw);
+    error = target_temp - current_temp;
+    int delta_temp = current_temp - prev_temp;
+    prev_temp = current_temp;
+    pTerm = ((long)PID_PGAIN * error) / 256;
+    const int H0 = min(HEATER_DUTY_FOR_SETPOINT(target_temp),HEATER_CURRENT);
+    heater_duty = H0 + pTerm;
+    if (error < 20) {
+        temp_iState += error;
+        temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max);
+        iTerm = ((long)PID_IGAIN * temp_iState) / 256;
+        heater_duty += iTerm;
+    }
+    int prev_error = abs(target_temp - prev_temp);
+    int log3 = 1; // discrete logarithm base 3, plus 1
+    if (prev_error > 81) {
+        prev_error /= 81;
+        log3 += 4;
+    }
+    if (prev_error >  9) {
+        prev_error /=  9;
+        log3 += 2;
+    }
+    if (prev_error >  3) {
+        prev_error /=  3;
+        log3 ++;
+    }
+    dTerm = ((long)PID_DGAIN * delta_temp) / (256*log3);
+    heater_duty += dTerm;
+    heater_duty = constrain(heater_duty, 0, HEATER_CURRENT);
+    analogWrite(HEATER_0_PIN, heater_duty);
+#if LED_PIN > -1
+    p_led = 1;//analogWrite(LED_PIN, constrain(LED_PWM_FOR_BRIGHTNESS(heater_duty),0,255));
+#endif
+#else
+    if (current_raw >= target_raw) {
+        p_heater0 = 0; //WRITE(HEATER_0_PIN,LOW);
+        heat0_led = 0;
+        //analogWrite(HEATER_0_PIN, 0);
+#if LED_PIN > -1
+        p_led = 0; //WRITE(LED_PIN,LOW);
+#endif
+    } else {
+        p_heater0 = 1; //WRITE(HEATER_0_PIN,HIGH);
+        heat0_led = 1;
+        // analogWrite(HEATER_0_PIN, HEATER_CURRENT);
+#if LED_PIN > -1
+        p_led = 1; //WRITE(LED_PIN,HIGH);
+#endif
+    }
+#endif
+#endif
+    if (millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
+        return;
+    previous_millis_bed_heater = millis();
+#ifndef TEMP_1_PIN
+    return;
+#endif
+#if TEMP_1_PIN == -1
+    return;
+#else
+
+#ifdef BED_USES_THERMISTOR
+    current_bed_raw = (int)(p_temp1.read()*1023.0f);///analogRead(TEMP_0_PIN);
+
+//analogRead(TEMP_1_PIN);
+#ifdef DEBUG_HEAT_MGMT
+    log_int("_HEAT_MGMT - analogRead(TEMP_1_PIN)", current_bed_raw);
+    log_int("_HEAT_MGMT - BNUMTEMPS", BNUMTEMPS);
+#endif
+
+    // If using thermistor, when the heater is colder than targer temp, we get a higher analog reading than target,
+    // this switches it up so that the reading appears lower than target for the control logic.
+    current_bed_raw = 1023 - current_bed_raw;
+// printf("current_bed_raw == %i\r\n", current_bed_raw);
+#endif
+
+#ifdef MINTEMP
+    if (current_bed_raw >= target_bed_raw || current_bed_raw < minttemp)
+#else
+    if (current_bed_raw >= target_bed_raw)
+#endif
+    {
+#if HEATER_1_PIN > -1
+        p_heater1 = 0; //WRITE(HEATER_1_PIN,LOW);
+        heat1_led = 0;
+#endif
+    } else {
+#if HEATER_1_PIN > -1
+        p_heater1 = 1; //WRITE(HEATER_1_PIN,HIGH);
+        heat1_led = 1;
+#endif
+    }
+#endif
+
+#ifdef CONTROLLERFAN_PIN
+    controllerFan(); //Check if fan should be turned on to cool stepper drivers down
+#endif
+}
+
+#if defined (HEATER_USES_THERMISTOR) || defined (BED_USES_THERMISTOR)
+int temp2analog_thermistor(int celsius, const short table[][2], int numtemps) {
+    int raw = 0;
+    int i;
+
+    for (i=1; i<numtemps; i++) {
+        if (table[i][1] < celsius) {
+            raw = table[i-1][0] +
+                  (celsius - table[i-1][1]) *
+                  (table[i][0] - table[i-1][0]) /
+                  (table[i][1] - table[i-1][1]);
+
+            break;
+        }
+    }
+
+    // Overflow: Set to last value in the table
+    if (i == numtemps) raw = table[i-1][0];
+
+    return 1023 - raw;
+}
+#endif
+
+#if defined (HEATER_USES_THERMISTOR) || defined (BED_USES_THERMISTOR)
+int analog2temp_thermistor(int raw,const short table[][2], int numtemps) {
+    int celsius = 0;
+    int i;
+
+    raw = 1023 - raw;
+
+    for (i=1; i<numtemps; i++) {
+        if (table[i][0] > raw) {
+            celsius  = table[i-1][1] +
+                       (raw - table[i-1][0]) *
+                       (table[i][1] - table[i-1][1]) /
+                       (table[i][0] - table[i-1][0]);
+            break;
+        }
+    }
+
+    // Overflow: Set to last value in the table
+    if (i == numtemps) celsius = table[i-1][1];
+
+    return celsius;
+}
+#endif
+
+inline void kill() {
+#if TEMP_0_PIN > -1
+    target_raw=0;
+    p_heater0 = 0; //WRITE(HEATER_0_PIN,LOW);
+    heat0_led = 0;
+#endif
+#if TEMP_1_PIN > -1
+    target_bed_raw=0;
+#if (HEATER_1_PIN > -1)
+    p_heater1 = 0; // WRITE(HEATER_1_PIN,LOW);
+    heat1_led = 0;
+
+#endif
+#endif
+    disable_x();
+    disable_y();
+    disable_z();
+    disable_e();
+
+#if (PS_ON_PIN > -1)
+    pinMode(PS_ON_PIN,INPUT);
+#endif
+}
+
+inline void manage_inactivity(int debug) {
+    if ( (millis()-previous_millis_cmd) >  max_inactive_time ) if (max_inactive_time) kill();
+    if ( (millis()-previous_millis_cmd) >  stepper_inactive_time ) if (stepper_inactive_time) {
+            disable_x();
+            disable_y();
+            disable_z();
+            disable_e();
+        }
+}
+
+#ifdef RAMP_ACCELERATION
+void setup_acceleration() {
+    for (int i=0; i < NUM_AXIS; i++) {
+        axis_max_interval[i]                = 100000000.0 / (max_start_speed_units_per_second[i] * axis_steps_per_unit[i]);
+        axis_steps_per_sqr_second[i]        = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i];
+        axis_travel_steps_per_sqr_second[i] = max_travel_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i];
+    }
+}
+#endif
+
+#ifdef DEBUG
+void log_message(char*   message) {
+    print_string("DEBUG");
+    print_string(message);
+}
+
+void log_bool(char* message, int value) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": %i", value);
+}
+
+void log_int(char* message, int value) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": %i", value);
+}
+
+void log_long(char* message, long value) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": %l", value);
+}
+
+void log_float(char* message, float value) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": %f", value);
+}
+
+void log_uint(char* message, unsigned int value) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": %i", value);
+}
+
+void log_ulong(char* message, unsigned long value) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": %l", value);
+}
+
+void log_int_array(char* message, int value[], int array_lenght) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": {");
+    for (int i=0; i < array_lenght; i++) {
+        print_string("%i",value[i]);
+        if (i != array_lenght-1) print_string(", ");
+    }
+    print_string("}\r\n");
+}
+
+void log_long_array(char* message, long value[], int array_lenght) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": {");
+    for (int i=0; i < array_lenght; i++) {
+        print_string("%l",value[i]);
+        if (i != array_lenght-1) print_string(", ");
+    }
+    print_string("}\r\n");
+}
+
+void log_float_array(char* message, float value[], int array_lenght) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": {");
+    for (int i=0; i < array_lenght; i++) {
+        print_string("%f",value[i]);
+        if (i != array_lenght-1) print_string(", ");
+    }
+    print_string("}\r\n");
+}
+
+void log_uint_array(char* message, unsigned int value[], int array_lenght) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": {");
+    for (int i=0; i < array_lenght; i++) {
+        print_string("%i", value[i]);
+        if (i != array_lenght-1) print_string(", ");
+    }
+    print_string("}\r\n");
+}
+
+void log_ulong_array(char* message, unsigned long value[], int array_lenght) {
+    print_string("DEBUG");
+    print_string(message);
+    print_string(": {");
+    for (int i=0; i < array_lenght; i++) {
+        print_string("%l",value[i]);
+        if (i != array_lenght-1) print_string(", ");
+    }
+    print_string("}\r\n");
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sprinter.h	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,64 @@
+// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
+// Licence: GPL
+extern "C" void __cxa_pure_virtual();
+void __cxa_pure_virtual(){};
+void get_command();
+void process_commands();
+
+void manage_inactivity(int debug);
+void setup_acceleration();
+
+void manage_heater();
+
+#if defined HEATER_USES_THERMISTOR
+#define temp2analogh( c ) temp2analog_thermistor(c,temptable,NUMTEMPS)
+#define analog2temp( c ) analog2temp_thermistor(c,temptable,NUMTEMPS)
+#endif
+
+#if defined BED_USES_THERMISTOR
+#define temp2analogBed( c ) temp2analog_thermistor((c),bedtemptable,BNUMTEMPS)
+#define analog2tempBed( c ) analog2temp_thermistor((c),bedtemptable,BNUMTEMPS)
+#endif
+
+#if defined (HEATER_USES_THERMISTOR) || defined (BED_USES_THERMISTOR)
+int temp2analog_thermistor(int celsius, const short table[][2], int numtemps);
+int analog2temp_thermistor(int raw,const short table[][2], int numtemps);
+#endif
+
+#if X_ENABLE_PIN != NC
+#define  enable_x() p_x_enable = X_ENABLE_ON;//WRITE(X_ENABLE_PIN, X_ENABLE_ON)
+#define disable_x() p_x_enable = !X_ENABLE_ON;//WRITE(X_ENABLE_PIN,!X_ENABLE_ON)
+#else
+#define enable_x() ;
+#define disable_x() ;
+#endif
+#if Y_ENABLE_PIN != NC
+#define  enable_y() p_y_enable = Y_ENABLE_ON;// WRITE(Y_ENABLE_PIN, Y_ENABLE_ON)
+#define disable_y() p_y_enable = !Y_ENABLE_ON;//WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON)
+#else
+#define enable_y() ;
+#define disable_y() ;
+#endif
+#if Z_ENABLE_PIN != NC
+#define  enable_z() p_z_enable = Z_ENABLE_ON;//WRITE(Z_ENABLE_PIN, Z_ENABLE_ON)
+#define disable_z() p_z_enable = !Z_ENABLE_ON;//WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON)
+#else
+#define enable_z() ;
+#define disable_z() ;
+#endif
+#if E_ENABLE_PIN != NC
+#define  enable_e() p_e_enable = E_ENABLE_ON;//WRITE(E_ENABLE_PIN, E_ENABLE_ON)
+#define disable_e() p_e_enable = !E_ENABLE_ON;//WRITE(E_ENABLE_PIN,!E_ENABLE_ON)
+#else
+#define enable_e() ;
+#define disable_e() ;
+#endif
+
+void FlushSerialRequestResend();
+void ClearToSend();
+
+void get_coordinates();
+void prepare_move();
+void linear_move(unsigned long steps_remaining[]);
+void do_step(int axis);
+void kill(int debug);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configuration.h	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,173 @@
+#ifndef PARAMETERS_H
+#define PARAMETERS_H
+
+//// Thermistor settings:
+// 1 is 100k thermistor
+// 2 is 200k thermistor
+// 3 is mendel-parts thermistor
+// 4 is 10k thermistor
+// 5 is ParCan supplied 104GT-2 100K
+// 6 is EPCOS 100k
+// 7 is 100k Honeywell thermistor 135-104LAG-J01
+#define THERMISTORHEATER 1
+#define THERMISTORBED 1 // I use a custom resistor voltage devider network with a 100k vDividerresitor!
+
+//// Calibration variables
+// X, Y, Z, E steps per unit - Metric Prusa Mendel with Wade extruder:
+float axis_steps_per_unit[] = {1280.00, 1280.00, 1280.00, 368.421}; //476.8 
+// Metric Prusa Mendel with Makergear geared stepper extruder:
+//float axis_steps_per_unit[] = {80,80,3200/1.25,1380}; 
+// MakerGear Hybrid Prusa Mendel:
+// Z axis value is for .9 stepper(if you have 1.8 steppers for Z, you need to use 2272.7272)
+//float axis_steps_per_unit[] = {104.987, 104.987, 4545.4544, 1487};
+
+// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.
+//If your axes are only moving in one direction, make sure the endstops are connected properly.
+//If your axes move in one direction ONLY when the endstops are triggered, set [XYZ]_ENDSTOP_INVERT to true here:
+const bool X_ENDSTOP_INVERT = false;
+const bool Y_ENDSTOP_INVERT = false;
+const bool Z_ENDSTOP_INVERT = false;
+
+
+//// ADVANCED SETTINGS - to tweak parameters
+
+#include "thermistortables.h"
+
+// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
+#define X_ENABLE_ON 0
+#define Y_ENABLE_ON 0
+#define Z_ENABLE_ON 0
+#define E_ENABLE_ON 0
+
+// Disables axis when it's not being used.
+const bool DISABLE_X = false;
+const bool DISABLE_Y = false;
+const bool DISABLE_Z = false;
+const bool DISABLE_E = false;
+
+// Inverting axis direction
+const bool INVERT_X_DIR = true;
+const bool INVERT_Y_DIR = true;
+const bool INVERT_Z_DIR = true;
+const bool INVERT_E_DIR = false;
+
+//// ENDSTOP SETTINGS:
+// Sets direction of endstops when homing; 1=MAX, -1=MIN
+#define X_HOME_DIR -1
+#define Y_HOME_DIR -1
+#define Z_HOME_DIR -1
+
+const bool min_software_endstops = true; //If true, axis won't move to coordinates less than zero.
+const bool max_software_endstops = true;  //If true, axis won't move to coordinates greater than the defined lengths below.
+const int X_MAX_LENGTH = 180;
+const int Y_MAX_LENGTH = 150;
+const int Z_MAX_LENGTH = 110; //not full height because of too much tension in the bearings..//190;
+
+//// MOVEMENT SETTINGS
+const int NUM_AXIS = 4; // The axis order in all axis related arrays is X, Y, Z, E
+float max_feedrate[] ={200, 200, 50, 200}; //{200000, 200000, 240, 500000}; //X=200, Y=230, Z=230
+float homing_feedrate[] = {150,150,50};
+bool axis_relative_modes[] = {false, false, false, false};
+
+// Min step delay in microseconds. If you are experiencing missing steps, try to raise the delay microseconds, but be aware this
+// If you enable this, make sure STEP_DELAY_RATIO is disabled.
+//#define STEP_DELAY_MICROS 1
+
+// Step delay over interval ratio. If you are still experiencing missing steps, try to uncomment the following line, but be aware this
+// If you enable this, make sure STEP_DELAY_MICROS is disabled. (except for Gen6: both need to be enabled.)
+//#define STEP_DELAY_RATIO 0.25
+
+// Comment this to disable ramp acceleration
+#define RAMP_ACCELERATION
+
+//// Acceleration settings
+#ifdef RAMP_ACCELERATION
+// X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot.
+float max_start_speed_units_per_second[] = {25.0,25.0,0.2,10.0};
+long max_acceleration_units_per_sq_second[] = {1000,1000,50,10000}; // X, Y, Z and E max acceleration in mm/s^2 for printing moves or retracts
+long max_travel_acceleration_units_per_sq_second[] = {500,500,50,500}; // X, Y, Z max acceleration in mm/s^2 for travel moves
+#endif
+
+// Machine UUID
+// This may be useful if you have multiple machines and wish to identify them by using the M115 command. 
+// By default we set it to zeros.
+char uuid[] = "00000000-0000-0000-0000-000000000001";
+
+//// PID settings:
+// Uncomment the following line to enable PID support. This is untested and could be disastrous. Be careful.
+//#define PIDTEMP 1
+#ifdef PIDTEMP
+#define PID_INTEGRAL_DRIVE_MAX 80 // too big, and heater will lag after changing temperature, too small and it might not compensate enough for long-term errors
+#define PID_PGAIN 2560 //256 is 1.0  // value of X means that error of 1 degree is changing PWM duty by X, probably no need to go over 25
+#define PID_IGAIN 64 //256 is 1.0  // value of X (e.g 0.25) means that each degree error over 1 sec (2 measurements) changes duty cycle by 2X (=0.5) units (verify?)
+#define PID_DGAIN 4096 //256 is 1.0  // value of X means that around reached setpoint, each degree change over one measurement (half second) adjusts PWM by X units to compensate
+// magic formula 1, to get approximate "zero error" PWM duty. Take few measurements with low PWM duty and make linear fit to get the formula
+#define HEATER_DUTY_FOR_SETPOINT(setpoint) ((int)((187L*(long)setpoint)>>8)-27)  // for my makergear hot-end: linear fit {50,10},{60,20},{80,30},{105,50},{176,100},{128,64},{208,128}
+// magic formula 2, to make led brightness approximately linear
+#define LED_PWM_FOR_BRIGHTNESS(brightness) ((64*brightness-1384)/(300-brightness))
+#endif
+
+// Change this value (range 1-255) to limit the current to the nozzle
+#define HEATER_CURRENT 255
+
+// How often should the heater check for new temp readings, in milliseconds
+#define HEATER_CHECK_INTERVAL 150 // down to 10 should be possible??? // 500
+#define BED_CHECK_INTERVAL 5000
+// Comment the following line to enable heat management during acceleration
+#define DISABLE_CHECK_DURING_ACC
+#ifndef DISABLE_CHECK_DURING_ACC
+  // Uncomment the following line to disable heat management during moves
+  //#define DISABLE_CHECK_DURING_MOVE
+#endif
+// Uncomment the following line to disable heat management during travel moves (and extruder-only moves, eg: retracts), strongly recommended if you are missing steps mid print.
+// Probably this should remain commented if are using PID.
+// It also defines the max milliseconds interval after which a travel move is not considered so for the sake of this feature.
+#define DISABLE_CHECK_DURING_TRAVEL 1000
+
+//// Temperature smoothing - only uncomment this if your temp readings are noisy (Gen6 without EvdZ's 5V hack)
+#define SMOOTHING //--> NEW
+#define SMOOTHFACTOR 8 //16 //best to use a power of two here - determines how many values are averaged together by the smoothing algorithm
+
+//// Experimental watchdog and minimal temp
+// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature
+// If the temperature has not increased at the end of that period, the target temperature is set to zero. It can be reset with another M104/M109
+//#define WATCHPERIOD 5000 //5 seconds
+
+// Actual temperature must be close to target for this long before M109 returns success
+//#define TEMP_RESIDENCY_TIME 20  // (seconds)
+//#define TEMP_HYSTERESIS 5       // (C&#65533;) range of +/- temperatures considered "close" to the target one
+
+//// The minimal temperature defines the temperature below which the heater will not be enabled
+#define MINTEMP 10 //5
+
+//// Experimental max temp
+// When temperature exceeds max temp, your heater will be switched off.
+// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
+// You should use MINTEMP for thermistor short/failure protection.
+#define MAXTEMP 280 //257
+
+// Select one of these only to define how the nozzle temp is read.
+#define HEATER_USES_THERMISTOR
+// Select one of these only to define how the bed temp is read.
+#define BED_USES_THERMISTOR
+
+//This is for controlling a fan to cool down the stepper drivers
+//it will turn on when any driver is enabled
+//and turn off after the set amount of seconds from last driver being disabled again
+//#define CONTROLLERFAN_PIN 23 //Pin used for the fan to cool controller, comment out to disable this function
+#define CONTROLLERFAN_SEC 60 //How many seconds, after all motors were disabled, the fan should run
+
+// Uncomment the following line to enable debugging. You can better control debugging below the following line
+//#define DEBUG
+#ifdef DEBUG
+  #define DEBUG_PREPARE_MOVE //Enable this to debug prepare_move() function
+  #define DEBUG_BRESENHAM //Enable this to debug the Bresenham algorithm
+  #define DEBUG_RAMP_ACCELERATION //Enable this to debug all constant acceleration info
+  #define DEBUG_MOVE_TIME //Enable this to time each move and print the result
+  #define DEBUG_HEAT_MGMT //Enable this to debug heat management. WARNING, this will cause axes to jitter!
+  #define DEBUG_DISABLE_CHECK_DURING_TRAVEL //Debug the namesake feature, see above in this file
+#endif
+
+#define BAUDRATE 115200
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/export.bld	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pins.h	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,43 @@
+#define NC -1
+
+#define X_STEP_PIN         p5
+#define X_DIR_PIN          p6
+#define X_ENABLE_PIN       NC // not used. For me --> ALWAYS ON!
+#define X_MIN_PIN           NC //p28
+#define X_MAX_PIN           NC
+
+
+#define Y_STEP_PIN         p7
+#define Y_DIR_PIN          p8
+#define Y_ENABLE_PIN       NC // not used. For me --> ALWAYS ON!
+#define Y_MIN_PIN          NC //p29
+#define Y_MAX_PIN          NC
+
+#define Z_STEP_PIN         p9
+#define Z_DIR_PIN          p10
+#define Z_ENABLE_PIN       NC 
+#define Z_MIN_PIN          NC //p30
+#define Z_MAX_PIN          NC
+
+#define E_STEP_PIN         p11
+#define E_DIR_PIN          p12
+#define E_ENABLE_PIN       NC // not used. For me --> ALWAYS ON!
+
+#define ENABLE_ALL_STEPPERS P13 //just set always to 0(it must be inverted!)
+
+#define HEATER_0_PIN       p21 // I guess this is for the extruder
+#define HEATER_1_PIN       p22 //p22 if you want to use a heated build platform NOt connected atm
+
+#define TEMP_0_PIN         p16 //EXtruder temp
+#define TEMP_1_PIN         p15 //p19 if you want to use a heated build platform with thermistor
+
+#define SDPOWER            NC
+#define SDSS               NC
+#define LED_PIN            LED3 
+#define FAN_PIN            LED4
+#define PS_ON_PIN          NC
+#define KILL_PIN           NC
+#define ALARM_PIN          NC
+
+//List of pins which to ignore when asked to change by gcode, 0 and 1 are RX and TX, do not mess with those!
+const int sensitive_pins[] = {0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, E_STEP_PIN, E_DIR_PIN, E_ENABLE_PIN, LED_PIN, PS_ON_PIN, HEATER_0_PIN, HEATER_1_PIN, FAN_PIN, TEMP_0_PIN, TEMP_1_PIN};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thermistortables.h	Sun Jul 08 16:17:09 2012 +0000
@@ -0,0 +1,691 @@
+#ifndef THERMISTORTABLES_H_
+#define THERMISTORTABLES_H_
+
+#if (THERMISTORHEATER == 1) || (THERMISTORBED == 1) //100k bed thermistor
+// Thermistor lookup table for RepRap Temperature Sensor Boards (http://make.rrrf.org/ts)
+// Made with createTemperatureLookup.py (http://svn.reprap.org/trunk/reprap/firmware/Arduino/utilities/createTemperatureLookup.py)
+// ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=4036 --max-adc=1023
+// r0: 100000
+// t0: 25
+// r1: 0
+// r2: 4700
+// beta: 4036
+// max adc: 1023
+#define NUMTEMPS_1 256
+const short temptable_1[NUMTEMPS_1][2] = {
+  {1, 399}, //{1, 864},
+  {5, 398}, // {5, 508},
+   {9, 397}, //{9, 428},
+   {13, 385},
+   {17, 357},
+   {21, 337},
+   {25, 321},
+   {29, 308},
+   {33, 297},
+   {37, 287},
+   {41, 279},
+   {45, 272},
+   {49, 265},
+   {53, 259},
+   {57, 254},
+   {61, 249},
+   {65, 245},
+   {69, 240},
+   {73, 236},
+   {77, 233},
+   {81, 229},
+   {85, 226},
+   {89, 223},
+   {93, 220},
+   {97, 217},
+   {101, 215},
+   {105, 212},
+   {109, 210},
+   {113, 207},
+   {117, 205},
+   {121, 203},
+   {125, 201},
+   {129, 199},
+   {133, 197},
+   {137, 195},
+   {141, 193},
+   {145, 191},
+   {149, 190},
+   {153, 188},
+   {157, 187},
+   {161, 185},
+   {165, 183},
+   {169, 182},
+   {173, 181},
+   {177, 179},
+   {181, 178},
+   {185, 176},
+   {189, 175},
+   {193, 174},
+   {197, 173},
+   {201, 171},
+   {205, 170},
+   {209, 169},
+   {213, 168},
+   {217, 167},
+   {221, 166},
+   {225, 164},
+   {229, 163},
+   {233, 162},
+   {237, 161},
+   {241, 160},
+   {245, 159},
+   {249, 158},
+   {253, 157},
+   {257, 156},
+   {261, 155},
+   {265, 154},
+   {269, 154},
+   {273, 153},
+   {277, 152},
+   {281, 151},
+   {285, 150},
+   {289, 149},
+   {293, 148},
+   {297, 147},
+   {301, 147},
+   {305, 146},
+   {309, 145},
+   {313, 144},
+   {317, 143},
+   {321, 143},
+   {325, 142},
+   {329, 141},
+   {333, 140},
+   {337, 140},
+   {341, 139},
+   {345, 138},
+   {349, 137},
+   {353, 137},
+   {357, 136},
+   {361, 135},
+   {365, 135},
+   {369, 134},
+   {373, 133},
+   {377, 132},
+   {381, 132},
+   {385, 131},
+   {389, 130},
+   {393, 130},
+   {397, 129},
+   {401, 128},
+   {405, 128},
+   {409, 127},
+   {413, 126},
+   {417, 126},
+   {421, 125},
+   {425, 125},
+   {429, 124},
+   {433, 123},
+   {437, 123},
+   {441, 122},
+   {445, 121},
+   {449, 121},
+   {453, 120},
+   {457, 120},
+   {461, 119},
+   {465, 118},
+   {469, 118},
+   {473, 117},
+   {477, 117},
+   {481, 116},
+   {485, 115},
+   {489, 115},
+   {493, 114},
+   {497, 114},
+   {501, 113},
+   {505, 113},
+   {509, 112},
+   {513, 111},
+   {517, 111},
+   {521, 110},
+   {525, 110},
+   {529, 109},
+   {533, 109},
+   {537, 108},
+   {541, 107},
+   {545, 107},
+   {549, 106},
+   {553, 106},
+   {557, 105},
+   {561, 105},
+   {565, 104},
+   {569, 103},
+   {573, 103},
+   {577, 102},
+   {581, 102},
+   {585, 101},
+   {589, 101},
+   {593, 100},
+   {597, 100},
+   {601, 99},
+   {605, 98},
+   {609, 98},
+   {613, 97},
+   {617, 97},
+   {621, 96},
+   {625, 96},
+   {629, 95},
+   {633, 95},
+   {637, 94},
+   {641, 93},
+   {645, 93},
+   {649, 92},
+   {653, 92},
+   {657, 91},
+   {661, 91},
+   {665, 90},
+   {669, 90},
+   {673, 89},
+   {677, 88},
+   {681, 88},
+   {685, 87},
+   {689, 87},
+   {693, 86},
+   {697, 86},
+   {701, 85},
+   {705, 84},
+   {709, 84},
+   {713, 83},
+   {717, 83},
+   {721, 82},
+   {725, 81},
+   {729, 81},
+   {733, 80},
+   {737, 80},
+   {741, 79},
+   {745, 78},
+   {749, 78},
+   {753, 77},
+   {757, 77},
+   {761, 76},
+   {765, 75},
+   {769, 75},
+   {773, 74},
+   {777, 74},
+   {781, 73},
+   {785, 72},
+   {789, 72},
+   {793, 71},
+   {797, 70},
+   {801, 70},
+   {805, 69},
+   {809, 68},
+   {813, 68},
+   {817, 67},
+   {821, 66},
+   {825, 65},
+   {829, 65},
+   {833, 64},
+   {837, 63},
+   {841, 63},
+   {845, 62},
+   {849, 61},
+   {853, 60},
+   {857, 60},
+   {861, 59},
+   {865, 58},
+   {869, 57},
+   {873, 56},
+   {877, 55},
+   {881, 55},
+   {885, 54},
+   {889, 53},
+   {893, 52},
+   {897, 51},
+   {901, 50},
+   {905, 49},
+   {909, 48},
+   {913, 47},
+   {917, 46},
+   {921, 45},
+   {925, 44},
+   {929, 43},
+   {933, 41},
+   {937, 40},
+   {941, 39},
+   {945, 38},
+   {949, 36},
+   {953, 35},
+   {957, 34},
+   {961, 32},
+   {965, 30},
+   {969, 29},
+   {973, 27},
+   {977, 25},
+   {981, 23},
+   {985, 21},
+   {989, 18},
+   {993, 16},
+   {997, 13},
+   {1001, 10},
+   {1005, 6},
+   {1009, 1},
+   {1013, 0},
+   {1017, 0},
+   {1021, 0}
+};
+
+/*#define NUMTEMPS_1 61
+const short temptable_1[NUMTEMPS_1][2] = {
+{    23    ,    300    },
+{    25    ,    295    },
+{    27    ,    290    },
+{    28    ,    285    },
+{    31    ,    280    },
+{    33    ,    275    },
+{    35    ,    270    },
+{    38    ,    265    },
+{    41    ,    260    },
+{    44    ,    255    },
+{    48    ,    250    },
+{    52    ,    245    },
+{    56    ,    240    },
+{    61    ,    235    },
+{    66    ,    230    },
+{    71    ,    225    },
+{    78    ,    220    },
+{    84    ,    215    },
+{    92    ,    210    },
+{    100    ,    205    },
+{    109    ,    200    },
+{    120    ,    195    },
+{    131    ,    190    },
+{    143    ,    185    },
+{    156    ,    180    },
+{    171    ,    175    },
+{    187    ,    170    },
+{    205    ,    165    },
+{    224    ,    160    },
+{    245    ,    155    },
+{    268    ,    150    },
+{    293    ,    145    },
+{    320    ,    140    },
+{    348    ,    135    },
+{    379    ,    130    },
+{    411    ,    125    },
+{    445    ,    120    },
+{    480    ,    115    },
+{    516    ,    110    },
+{    553    ,    105    },
+{    591    ,    100    },
+{    628    ,    95    },
+{    665    ,    90    },
+{    702    ,    85    },
+{    737    ,    80    },
+{    770    ,    75    },
+{    801    ,    70    },
+{    830    ,    65    },
+{    857    ,    60    },
+{    881    ,    55    },
+{    903    ,    50    },
+{    922    ,    45    },
+{    939    ,    40    },
+{    954    ,    35    },
+{    966    ,    30    },
+{    977    ,    25    },
+{    985    ,    20    },
+{    993    ,    15    },
+{    999    ,    10    },
+{    1004    ,    5    },
+{    1008    ,    0    } //safety
+};*/
+#endif
+#if (THERMISTORHEATER == 2) || (THERMISTORBED == 2) //200k bed thermistor verified by arcol
+#define NUMTEMPS_2 64
+const short temptable_2[NUMTEMPS_2][2] = {
+   {  16, 315},
+   {  17, 310},
+   {  18, 305},
+   {  19, 300},
+   {  20, 295},
+   {  21, 290},
+   {  22, 285},
+   {  23, 280},
+   {  24, 275},
+   {  25, 270},
+   {  29, 265},
+   {  30, 260},
+   {  35, 255},
+   {  40, 250},
+   {  45, 245},
+   {  50, 240},
+   {  55, 235},
+   {  60, 230},
+   {  65, 225},
+   {  70, 220},
+   {  90, 215},
+   {  95, 210},
+   { 103, 205},
+   { 105, 200},
+   { 115, 195},
+   { 130, 190},
+   { 150, 185},
+   { 167, 180},
+   { 190, 175},
+   { 200, 170},
+   { 230, 165},
+   { 250, 160},
+   { 270, 155},
+   { 300, 150},
+   { 330, 145},
+   { 360, 140},
+   { 380, 135},
+   { 408, 130},
+   { 450, 125},
+   { 500, 120},
+   { 530, 115},
+   { 550, 110},
+   { 570, 105},
+   { 595, 100},
+   { 615,  95},
+   { 640,  90},
+   { 665,  85},
+   { 700,  80},
+   { 740,  75},
+   { 780,  70},
+   { 810,  65},
+   { 840,  60},
+   { 880,  55},
+   { 920,  50},
+   { 960,  45},
+   { 980,  40},
+   { 990,  35},
+   {1000,  30},
+   {1005,  25},
+   {1006,  20},
+   {1009,  15},
+   {1010,  10},
+   {1020,   5},
+   {1023,   0} //safety
+};
+
+#endif
+#if (THERMISTORHEATER == 3) || (THERMISTORBED == 3) //mendel-parts
+#define NUMTEMPS_3 28
+const short temptable_3[NUMTEMPS_3][2] = {
+        {1,864},
+        {21,300},
+        {25,290},
+        {29,280},
+        {33,270},
+        {39,260},
+        {46,250},
+        {54,240},
+        {64,230},
+        {75,220},
+        {90,210},
+        {107,200},
+        {128,190},
+        {154,180},
+        {184,170},
+        {221,160},
+        {265,150},
+        {316,140},
+        {375,130},
+        {441,120},
+        {513,110},
+        {588,100},
+        {734,80},
+        {856,60},
+        {938,40},
+        {986,20},
+        {1008,0},
+        {1018,-20}
+    };
+
+#endif
+#if (THERMISTORHEATER == 4) || (THERMISTORBED == 4) //10k thermistor
+
+#define NUMTEMPS_4 20
+short temptable_4[NUMTEMPS_4][2] = {
+   {1, 430},
+   {54, 137},
+   {107, 107},
+   {160, 91},
+   {213, 80},
+   {266, 71},
+   {319, 64},
+   {372, 57},
+   {425, 51},
+   {478, 46},
+   {531, 41},
+   {584, 35},
+   {637, 30},
+   {690, 25},
+   {743, 20},
+   {796, 14},
+   {849, 7},
+   {902, 0},
+   {955, -11},
+   {1008, -35}
+};
+#endif
+
+#if (THERMISTORHEATER == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)
+
+#define NUMTEMPS_5 61
+const short temptable_5[NUMTEMPS_5][2] = {
+{1, 713},
+{18, 316},
+{35, 266},
+{52, 239},
+{69, 221},
+{86, 208},
+{103, 197},
+{120, 188},
+{137, 181},
+{154, 174},
+{171, 169},
+{188, 163},
+{205, 159},
+{222, 154},
+{239, 150},
+{256, 147},
+{273, 143},
+{290, 140},
+{307, 136},
+{324, 133},
+{341, 130},
+{358, 128},
+{375, 125},
+{392, 122},
+{409, 120},
+{426, 117},
+{443, 115},
+{460, 112},
+{477, 110},
+{494, 108},
+{511, 106},
+{528, 103},
+{545, 101},
+{562, 99},
+{579, 97},
+{596, 95},
+{613, 92},
+{630, 90},
+{647, 88},
+{664, 86},
+{681, 84},
+{698, 81},
+{715, 79},
+{732, 77},
+{749, 75},
+{766, 72},
+{783, 70},
+{800, 67},
+{817, 64},
+{834, 61},
+{851, 58},
+{868, 55},
+{885, 52},
+{902, 48},
+{919, 44},
+{936, 40},
+{953, 34},
+{970, 28},
+{987, 20},
+{1004, 8},
+{1021, 0}
+};
+#endif
+
+#if (THERMISTORHEATER == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor
+#define NUMTEMPS_6 36
+const short temptable_6[NUMTEMPS_6][2] = {
+   {28, 250},
+   {31, 245},
+   {35, 240},
+   {39, 235},
+   {42, 230},
+   {44, 225},
+   {49, 220},
+   {53, 215},
+   {62, 210},
+   {73, 205},
+   {72, 200},
+   {94, 190},
+   {102, 185},
+   {116, 170},
+   {143, 160},
+   {183, 150},
+   {223, 140},
+   {270, 130},
+   {318, 120},
+   {383, 110},
+   {413, 105},
+   {439, 100},
+   {484, 95},
+   {513, 90},
+   {607, 80},
+   {664, 70},
+   {781, 60},
+   {810, 55},
+   {849, 50},
+   {914, 45},
+   {914, 40},
+   {935, 35},
+   {954, 30},
+   {970, 25},
+   {978, 22},
+   {1008, 3}
+};
+#endif
+
+#if (THERMISTORHEATER == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01
+#define NUMTEMPS_7 54
+const short temptable_7[NUMTEMPS_7][2] = {
+   {46, 270},
+   {50, 265},
+   {54, 260},
+   {58, 255},
+   {62, 250},
+   {67, 245},
+   {72, 240},
+   {79, 235},
+   {85, 230},
+   {91, 225},
+   {99, 220},
+   {107, 215},
+   {116, 210},
+   {126, 205},
+   {136, 200},
+   {149, 195},
+   {160, 190},
+   {175, 185},
+   {191, 180},
+   {209, 175},
+   {224, 170},
+   {246, 165},
+   {267, 160},
+   {293, 155},
+   {316, 150},
+   {340, 145},
+   {364, 140},
+   {396, 135},
+   {425, 130},
+   {460, 125},
+   {489, 120},
+   {526, 115},
+   {558, 110},
+   {591, 105},
+   {628, 100},
+   {660, 95},
+   {696, 90},
+   {733, 85},
+   {761, 80},
+   {794, 75},
+   {819, 70},
+   {847, 65},
+   {870, 60},
+   {892, 55},
+   {911, 50},
+   {929, 45},
+   {944, 40},
+   {959, 35},
+   {971, 30},
+   {981, 25},
+   {989, 20},
+   {994, 15},
+   {1001, 10},
+   {1005, 5}
+};
+#endif
+
+
+
+#if THERMISTORHEATER == 1
+#define NUMTEMPS NUMTEMPS_1
+#define temptable temptable_1
+#elif THERMISTORHEATER == 2
+#define NUMTEMPS NUMTEMPS_2
+#define temptable temptable_2
+#elif THERMISTORHEATER == 3
+#define NUMTEMPS NUMTEMPS_3
+#define temptable temptable_3
+#elif THERMISTORHEATER == 4
+#define NUMTEMPS NUMTEMPS_4
+#define temptable temptable_4
+#elif THERMISTORHEATER == 5
+#define NUMTEMPS NUMTEMPS_5
+#define temptable temptable_5
+#elif THERMISTORHEATER == 6
+#define NUMTEMPS NUMTEMPS_6
+#define temptable temptable_6
+#elif THERMISTORHEATER == 7
+#define NUMTEMPS NUMTEMPS_7
+#define temptable temptable_7
+#elif defined HEATER_USES_THERMISTOR
+#error No heater thermistor table specified
+#endif
+#if THERMISTORBED == 1
+#define BNUMTEMPS NUMTEMPS_1
+#define bedtemptable temptable_1
+#elif THERMISTORBED == 2
+#define BNUMTEMPS NUMTEMPS_2
+#define bedtemptable temptable_2
+#elif THERMISTORBED == 3
+#define BNUMTEMPS NUMTEMPS_3
+#define bedtemptable temptable_3
+#elif THERMISTORBED == 4
+#define BNUMTEMPS NUMTEMPS_4
+#define bedtemptable temptable_4
+#elif THERMISTORBED == 5
+#define BNUMTEMPS NUMTEMPS_5
+#define bedtemptable temptable_5
+#elif THERMISTORBED == 6
+#define BNUMTEMPS NUMTEMPS_6
+#define bedtemptable temptable_6
+#elif THERMISTORBED == 7
+#define BNUMTEMPS NUMTEMPS_7
+#define bedtemptable temptable_7
+#elif defined BED_USES_THERMISTOR
+#error No bed thermistor table specified
+#endif
+
+#endif //THERMISTORTABLES_H_