diff options
author | adrian-bowyer <adrian-bowyer@cb376a5e-1013-0410-a455-b6b1f9ac8223> | 2008-11-20 14:50:19 +0000 |
---|---|---|
committer | adrian-bowyer <adrian-bowyer@cb376a5e-1013-0410-a455-b6b1f9ac8223> | 2008-11-20 14:50:19 +0000 |
commit | 77fc82ad8589ddeed0bd20b8bac5662233112013 (patch) | |
tree | 31ae588de09126046f96c4f2072b2fa34921a5d2 | |
parent | 02038b9b3f406b109a54fe901148ce265b5b7752 (diff) | |
download | reprap-backup-77fc82ad8589ddeed0bd20b8bac5662233112013.tar.gz reprap-backup-77fc82ad8589ddeed0bd20b8bac5662233112013.zip |
Arduino/Sanguino GCode firmware updated to allow multiple extruders in the Sanguino version.
Some code tidying too.
git-svn-id: https://reprap.svn.sourceforge.net/svnroot/reprap@2247 cb376a5e-1013-0410-a455-b6b1f9ac8223
28 files changed, 5047 insertions, 227 deletions
diff --git a/trunk/reprap/firmware/GCode_Interpreter/GCode_Interpreter.pde b/trunk/reprap/firmware/GCode_Interpreter/GCode_Interpreter.pde index 63438124..f243cd36 100644 --- a/trunk/reprap/firmware/GCode_Interpreter/GCode_Interpreter.pde +++ b/trunk/reprap/firmware/GCode_Interpreter/GCode_Interpreter.pde @@ -5,33 +5,32 @@ // v1.1 by Zach Hoeken - cleaned up and did lots of tweaks (hoeken@gmail.com) // v1.2 by Chris Meighan - cleanup / G2&G3 support (cmeighan@gmail.com) // v1.3 by Zach Hoeken - added thermocouple support and multi-sample temp readings. (hoeken@gmail.com) -// Sanguino v1.4 by Adrian Bowyer - switch to the Sanguino; extensive mods... (a.bowyer@bath.ac.uk) +// Sanguino v1.4 by Adrian Bowyer - added the Sanguino; extensive mods... (a.bowyer@bath.ac.uk) #include <ctype.h> #include <HardwareSerial.h> +#include "parameters.h" +#include "pins.h" +#include "extruder.h" -// Uncomment the next line to run stand-alone tests on the machine (also see the -// ends of this, the process_string, the extruder, and the stepper_control tabs). -//#define TEST_MACHINE -//our command string -#define COMMAND_SIZE 128 -char word[COMMAND_SIZE]; -char c = '?'; -byte serial_count = 0; -boolean comment = false; +byte extruder_in_use = 0; +extruder ex0(EXTRUDER_0_MOTOR_DIR_PIN, EXTRUDER_0_MOTOR_SPEED_PIN , EXTRUDER_0_HEATER_PIN, + EXTRUDER_0_FAN_PIN, EXTRUDER_0_TEMPERATURE_PIN, EXTRUDER_0_VALVE_DIR_PIN, + EXTRUDER_0_VALVE_ENABLE_PIN); + +extruder* ex[EXTRUDER_COUNT]; void setup() { - //Do startup stuff here + ex[0] = &ex0; Serial.begin(19200); Serial.println("start"); //other initialization. init_process_string(); init_steppers(); - init_extruder(); } void loop() @@ -40,54 +39,9 @@ void loop() //keep it hot! - extruder_manage_temperature(); - - //read in characters if we got them. - if (Serial.available()) - { - c = Serial.read(); - if(c == '\r') - c = '\n'; - // Throw away control chars except \n - if(c >= ' ' || c == '\n') - { - - //newlines are ends of commands. - if (c != '\n') - { - // Start of comment - ignore any bytes received from now on - if (c == ';') - comment = true; - - // If we're not in comment mode, add it to our array. - if (!comment) - word[serial_count++] = c; - } - - } - } - - // Data runaway? - if(serial_count >= COMMAND_SIZE) - init_process_string(); - - //if we've got a real command, do it - if (serial_count && c == '\n') - { - // Terminate string - word[serial_count] = 0; - - //process our command! - process_string(word, serial_count); - - //clear command. - init_process_string(); - - // Say we're ready for the next one - - Serial.println("ok"); - } - + manage_all_extruders(); + get_and_do_command(); + #else // Run the parts of the machine as a test @@ -96,9 +50,6 @@ void loop() // what you type in a terminal window connected // to the Sanguino. -// If that works, comment out the next line to test the rest: -#define COMMS_TEST - #ifdef COMMS_TEST comms_test(); @@ -110,35 +61,38 @@ void loop() c = Serial.read(); Serial.println(c); } - - switch(c) + if(c >= '0' && c <= '9') { - case 0: - break; - - case 'x': - X_motor_test(); - break; - case 'y': - Y_motor_test(); - break; - case 'z': - Z_motor_test(); - break; - case 'h': - extruder_heater_test(); - break; - case 'e': - extruder_drive_test(); - break; - case 'v': - extruder_valve_test(); - break; - case 'f': - extruder_fan_test(); - break; + extruder_in_use = c - '0'; + if(extruder_in_use >= EXTRUDER_COUNT) + extruder_in_use = EXTRUDER_COUNT - 1; + } else + { + switch(c) + { + case 'x': + X_motor_test(); + break; + case 'y': + Y_motor_test(); + break; + case 'z': + Z_motor_test(); + break; + case 'h': + ex[extruder_in_use]->heater_test(); + break; + case 'e': + ex[extruder_in_use]->drive_test(); + break; + case 'v': + ex[extruder_in_use]->valve_test(); + break; + case 'f': + ex[extruder_in_use]->fan_test(); + break; - default: + default: Serial.println("Commands:\n"); Serial.println(" x - X motor test"); Serial.println(" y - Y motor test"); @@ -147,9 +101,11 @@ void loop() Serial.println(" e - extruder drive test"); Serial.println(" v - extruder valve test"); Serial.println(" f - extruder fan test"); + Serial.println(" 0..9 - select extruder"); Serial.println(" s - stop current test at the end of its cycle then print this list\n\n"); Serial.print("Command: "); c = 0; + } } #endif diff --git a/trunk/reprap/firmware/GCode_Interpreter/ThermistorTable.h b/trunk/reprap/firmware/GCode_Interpreter/ThermistorTable.h index 07a35377..1fa53628 100644 --- a/trunk/reprap/firmware/GCode_Interpreter/ThermistorTable.h +++ b/trunk/reprap/firmware/GCode_Interpreter/ThermistorTable.h @@ -1,6 +1,12 @@ #ifndef THERMISTORTABLE_H_ #define THERMISTORTABLE_H_ +// Uncomment the next line if you are using a thermistor; leave it if you have a thermocouple +//#define USE_THERMISTOR + +// How many temperature samples to take. each sample takes about 100 usecs. +#define TEMPERATURE_SAMPLES 3 + // 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=4066 --max-adc=1023 @@ -10,6 +16,7 @@ // r2: 4700 // beta: 4066 // max adc: 1023 +#ifdef USE_THERMISTOR #define NUMTEMPS 20 short temptable[NUMTEMPS][2] = { {1, 841}, @@ -34,3 +41,4 @@ short temptable[NUMTEMPS][2] = { {1008, 3} }; #endif +#endif diff --git a/trunk/reprap/firmware/GCode_Interpreter/extruder.h.dist b/trunk/reprap/firmware/GCode_Interpreter/extruder.h.dist new file mode 100644 index 00000000..afb7ece0 --- /dev/null +++ b/trunk/reprap/firmware/GCode_Interpreter/extruder.h.dist @@ -0,0 +1,56 @@ +#ifndef EXTRUDER_H +#define EXTRUDER_H + +#define EXTRUDER_FORWARD true +#define EXTRUDER_REVERSE false + +#define EXTRUDER_COUNT 1 + +void manage_all_extruders(); + +class extruder +{ +private: + +//these our the default values for the extruder. + int e_speed; + int target_celsius; + int max_celsius; + byte heater_low; + byte heater_high; + byte heater_current; + +//this is for doing encoder based extruder control + int rpm; + long e_delay; + int error; + int last_extruder_error; + int error_delta; + bool e_direction; + bool valve_open; + +// The pins we control + byte motor_dir_pin, motor_speed_pin, heater_pin, fan_pin, temp_pin, valve_dir_pin, valve_en_pin; + +public: + + extruder(byte md_pin, byte ms_pin, byte h_pin, byte f_pin, byte t_pin, byte vd_pin, byte ve_pin); + void wait_for_heater(); + void valve_set(bool open, int millis); + void set_direction(bool direction); + void set_speed(byte e_speed); + void set_cooler(byte e_speed); + void set_temperature(int temp); + int get_temperature(); + int sample_temperature(byte pin); + void manage(); + +#ifdef TEST_MACHINE + void heater_test(); + void drive_test(); + void valve_test(); + void fan_test(); +#endif + +}; +#endif diff --git a/trunk/reprap/firmware/GCode_Interpreter/extruder.pde b/trunk/reprap/firmware/GCode_Interpreter/extruder.pde index 6cb0311d..3130e4a9 100644 --- a/trunk/reprap/firmware/GCode_Interpreter/extruder.pde +++ b/trunk/reprap/firmware/GCode_Interpreter/extruder.pde @@ -1,115 +1,137 @@ -// Yep, this is actually -*- c++ -*- +#include "parameters.h" +#include "pins.h" #include "ThermistorTable.h" +#include "extruder.h" -#define EXTRUDER_0_FORWARD true -#define EXTRUDER_0_REVERSE false - -//these our the default values for the extruder. -int extruder_speed = 128; -int extruder_target_celsius = 0; -int extruder_max_celsius = 0; -byte extruder_heater_low = 64; -byte extruder_heater_high = 255; -byte extruder_heater_current = 0; - -//this is for doing encoder based extruder control -int extruder_rpm = 0; -long extruder_delay = 0; -int extruder_error = 0; -int last_extruder_error = 0; -int extruder_error_delta = 0; -bool extruder_direction = EXTRUDER_0_FORWARD; -bool valve_open = false; - -void init_extruder() +void manage_all_extruders() { - //default to cool... - extruder_set_temperature(-273); - + for(byte i = 0; i < EXTRUDER_COUNT; i++) + ex[i]->manage(); +} + +extruder::extruder(byte md_pin, byte ms_pin, byte h_pin, byte f_pin, byte t_pin, byte vd_pin, byte ve_pin) +{ + motor_dir_pin = md_pin; + motor_speed_pin = ms_pin; + heater_pin = h_pin; + fan_pin = f_pin; + temp_pin = t_pin; + valve_dir_pin = vd_pin; + valve_en_pin = ve_pin; + //setup our pins - pinMode(EXTRUDER_0_MOTOR_DIR_PIN, OUTPUT); - pinMode(EXTRUDER_0_MOTOR_SPEED_PIN, OUTPUT); - pinMode(EXTRUDER_0_HEATER_PIN, OUTPUT); - pinMode(EXTRUDER_0_FAN_PIN, OUTPUT); - pinMode(EXTRUDER_0_VALVE_DIR_PIN, OUTPUT); - pinMode(EXTRUDER_0_VALVE_ENABLE_PIN, OUTPUT); + pinMode(motor_dir_pin, OUTPUT); + pinMode(motor_speed_pin, OUTPUT); + pinMode(heater_pin, OUTPUT); + pinMode(fan_pin, OUTPUT); + pinMode(temp_pin, INPUT); + pinMode(valve_dir_pin, OUTPUT); + pinMode(valve_en_pin, OUTPUT); //initialize values - digitalWrite(EXTRUDER_0_MOTOR_DIR_PIN, EXTRUDER_0_FORWARD); - analogWrite(EXTRUDER_0_FAN_PIN, 0); - analogWrite(EXTRUDER_0_HEATER_PIN, 0); - analogWrite(EXTRUDER_0_MOTOR_SPEED_PIN, 0); - digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, false); - digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 0); + digitalWrite(motor_dir_pin, EXTRUDER_FORWARD); + analogWrite(fan_pin, 0); + analogWrite(heater_pin, 0); + analogWrite(motor_speed_pin, 0); + digitalWrite(valve_dir_pin, false); + digitalWrite(valve_en_pin, 0); + + //these our the default values for the extruder. + e_speed = 128; + target_celsius = -273; + max_celsius = 0; + heater_low = 64; + heater_high = 255; + heater_current = 0; + valve_open = false; + +//this is for doing encoder based extruder control + rpm = 0; + e_delay = 0; + error = 0; + last_extruder_error = 0; + error_delta = 0; + e_direction = EXTRUDER_FORWARD; + + //default to cool + set_temperature(target_celsius); } -void wait_for_heater() +void extruder::wait_for_heater() { //warmup if we're too cold. - while (extruder_get_temperature() < (extruder_target_celsius - 5)) + byte count = 0; + int oldT, newT; + oldT = get_temperature(); + while (get_temperature() < (target_celsius - 5)) { - extruder_manage_temperature(); - //Serial.print("T: "); - //Serial.println(extruder_get_temperature()); + manage_all_extruders(); + count++; + if(count > 20) + { + newT = get_temperature(); + if(newT > oldT) + { + oldT = newT; + } else + { + // Temp's stuck - dud heater or temperature sensor + // Tell the host and return. + Serial.print("E: "); + Serial.println(newT); + return; + } + count = 0; + } delay(1000); } } -void valve_set(bool open, int millis) +void extruder::valve_set(bool open, int millis) { wait_for_heater(); valve_open = open; - digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, open); - digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 1); + digitalWrite(valve_dir_pin, open); + digitalWrite(valve_en_pin, 1); delay(millis); - digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 0); + digitalWrite(valve_en_pin, 0); } -void extruder_set_direction(bool direction) +void extruder::set_direction(bool dir) { - extruder_direction = direction; - digitalWrite(EXTRUDER_0_MOTOR_DIR_PIN, direction); + e_direction = dir; + digitalWrite(motor_dir_pin, e_direction); } -void extruder_set_speed(byte speed) +void extruder::set_speed(byte sp) { - if(speed > 0) + e_speed = sp; + if(e_speed > 0) wait_for_heater(); - analogWrite(EXTRUDER_0_MOTOR_SPEED_PIN, speed); + analogWrite(motor_speed_pin, e_speed); } -void extruder_set_cooler(byte speed) +void extruder::set_cooler(byte sp) { - analogWrite(EXTRUDER_0_FAN_PIN, speed); + analogWrite(fan_pin, sp); } -void extruder_set_temperature(int temp) +void extruder::set_temperature(int temp) { - extruder_target_celsius = temp; - extruder_max_celsius = (int)((float)temp * 1.1); + target_celsius = temp; + max_celsius = (temp*11)/10; } /** * Samples the temperature and converts it to degrees celsius. * Returns degrees celsius. */ -int extruder_get_temperature() -{ - if (EXTRUDER_0_THERMISTOR_PIN > -1) - return extruder_read_thermistor(); - else if (EXTRUDER_0_THERMOCOUPLE_PIN > -1) - return extruder_read_thermocouple(); -} - -/* -* This function gives us the temperature from the thermistor in Celsius -*/ - -int extruder_read_thermistor() +int extruder::get_temperature() { - int raw = extruder_sample_temperature(EXTRUDER_0_THERMISTOR_PIN); +#ifdef USE_THERMISTOR + int raw = sample_temperature(temp_pin); int celsius = 0; byte i; @@ -134,20 +156,17 @@ int extruder_read_thermistor() else if (celsius < 0) celsius = 0; return celsius; +#else + return ( 5.0 * sample_temperature(temp_pin) * 100.0) / 1024.0; +#endif } -/* -* This function gives us the temperature from the thermocouple in Celsius -*/ -int extruder_read_thermocouple() -{ - return ( 5.0 * extruder_sample_temperature(EXTRUDER_0_THERMOCOUPLE_PIN) * 100.0) / 1024.0; -} + /* * This function gives us an averaged sample of the analog temperature pin. */ -int extruder_sample_temperature(byte pin) +int extruder::sample_temperature(byte pin) { int raw = 0; @@ -163,27 +182,29 @@ int extruder_sample_temperature(byte pin) } /*! - Manages motor and heater based on measured temperature: + Manages extruder functions to keep temps, speeds etc + at the set levels. Should be called only by manage_all_extruders(), + which should be called in all non-trivial loops. o If temp is too low, don't start the motor o Adjust the heater power to keep the temperature at the target */ -void extruder_manage_temperature() +void extruder::manage() { //make sure we know what our temp is. - int current_celsius = extruder_get_temperature(); + int current_celsius = get_temperature(); byte newheat = 0; //put the heater into high mode if we're not at our target. - if (current_celsius < extruder_target_celsius) - newheat = extruder_heater_high; + if (current_celsius < target_celsius) + newheat = heater_high; //put the heater on low if we're at our target. - else if (current_celsius < extruder_max_celsius) - newheat = extruder_heater_low; + else if (current_celsius < max_celsius) + newheat = heater_low; // Only update heat if it changed - if (extruder_heater_current != newheat) { - extruder_heater_current = newheat; - analogWrite(EXTRUDER_0_HEATER_PIN, extruder_heater_current); + if (heater_current != newheat) { + heater_current = newheat; + analogWrite(heater_pin, heater_current); } } @@ -191,21 +212,21 @@ void extruder_manage_temperature() bool heat_on; -void extruder_heater_test() +void extruder::heater_test() { - int t = extruder_get_temperature(); + int t = get_temperature(); if(t < 50 && !heat_on) { Serial.println("\n *** Turning heater on.\n"); heat_on = true; - analogWrite(EXTRUDER_0_HEATER_PIN, extruder_heater_high); + analogWrite(heater_pin, heater_high); } if(t > 100 && heat_on) { Serial.println("\n *** Turning heater off.\n"); heat_on = false; - analogWrite(EXTRUDER_0_HEATER_PIN, 0); + analogWrite(heater_pin, 0); } Serial.print("Temperature: "); @@ -219,25 +240,25 @@ void extruder_heater_test() delay(2000); } -void extruder_drive_test() +void extruder::drive_test() { Serial.println("Turning the extruder motor on forwards for 5 seconds."); - extruder_set_direction(true); - extruder_set_speed(200); + set_direction(true); + set_speed(200); delay(5000); - extruder_set_speed(0); + set_speed(0); Serial.println("Pausing for 2 seconds."); delay(2000); Serial.println("Turning the extruder motor on backwards for 5 seconds."); - extruder_set_direction(false); - extruder_set_speed(200); + set_direction(false); + set_speed(200); delay(5000); - extruder_set_speed(0); + set_speed(0); Serial.println("Pausing for 2 seconds."); delay(2000); } -void extruder_valve_test() +void extruder::valve_test() { Serial.println("Opening the valve."); valve_set(true, 500); @@ -249,14 +270,14 @@ void extruder_valve_test() delay(2000); } -void extruder_fan_test() +void extruder::fan_test() { Serial.println("Fan on."); - extruder_set_cooler(255); + set_cooler(255); Serial.println("Pausing for 2 seconds."); delay(2000); Serial.println("Fan off."); - extruder_set_cooler(0); + set_cooler(0); Serial.println("Pausing for 2 seconds."); delay(2000); } diff --git a/trunk/reprap/firmware/GCode_Interpreter/process_string.pde b/trunk/reprap/firmware/GCode_Interpreter/process_string.pde index c22d83c8..61c2bfb3 100644 --- a/trunk/reprap/firmware/GCode_Interpreter/process_string.pde +++ b/trunk/reprap/firmware/GCode_Interpreter/process_string.pde @@ -1,4 +1,14 @@ -// Yep, this is actually -*- c++ -*- + +#include "parameters.h" +#include "pins.h" +#include "extruder.h" + +//our command string +#define COMMAND_SIZE 128 +char word[COMMAND_SIZE]; +char c = '?'; +byte serial_count = 0; +boolean comment = false; // our point structure to make things nice. struct LongPoint @@ -54,19 +64,69 @@ byte x_direction = 1; byte y_direction = 1; byte z_direction = 1; +int extruder_speed = 0; + int scan_int(char *str, int *valp); int scan_float(char *str, float *valp); //init our string processing void init_process_string() { - //init our command - //for (byte i=0; i<COMMAND_SIZE; i++) - // word[i] = 0; serial_count = 0; comment = false; } +// Get a command and process it + +void get_and_do_command() +{ + //read in characters if we got them. + if (Serial.available()) + { + c = Serial.read(); + if(c == '\r') + c = '\n'; + // Throw away control chars except \n + if(c >= ' ' || c == '\n') + { + + //newlines are ends of commands. + if (c != '\n') + { + // Start of comment - ignore any bytes received from now on + if (c == ';') + comment = true; + + // If we're not in comment mode, add it to our array. + if (!comment) + word[serial_count++] = c; + } + + } + } + + // Data runaway? + if(serial_count >= COMMAND_SIZE) + init_process_string(); + + //if we've got a real command, do it + if (serial_count && c == '\n') + { + // Terminate string + word[serial_count] = 0; + + //process our command! + process_string(word, serial_count); + + //clear command. + init_process_string(); + + // Say we're ready for the next one + + Serial.println("ok"); + } +} + //our feedrate variables. float feedrate = 0.0; long feedrate_micros = 0; @@ -450,33 +510,33 @@ void process_string(char instruction[], int size) */ //turn extruder on, forward case 101: - extruder_set_direction(1); - extruder_set_speed(extruder_speed); + ex[extruder_in_use]->set_direction(1); + ex[extruder_in_use]->set_speed(extruder_speed); break; //turn extruder on, reverse case 102: - extruder_set_direction(0); - extruder_set_speed(extruder_speed); + ex[extruder_in_use]->set_direction(0); + ex[extruder_in_use]->set_speed(extruder_speed); break; //turn extruder off case 103: - extruder_set_speed(0); + ex[extruder_in_use]->set_speed(0); break; //custom code for temperature control case 104: if (gc.seen & GCODE_S) { - extruder_set_temperature((int)gc.S); + ex[extruder_in_use]->set_temperature((int)gc.S); // //warmup if we're too cold. -// while (extruder_get_temperature() < extruder_target_celsius) +// while (ex[extruder_in_use]->get_temperature() < extruder_target_celsius) // { -// extruder_manage_temperature(); +// manage_all_extruders(); // Serial.print("T: "); -// Serial.println(extruder_get_temperature()); +// Serial.println(ex[extruder_in_use]->get_temperature()); // delay(1000); // } } @@ -485,17 +545,17 @@ void process_string(char instruction[], int size) //custom code for temperature reading case 105: Serial.print("T:"); - Serial.println(extruder_get_temperature()); + Serial.println(ex[extruder_in_use]->get_temperature()); break; //turn fan on case 106: - extruder_set_cooler(255); + ex[extruder_in_use]->set_cooler(255); break; //turn fan off case 107: - extruder_set_cooler(0); + ex[extruder_in_use]->set_cooler(0); break; //set max extruder speed, 0-255 PWM @@ -506,12 +566,12 @@ void process_string(char instruction[], int size) // Open the valve case 126: - valve_set(true, (int)(gc.P + 0.5)); + ex[extruder_in_use]->valve_set(true, (int)(gc.P + 0.5)); break; // Close the valve case 127: - valve_set(false, (int)(gc.P + 0.5)); + ex[extruder_in_use]->valve_set(false, (int)(gc.P + 0.5)); break; diff --git a/trunk/reprap/firmware/GCode_Interpreter/stepper_control.pde b/trunk/reprap/firmware/GCode_Interpreter/stepper_control.pde index 5d59fa6c..b4860101 100644 --- a/trunk/reprap/firmware/GCode_Interpreter/stepper_control.pde +++ b/trunk/reprap/firmware/GCode_Interpreter/stepper_control.pde @@ -1,4 +1,6 @@ -// Yep, this is actually -*- c++ -*- +#include "parameters.h" +#include "pins.h" +#include "extruder.h" //init our variables long max_delta; @@ -33,13 +35,18 @@ void init_steppers() pinMode(X_STEP_PIN, OUTPUT); pinMode(X_DIR_PIN, OUTPUT); - pinMode(X_ENABLE_PIN, OUTPUT); + pinMode(Y_STEP_PIN, OUTPUT); pinMode(Y_DIR_PIN, OUTPUT); - pinMode(Y_ENABLE_PIN, OUTPUT); + pinMode(Z_STEP_PIN, OUTPUT); pinMode(Z_DIR_PIN, OUTPUT); + +#ifdef SANGUINO + pinMode(X_ENABLE_PIN, OUTPUT); + pinMode(Y_ENABLE_PIN, OUTPUT); pinMode(Z_ENABLE_PIN, OUTPUT); +#endif #if ENDSTOPS_MIN_ENABLED == 1 pinMode(X_MIN_PIN, INPUT); @@ -137,7 +144,7 @@ void dda_move(long micro_delay) } //keep it hot =) - extruder_manage_temperature(); + manage_all_extruders(); //wait for next step. if (milli_delay > 0) @@ -305,6 +312,9 @@ void enable_steppers() // taking account of the fact that some or all axes // may share an enable line (check using macros at // compile time to avoid needless code) + // Not enough pins for enable on Arduino + +#ifdef SANGUINO if ( target_units.x == current_units.x #if X_ENABLE_PIN == Y_ENABLE_PIN && target_units.y == current_units.y @@ -338,14 +348,17 @@ void enable_steppers() digitalWrite(Z_ENABLE_PIN, !ENABLE_ON); else digitalWrite(Z_ENABLE_PIN, ENABLE_ON); +#endif } void disable_steppers() { + #ifdef SANGUINO //disable our steppers digitalWrite(X_ENABLE_PIN, !ENABLE_ON); digitalWrite(Y_ENABLE_PIN, !ENABLE_ON); digitalWrite(Z_ENABLE_PIN, !ENABLE_ON); +#endif } void delayMicrosecondsInterruptible(unsigned int us) diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/GCode_Interpreter.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/GCode_Interpreter.pde index 63438124..63438124 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/GCode_Interpreter.pde +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/GCode_Interpreter.pde diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/ThermistorTable.h b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/ThermistorTable.h index 07a35377..07a35377 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/ThermistorTable.h +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/ThermistorTable.h diff --git a/trunk/reprap/firmware/GCode_Interpreter/_init.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/_init.pde index 1db13f72..1db13f72 100644 --- a/trunk/reprap/firmware/GCode_Interpreter/_init.pde +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/_init.pde diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.cpp b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.cpp new file mode 100644 index 00000000..d60d8b4d --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.cpp @@ -0,0 +1,1528 @@ +#include "WProgram.h" +void init_extruder(); +void wait_for_heater(); +void valve_set(bool open, int millis); +void extruder_set_direction(bool direction); +void extruder_set_speed(byte speed); +void extruder_set_cooler(byte speed); +void extruder_set_temperature(int temp); +int extruder_get_temperature(); +int extruder_read_thermistor(); +int extruder_read_thermocouple(); +int extruder_sample_temperature(byte pin); +void extruder_manage_temperature(); +void extruder_heater_test(); +void extruder_drive_test(); +void extruder_valve_test(); +void extruder_fan_test(); +void init_process_string(); +int parse_string(struct GcodeParser * gc, char instruction[], int size); +void process_string(char instruction[], int size); +int scan_float(char *str, float *valp, unsigned int *seen, unsigned int flag); +int scan_int(char *str, int *valp, unsigned int *seen, unsigned int flag); +void comms_test(); +void init_steppers(); +void dda_move(long micro_delay); +bool can_step(byte min_pin, byte max_pin, long current, long target, byte direction); +void do_step(byte step_pin); +bool read_switch(byte pin); +long to_steps(float steps_per_unit, float units); +void set_target(float x, float y, float z); +void set_position(float x, float y, float z); +void calculate_deltas(); +long calculate_feedrate_delay(float feedrate); +long getMaxSpeed(); +void enable_steppers(); +void disable_steppers(); +void delayMicrosecondsInterruptible(unsigned int us); +void X_motor_test(); +void Y_motor_test(); +void Z_motor_test(); +#include "ctype.h" +#include "HardwareSerial.h" +#include "parameters.h" +#include "pins.h" +#include "ThermistorTable.h" +// Yep, this is actually -*- c++ -*- + +// Sanguino G-code Interpreter +// Arduino v1.0 by Mike Ellery - initial software (mellery@gmail.com) +// v1.1 by Zach Hoeken - cleaned up and did lots of tweaks (hoeken@gmail.com) +// v1.2 by Chris Meighan - cleanup / G2&G3 support (cmeighan@gmail.com) +// v1.3 by Zach Hoeken - added thermocouple support and multi-sample temp readings. (hoeken@gmail.com) +// Sanguino v1.4 by Adrian Bowyer - switch to the Sanguino; extensive mods... (a.bowyer@bath.ac.uk) + +// Uncomment the next line to run stand-alone tests on the machine (also see the +// ends of this, the process_string, the extruder, and the stepper_control tabs). +//#define TEST_MACHINE + + +//our command string +#define COMMAND_SIZE 128 +char word[COMMAND_SIZE]; +char c = '?'; +byte serial_count = 0; +boolean comment = false; + +void setup() +{ + //Do startup stuff here + Serial.begin(19200); + Serial.println("start"); + + //other initialization. + init_process_string(); + init_steppers(); + init_extruder(); +} + +void loop() +{ +#ifndef TEST_MACHINE + + + //keep it hot! + extruder_manage_temperature(); + + //read in characters if we got them. + if (Serial.available()) + { + c = Serial.read(); + if(c == '\r') + c = '\n'; + // Throw away control chars except \n + if(c >= ' ' || c == '\n') + { + + //newlines are ends of commands. + if (c != '\n') + { + // Start of comment - ignore any bytes received from now on + if (c == ';') + comment = true; + + // If we're not in comment mode, add it to our array. + if (!comment) + word[serial_count++] = c; + } + + } + } + + // Data runaway? + if(serial_count >= COMMAND_SIZE) + init_process_string(); + + //if we've got a real command, do it + if (serial_count && c == '\n') + { + // Terminate string + word[serial_count] = 0; + + //process our command! + process_string(word, serial_count); + + //clear command. + init_process_string(); + + // Say we're ready for the next one + + Serial.println("ok"); + } + +#else + +// Run the parts of the machine as a test + +// Do the comms test first. It should echo +// what you type in a terminal window connected +// to the Sanguino. + +// If that works, comment out the next line to test the rest: +#define COMMS_TEST + +#ifdef COMMS_TEST + + comms_test(); + +#else + + if (Serial.available() > 0) + { + c = Serial.read(); + Serial.println(c); + } + + switch(c) + { + case 0: + break; + + case 'x': + X_motor_test(); + break; + case 'y': + Y_motor_test(); + break; + case 'z': + Z_motor_test(); + break; + case 'h': + extruder_heater_test(); + break; + case 'e': + extruder_drive_test(); + break; + case 'v': + extruder_valve_test(); + break; + case 'f': + extruder_fan_test(); + break; + + default: + Serial.println("Commands:\n"); + Serial.println(" x - X motor test"); + Serial.println(" y - Y motor test"); + Serial.println(" z - Z motor test"); + Serial.println(" h - extruder heater test"); + Serial.println(" e - extruder drive test"); + Serial.println(" v - extruder valve test"); + Serial.println(" f - extruder fan test"); + Serial.println(" s - stop current test at the end of its cycle then print this list\n\n"); + Serial.print("Command: "); + c = 0; + } + +#endif + +#endif +} + + + +// Yep, this is actually -*- c++ -*- + +#define EXTRUDER_0_FORWARD true +#define EXTRUDER_0_REVERSE false + +//these our the default values for the extruder. +int extruder_speed = 128; +int extruder_target_celsius = 0; +int extruder_max_celsius = 0; +byte extruder_heater_low = 64; +byte extruder_heater_high = 255; +byte extruder_heater_current = 0; + +//this is for doing encoder based extruder control +int extruder_rpm = 0; +long extruder_delay = 0; +int extruder_error = 0; +int last_extruder_error = 0; +int extruder_error_delta = 0; +bool extruder_direction = EXTRUDER_0_FORWARD; +bool valve_open = false; + +void init_extruder() +{ + //default to cool... + extruder_set_temperature(-273); + + //setup our pins + pinMode(EXTRUDER_0_MOTOR_DIR_PIN, OUTPUT); + pinMode(EXTRUDER_0_MOTOR_SPEED_PIN, OUTPUT); + pinMode(EXTRUDER_0_HEATER_PIN, OUTPUT); + pinMode(EXTRUDER_0_FAN_PIN, OUTPUT); + pinMode(EXTRUDER_0_VALVE_DIR_PIN, OUTPUT); + pinMode(EXTRUDER_0_VALVE_ENABLE_PIN, OUTPUT); + + //initialize values + digitalWrite(EXTRUDER_0_MOTOR_DIR_PIN, EXTRUDER_0_FORWARD); + analogWrite(EXTRUDER_0_FAN_PIN, 0); + analogWrite(EXTRUDER_0_HEATER_PIN, 0); + analogWrite(EXTRUDER_0_MOTOR_SPEED_PIN, 0); + digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, false); + digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 0); +} + +void wait_for_heater() +{ + //warmup if we're too cold. + while (extruder_get_temperature() < (extruder_target_celsius - 5)) + { + extruder_manage_temperature(); + //Serial.print("T: "); + //Serial.println(extruder_get_temperature()); + delay(1000); + } +} + +void valve_set(bool open, int millis) +{ + wait_for_heater(); + valve_open = open; + digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, open); + digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 1); + delay(millis); + digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 0); + digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, 0); +} + + +void extruder_set_direction(bool direction) +{ + extruder_direction = direction; + digitalWrite(EXTRUDER_0_MOTOR_DIR_PIN, direction); +} + +void extruder_set_speed(byte speed) +{ + if(speed > 0) + wait_for_heater(); + analogWrite(EXTRUDER_0_MOTOR_SPEED_PIN, speed); +} + +void extruder_set_cooler(byte speed) +{ + analogWrite(EXTRUDER_0_FAN_PIN, speed); +} + +void extruder_set_temperature(int temp) +{ + extruder_target_celsius = temp; + extruder_max_celsius = (int)((float)temp * 1.1); +} + +/** +* Samples the temperature and converts it to degrees celsius. +* Returns degrees celsius. +*/ +int extruder_get_temperature() +{ + if (EXTRUDER_0_THERMISTOR_PIN > -1) + return extruder_read_thermistor(); + else if (EXTRUDER_0_THERMOCOUPLE_PIN > -1) + return extruder_read_thermocouple(); +} + +/* +* This function gives us the temperature from the thermistor in Celsius +*/ + +int extruder_read_thermistor() +{ + int raw = extruder_sample_temperature(EXTRUDER_0_THERMISTOR_PIN); + + int celsius = 0; + byte i; + + for (i=1; i<NUMTEMPS; i++) + { + if (temptable[i][0] > raw) + { + celsius = temptable[i-1][1] + + (raw - temptable[i-1][0]) * + (temptable[i][1] - temptable[i-1][1]) / + (temptable[i][0] - temptable[i-1][0]); + + break; + } + } + + // Overflow: Set to last value in the table + if (i == NUMTEMPS) celsius = temptable[i-1][1]; + // Clamp to byte + if (celsius > 255) celsius = 255; + else if (celsius < 0) celsius = 0; + + return celsius; +} + +/* +* This function gives us the temperature from the thermocouple in Celsius +*/ +int extruder_read_thermocouple() +{ + return ( 5.0 * extruder_sample_temperature(EXTRUDER_0_THERMOCOUPLE_PIN) * 100.0) / 1024.0; +} + +/* +* This function gives us an averaged sample of the analog temperature pin. +*/ +int extruder_sample_temperature(byte pin) +{ + int raw = 0; + + //read in a certain number of samples + for (byte i=0; i<TEMPERATURE_SAMPLES; i++) + raw += analogRead(pin); + + //average the samples + raw = raw/TEMPERATURE_SAMPLES; + + //send it back. + return raw; +} + +/*! + Manages motor and heater based on measured temperature: + o If temp is too low, don't start the motor + o Adjust the heater power to keep the temperature at the target + */ +void extruder_manage_temperature() +{ + //make sure we know what our temp is. + int current_celsius = extruder_get_temperature(); + byte newheat = 0; + + //put the heater into high mode if we're not at our target. + if (current_celsius < extruder_target_celsius) + newheat = extruder_heater_high; + //put the heater on low if we're at our target. + else if (current_celsius < extruder_max_celsius) + newheat = extruder_heater_low; + + // Only update heat if it changed + if (extruder_heater_current != newheat) { + extruder_heater_current = newheat; + analogWrite(EXTRUDER_0_HEATER_PIN, extruder_heater_current); + } +} + +#ifdef TEST_MACHINE + +bool heat_on; + +void extruder_heater_test() +{ + int t = extruder_get_temperature(); + if(t < 50 && !heat_on) + { + Serial.println("\n *** Turning heater on.\n"); + heat_on = true; + analogWrite(EXTRUDER_0_HEATER_PIN, extruder_heater_high); + } + + if(t > 100 && heat_on) + { + Serial.println("\n *** Turning heater off.\n"); + heat_on = false; + analogWrite(EXTRUDER_0_HEATER_PIN, 0); + } + + Serial.print("Temperature: "); + Serial.print(t); + Serial.print(" deg C. The heater is "); + if(heat_on) + Serial.println("on."); + else + Serial.println("off."); + + delay(2000); +} + +void extruder_drive_test() +{ + Serial.println("Turning the extruder motor on forwards for 5 seconds."); + extruder_set_direction(true); + extruder_set_speed(200); + delay(5000); + extruder_set_speed(0); + Serial.println("Pausing for 2 seconds."); + delay(2000); + Serial.println("Turning the extruder motor on backwards for 5 seconds."); + extruder_set_direction(false); + extruder_set_speed(200); + delay(5000); + extruder_set_speed(0); + Serial.println("Pausing for 2 seconds."); + delay(2000); +} + +void extruder_valve_test() +{ + Serial.println("Opening the valve."); + valve_set(true, 500); + Serial.println("Pausing for 2 seconds."); + delay(2000); + Serial.println("Closing the valve."); + valve_set(false, 500); + Serial.println("Pausing for 2 seconds."); + delay(2000); +} + +void extruder_fan_test() +{ + Serial.println("Fan on."); + extruder_set_cooler(255); + Serial.println("Pausing for 2 seconds."); + delay(2000); + Serial.println("Fan off."); + extruder_set_cooler(0); + Serial.println("Pausing for 2 seconds."); + delay(2000); +} + + + +#endif + +// Yep, this is actually -*- c++ -*- + +// our point structure to make things nice. +struct LongPoint +{ + long x; + long y; + long z; +}; + +struct FloatPoint +{ + float x; + float y; + float z; +}; + +/* gcode line parse results */ +struct GcodeParser +{ + unsigned int seen; + int G; + int M; + float P; + float X; + float Y; + float Z; + float I; + float J; + float F; + float S; + float R; + float Q; +}; + +FloatPoint current_units; +FloatPoint target_units; +FloatPoint delta_units; + +FloatPoint current_steps; +FloatPoint target_steps; +FloatPoint delta_steps; + +boolean abs_mode = true; //0 = incremental; 1 = absolute + +//default to mm for units +float x_units = X_STEPS_PER_MM; +float y_units = Y_STEPS_PER_MM; +float z_units = Z_STEPS_PER_MM; +float curve_section = CURVE_SECTION_MM; + +//our direction vars +byte x_direction = 1; +byte y_direction = 1; +byte z_direction = 1; + +int scan_int(char *str, int *valp); +int scan_float(char *str, float *valp); + +//init our string processing +void init_process_string() +{ + //init our command + //for (byte i=0; i<COMMAND_SIZE; i++) + // word[i] = 0; + serial_count = 0; + comment = false; +} + +//our feedrate variables. +float feedrate = 0.0; +long feedrate_micros = 0; + +/* keep track of the last G code - this is the command mode to use + * if there is no command in the current string + */ +int last_gcode_g = -1; + +/* bit-flags for commands and parameters */ +#define GCODE_G (1<<0) +#define GCODE_M (1<<1) +#define GCODE_P (1<<2) +#define GCODE_X (1<<3) +#define GCODE_Y (1<<4) +#define GCODE_Z (1<<5) +#define GCODE_I (1<<6) +#define GCODE_J (1<<7) +#define GCODE_K (1<<8) +#define GCODE_F (1<<9) +#define GCODE_S (1<<10) +#define GCODE_Q (1<<11) +#define GCODE_R (1<<12) + +#define TYPE_INT 1 +#define TYPE_FLOAT 2 + + +#define PARSE_INT(ch, str, len, val, seen, flag) \ + case ch: \ + len = scan_int(str, &val, &seen, flag); \ + break; + +#define PARSE_FLOAT(ch, str, len, val, seen, flag) \ + case ch: \ + len = scan_float(str, &val, &seen, flag); \ + break; + +int parse_string(struct GcodeParser * gc, char instruction[], int size) +{ + int ind; + int len; /* length of parameter argument */ + + gc->seen = 0; + + len=0; + /* scan the string for commands and parameters, recording the arguments for each, + * and setting the seen flag for each that is seen + */ + for (ind=0; ind<size; ind += (1+len)) + { + len = 0; + switch (instruction[ind]) + { + PARSE_INT('G', &instruction[ind+1], len, gc->G, gc->seen, GCODE_G); + PARSE_INT('M', &instruction[ind+1], len, gc->M, gc->seen, GCODE_M); + PARSE_FLOAT('S', &instruction[ind+1], len, gc->S, gc->seen, GCODE_S); + PARSE_FLOAT('P', &instruction[ind+1], len, gc->P, gc->seen, GCODE_P); + PARSE_FLOAT('X', &instruction[ind+1], len, gc->X, gc->seen, GCODE_X); + PARSE_FLOAT('Y', &instruction[ind+1], len, gc->Y, gc->seen, GCODE_Y); + PARSE_FLOAT('Z', &instruction[ind+1], len, gc->Z, gc->seen, GCODE_Z); + PARSE_FLOAT('I', &instruction[ind+1], len, gc->I, gc->seen, GCODE_I); + PARSE_FLOAT('J', &instruction[ind+1], len, gc->J, gc->seen, GCODE_J); + PARSE_FLOAT('F', &instruction[ind+1], len, gc->F, gc->seen, GCODE_F); + PARSE_FLOAT('R', &instruction[ind+1], len, gc->R, gc->seen, GCODE_R); + PARSE_FLOAT('Q', &instruction[ind+1], len, gc->Q, gc->seen, GCODE_Q); + default: + break; + } + } +} + + +//Read the string and execute instructions +void process_string(char instruction[], int size) +{ + + GcodeParser gc; /* string parse result */ + + //the character / means delete block... used for comments and stuff. + if (instruction[0] == '/') + return; + + //init baby! + FloatPoint fp; + fp.x = 0.0; + fp.y = 0.0; + fp.z = 0.0; + + //get all our parameters! + parse_string(&gc, instruction, size); + /* if no command was seen, but parameters were, then use the last G code as + * the current command + */ + if ((!(gc.seen & (GCODE_G | GCODE_M))) && + ((gc.seen != 0) && + (last_gcode_g >= 0)) + ) + { + /* yes - so use the previous command with the new parameters */ + gc.G = last_gcode_g; + gc.seen |= GCODE_G; + } + //did we get a gcode? + if (gc.seen & GCODE_G) + { + last_gcode_g = gc.G; /* remember this for future instructions */ + fp = current_units; + if (abs_mode) + { + if (gc.seen & GCODE_X) + fp.x = gc.X; + if (gc.seen & GCODE_Y) + fp.y = gc.Y; + if (gc.seen & GCODE_Z) + fp.z = gc.Z; + } + else + { + if (gc.seen & GCODE_X) + fp.x += gc.X; + if (gc.seen & GCODE_Y) + fp.y += gc.Y; + if (gc.seen & GCODE_Z) + fp.z += gc.Z; + } + + // Get feedrate if supplied + if ( gc.seen & GCODE_F ) + feedrate = gc.F; + + //do something! + switch (gc.G) + { + //Rapid Positioning + //Linear Interpolation + //these are basically the same thing. + case 0: + case 1: + //set our target. + set_target(fp.x, fp.y, fp.z); + + // Use currently set feedrate if doing a G1 + if (gc.G == 1) + feedrate_micros = calculate_feedrate_delay(feedrate); + // Use our max for G0 + else + feedrate_micros = getMaxSpeed(); + //finally move. + dda_move(feedrate_micros); + break; +#ifdef SANGUINO +// No room for this in the Arduino + //Clockwise arc + case 2: + //Counterclockwise arc + case 3: + { + FloatPoint cent; + + // Centre coordinates are always relative + if (gc.seen & GCODE_I) cent.x = current_units.x + gc.I; + else cent.x = current_units.x; + if (gc.seen & GCODE_J) cent.y = current_units.y + gc.J; + + float angleA, angleB, angle, radius, length, aX, aY, bX, bY; + + aX = (current_units.x - cent.x); + aY = (current_units.y - cent.y); + bX = (fp.x - cent.x); + bY = (fp.y - cent.y); + + // Clockwise + if (gc.G == 2) + { + angleA = atan2(bY, bX); + angleB = atan2(aY, aX); + } + // Counterclockwise + else + { + angleA = atan2(aY, aX); + angleB = atan2(bY, bX); + } + + // Make sure angleB is always greater than angleA + // and if not add 2PI so that it is (this also takes + // care of the special case of angleA == angleB, + // ie we want a complete circle) + if (angleB <= angleA) + angleB += 2 * M_PI; + angle = angleB - angleA; + + radius = sqrt(aX * aX + aY * aY); + length = radius * angle; + int steps, s, step; + + // Maximum of either 2.4 times the angle in radians or the length of the curve divided by the constant specified in _init.pde + steps = (int) ceil(max(angle * 2.4, length / curve_section)); + + FloatPoint newPoint; + float arc_start_z = current_units.z; + for (s = 1; s <= steps; s++) + { + step = (gc.G == 3) ? s : steps - s; // Work backwards for CW + newPoint.x = cent.x + radius * cos(angleA + angle + * ((float) step / steps)); + newPoint.y = cent.y + radius * sin(angleA + angle + * ((float) step / steps)); + set_target(newPoint.x, newPoint.y, arc_start_z + (fp.z + - arc_start_z) * s / steps); + + // Need to calculate rate for each section of curve + if (feedrate > 0) + feedrate_micros = calculate_feedrate_delay(feedrate); + else + feedrate_micros = getMaxSpeed(); + + // Make step + dda_move(feedrate_micros); + } + } + break; +#endif + + case 4: //Dwell + delay((int)(gc.P + 0.5)); // Changed by AB from 1000*gc.P + break; + + //Inches for Units + case 20: + x_units = X_STEPS_PER_INCH; + y_units = Y_STEPS_PER_INCH; + z_units = Z_STEPS_PER_INCH; + curve_section = CURVE_SECTION_INCHES; + + calculate_deltas(); + break; + + //mm for Units + case 21: + x_units = X_STEPS_PER_MM; + y_units = Y_STEPS_PER_MM; + z_units = Z_STEPS_PER_MM; + curve_section = CURVE_SECTION_MM; + + calculate_deltas(); + break; + + //go home. + case 28: + set_target(0.0, 0.0, 0.0); + dda_move(getMaxSpeed()); + break; + + //go home via an intermediate point. + case 30: + //set our target. + set_target(fp.x, fp.y, fp.z); + + //go there. + dda_move(getMaxSpeed()); + + //go home. + set_target(0.0, 0.0, 0.0); + dda_move(getMaxSpeed()); + break; + + // Drilling canned cycles + case 81: // Without dwell + case 82: // With dwell + case 83: // Peck drilling + { + float retract = gc.R; + + if (!abs_mode) + retract += current_units.z; + + // Retract to R position if Z is currently below this + if (current_units.z < retract) + { + set_target(current_units.x, current_units.y, retract); + dda_move(getMaxSpeed()); + } + + // Move to start XY + set_target(fp.x, fp.y, current_units.z); + dda_move(getMaxSpeed()); + + // Do the actual drilling + float target_z = retract; + float delta_z; + + // For G83 move in increments specified by Q code, otherwise do in one pass + if (gc.G == 83) + delta_z = gc.Q; + else + delta_z = retract - fp.z; + + do { + // Move rapidly to bottom of hole drilled so far (target Z if starting hole) + set_target(fp.x, fp.y, target_z); + dda_move(getMaxSpeed()); + + // Move with controlled feed rate by delta z (or to bottom of hole if less) + target_z -= delta_z; + if (target_z < fp.z) + target_z = fp.z; + set_target(fp.x, fp.y, target_z); + if (feedrate > 0) + feedrate_micros = calculate_feedrate_delay(feedrate); + else + feedrate_micros = getMaxSpeed(); + dda_move(feedrate_micros); + + // Dwell if doing a G82 + if (gc.G == 82) + delay((int)(gc.P * 1000)); + + // Retract + set_target(fp.x, fp.y, retract); + dda_move(getMaxSpeed()); + } while (target_z > fp.z); + } + break; + + + case 90: //Absolute Positioning + abs_mode = true; + break; + + + case 91: //Incremental Positioning + abs_mode = false; + break; + + + case 92: //Set position as fp + set_position(fp.x, fp.y, fp.z); + break; + + /* + //Inverse Time Feed Mode + case 93: + + break; //TODO: add this + + //Feed per Minute Mode + case 94: + + break; //TODO: add this + */ + + default: + Serial.print("huh? G"); + Serial.println(gc.G, DEC); + } + } + + //find us an m code. + if (gc.seen & GCODE_M) + { + switch (gc.M) + { + //TODO: this is a bug because search_string returns 0. gotta fix that. + case 0: + true; + break; + /* + case 0: + //todo: stop program + break; + + case 1: + //todo: optional stop + break; + + case 2: + //todo: program end + break; + */ + //turn extruder on, forward + case 101: + extruder_set_direction(1); + extruder_set_speed(extruder_speed); + break; + + //turn extruder on, reverse + case 102: + extruder_set_direction(0); + extruder_set_speed(extruder_speed); + break; + + //turn extruder off + case 103: + extruder_set_speed(0); + break; + + //custom code for temperature control + case 104: + if (gc.seen & GCODE_S) + { + extruder_set_temperature((int)gc.S); + +// //warmup if we're too cold. +// while (extruder_get_temperature() < extruder_target_celsius) +// { +// extruder_manage_temperature(); +// Serial.print("T: "); +// Serial.println(extruder_get_temperature()); +// delay(1000); +// } + } + break; + + //custom code for temperature reading + case 105: + Serial.print("T:"); + Serial.println(extruder_get_temperature()); + break; + + //turn fan on + case 106: + extruder_set_cooler(255); + break; + + //turn fan off + case 107: + extruder_set_cooler(0); + break; + + //set max extruder speed, 0-255 PWM + case 108: + if (gc.seen & GCODE_S) + extruder_speed = (int)gc.S; + break; + + // Open the valve + case 126: + valve_set(true, (int)(gc.P + 0.5)); + break; + + // Close the valve + case 127: + valve_set(false, (int)(gc.P + 0.5)); + break; + + + default: + Serial.print("Huh? M"); + Serial.println(gc.M, DEC); + } + } + +} + +int scan_float(char *str, float *valp, unsigned int *seen, unsigned int flag) +{ + float res; + int len; + char *end; + + res = (float)strtod(str, &end); + + len = end - str; + + if (len > 0) + { + *valp = res; + *seen |= flag; + } + else + *valp = 0; + + return len; /* length of number */ +} + +int scan_int(char *str, int *valp, unsigned int *seen, unsigned int flag) +{ + int res; + int len; + char *end; + + res = (int)strtol(str, &end, 10); + len = end - str; + + if (len > 0) + { + *valp = res; + *seen |= flag; + } + else + *valp = 0; + + return len; /* length of number */ +} + +#ifdef TEST_MACHINE + +// Read and echo bytes. + +void comms_test() +{ + if (Serial.available() > 0) + Serial.print((char)Serial.read()); +} + +#endif + + + +// Yep, this is actually -*- c++ -*- + +//init our variables +long max_delta; +long x_counter; +long y_counter; +long z_counter; +bool x_can_step; +bool y_can_step; +bool z_can_step; +int milli_delay; + +#if INVERT_ENABLE_PINS == 1 +#define ENABLE_ON LOW +#else +#define ENABLE_ON HIGH +#endif + +#define ENDSTOPS_MIN_ENABLED 1 + +void init_steppers() +{ + //turn them off to start. +#ifdef SANGUINO + disable_steppers(); +#endif + + //init our points. + current_units.x = 0.0; + current_units.y = 0.0; + current_units.z = 0.0; + target_units.x = 0.0; + target_units.y = 0.0; + target_units.z = 0.0; + + pinMode(X_STEP_PIN, OUTPUT); + pinMode(X_DIR_PIN, OUTPUT); + pinMode(Y_STEP_PIN, OUTPUT); + pinMode(Y_DIR_PIN, OUTPUT); + pinMode(Z_STEP_PIN, OUTPUT); + pinMode(Z_DIR_PIN, OUTPUT); + +#ifdef SANGUINO + pinMode(X_ENABLE_PIN, OUTPUT); + pinMode(Y_ENABLE_PIN, OUTPUT); + pinMode(Z_ENABLE_PIN, OUTPUT); +#endif + +#if ENDSTOPS_MIN_ENABLED == 1 + pinMode(X_MIN_PIN, INPUT); + pinMode(Y_MIN_PIN, INPUT); + pinMode(Z_MIN_PIN, INPUT); +#endif +#if ENDSTOPS_MAX_ENABLED == 1 + pinMode(X_MAX_PIN, INPUT); + pinMode(Y_MAX_PIN, INPUT); + pinMode(Z_MAX_PIN, INPUT); +#endif + + //figure our stuff. + calculate_deltas(); +} + +void dda_move(long micro_delay) +{ + //turn on steppers to start moving =) +#ifdef SANGUINO + enable_steppers(); +#endif + + //figure out our deltas + max_delta = max(delta_steps.x, delta_steps.y); + max_delta = max(delta_steps.z, max_delta); + + //init stuff. + long x_counter = -max_delta/2; + long y_counter = -max_delta/2; + long z_counter = -max_delta/2; + + //our step flags + bool x_can_step = 0; + bool y_can_step = 0; + bool z_can_step = 0; + + //how long do we delay for? + if (micro_delay >= 16383) + milli_delay = micro_delay / 1000; + else + milli_delay = 0; + + //do our DDA line! + do + { + x_can_step = can_step(X_MIN_PIN, X_MAX_PIN, current_steps.x, target_steps.x, x_direction); + y_can_step = can_step(Y_MIN_PIN, Y_MAX_PIN, current_steps.y, target_steps.y, y_direction); + z_can_step = can_step(Z_MIN_PIN, Z_MAX_PIN, current_steps.z, target_steps.z, z_direction); + + if (x_can_step) + { + x_counter += delta_steps.x; + + if (x_counter > 0) + { + do_step(X_STEP_PIN); + x_counter -= max_delta; + + if (x_direction) + current_steps.x++; + else + current_steps.x--; + } + } + + if (y_can_step) + { + y_counter += delta_steps.y; + + if (y_counter > 0) + { + do_step(Y_STEP_PIN); + y_counter -= max_delta; + + if (y_direction) + current_steps.y++; + else + current_steps.y--; + } + } + + if (z_can_step) + { + z_counter += delta_steps.z; + + if (z_counter > 0) + { + do_step(Z_STEP_PIN); + z_counter -= max_delta; + + if (z_direction) + current_steps.z++; + else + current_steps.z--; + } + } + + //keep it hot =) + extruder_manage_temperature(); + + //wait for next step. + if (milli_delay > 0) + delay(milli_delay); + else + delayMicrosecondsInterruptible(micro_delay); + } + while (x_can_step || y_can_step || z_can_step); + + //set our points to be the same + current_units.x = target_units.x; + current_units.y = target_units.y; + current_units.z = target_units.z; + calculate_deltas(); +} + +bool can_step(byte min_pin, byte max_pin, long current, long target, byte direction) +{ + //stop us if we're on target + if (target == current) + return false; +#if ENDSTOPS_MIN_ENABLED == 1 + //stop us if we're at home and still going + else if (read_switch(min_pin) && !direction) + return false; +#endif +#if ENDSTOPS_MAX_ENABLED == 1 + //stop us if we're at max and still going + else if (read_switch(max_pin) && direction) + return false; +#endif + + //default to being able to step + return true; +} + +void do_step(byte step_pin) +{ + digitalWrite(step_pin, HIGH); + delayMicroseconds(5); + digitalWrite(step_pin, LOW); +} + +bool read_switch(byte pin) +{ + //dual read as crude debounce + #if ENDSTOPS_INVERTING == 1 + return !digitalRead(pin) && !digitalRead(pin); + #else + return digitalRead(pin) && digitalRead(pin); + #endif +} + +long to_steps(float steps_per_unit, float units) +{ + return steps_per_unit * units; +} + +void set_target(float x, float y, float z) +{ + target_units.x = x; + target_units.y = y; + target_units.z = z; + + calculate_deltas(); +} + +void set_position(float x, float y, float z) +{ + current_units.x = x; + current_units.y = y; + current_units.z = z; + + calculate_deltas(); +} + +void calculate_deltas() +{ + //figure our deltas. + delta_units.x = abs(target_units.x - current_units.x); + delta_units.y = abs(target_units.y - current_units.y); + delta_units.z = abs(target_units.z - current_units.z); + + //set our steps current, target, and delta + current_steps.x = to_steps(x_units, current_units.x); + current_steps.y = to_steps(y_units, current_units.y); + current_steps.z = to_steps(z_units, current_units.z); + + target_steps.x = to_steps(x_units, target_units.x); + target_steps.y = to_steps(y_units, target_units.y); + target_steps.z = to_steps(z_units, target_units.z); + + delta_steps.x = abs(target_steps.x - current_steps.x); + delta_steps.y = abs(target_steps.y - current_steps.y); + delta_steps.z = abs(target_steps.z - current_steps.z); + + //what is our direction + x_direction = (target_units.x >= current_units.x); + y_direction = (target_units.y >= current_units.y); + z_direction = (target_units.z >= current_units.z); + + //set our direction pins as well +#if INVERT_X_DIR == 1 + digitalWrite(X_DIR_PIN, !x_direction); +#else + digitalWrite(X_DIR_PIN, x_direction); +#endif +#if INVERT_Y_DIR == 1 + digitalWrite(Y_DIR_PIN, !y_direction); +#else + digitalWrite(Y_DIR_PIN, y_direction); +#endif +#if INVERT_Z_DIR == 1 + digitalWrite(Z_DIR_PIN, !z_direction); +#else + digitalWrite(Z_DIR_PIN, z_direction); +#endif +} + + +long calculate_feedrate_delay(float feedrate) +{ + //how long is our line length? + float distance = sqrt(delta_units.x*delta_units.x + + delta_units.y*delta_units.y + + delta_units.z*delta_units.z); + long master_steps = 0; + + //find the dominant axis. + if (delta_steps.x > delta_steps.y) + { + if (delta_steps.z > delta_steps.x) + master_steps = delta_steps.z; + else + master_steps = delta_steps.x; + } + else + { + if (delta_steps.z > delta_steps.y) + master_steps = delta_steps.z; + else + master_steps = delta_steps.y; + } + + //calculate delay between steps in microseconds. this is sort of tricky, but not too bad. + //the formula has been condensed to save space. here it is in english: + // (feedrate is in mm/minute) + // distance / feedrate * 60000000.0 = move duration in microseconds + // move duration / master_steps = time between steps for master axis. + + return ((distance * 60000000.0) / feedrate) / master_steps; +} + +long getMaxSpeed() +{ + if (delta_steps.z > 0) + return calculate_feedrate_delay(FAST_Z_FEEDRATE); + else + return calculate_feedrate_delay(FAST_XY_FEEDRATE); +} + +#ifdef SANGUINO +void enable_steppers() +{ + // Enable steppers only for axes which are moving + // taking account of the fact that some or all axes + // may share an enable line (check using macros at + // compile time to avoid needless code) + if ( target_units.x == current_units.x + #if X_ENABLE_PIN == Y_ENABLE_PIN + && target_units.y == current_units.y + #endif + #if X_ENABLE_PIN == Z_ENABLE_PIN + && target_units.z == current_units.z + #endif + ) + digitalWrite(X_ENABLE_PIN, !ENABLE_ON); + else + digitalWrite(X_ENABLE_PIN, ENABLE_ON); + if ( target_units.y == current_units.y + #if Y_ENABLE_PIN == X_ENABLE_PIN + && target_units.x == current_units.x + #endif + #if Y_ENABLE_PIN == Z_ENABLE_PIN + && target_units.z == current_units.z + #endif + ) + digitalWrite(Y_ENABLE_PIN, !ENABLE_ON); + else + digitalWrite(Y_ENABLE_PIN, ENABLE_ON); + if ( target_units.z == current_units.z + #if Z_ENABLE_PIN == X_ENABLE_PIN + && target_units.x == current_units.x + #endif + #if Z_ENABLE_PIN == Y_ENABLE_PIN + && target_units.y == current_units.y + #endif + ) + digitalWrite(Z_ENABLE_PIN, !ENABLE_ON); + else + digitalWrite(Z_ENABLE_PIN, ENABLE_ON); +} + +void disable_steppers() +{ + //disable our steppers + digitalWrite(X_ENABLE_PIN, !ENABLE_ON); + digitalWrite(Y_ENABLE_PIN, !ENABLE_ON); + digitalWrite(Z_ENABLE_PIN, !ENABLE_ON); +} +#endif + +void delayMicrosecondsInterruptible(unsigned int us) +{ + +#if F_CPU >= 16000000L + // for the 16 MHz clock on most Arduino boards + + // for a one-microsecond delay, simply return. the overhead + // of the function call yields a delay of approximately 1 1/8 us. + if (--us == 0) + return; + + // the following loop takes a quarter of a microsecond (4 cycles) + // per iteration, so execute it four times for each microsecond of + // delay requested. + us <<= 2; + + // account for the time taken in the preceeding commands. + us -= 2; +#else + // for the 8 MHz internal clock on the ATmega168 + + // for a one- or two-microsecond delay, simply return. the overhead of + // the function calls takes more than two microseconds. can't just + // subtract two, since us is unsigned; we'd overflow. + if (--us == 0) + return; + if (--us == 0) + return; + + // the following loop takes half of a microsecond (4 cycles) + // per iteration, so execute it twice for each microsecond of + // delay requested. + us <<= 1; + + // partially compensate for the time taken by the preceeding commands. + // we can't subtract any more than this or we'd overflow w/ small delays. + us--; +#endif + + // busy wait + __asm__ __volatile__ ( + "1: sbiw %0,1" "\n\t" // 2 cycles + "brne 1b" : "=w" (us) : "0" (us) // 2 cycles + ); +} + +#ifdef TEST_MACHINE + +void X_motor_test() +{ + Serial.println("Moving X forward by 100 mm at half maximum speed."); + set_target(100, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); + + Serial.println("Moving X back to the start."); + set_target(0, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); +} + +void Y_motor_test() +{ + + Serial.println("Moving Y forward by 100 mm at half maximum speed."); + set_target(0, 100, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); + + Serial.println("Moving Y back to the start."); + set_target(0, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); +} + +void Z_motor_test() +{ + Serial.println("Moving Z down by 5 mm at half maximum speed."); + set_target(0, 0, 5); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_Z_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); + + Serial.println("Moving Z back to the start."); + set_target(0, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_Z_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); +} + +#endif + +int main(void) +{ + init(); + + setup(); + + for (;;) + loop(); + + return 0; +} + diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.elf b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.elf Binary files differnew file mode 100755 index 00000000..07bfe1f9 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.elf diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.hex b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.hex new file mode 100644 index 00000000..87a43945 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.hex @@ -0,0 +1,779 @@ +:100000000C9478000C94A0000C94A0000C94A00018
+:100010000C94A0000C94A0000C94A0000C94A000E0
+:100020000C94A0000C94A0000C94A0000C94A000D0
+:100030000C94A0000C94A0000C94A0000C94A000C0
+:100040000C94000E0C94A0000C941A110C94A000B7
+:100050000C94A0000C94A0000C94A0000C94A000A0
+:100060000C94A0000C94A000000024272A00002576
+:10007000282B000023262904040404040404040299
+:100080000202020202030303030303010204081035
+:100090002040800102040810200102040810200002
+:1000A0000000070002010000030406000000000039
+:1000B000000000494E46494E4954594E414ECDCC60
+:1000C000CC3D0AD7233C17B7D13877CC2B32959546
+:1000D000E6241FB14F0A000020410000C842004042
+:1000E0001C4620BCBE4CCA1B0E5AAEC59D749F1048
+:1000F00011241FBECFEFD4E0DEBFCDBF11E0A0E0E2
+:10010000B1E0E8E0F0E302C005900D92A638B10737
+:10011000D9F713E0A6E8B1E001C01D92AA30B107FB
+:10012000E1F710E0C0EFD0E004C02297FE010E948A
+:100130009E17CE3ED107C9F70E94F50D0C94031807
+:100140000C9400009093090280930802AA2797FD5F
+:10015000A095BA2FBC01CD010E94BC152DEC3CEC42
+:100160004CE85FE30E9470160E94891570930B02A1
+:1001700060930A02089510920602109207020895F1
+:100180000E9470160E9489150895019739F0880F12
+:10019000991F880F991F02970197F1F708952F92E1
+:1001A0003F924F925F926F927F928F929F92AF9207
+:1001B000BF92CF92DF92EF92FF920F931F93CF9354
+:1001C000DF93CDB7DEB72C970FB6F894DEBF0FBE26
+:1001D000CDBF69877A878B879C87209032023090C9
+:1001E0003302409034025090350280913602909153
+:1001F0003702A0913802B09139028D839E83AF837C
+:10020000B88780913A0290913B02A0913C02B09154
+:100210003D0289839A83AB83BC83609056027090C1
+:1002200057028090580290905902A0905A02B090C4
+:100230005B02C0905C02D0905D02A6019501C401F2
+:10024000B3010E946C16E0905E02F0905F02009194
+:1002500060021091610218165CF4A4019301C801B8
+:10026000B7010E946C1618165CF0C401B3010DC0F2
+:10027000A6019501C801B7010E946C1618161CF45E
+:10028000C801B70102C0C601B5010E9489155B0112
+:100290006C01A2019101C201B1010E9470167B01A3
+:1002A0008C012D813E814F815885CA01B9010E9480
+:1002B00070169B01AC01C801B7010E94B9147B0103
+:1002C0008C0129813A814B815C81CA01B9010E946C
+:1002D00070169B01AC01C801B7010E94B9140E94BD
+:1002E000D71620EC31EE44E65CE40E9470162985B6
+:1002F0003A854B855C850E9421157B018C01C601E6
+:10030000B5010E94BC159B01AC01C801B7010E9458
+:1003100021150E9489152C960FB6F894DEBF0FBEEA
+:10032000CDBFDF91CF911F910F91FF90EF90DF90A4
+:10033000CF90BF90AF909F908F907F906F905F9085
+:100340004F903F902F90089520E030E040E050E043
+:1003500060915E0270915F028091600290916102F3
+:100360000E946C1618163CF460E070E088E492E499
+:100370000E94CF00089560E070E088EC94E40E9451
+:10038000CF0008952F923F924F925F926F927F928B
+:100390008F929F92AF92BF92CF92DF92EF92FF9295
+:1003A0000F931F93CF93DF93CDB7DEB7A0970FB610
+:1003B000F894DEBF0FBECDBF809126029091270238
+:1003C000A0912802B09129028D8F9E8FAF8FB8A384
+:1003D00080911A0290911B02A0911C02B0911D0203
+:1003E000898F9A8FAB8FBC8F9C01AD016D8D7E8DF7
+:1003F0008F8D98A10E94B8147B018C0120E030E021
+:1004000040E050E00E946C16181624F017FB10957F
+:1004100017F91095E0923202F09233020093340201
+:100420001093350280912A0290912B02A0912C0208
+:10043000B0912D028D8B9E8BAF8BB88F80911E0259
+:1004400090911F02A0912002B0912102898B9A8B7A
+:10045000AB8BBC8B9C01AD016D897E898F89988D9A
+:100460000E94B8147B018C0120E030E040E050E0B5
+:100470000E946C16181624F017FB109517F91095AA
+:10048000E0923602F092370200933802109339025C
+:1004900080912E0290912F02A0913002B0913102F2
+:1004A0008D879E87AF87B88B80912202909123021F
+:1004B000A0912402B091250289879A87AB87BC87D7
+:1004C0009C01AD016D857E858F8598890E94B81449
+:1004D0007B018C0120E030E040E050E00E946C168F
+:1004E000181624F017FB109517F91095E0923A02B0
+:1004F000F0923B0200933C0210933D02E0907101A8
+:10050000F09072010091730110917401298D3A8D60
+:100510004B8D5C8DC801B7010E9470160E94891531
+:100520000E94BC151B012C0160933E0270933F0298
+:100530008093400290934102609075017090760123
+:10054000809077019090780129893A894B895C895C
+:10055000C401B3010E9470160E9489150E94BC1547
+:100560006D837E838F8398876093420270934302EA
+:100570008093440290934502A0907901B0907A0153
+:10058000C0907B01D0907C0129853A854B855C85A4
+:10059000C601B5010E9470160E9489150E94BC1503
+:1005A00069837A838B839C836093460270934702AE
+:1005B00080934802909349022D8D3E8D4F8D58A116
+:1005C000C801B7010E9470160E9489150E94BC15CF
+:1005D0007B018C0160934A0270934B0280934C0222
+:1005E00090934D022D893E894F89588DC401B301E6
+:1005F0000E9470160E9489150E94BC153B014C0197
+:1006000060934E0270934F02809350029093510278
+:100610002D853E854F855889C601B5010E9470160B
+:100620000E9489150E94BC155B016C016093520207
+:10063000709353028093540290935502A20191014A
+:10064000C801B7010E94B8147B018C0120E030E0A2
+:1006500040E050E00E946C16181624F017FB10952D
+:1006600017F91095E0925602F09257020093580243
+:10067000109359022D813E814F815885C401B301E9
+:100680000E94B8147B018C0120E030E040E050E093
+:100690000E946C16181624F017FB109517F9109588
+:1006A000E0925A02F0925B0200935C0210935D02AA
+:1006B00029813A814B815C81C601B5010E94B81441
+:1006C0007B018C0120E030E040E050E00E946C169D
+:1006D000181624F017FB109517F91095E0925E029A
+:1006E000F0925F02009360021093610210E0298D86
+:1006F0003A8D4B8D5C8D6D8D7E8D8F8D98A10E9476
+:100700006C1688230CF011E0109381011092820185
+:1007100029893A894B895C896D897E898F89988D71
+:100720000E946C1688231CF081E080938201109255
+:10073000830129853A854B855C856D857E858F850E
+:1007400098890E946C1688231CF081E080938301B5
+:10075000612F83E00E94200F6091820187E00E9458
+:10076000200F6091830182E10E94200FA0960FB6B6
+:10077000F894DEBF0FBECDBFDF91CF911F910F91D7
+:10078000FF90EF90DF90CF90BF90AF909F908F90B1
+:100790007F906F905F904F903F902F900895EF92D1
+:1007A000FF920F931F9360931A0270931B02809322
+:1007B0001C0290931D0220931E0230931F0240934F
+:1007C000200250932102E0922202F0922302009331
+:1007D0002402109325020E94C2011F910F91FF90E5
+:1007E000EF900895EF92FF920F931F93609326026C
+:1007F00070932702809328029093290220932A0263
+:1008000030932B0240932C0250932D02E0922E0243
+:10081000F0922F0200933002109331020E94C20125
+:100820001F910F91FF90EF90089580936F01682FB3
+:100830008CE00E94200F08951F93182F0E94D40E61
+:10084000892B11F420E007C0812F0E94D40E20E0F4
+:10085000892B09F021E0822F99271F910895CF92CB
+:10086000EF92FF920F931F93E216F306040715070A
+:1008700019F480E090E00AC00E941C04882321F053
+:1008800080E090E0CC2011F081E090E01F910F918A
+:10089000FF90EF90CF9008951F93182F61E00E9472
+:1008A000200F85E090E00E945F0E60E0812F0E94A3
+:1008B000200F1F91089580E090E0A0E0B0E08093C9
+:1008C0001A0290931B02A0931C02B0931D02809306
+:1008D0001E0290931F02A0932002B09321028093E6
+:1008E000220290932302A0932402B09325028093C6
+:1008F000260290932702A0932802B09329028093A6
+:100900002A0290932B02A0932C02B0932D02809385
+:100910002E0290932F02A0933002B093310261E037
+:1009200082E00E94B60E61E083E00E94B60E61E0B4
+:100930008AE00E94B60E61E087E00E94B60E61E098
+:1009400083E10E94B60E61E082E10E94B60E60E093
+:1009500084E00E94B60E60E088E00E94B60E60E07F
+:1009600081E10E94B60E0E94C2010895AF92BF922B
+:10097000CF92DF92EF92FF920F931F93CF93DF936B
+:10098000CDB7DEB722970FB6F894DEBF0FBECDBF4E
+:100990008C017B016A0159014AE050E0BE016F5FA2
+:1009A0007F4F0E948A1329813A81201B310B121636
+:1009B00013065CF4F70171836083F60180819181F5
+:1009C0008A299B299183808303C0F70111821082B9
+:1009D000C90122960FB6F894DEBF0FBECDBFDF91DE
+:1009E000CF911F910F91FF90EF90DF90CF90BF902C
+:1009F000AF900895AF92BF92CF92DF92EF92FF92A5
+:100A00000F931F93CF93DF93CDB7DEB722970FB627
+:100A1000F894DEBF0FBECDBF8C017B016A01590186
+:100A2000BE016F5F7F4F0E943D1229813A81201BDA
+:100A3000310B121613066CF4F70160837183828305
+:100A40009383F601808191818A299B2991838083F8
+:100A500009C080E090E0A0E0B0E0F70180839183DE
+:100A6000A283B383C90122960FB6F894DEBF0FBEEE
+:100A7000CDBFDF91CF911F910F91FF90EF90DF904D
+:100A8000CF90BF90AF9008952F923F924F925F9278
+:100A90006F927F928F929F92AF92BF92CF92DF928E
+:100AA000EF92FF920F931F93CF93DF93CDB7DEB7F3
+:100AB00062970FB6F894DEBF0FBECDBF9A8B898BBD
+:100AC0006B015A834983FC0111821082EE24FF24BA
+:100AD0003696FC83EB838B010F5F1F4F82969E83BC
+:100AE0008D83E989FA893E96F887EF8389899A8907
+:100AF00042969A878987E989FA893A96FC87EB8733
+:100B000089899A898A969E878D87E989FA89B69616
+:100B1000F88BEF8776E1272E312C89899A89280E68
+:100B2000391E6AE1462E512C480E591E54E0652E9E
+:100B3000712C680E791E4EE1842E912C880E991E20
+:100B400032E0A32EB12CA80EB91E89C0F601EE0D1D
+:100B5000FF1DE081E035F1F1E1358CF4E93409F471
+:100B600055C0EA3434F4E63409F45CC0E734B9F42F
+:100B700019C0EA3409F450C0ED3489F419C0E335E2
+:100B800011F1E43534F4E13509F459C0E23539F4B2
+:100B90004FC0E93569F1EA3591F1E83511F180E0AE
+:100BA00090E058C021E030E049895A89B50105C07C
+:100BB00022E030E049895A89B301C8018E0D9F1D9A
+:100BC0000E94B60447C020E034E049895A896D810B
+:100BD0007E813BC024E030E049895A896B817C8169
+:100BE00034C028E030E049895A896B857C852DC066
+:100BF00020E130E049895A896F81788526C020E25A
+:100C000030E049895A8969857A851FC020E430E03F
+:100C100049895A89B10119C020E830E049895A89C7
+:100C2000B20113C020E032E049895A89B4010DC0F5
+:100C300020E030E149895A896F85788906C020E033
+:100C400038E049895A896D857E85C8018E0D9F1DC2
+:100C50000E94FA040894E11CF11CE80EF91EE981D7
+:100C6000FA81EE16FF060CF471CF62960FB6F89477
+:100C7000DEBF0FBECDBFDF91CF911F910F91FF90CF
+:100C8000EF90DF90CF90BF90AF909F908F907F902C
+:100C90006F905F904F903F902F9008959927BC01DF
+:100CA00085E00E94860F08958FEE9EEF0E94A200BD
+:100CB00061E08CE00E94B60E61E08BE00E94B60E0F
+:100CC00061E086E00E94B60E61E085E00E94B60E0B
+:100CD00061E080E10E94B60E61E08FE00E94B60EF6
+:100CE00061E08CE00E94200F60E070E085E00E94EF
+:100CF000860F60E070E086E00E94860F60E070E0A2
+:100D00008BE00E94860F60E080E10E94200F60E08F
+:100D10008FE00E94200F08950F931F93CF93DF93CE
+:100D2000082FC0E0D0E010E0802F0E946B0FC80FAA
+:100D3000D91F1F5F1330C1F7CE0163E070E00E943E
+:100D40003817CB01DF91CF911F910F91089580E06B
+:100D50000E948C06AA2797FDA095BA2FBC01CD0151
+:100D60000E94BC1520E030E040EA50E40E9470167A
+:100D700020E030E048EC52E40E94701620E030E0C1
+:100D800040E85AE30E9470160E948915DC01CB01ED
+:100D900008950E94A70608950E94C9069C018091AB
+:100DA000080290910902281739071CF460916E011E
+:100DB0000BC080910A0290910B022817390714F09A
+:100DC00060E002C060916D0180910C02861731F0E5
+:100DD00060930C02772786E00E94860F08953F9269
+:100DE0004F925F926F927F928F929F92AF92BF923B
+:100DF000CF92DF92EF92FF920F931F93CF93DF93E7
+:100E0000CDB7DEB728970FB6F894DEBF0FBECDBFC3
+:100E10006D837E838F839887A0905602B09057028F
+:100E2000C0905802D0905902E0905A02F0905B02B4
+:100E300000915C0210915D02A8019701C601B50105
+:100E40000E946C1618161CF4C601B50102C0C80138
+:100E5000B7010E94891560936A0270936B028093B8
+:100E60006C0290936D02A0905E02B0905F02C09001
+:100E70006002D09061020E94BC157B018C019B0135
+:100E8000AC01C601B5010E946C1618161CF4C6010F
+:100E9000B50102C0C801B7010E94891560936A02BA
+:100EA00070936B0280936C0290936D0222E030E0AD
+:100EB00040E050E00E946D17442455243201421A4C
+:100EC000530A640A750A2D813E814F8158852F3F50
+:100ED0008FE3380780E0480780E058076CF0CA01CC
+:100EE000B90128EE33E040E050E00E946D173093E6
+:100EF0007E0220937D0204C010927E0210927D0239
+:100F00005301420149825A826B827C8260914A027B
+:100F100070914B0280914C0290914D020E94891574
+:100F20007B018C0160913E0270913F0280914002F2
+:100F3000909141020E9489159B01AC01C0908101F2
+:100F400069E084E00E942F04382E60914E02709177
+:100F50004F0280915002909151020E9489157B01AD
+:100F60008C01609142027091430280914402909101
+:100F700045020E9489159B01AC01C09082016DE081
+:100F800088E00E942F04D82E609152027091530283
+:100F900080915402909155020E9489157B018C0129
+:100FA00060914602709147028091480290914902F7
+:100FB0000E9489159B01AC01C090830160E181E131
+:100FC0000E942F04182F332009F44FC0C301B2012F
+:100FD0000E94BC1520915602309157024091580250
+:100FE000509159020E94B9140E9489152B013C01AD
+:100FF0001616170618061906C4F582E00E944C045E
+:1010000080916A0290916B02A0916C02B0916D0286
+:10101000481A590A6A0A7B0A80918101882379F06B
+:1010200020E030E040E85FE360913E0270913F02D3
+:1010300080914002909141020E94B9140EC020E0BC
+:1010400030E040E85FE360913E0270913F028091A2
+:101050004002909141020E94B81460933E02709346
+:101060003F028093400290934102DD2009F45CC06E
+:1010700069817A818B819C810E94BC1520915A02E2
+:1010800030915B0240915C0250915D020E94B91464
+:101090000E94891569837A838B839C8316161706B1
+:1010A000180619060CF040C08AE00E944C0480919A
+:1010B0006A0290916B02A0916C02B0916D0229813D
+:1010C0003A814B815C81281B390B4A0B5B0B2983CE
+:1010D0003A834B835C8380918201882379F020E0FE
+:1010E00030E040E85FE360914202709143028091FA
+:1010F0004402909145020E94B9140EC020E030E0F5
+:1011000040E85FE3609142027091430280914402A3
+:10111000909145020E94B81460934202709343027A
+:101120008093440290934502112309F44FC0C501F6
+:10113000B4010E94BC1520915E0230915F02409183
+:101140006002509161020E94B9140E9489154B01FE
+:101150005C011616170618061906C4F583E10E94ED
+:101160004C0480916A0290916B02A0916C02B09144
+:101170006D02881A990AAA0ABB0A80918301882302
+:1011800079F020E030E040E85FE360914602709142
+:10119000470280914802909149020E94B9140EC002
+:1011A00020E030E040E85FE3609146027091470242
+:1011B00080914802909149020E94B81460934602BF
+:1011C0007093470280934802909349020E94CC0694
+:1011D00060917D0270917E02161617063CF48827F6
+:1011E00077FD8095982F0E943D0E04C08D819E81D1
+:1011F0000E94C500332009F089CEDD2009F086CE9B
+:10120000112309F083CE8091260290912702A091AC
+:101210002802B091290280931A0290931B02A09396
+:101220001C02B0931D0280912A0290912B02A09182
+:101230002C02B0912D0280931E0290931F02A09366
+:101240002002B093210280912E0290912F02A09152
+:101250003002B09131028093220290932302A09336
+:101260002402B09325020E94C20128960FB6F8947A
+:10127000DEBF0FBECDBFDF91CF911F910F91FF90C9
+:10128000EF90DF90CF90BF90AF909F908F907F9026
+:101290006F905F904F903F90089508C00E94CC06D9
+:1012A00068EE73E080E090E00E943D0E0E94C90667
+:1012B000209108023091090225503040821793078F
+:1012C0006CF308951F93182F882311F00E944D0985
+:1012D000612F77278BE00E94860F1F910895DF9280
+:1012E000EF92FF920F931F93D82E7B010E944D091E
+:1012F000D09219026D2D80E10E94200F61E08FE0F5
+:101300000E94200F0027F7FC0095102FC801B7019D
+:101310000E943D0E60E08FE00E94200F60E080E1BF
+:101320000E94200F1F910F91FF90EF90DF90089582
+:101330002F923F924F925F926F927F928F929F92E5
+:10134000AF92BF92CF92DF92EF92FF920F931F93D3
+:10135000CF93DF93CDB7DEB7C354D0400FB6F89428
+:10136000DEBF0FBECDBFFC01AB0180818F3209F41F
+:1013700068C3BF01CE0101960E94440529813A81CC
+:10138000C90183709070892B71F42115310559F0D2
+:10139000809184019091850197FD05C09C838B838A
+:1013A00021603A832983E980FA80E0FEA5C20B819F
+:1013B0001C811093850100938401A0902202B090BB
+:1013C0002302C0902402D090250280911E029091A9
+:1013D0001F02A0912002B09121028FA798ABA9AB68
+:1013E000BAAB80911A0290911B02A0911C02B0919D
+:1013F0001D028BAB9CABADABBEAB90917001249644
+:101400009FAF2497C701887090702496AFAD249742
+:10141000AA2329F1892B29F48BA99CA9ADA9BEA9DE
+:1014200004C08B859C85AD85BE858FAB98AFA9AF79
+:10143000BAAFE4FC05C08FA598A9A9A9BAA904C0B0
+:101440008F859889A989BA898BAF9CAFADAFBEAFA4
+:10145000E5FE44C02B883C884D885E8841C0892BBE
+:1014600049F48BA99CA9ADA9BEA98FAB98AFA9AF30
+:10147000BAAF0EC02B853C854D855E856BA97CA9D6
+:101480008DA99EA90E94B9146FAB78AF89AF9AAFAE
+:10149000E4FC09C08FA598A9A9A9BAA98BAF9CAFF4
+:1014A000ADAFBEAF0EC02F85388949895A896FA567
+:1014B00078A989A99AA90E94B9146BAF7CAF8DAFA6
+:1014C0009EAFE5FE0BC02B893C894D895E89C60124
+:1014D000B5010E94B9141B012C0102C0150126019F
+:1014E000F1FE0CC08F8D98A1A9A1BAA180936202D0
+:1014F00090936302A0936402B09365020C311105CE
+:1015000009F4C6C00D311105ACF40430110509F41D
+:1015100058C0053011052CF40230110508F0DAC16D
+:1015200022C00431110509F45FC00531110509F02D
+:10153000D1C17FC0043511054CF4013511050CF003
+:10154000CDC00E31110509F0C5C1B7C00B3511056D
+:1015500009F4B0C10C35110509F4AFC10A35110504
+:1015600009F0B8C1A3C1820171012BAD3CAD4DADF5
+:101570005EAD6FA978AD89AD9AAD0E94F2038B8103
+:101580009C81019759F4609162027091630280918D
+:101590006402909165020E94CF0002C00E94A401E3
+:1015A0006093660270936702809368029093690269
+:1015B0006091660270916702809168029091690261
+:1015C00079C020E030E040E05FE36F817885898575
+:1015D0009A850E94B9140E948915882777FD809505
+:1015E000982F0E943D0E88C188EF91E2ABE4B3E4EE
+:1015F0008093710190937201A0937301B093740171
+:101600008093750190937601A0937701B093780150
+:1016100080E090E0AEEFB5E48093790190937A0199
+:10162000A0937B01B0937C0180E792E4A1EABCE344
+:1016300024C08BE49AEEAFEFB0E4809371019093F5
+:101640007201A0937301B09374018093750190931C
+:101650007601A0937701B093780180E090E0A0EA52
+:10166000B3E48093790190937A01A0937B01B093C6
+:101670007C0180E090E0A0E0BFE380937D01909347
+:101680007E01A0937F01B09380010E94C20134C10A
+:101690000F2EF0E0EF2EF0E0FF2EF0E00F2FF0E045
+:1016A0001F2FF02DA8019701C801B7010E94F20376
+:1016B0000E94A4010E94EF061FC1820171012BAD9F
+:1016C0003CAD4DAD5EAD6FA978AD89AD9AAD0E94D0
+:1016D000F2030E94A4010E94EF06DACF6FA078A463
+:1016E00089A49AA424969FAD2497992341F4A60136
+:1016F0009501C401B3010E94B9143B014C01A4013E
+:101700009301C601B5010E941D15882384F484014C
+:1017100073012FA538A949A95AA96BA97CA98DA93C
+:101720009EA90E94F2030E94A4010E94EF06E0908D
+:101730002202F090230200912402109125022BAD89
+:101740003CAD4DAD5EAD6FA978AD89AD9AAD0E944F
+:10175000F2030E94A4010E94EF068B819C818335D5
+:10176000910559F48BA59CA5ADA5BEA523968CAF7C
+:101770009DAFAEAFBFAF23970CC0A2019101C401D2
+:10178000B3010E94B81423966CAF7DAF8EAF9FAFAC
+:10179000239764015301860175012BAD3CAD4DAD1E
+:1017A0005EAD6FA978AD89AD9AAD0E94F2030E943B
+:1017B000A4010E94EF0623962CAD3DAD4EAD5FAD6A
+:1017C0002397C601B5010E94B8145B016C01A20108
+:1017D00091010E941D15882314F4620151018601B4
+:1017E00075012BAD3CAD4DAD5EAD6FA978AD89AD4A
+:1017F0009AAD0E94F203E0906202F09063020091C1
+:1018000064021091650220E030E040E050E0C80141
+:10181000B7010E946C1618162CF4C801B7010E947B
+:10182000CF0002C00E94A401609366027093670219
+:1018300080936802909369026091660270916702DA
+:1018400080916802909169020E94EF068B819C81D1
+:101850008235910591F420E030E04AE754E46F814D
+:10186000788589859A850E9470160E948915882737
+:1018700077FD8095982F0E943D0E840173012BAD5A
+:101880003CAD4DAD5EAD6FA978AD89AD9AAD0E940E
+:10189000F2030E94A4010E94EF06A2019101C60179
+:1018A000B5010E946C1618163CF575CF81E0809347
+:1018B000700122C0109270011FC0820171012BAD16
+:1018C0003CAD4DAD5EAD6FA978AD89AD9AAD0E94CE
+:1018D000CF0312C060E071E08FE792E00E948010B9
+:1018E0004B815C81662757FD6095762F2AE030E0BA
+:1018F0008FE792E00E94621029813A8121FFA1C006
+:101900008D819E818936910509F44AC08A369105F8
+:10191000B4F48636910569F18736910544F4009751
+:1019200009F48FC08536910509F079C020C087364B
+:10193000910539F18836910509F071C024C08C36C3
+:10194000910509F441C08D36910544F48A3691051C
+:10195000A9F18B36910509F062C032C08E3791052E
+:1019600009F43FC08F37910509F059C048C081E0A4
+:1019700001C080E00E94150480916B010E94620901
+:1019800060C080E0FBCF32FF5CC06BA17CA18DA169
+:101990009EA10E948915DC01CB010E94A20051C0CA
+:1019A00067E071E08FE792E00E9480100E94C90614
+:1019B000BC018FE792E00E94751043C08FEF01C019
+:1019C00080E00E944E063DC032FF3BC06BA17CA16F
+:1019D0008DA19EA10E94891570936C0160936B018B
+:1019E00030C020E030E040E05FE36F81788589859A
+:1019F0009A850E94B9140E94891581E00DC020E0EB
+:101A000030E040E05FE36F81788589859A850E94A8
+:101A1000B9140E94891580E00E946F0912C06AE023
+:101A200071E08FE792E00E9480104D815E81662711
+:101A300057FD6095762F2AE030E08FE792E00E9414
+:101A40006210CD5BDF4F0FB6F894DEBF0FBECDBF87
+:101A5000DF91CF911F910F91FF90EF90DF90CF908A
+:101A6000BF90AF909F908F907F906F905F904F90BE
+:101A70003F902F9008950F931F938FEF0E948C0635
+:101A8000AC01EEE1F1E0A1E0B0E0608171814617C8
+:101A900057071CF5AA0FBB1FAA0FBB1FFD01EA5E6B
+:101AA000FE4F0281138120813181421B530BA65EC0
+:101AB000BE4FFD0182819381801B910B621B730BD2
+:101AC0009C01429FC001439F900D529F900D112495
+:101AD0000E943817600F711F10C08A2F8F5F1196F8
+:101AE0003496A431B10589F6843119F060E070E0D4
+:101AF0000BC060916801709169016F3F710521F021
+:101B00001CF06FEF70E004C077FF02C060E070E08F
+:101B1000CB011F910F9108950E94CC068FE792E0B0
+:101B20000E949510882311F18FE792E00E94921095
+:101B300080936A018D3019F48AE080936A01909154
+:101B40006A0190329CF09B3319F481E08093070284
+:101B500080910702882351F480910602E82FFF2725
+:101B6000EA57FE4F90838F5F8093060280910602B2
+:101B700087FF04C0109206021092070260910602CD
+:101B80006623B9F080916A018A3099F47727FB01C6
+:101B9000EA57FE4F108286E891E00E949809109261
+:101BA00006021092070261E171E08FE792E00E9465
+:101BB000841008950F931F930FE712E040E05BE459
+:101BC00060E070E0C8010E94991064E171E0C80112
+:101BD0000E94841010920602109207020E945B0479
+:101BE0000E9454061F910F910895CFEFD4E0DEBFFD
+:101BF000CDBF0E946C0E0E94DA0D0E948C0DFDCFAD
+:101C00001F920F920FB60F9211248F939F93AF9351
+:101C1000BF938091840290918502A0918602B09139
+:101C200087020196A11DB11D8093840290938502C5
+:101C3000A0938602B0938702BF91AF919F918F913D
+:101C40000F900FBE0F901F901895609184027091B5
+:101C50008502809186029091870227E0660F771FA8
+:101C6000881F991F2A95D1F72DE730E040E050E01A
+:101C70000E944B17CA01B9010895AF92BF92CF924B
+:101C8000DF92EF92FF920F931F935B016C010E9412
+:101C9000250E7B018C010E94250E6E197F09800B99
+:101CA000910B6A157B058C059D05A8F31F910F917B
+:101CB000FF90EF90DF90CF90BF90AF900895019785
+:101CC00051F0880F991F880F991F02972FB7F8942A
+:101CD0000197F1F72FBF0895789410928402109223
+:101CE0008502109286021092870284B5826084BDBC
+:101CF00084B5816084BD85B5826085BD85B5816010
+:101D000085BDEEE6F0E0808181608083E1E8F0E06F
+:101D1000808182608083808181608083E0E8F0E060
+:101D2000808181608083E1EBF0E08081846080834A
+:101D3000E0EBF0E0808181608083ECE7F0E080817F
+:101D40008F778083808180648083EAE7F0E0808100
+:101D500084608083808182608083808181608083D1
+:101D60008081806880831092C1000895282F3327D6
+:101D7000C90185579F4FFC01949129583F4FF901A4
+:101D80008491882381F0E82FFF27E859FF4FE491E1
+:101D9000FF27662329F48081909589238083089505
+:101DA0008081892B80830895482F5527CA01815649
+:101DB0009F4FFC012491CA0185579F4FFC019491CC
+:101DC00049585F4FFA013491332319F480E090E0D1
+:101DD0000895222331F1233021F4809180008F7700
+:101DE00005C0243031F4809180008F7D8093800085
+:101DF00018C0213019F484B58F7704C0223021F443
+:101E000084B58F7D84BD0DC0263021F48091B00053
+:101E10008F7705C0273029F48091B0008F7D8093A3
+:101E2000B000E32FFF27EE58FF4FE491FF2780819A
+:101E300020E030E0892311F021E030E0C90108956D
+:101E4000482F5527CA0181569F4FFC012491CA0192
+:101E500085579F4FFC01949149585F4FFA01349187
+:101E60003323C1F1222331F1233021F4809180000A
+:101E70008F7705C0243031F4809180008F7D80936E
+:101E8000800018C0213019F484B58F7704C0223047
+:101E900021F484B58F7D84BD0DC0263021F480915E
+:101EA000B0008F7705C0273029F48091B0008F7D76
+:101EB0008093B000E32FFF27E359FF4FE491FF2702
+:101EC000662329F4808190958923808308958081F9
+:101ED000892B8083089590917C008F70907F892B4F
+:101EE00080937C0080917A00806480937A00809156
+:101EF0007A0086FDFCCF20917800809179009927A7
+:101F0000982F88273327822B932B08951F93CF93E5
+:101F1000DF93182FEB0161E00E94B60EE12FFF273F
+:101F2000E156FF4F8491833051F4809180008068A6
+:101F300080938000D0938900C093880037C084309C
+:101F400051F480918000806280938000D0938B0058
+:101F5000C0938A002BC0813029F484B5806884BD89
+:101F6000C7BD24C0823029F484B5806284BDC8BD59
+:101F70001DC0863041F48091B00080688093B0002D
+:101F8000C093B30013C0873041F48091B0008062E9
+:101F90008093B000C093B40009C0C038D10514F4D8
+:101FA00060E001C061E0812F0E94200FDF91CF919E
+:101FB0001F91089508950895CB01BA01332744274E
+:101FC00055270E94601108952AE00E94DC0F0895B1
+:101FD000AB01662777270E94E40F0895862F0E94A1
+:101FE00058110895862F0E94581108950F931F933A
+:101FF0008C016DE00E94F20F6AE0C8010E94F20FAE
+:102000001F910F9108950F931F938C010E94E40F6D
+:10201000C8010E94F60F1F910F9108950F931F930F
+:102020008C010E94EE0FC8010E94F60F1F910F91C4
+:1020300008950F931F938C010E94F20FC8010E9414
+:10204000F60F1F910F910895EF92FF920F931F9338
+:10205000CF93DF93EC017A018B0177FF0BC06DE228
+:102060000E94F20F10950095F094E094E11CF11C91
+:10207000011D111D2AE0B801A701CE010E94DC0F4D
+:10208000DF91CF911F910F91FF90EF9008950F93E3
+:102090001F938C010E942410C8010E94F60F1F910B
+:1020A0000F9108952115310521F4642F0E94F20F3C
+:1020B00008952A30310519F40E94241008950E94D1
+:1020C000DC0F08950F931F938C010E945210C801DA
+:1020D0000E94F60F1F910F910895AB01662757FDDF
+:1020E0006095762F0E94241008950F931F938C0102
+:1020F0000E946D10C8010E94F60F1F910F91089564
+:10210000CB010E94301208950F931F938C010E94FF
+:102110008010C8010E94F60F1F910F9108950E9430
+:10212000111108950E94F21008950E94E11099275C
+:102130000895CB01BA010E94A01008950895089552
+:10214000EF92FF920F931F937B018C0122E030E00E
+:1021500040E050E00E946D17205C3D4B404F5F4FC8
+:10216000CA01B901A80197010E946D1721503040A2
+:1021700040405040BB2757FDBA95A52F942F832F81
+:102180002F5F3F4F4F4F5F4F8093C50021502093EB
+:10219000C400E1ECF0E08081806180838081886010
+:1021A00080838081806880831F910F91FF90EF90E2
+:1021B0000895982F8091C00085FFFCCF9093C600B2
+:1021C0000895809180029091810280589F4F2091C4
+:1021D000820230918302821B930B60E870E00E94C0
+:1021E00038170895409182025091830280918002B5
+:1021F000909181028417950719F48FEF9FEF08954E
+:10220000FA01E857FD4F2081CA01019660E870E0AD
+:102210000E9438179093830280938202822F99271D
+:10222000089580918202909183029093810280931D
+:10223000800208951F920F920FB60F9211242F93D0
+:102240003F934F935F936F937F938F939F93AF933E
+:10225000BF93EF93FF934091C600E0918002F0910D
+:102260008102CF01019660E870E00E9438179C015E
+:1022700080918202909183022817390739F0E8573C
+:10228000FD4F40833093810220938002FF91EF91B4
+:10229000BF91AF919F918F917F916F915F914F917E
+:1022A0003F912F910F900FBE0F901F90189508959A
+:1022B000982F8091C00085FFFCCF9093C6000895B1
+:1022C0002F923F924F925F926F927F928F929F9246
+:1022D000AF92BF92CF92DF92EF92FF920F931F9334
+:1022E000CF93DF93CDB7DEB7A0970FB6F894DEBFDC
+:1022F0000FBECDBF6B017C0129013A01611571054B
+:102300008105910541F48091C00085FFFCCF80E3F9
+:102310008093C6004BC08824992454011E01089460
+:10232000211C311C8101080D191DC701B601A30133
+:1023300092010E944B17F80160830894811C911C44
+:10234000A11CB11CC701B601A30192010E944B1749
+:1023500069017A01211531054105510519F70894E4
+:1023600081089108A108B108F101E80DF91D089450
+:10237000811C911CA11CB11C14C0089481089108F7
+:10238000A108B10880818A3018F4982F905D02C0AE
+:10239000982F995C8091C00085FFFCCF9093C60078
+:1023A000319781149104A104B10439F7A0960FB6B6
+:1023B000F894DEBF0FBECDBFDF91CF911F910F917B
+:1023C000FF90EF90DF90CF90BF90AF909F908F9055
+:1023D0007F906F905F904F903F902F90089520E1F5
+:1023E00030E040E050E00E946011089528E030E0C5
+:1023F00040E050E00E946011089522E030E040E0AB
+:1024000050E00E94601108958091C00085FFFCCFCC
+:102410008AE08093C6000895EF92FF920F931F9376
+:102420007B018C0197FF0FC08091C00085FFFCCF1E
+:102430008DE28093C60010950095F094E094E11C25
+:10244000F11C011D111D2AE030E040E050E0C80100
+:10245000B7010E9460111F910F91FF90EF900895B6
+:10246000FC0107C08091C00085FFFCCF319690939E
+:10247000C60090819923B1F70895A0E0B0E0E3E4AD
+:10248000F2E10C94D017EC015B016115710519F0B4
+:10249000FB0191838083D9908D2D99270E94A217EB
+:1024A000892BC9F7FDE2DF1621F4D990CC24C3941F
+:1024B00005C08BE2D81609F4D990CC248E010150C6
+:1024C000104043E050E063EB70E0C8010E94A014AC
+:1024D000892B09F58E010E5F1F4F45E050E066EB3A
+:1024E00070E0C8010E94A014892B19F48E01095FC5
+:1024F0001F4FA114B10419F0F50111830083C0FE30
+:1025000005C060E070E080E89FEFFFC060E070E031
+:1025100080E89FE7FAC043E050E06BEB70E0C80151
+:102520000E94A014892B61F4A114B10421F0229619
+:10253000F501D183C08360E070E080EC9FE7E5C0E7
+:1025400088249924EE24FF2487014D2D40534A30DE
+:10255000A8F5F2E0CF2A8C2D99279C0128703070C5
+:1025600082FF06C0232B81F50894811C911C2CC08E
+:10257000232B19F0089481089108D801C701E2E0E3
+:10258000880F991FAA1FBB1FEA95D1F7E80EF91E05
+:102590000A1F1B1FEE0CFF1C001F111FE40EF11C75
+:1025A000011D111D88E9E81689E9F80689E908077F
+:1025B00089E1180748F0E4E0CE2A06C04E3F31F426
+:1025C000C3FC3AC0F8E0CF2AD990BFCF453311F011
+:1025D000453191F589918D3219F480E1C82A05C001
+:1025E0008B3219F021E030E003C0899122E030E025
+:1025F000482F40534A3018F420E030E007C0C21B97
+:10260000D30B1AC0ECE020383E075CF4C901880FF8
+:10261000991F880F991F280F391F220F331F240F6E
+:10262000311D499140534A3068F3C4FE03C03095D0
+:1026300021953F4F820E931EDD2492E0692E712C6E
+:102640006C207D20C1FE07C0A114B10421F02197A8
+:10265000F501D183C083C801B7010E94BA157B017F
+:102660008C01C0FE06C0672821F017FB109517F9F2
+:1026700010955701680120E030E040E050E0C801CB
+:10268000B7010E941D15882309F43DC097FE09C0BB
+:10269000C2EDD0E0909481949108939400E210E010
+:1026A00010C0CAEED0E0FACFFE01259135914591D8
+:1026B0005491C601B5010E9470165B016C01801A2D
+:1026C000910A8016910684F7159507950115110555
+:1026D00011F02497F6CF860175018C2D880F8D2D72
+:1026E000881F8F3F51F020E030E040E050E0C6010D
+:1026F000B5010E941D15882331F482E290E0909389
+:10270000090380930803C801B701EEE0CDB7DEB737
+:102710000C94EC17A0E0B0E0E0E9F3E10C94CD17E5
+:102720008C012B01EA016115710519F0FB01918300
+:102730008083209749F0CE010297839728F060E0CC
+:1027400070E080E090E0F7C0F801E1908F018E2DFD
+:1027500099270E94A217892BB9F7FDE2EF1631F4F1
+:10276000F801E1908F013324339407C0FBE2EF16A8
+:1027700019F4F801E1908F013324209719F0C0314A
+:10278000D105E1F4F0E3EF1679F4F80180818837A0
+:1027900011F0883549F4F801E1800E5F1F4FF2E037
+:1027A0003F2AC0E1D0E00AC0209741F480E3E81658
+:1027B00019F4C8E0D0E002C0CAE0D0E0C830D105CA
+:1027C00071F0C930D10524F4C230D10519F50DC01E
+:1027D000CA30D10581F0C031D105E1F415C0A12C7A
+:1027E000B12CC12CB0E1DB2E22C0A12CB12CC12C0C
+:1027F000A0E4DA2E1CC0FCECAF2EFCECBF2EFCECEF
+:10280000CF2EFCE0DF2E13C0A12CB12CC12CE8E0B0
+:10281000DE2E0DC09E01442737FD4095542F60E009
+:1028200070E080E090E80E944B1759016A0120E0B7
+:1028300030E040E050E060E03E01882477FC809486
+:10284000982C70EDF72EFE0CE9E0EF1570F48E2D4C
+:1028500081548A3118F499ECF92E06C08E2D8156D8
+:102860008A3150F589EAF82EFE0C8F2D99278C17A6
+:102870009D0714F567FD1CC0A216B306C406D50655
+:10288000B0F0CA01B901A40193010E94AD179B01E8
+:10289000AC012F0D311D411D511D2130F0E03F07CE
+:1028A000F0E04F07F0E85F0710F461E001C06FEF60
+:1028B000F801E1908F01C5CF4114510481F06623E6
+:1028C00031F001501040F2011183008308C031FE45
+:1028D0001AC002501040F2011183008314C067FF38
+:1028E00012C030FE05C020E030E040E050E804C0F7
+:1028F0002FEF3FEF4FEF5FE782E290E09093090305
+:102900008093080316C030FE08C05095409530955E
+:1029100021953F4F4F4F5F4F0CC057FF0AC082E2D7
+:1029200090E090930903809308032FEF3FEF4FEF60
+:102930005FE7CA01B901E1E1CDB7DEB70C94E91751
+:10294000FB01DC014150504088F08D9181341CF036
+:102950008B350CF4805E659161341CF06B350CF4A2
+:10296000605E861B611171F3990B0895881BFCCF83
+:102970005058BB27AA270ED075C166D130F06BD155
+:1029800020F031F49F3F11F41EF45BC10EF4E0958A
+:10299000E7FB51C1E92F77D180F3BA1762077307BC
+:1029A0008407950718F071F49EF58FC10EF4E09539
+:1029B0000B2EBA2FA02D0B01B90190010C01CA01F9
+:1029C000A0011124FF27591B99F0593F50F4503EA4
+:1029D00068F11A16F040A22F232F342F4427585F96
+:1029E000F3CF469537952795A795F0405395C9F7AE
+:1029F0007EF41F16BA0B620B730B840BBAF0915066
+:102A0000A1F0FF0FBB1F661F771F881FC2F70EC004
+:102A1000BA0F621F731F841F48F4879577956795D7
+:102A2000B795F7959E3F08F0B3CF9395880F08F0C0
+:102A30009927EE0F979587950895D9D008F481E0EE
+:102A400008950CD00FC107D140F0FED030F021F432
+:102A50005F3F19F0F0C0511139C1F3C014D198F3A0
+:102A60009923C9F35523B1F3951B550BBB27AA270F
+:102A700062177307840738F09F5F5F4F220F331F81
+:102A8000441FAA1FA9F333D00E2E3AF0E0E830D04D
+:102A900091505040E695001CCAF729D0FE2F27D050
+:102AA000660F771F881FBB1F261737074807AB071E
+:102AB000B0E809F0BB0B802DBF01FF2793585F4F93
+:102AC0002AF09E3F510568F0B6C000C15F3FECF3AD
+:102AD000983EDCF3869577956795B795F7959F5F58
+:102AE000C9F7880F911D9695879597F90895E1E0AC
+:102AF000660F771F881FBB1F621773078407BA070B
+:102B000020F0621B730B840BBA0BEE1F88F7E09565
+:102B1000089504D06894B111D9C00895BCD088F04C
+:102B20009F5790F0B92F9927B751A0F0D1F0660FB9
+:102B3000771F881F991F1AF0BA95C9F712C0B130D4
+:102B400081F0C3D0B1E00895C0C0672F782F8827E7
+:102B5000B85F39F0B93FCCF3869577956795B39513
+:102B6000D9F73EF490958095709561957F4F8F4F82
+:102B70009F4F0895E89409C097FB3EF49095809587
+:102B8000709561957F4F8F4F9F4F9923A9F0F92F33
+:102B900096E9BB279395F695879577956795B795B1
+:102BA000F111F8CFFAF4BB0F11F460FF1BC06F5F97
+:102BB0007F4F8F4F9F4F16C0882311F096E911C0A9
+:102BC000772321F09EE8872F762F05C0662371F0CA
+:102BD00096E8862F70E060E02AF09A95660F771FDE
+:102BE000881FDAF7880F9695879597F90895990FBA
+:102BF0000008550FAA0BE0E8FEEF16161706E807C7
+:102C0000F907C0F012161306E407F50798F0621BE7
+:102C1000730B840B950B39F40A2661F0232B242BBC
+:102C2000252B21F408950A2609F4A140A6958FEFDB
+:102C3000811D811D089597F99F6780E870E060E02D
+:102C400008959FEF80EC089500240A941616170645
+:102C500018060906089500240A941216130614068D
+:102C600005060895092E0394000C11F4882352F0F0
+:102C7000BB0F40F4BF2B11F460FF04C06F5F7F4FA8
+:102C80008F4F9F4F089557FD9058440F551F59F08F
+:102C90005F3F71F04795880F97FB991F61F09F3F49
+:102CA00079F087950895121613061406551FF2CF72
+:102CB0004695F1DF08C0161617061806991FF1CFC2
+:102CC00086957105610508940895E894BB276627E9
+:102CD0007727CB0197F908958ADF08F48FEF0895DD
+:102CE0000BD0C0CFB1DF28F0B6DF18F0952309F084
+:102CF000A2CFA7CF1124EACFC6DFA0F3959FD1F3CF
+:102D0000950F50E0551F629FF001729FBB27F00D99
+:102D1000B11D639FAA27F00DB11DAA1F649F6627EE
+:102D2000B00DA11D661F829F2227B00DA11D621F3D
+:102D3000739FB00DA11D621F839FA00D611D221FF7
+:102D4000749F3327A00D611D231F849F600D211DDB
+:102D5000822F762F6A2F11249F5750408AF0E1F07E
+:102D600088234AF0EE0FFF1FBB1F661F771F881FC7
+:102D700091505040A9F79E3F510570F05CCFA6CF0F
+:102D80005F3FECF3983EDCF3869577956795B795B2
+:102D9000F795E7959F5FC1F7FE2B880F911D9695DC
+:102DA000879597F9089511F40EF44BCF4AC073DF5D
+:102DB000D0F39923D9F3CEF39F57550B87FF51D00A
+:102DC00056959795B0E020F4660F771F881FBB1FBC
+:102DD0001F930F9300249001A0018001F001A0E84F
+:102DE0000E0F1F1F0A1E511D601B710B8009B50BB2
+:102DF00048F4600F711F801DB51F0E1B1F0B0A0AC0
+:102E0000510907C02E0F3F1F4A1F0E0F1F1F0A1E1A
+:102E1000511D660F771F881FBB1FA695F795E79575
+:102E2000F8F60617170708065B07211D311D411D1F
+:102E30000F911F91B901842F9158880F969587950E
+:102E400008959F3F49F0915028F4869577956795AE
+:102E5000B7959F5F80389F4F880F9695879597F914
+:102E6000089591505040660F771F881FD2F708953C
+:102E700097FB092E07260AD077FD04D049D006D04B
+:102E800000201AF4709561957F4F0895F6F790959C
+:102E900081959F4F0895A1E21A2EAA1BBB1BFD012D
+:102EA0000DC0AA1FBB1FEE1FFF1FA217B307E40729
+:102EB000F50720F0A21BB30BE40BF50B661F771F81
+:102EC000881F991F1A9469F7609570958095909561
+:102ED0009B01AC01BD01CF01089597FB092E05268A
+:102EE0000ED057FD04D0D7DF0AD0001C38F450951F
+:102EF0004095309521953F4F4F4F5F4F0895F6F71E
+:102F000090958095709561957F4F8F4F9F4F089555
+:102F1000AA1BBB1B51E107C0AA1FBB1FA617B707FF
+:102F200010F0A61BB70B881F991F5A95A9F780951B
+:102F30009095BC01CD010895EE0FFF1F0590F4910F
+:102F4000E02D0994911106C0803219F08950855006
+:102F5000D0F70895992788270895629FD001739F1D
+:102F6000F001829FE00DF11D649FE00DF11D929F25
+:102F7000F00D839FF00D749FF00D659FF00D992764
+:102F8000729FB00DE11DF91F639FB00DE11DF91F88
+:102F9000BD01CF01112408952F923F924F925F926D
+:102FA0006F927F928F929F92AF92BF92CF92DF9259
+:102FB000EF92FF920F931F93CF93DF93CDB7DEB7BE
+:102FC000CA1BDB0B0FB6F894DEBF0FBECDBF099452
+:102FD0002A88398848885F846E847D848C849B84A9
+:102FE000AA84B984C884DF80EE80FD800C811B81B7
+:102FF000AA81B981CE0FD11D0FB6F894DEBF0FBEE6
+:08300000CDBFED010895FFCFE3
+:103008006875683F204700543A004875683F204D6E
+:10301800006F6B007374617274000100490336001D
+:10302800FF006B00D100A000B800D500A6000A017F
+:1030380099003F018E0074018400A9017C00DE0123
+:10304800740013026C00480265007D025D00B20244
+:103058005600E7024E001C03460051033D0086035C
+:103068003200BB032200F00303003F800040FF0151
+:10307800014BEAFF404BEAFF400000A0430000007C
+:063088003F010101FFFF02
+:00000001FF
diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.pde new file mode 100644 index 00000000..63438124 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.pde @@ -0,0 +1,158 @@ +// Yep, this is actually -*- c++ -*- + +// Sanguino G-code Interpreter +// Arduino v1.0 by Mike Ellery - initial software (mellery@gmail.com) +// v1.1 by Zach Hoeken - cleaned up and did lots of tweaks (hoeken@gmail.com) +// v1.2 by Chris Meighan - cleanup / G2&G3 support (cmeighan@gmail.com) +// v1.3 by Zach Hoeken - added thermocouple support and multi-sample temp readings. (hoeken@gmail.com) +// Sanguino v1.4 by Adrian Bowyer - switch to the Sanguino; extensive mods... (a.bowyer@bath.ac.uk) + +#include <ctype.h> +#include <HardwareSerial.h> + +// Uncomment the next line to run stand-alone tests on the machine (also see the +// ends of this, the process_string, the extruder, and the stepper_control tabs). +//#define TEST_MACHINE + + +//our command string +#define COMMAND_SIZE 128 +char word[COMMAND_SIZE]; +char c = '?'; +byte serial_count = 0; +boolean comment = false; + +void setup() +{ + //Do startup stuff here + Serial.begin(19200); + Serial.println("start"); + + //other initialization. + init_process_string(); + init_steppers(); + init_extruder(); +} + +void loop() +{ +#ifndef TEST_MACHINE + + + //keep it hot! + extruder_manage_temperature(); + + //read in characters if we got them. + if (Serial.available()) + { + c = Serial.read(); + if(c == '\r') + c = '\n'; + // Throw away control chars except \n + if(c >= ' ' || c == '\n') + { + + //newlines are ends of commands. + if (c != '\n') + { + // Start of comment - ignore any bytes received from now on + if (c == ';') + comment = true; + + // If we're not in comment mode, add it to our array. + if (!comment) + word[serial_count++] = c; + } + + } + } + + // Data runaway? + if(serial_count >= COMMAND_SIZE) + init_process_string(); + + //if we've got a real command, do it + if (serial_count && c == '\n') + { + // Terminate string + word[serial_count] = 0; + + //process our command! + process_string(word, serial_count); + + //clear command. + init_process_string(); + + // Say we're ready for the next one + + Serial.println("ok"); + } + +#else + +// Run the parts of the machine as a test + +// Do the comms test first. It should echo +// what you type in a terminal window connected +// to the Sanguino. + +// If that works, comment out the next line to test the rest: +#define COMMS_TEST + +#ifdef COMMS_TEST + + comms_test(); + +#else + + if (Serial.available() > 0) + { + c = Serial.read(); + Serial.println(c); + } + + switch(c) + { + case 0: + break; + + case 'x': + X_motor_test(); + break; + case 'y': + Y_motor_test(); + break; + case 'z': + Z_motor_test(); + break; + case 'h': + extruder_heater_test(); + break; + case 'e': + extruder_drive_test(); + break; + case 'v': + extruder_valve_test(); + break; + case 'f': + extruder_fan_test(); + break; + + default: + Serial.println("Commands:\n"); + Serial.println(" x - X motor test"); + Serial.println(" y - Y motor test"); + Serial.println(" z - Z motor test"); + Serial.println(" h - extruder heater test"); + Serial.println(" e - extruder drive test"); + Serial.println(" v - extruder valve test"); + Serial.println(" f - extruder fan test"); + Serial.println(" s - stop current test at the end of its cycle then print this list\n\n"); + Serial.print("Command: "); + c = 0; + } + +#endif + +#endif +} diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.rom b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.rom new file mode 100755 index 00000000..f8867a2c --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/GCode_Interpreter.rom @@ -0,0 +1,780 @@ +S02B00002F686F6D652F656E7361622F776F726B73706163652F6669726D776172652F53616E6775696E6F2F98
+S11300000C9478000C94A0000C94A0000C94A00014
+S11300100C94A0000C94A0000C94A0000C94A000DC
+S11300200C94A0000C94A0000C94A0000C94A000CC
+S11300300C94A0000C94A0000C94A0000C94A000BC
+S11300400C94000E0C94A0000C941A110C94A000B3
+S11300500C94A0000C94A0000C94A0000C94A0009C
+S11300600C94A0000C94A000000024272A00002572
+S1130070282B000023262904040404040404040295
+S11300800202020202030303030303010204081031
+S113009020408001020408102001020408102000FE
+S11300A00000070002010000030406000000000035
+S11300B0000000494E46494E4954594E414ECDCC5C
+S11300C0CC3D0AD7233C17B7D13877CC2B32959542
+S11300D0E6241FB14F0A000020410000C84200403E
+S11300E01C4620BCBE4CCA1B0E5AAEC59D749F1044
+S11300F011241FBECFEFD4E0DEBFCDBF11E0A0E0DE
+S1130100B1E0E8E0F0E302C005900D92A638B10733
+S1130110D9F713E0A6E8B1E001C01D92AA30B107F7
+S1130120E1F710E0C0EFD0E004C02297FE010E9486
+S11301309E17CE3ED107C9F70E94F50D0C94031803
+S11301400C9400009093090280930802AA2797FD5B
+S1130150A095BA2FBC01CD010E94BC152DEC3CEC3E
+S11301604CE85FE30E9470160E94891570930B029D
+S113017060930A02089510920602109207020895ED
+S11301800E9470160E9489150895019739F0880F0E
+S1130190991F880F991F02970197F1F708952F92DD
+S11301A03F924F925F926F927F928F929F92AF9203
+S11301B0BF92CF92DF92EF92FF920F931F93CF9350
+S11301C0DF93CDB7DEB72C970FB6F894DEBF0FBE22
+S11301D0CDBF69877A878B879C87209032023090C5
+S11301E0330240903402509035028091360290914F
+S11301F03702A0913802B09139028D839E83AF8378
+S1130200B88780913A0290913B02A0913C02B09150
+S11302103D0289839A83AB83BC83609056027090BD
+S113022057028090580290905902A0905A02B090C0
+S11302305B02C0905C02D0905D02A6019501C401EE
+S1130240B3010E946C16E0905E02F0905F02009190
+S113025060021091610218165CF4A4019301C801B4
+S1130260B7010E946C1618165CF0C401B3010DC0EE
+S1130270A6019501C801B7010E946C1618161CF45A
+S1130280C801B70102C0C601B5010E9489155B010E
+S11302906C01A2019101C201B1010E9470167B019F
+S11302A08C012D813E814F815885CA01B9010E947C
+S11302B070169B01AC01C801B7010E94B9147B01FF
+S11302C08C0129813A814B815C81CA01B9010E9468
+S11302D070169B01AC01C801B7010E94B9140E94B9
+S11302E0D71620EC31EE44E65CE40E9470162985B2
+S11302F03A854B855C850E9421157B018C01C601E2
+S1130300B5010E94BC159B01AC01C801B7010E9454
+S113031021150E9489152C960FB6F894DEBF0FBEE6
+S1130320CDBFDF91CF911F910F91FF90EF90DF90A0
+S1130330CF90BF90AF909F908F907F906F905F9081
+S11303404F903F902F90089520E030E040E050E03F
+S113035060915E0270915F028091600290916102EF
+S11303600E946C1618163CF460E070E088E492E495
+S11303700E94CF00089560E070E088EC94E40E944D
+S1130380CF0008952F923F924F925F926F927F9287
+S11303908F929F92AF92BF92CF92DF92EF92FF9291
+S11303A00F931F93CF93DF93CDB7DEB7A0970FB60C
+S11303B0F894DEBF0FBECDBF809126029091270234
+S11303C0A0912802B09129028D8F9E8FAF8FB8A380
+S11303D080911A0290911B02A0911C02B0911D02FF
+S11303E0898F9A8FAB8FBC8F9C01AD016D8D7E8DF3
+S11303F08F8D98A10E94B8147B018C0120E030E01D
+S113040040E050E00E946C16181624F017FB10957B
+S113041017F91095E0923202F092330200933402FD
+S11304201093350280912A0290912B02A0912C0204
+S1130430B0912D028D8B9E8BAF8BB88F80911E0255
+S113044090911F02A0912002B0912102898B9A8B76
+S1130450AB8BBC8B9C01AD016D897E898F89988D96
+S11304600E94B8147B018C0120E030E040E050E0B1
+S11304700E946C16181624F017FB109517F91095A6
+S1130480E0923602F0923702009338021093390258
+S113049080912E0290912F02A0913002B0913102EE
+S11304A08D879E87AF87B88B80912202909123021B
+S11304B0A0912402B091250289879A87AB87BC87D3
+S11304C09C01AD016D857E858F8598890E94B81445
+S11304D07B018C0120E030E040E050E00E946C168B
+S11304E0181624F017FB109517F91095E0923A02AC
+S11304F0F0923B0200933C0210933D02E0907101A4
+S1130500F09072010091730110917401298D3A8D5C
+S11305104B8D5C8DC801B7010E9470160E9489152D
+S11305200E94BC151B012C0160933E0270933F0294
+S1130530809340029093410260907501709076011F
+S1130540809077019090780129893A894B895C8958
+S1130550C401B3010E9470160E9489150E94BC1543
+S11305606D837E838F8398876093420270934302E6
+S11305708093440290934502A0907901B0907A014F
+S1130580C0907B01D0907C0129853A854B855C85A0
+S1130590C601B5010E9470160E9489150E94BC15FF
+S11305A069837A838B839C836093460270934702AA
+S11305B080934802909349022D8D3E8D4F8D58A112
+S11305C0C801B7010E9470160E9489150E94BC15CB
+S11305D07B018C0160934A0270934B0280934C021E
+S11305E090934D022D893E894F89588DC401B301E2
+S11305F00E9470160E9489150E94BC153B014C0193
+S113060060934E0270934F02809350029093510274
+S11306102D853E854F855889C601B5010E94701607
+S11306200E9489150E94BC155B016C016093520203
+S1130630709353028093540290935502A201910146
+S1130640C801B7010E94B8147B018C0120E030E09E
+S113065040E050E00E946C16181624F017FB109529
+S113066017F91095E0925602F0925702009358023F
+S1130670109359022D813E814F815885C401B301E5
+S11306800E94B8147B018C0120E030E040E050E08F
+S11306900E946C16181624F017FB109517F9109584
+S11306A0E0925A02F0925B0200935C0210935D02A6
+S11306B029813A814B815C81C601B5010E94B8143D
+S11306C07B018C0120E030E040E050E00E946C1699
+S11306D0181624F017FB109517F91095E0925E0296
+S11306E0F0925F02009360021093610210E0298D82
+S11306F03A8D4B8D5C8D6D8D7E8D8F8D98A10E9472
+S11307006C1688230CF011E0109381011092820181
+S113071029893A894B895C896D897E898F89988D6D
+S11307200E946C1688231CF081E080938201109251
+S1130730830129853A854B855C856D857E858F850A
+S113074098890E946C1688231CF081E080938301B1
+S1130750612F83E00E94200F6091820187E00E9454
+S1130760200F6091830182E10E94200FA0960FB6B2
+S1130770F894DEBF0FBECDBFDF91CF911F910F91D3
+S1130780FF90EF90DF90CF90BF90AF909F908F90AD
+S11307907F906F905F904F903F902F900895EF92CD
+S11307A0FF920F931F9360931A0270931B0280931E
+S11307B01C0290931D0220931E0230931F0240934B
+S11307C0200250932102E0922202F092230200932D
+S11307D02402109325020E94C2011F910F91FF90E1
+S11307E0EF900895EF92FF920F931F936093260268
+S11307F070932702809328029093290220932A025F
+S113080030932B0240932C0250932D02E0922E023F
+S1130810F0922F0200933002109331020E94C20121
+S11308201F910F91FF90EF90089580936F01682FAF
+S11308308CE00E94200F08951F93182F0E94D40E5D
+S1130840892B11F420E007C0812F0E94D40E20E0F0
+S1130850892B09F021E0822F99271F910895CF92C7
+S1130860EF92FF920F931F93E216F3060407150706
+S113087019F480E090E00AC00E941C04882321F04F
+S113088080E090E0CC2011F081E090E01F910F9186
+S1130890FF90EF90CF9008951F93182F61E00E946E
+S11308A0200F85E090E00E945F0E60E0812F0E949F
+S11308B0200F1F91089580E090E0A0E0B0E08093C5
+S11308C01A0290931B02A0931C02B0931D02809302
+S11308D01E0290931F02A0932002B09321028093E2
+S11308E0220290932302A0932402B09325028093C2
+S11308F0260290932702A0932802B09329028093A2
+S11309002A0290932B02A0932C02B0932D02809381
+S11309102E0290932F02A0933002B093310261E033
+S113092082E00E94B60E61E083E00E94B60E61E0B0
+S11309308AE00E94B60E61E087E00E94B60E61E094
+S113094083E10E94B60E61E082E10E94B60E60E08F
+S113095084E00E94B60E60E088E00E94B60E60E07B
+S113096081E10E94B60E0E94C2010895AF92BF9227
+S1130970CF92DF92EF92FF920F931F93CF93DF9367
+S1130980CDB7DEB722970FB6F894DEBF0FBECDBF4A
+S11309908C017B016A0159014AE050E0BE016F5F9E
+S11309A07F4F0E948A1329813A81201B310B121632
+S11309B013065CF4F70171836083F60180819181F1
+S11309C08A299B299183808303C0F70111821082B5
+S11309D0C90122960FB6F894DEBF0FBECDBFDF91DA
+S11309E0CF911F910F91FF90EF90DF90CF90BF9028
+S11309F0AF900895AF92BF92CF92DF92EF92FF92A1
+S1130A000F931F93CF93DF93CDB7DEB722970FB623
+S1130A10F894DEBF0FBECDBF8C017B016A01590182
+S1130A20BE016F5F7F4F0E943D1229813A81201BD6
+S1130A30310B121613066CF4F70160837183828301
+S1130A409383F601808191818A299B2991838083F4
+S1130A5009C080E090E0A0E0B0E0F70180839183DA
+S1130A60A283B383C90122960FB6F894DEBF0FBEEA
+S1130A70CDBFDF91CF911F910F91FF90EF90DF9049
+S1130A80CF90BF90AF9008952F923F924F925F9274
+S1130A906F927F928F929F92AF92BF92CF92DF928A
+S1130AA0EF92FF920F931F93CF93DF93CDB7DEB7EF
+S1130AB062970FB6F894DEBF0FBECDBF9A8B898BB9
+S1130AC06B015A834983FC0111821082EE24FF24B6
+S1130AD03696FC83EB838B010F5F1F4F82969E83B8
+S1130AE08D83E989FA893E96F887EF8389899A8903
+S1130AF042969A878987E989FA893A96FC87EB872F
+S1130B0089899A898A969E878D87E989FA89B69612
+S1130B10F88BEF8776E1272E312C89899A89280E64
+S1130B20391E6AE1462E512C480E591E54E0652E9A
+S1130B30712C680E791E4EE1842E912C880E991E1C
+S1130B4032E0A32EB12CA80EB91E89C0F601EE0D19
+S1130B50FF1DE081E035F1F1E1358CF4E93409F46D
+S1130B6055C0EA3434F4E63409F45CC0E734B9F42B
+S1130B7019C0EA3409F450C0ED3489F419C0E335DE
+S1130B8011F1E43534F4E13509F459C0E23539F4AE
+S1130B904FC0E93569F1EA3591F1E83511F180E0AA
+S1130BA090E058C021E030E049895A89B50105C078
+S1130BB022E030E049895A89B301C8018E0D9F1D96
+S1130BC00E94B60447C020E034E049895A896D8107
+S1130BD07E813BC024E030E049895A896B817C8165
+S1130BE034C028E030E049895A896B857C852DC062
+S1130BF020E130E049895A896F81788526C020E256
+S1130C0030E049895A8969857A851FC020E430E03B
+S1130C1049895A89B10119C020E830E049895A89C3
+S1130C20B20113C020E032E049895A89B4010DC0F1
+S1130C3020E030E149895A896F85788906C020E02F
+S1130C4038E049895A896D857E85C8018E0D9F1DBE
+S1130C500E94FA040894E11CF11CE80EF91EE981D3
+S1130C60FA81EE16FF060CF471CF62960FB6F89473
+S1130C70DEBF0FBECDBFDF91CF911F910F91FF90CB
+S1130C80EF90DF90CF90BF90AF909F908F907F9028
+S1130C906F905F904F903F902F9008959927BC01DB
+S1130CA085E00E94860F08958FEE9EEF0E94A200B9
+S1130CB061E08CE00E94B60E61E08BE00E94B60E0B
+S1130CC061E086E00E94B60E61E085E00E94B60E07
+S1130CD061E080E10E94B60E61E08FE00E94B60EF2
+S1130CE061E08CE00E94200F60E070E085E00E94EB
+S1130CF0860F60E070E086E00E94860F60E070E09E
+S1130D008BE00E94860F60E080E10E94200F60E08B
+S1130D108FE00E94200F08950F931F93CF93DF93CA
+S1130D20082FC0E0D0E010E0802F0E946B0FC80FA6
+S1130D30D91F1F5F1330C1F7CE0163E070E00E943A
+S1130D403817CB01DF91CF911F910F91089580E067
+S1130D500E948C06AA2797FDA095BA2FBC01CD014D
+S1130D600E94BC1520E030E040EA50E40E94701676
+S1130D7020E030E048EC52E40E94701620E030E0BD
+S1130D8040E85AE30E9470160E948915DC01CB01E9
+S1130D9008950E94A70608950E94C9069C018091A7
+S1130DA0080290910902281739071CF460916E011A
+S1130DB00BC080910A0290910B022817390714F096
+S1130DC060E002C060916D0180910C02861731F0E1
+S1130DD060930C02772786E00E94860F08953F9265
+S1130DE04F925F926F927F928F929F92AF92BF9237
+S1130DF0CF92DF92EF92FF920F931F93CF93DF93E3
+S1130E00CDB7DEB728970FB6F894DEBF0FBECDBFBF
+S1130E106D837E838F839887A0905602B09057028B
+S1130E20C0905802D0905902E0905A02F0905B02B0
+S1130E3000915C0210915D02A8019701C601B50101
+S1130E400E946C1618161CF4C601B50102C0C80134
+S1130E50B7010E94891560936A0270936B028093B4
+S1130E606C0290936D02A0905E02B0905F02C090FD
+S1130E706002D09061020E94BC157B018C019B0131
+S1130E80AC01C601B5010E946C1618161CF4C6010B
+S1130E90B50102C0C801B7010E94891560936A02B6
+S1130EA070936B0280936C0290936D0222E030E0A9
+S1130EB040E050E00E946D17442455243201421A48
+S1130EC0530A640A750A2D813E814F8158852F3F4C
+S1130ED08FE3380780E0480780E058076CF0CA01C8
+S1130EE0B90128EE33E040E050E00E946D173093E2
+S1130EF07E0220937D0204C010927E0210927D0235
+S1130F005301420149825A826B827C8260914A0277
+S1130F1070914B0280914C0290914D020E94891570
+S1130F207B018C0160913E0270913F0280914002EE
+S1130F30909141020E9489159B01AC01C0908101EE
+S1130F4069E084E00E942F04382E60914E02709173
+S1130F504F0280915002909151020E9489157B01A9
+S1130F608C016091420270914302809144029091FD
+S1130F7045020E9489159B01AC01C09082016DE07D
+S1130F8088E00E942F04D82E60915202709153027F
+S1130F9080915402909155020E9489157B018C0125
+S1130FA060914602709147028091480290914902F3
+S1130FB00E9489159B01AC01C090830160E181E12D
+S1130FC00E942F04182F332009F44FC0C301B2012B
+S1130FD00E94BC152091560230915702409158024C
+S1130FE0509159020E94B9140E9489152B013C01A9
+S1130FF01616170618061906C4F582E00E944C045A
+S113100080916A0290916B02A0916C02B0916D0282
+S1131010481A590A6A0A7B0A80918101882379F067
+S113102020E030E040E85FE360913E0270913F02CF
+S113103080914002909141020E94B9140EC020E0B8
+S113104030E040E85FE360913E0270913F0280919E
+S11310504002909141020E94B81460933E02709342
+S11310603F028093400290934102DD2009F45CC06A
+S113107069817A818B819C810E94BC1520915A02DE
+S113108030915B0240915C0250915D020E94B91460
+S11310900E94891569837A838B839C8316161706AD
+S11310A0180619060CF040C08AE00E944C04809196
+S11310B06A0290916B02A0916C02B0916D02298139
+S11310C03A814B815C81281B390B4A0B5B0B2983CA
+S11310D03A834B835C8380918201882379F020E0FA
+S11310E030E040E85FE360914202709143028091F6
+S11310F04402909145020E94B9140EC020E030E0F1
+S113110040E85FE36091420270914302809144029F
+S1131110909145020E94B814609342027093430276
+S11311208093440290934502112309F44FC0C501F2
+S1131130B4010E94BC1520915E0230915F0240917F
+S11311406002509161020E94B9140E9489154B01FA
+S11311505C011616170618061906C4F583E10E94E9
+S11311604C0480916A0290916B02A0916C02B09140
+S11311706D02881A990AAA0ABB0A809183018823FE
+S113118079F020E030E040E85FE36091460270913E
+S1131190470280914802909149020E94B9140EC0FE
+S11311A020E030E040E85FE360914602709147023E
+S11311B080914802909149020E94B81460934602BB
+S11311C07093470280934802909349020E94CC0690
+S11311D060917D0270917E02161617063CF48827F2
+S11311E077FD8095982F0E943D0E04C08D819E81CD
+S11311F00E94C500332009F089CEDD2009F086CE97
+S1131200112309F083CE8091260290912702A091A8
+S11312102802B091290280931A0290931B02A09392
+S11312201C02B0931D0280912A0290912B02A0917E
+S11312302C02B0912D0280931E0290931F02A09362
+S11312402002B093210280912E0290912F02A0914E
+S11312503002B09131028093220290932302A09332
+S11312602402B09325020E94C20128960FB6F89476
+S1131270DEBF0FBECDBFDF91CF911F910F91FF90C5
+S1131280EF90DF90CF90BF90AF909F908F907F9022
+S11312906F905F904F903F90089508C00E94CC06D5
+S11312A068EE73E080E090E00E943D0E0E94C90663
+S11312B0209108023091090225503040821793078B
+S11312C06CF308951F93182F882311F00E944D0981
+S11312D0612F77278BE00E94860F1F910895DF927C
+S11312E0EF92FF920F931F93D82E7B010E944D091A
+S11312F0D09219026D2D80E10E94200F61E08FE0F1
+S11313000E94200F0027F7FC0095102FC801B70199
+S11313100E943D0E60E08FE00E94200F60E080E1BB
+S11313200E94200F1F910F91FF90EF90DF9008957E
+S11313302F923F924F925F926F927F928F929F92E1
+S1131340AF92BF92CF92DF92EF92FF920F931F93CF
+S1131350CF93DF93CDB7DEB7C354D0400FB6F89424
+S1131360DEBF0FBECDBFFC01AB0180818F3209F41B
+S113137068C3BF01CE0101960E94440529813A81C8
+S1131380C90183709070892B71F42115310559F0CE
+S1131390809184019091850197FD05C09C838B8386
+S11313A021603A832983E980FA80E0FEA5C20B819B
+S11313B01C811093850100938401A0902202B090B7
+S11313C02302C0902402D090250280911E029091A5
+S11313D01F02A0912002B09121028FA798ABA9AB64
+S11313E0BAAB80911A0290911B02A0911C02B09199
+S11313F01D028BAB9CABADABBEAB90917001249640
+S11314009FAF2497C701887090702496AFAD24973E
+S1131410AA2329F1892B29F48BA99CA9ADA9BEA9DA
+S113142004C08B859C85AD85BE858FAB98AFA9AF75
+S1131430BAAFE4FC05C08FA598A9A9A9BAA904C0AC
+S11314408F859889A989BA898BAF9CAFADAFBEAFA0
+S1131450E5FE44C02B883C884D885E8841C0892BBA
+S113146049F48BA99CA9ADA9BEA98FAB98AFA9AF2C
+S1131470BAAF0EC02B853C854D855E856BA97CA9D2
+S11314808DA99EA90E94B9146FAB78AF89AF9AAFAA
+S1131490E4FC09C08FA598A9A9A9BAA98BAF9CAFF0
+S11314A0ADAFBEAF0EC02F85388949895A896FA563
+S11314B078A989A99AA90E94B9146BAF7CAF8DAFA2
+S11314C09EAFE5FE0BC02B893C894D895E89C60120
+S11314D0B5010E94B9141B012C0102C0150126019B
+S11314E0F1FE0CC08F8D98A1A9A1BAA180936202CC
+S11314F090936302A0936402B09365020C311105CA
+S113150009F4C6C00D311105ACF40430110509F419
+S113151058C0053011052CF40230110508F0DAC169
+S113152022C00431110509F45FC00531110509F029
+S1131530D1C17FC0043511054CF4013511050CF0FF
+S1131540CDC00E31110509F0C5C1B7C00B35110569
+S113155009F4B0C10C35110509F4AFC10A35110500
+S113156009F0B8C1A3C1820171012BAD3CAD4DADF1
+S11315705EAD6FA978AD89AD9AAD0E94F2038B81FF
+S11315809C81019759F46091620270916302809189
+S11315906402909165020E94CF0002C00E94A401DF
+S11315A06093660270936702809368029093690265
+S11315B0609166027091670280916802909169025D
+S11315C079C020E030E040E05FE36F817885898571
+S11315D09A850E94B9140E948915882777FD809501
+S11315E0982F0E943D0E88C188EF91E2ABE4B3E4EA
+S11315F08093710190937201A0937301B09374016D
+S11316008093750190937601A0937701B09378014C
+S113161080E090E0AEEFB5E48093790190937A0195
+S1131620A0937B01B0937C0180E792E4A1EABCE340
+S113163024C08BE49AEEAFEFB0E4809371019093F1
+S11316407201A0937301B093740180937501909318
+S11316507601A0937701B093780180E090E0A0EA4E
+S1131660B3E48093790190937A01A0937B01B093C2
+S11316707C0180E090E0A0E0BFE380937D01909343
+S11316807E01A0937F01B09380010E94C20134C106
+S11316900F2EF0E0EF2EF0E0FF2EF0E00F2FF0E041
+S11316A01F2FF02DA8019701C801B7010E94F20372
+S11316B00E94A4010E94EF061FC1820171012BAD9B
+S11316C03CAD4DAD5EAD6FA978AD89AD9AAD0E94CC
+S11316D0F2030E94A4010E94EF06DACF6FA078A45F
+S11316E089A49AA424969FAD2497992341F4A60132
+S11316F09501C401B3010E94B9143B014C01A4013A
+S11317009301C601B5010E941D15882384F4840148
+S113171073012FA538A949A95AA96BA97CA98DA938
+S11317209EA90E94F2030E94A4010E94EF06E09089
+S11317302202F090230200912402109125022BAD85
+S11317403CAD4DAD5EAD6FA978AD89AD9AAD0E944B
+S1131750F2030E94A4010E94EF068B819C818335D1
+S1131760910559F48BA59CA5ADA5BEA523968CAF78
+S11317709DAFAEAFBFAF23970CC0A2019101C401CE
+S1131780B3010E94B81423966CAF7DAF8EAF9FAFA8
+S1131790239764015301860175012BAD3CAD4DAD1A
+S11317A05EAD6FA978AD89AD9AAD0E94F2030E9437
+S11317B0A4010E94EF0623962CAD3DAD4EAD5FAD66
+S11317C02397C601B5010E94B8145B016C01A20104
+S11317D091010E941D15882314F4620151018601B0
+S11317E075012BAD3CAD4DAD5EAD6FA978AD89AD46
+S11317F09AAD0E94F203E0906202F09063020091BD
+S113180064021091650220E030E040E050E0C8013D
+S1131810B7010E946C1618162CF4C801B7010E9477
+S1131820CF0002C00E94A401609366027093670215
+S113183080936802909369026091660270916702D6
+S113184080916802909169020E94EF068B819C81CD
+S11318508235910591F420E030E04AE754E46F8149
+S1131860788589859A850E9470160E948915882733
+S113187077FD8095982F0E943D0E840173012BAD56
+S11318803CAD4DAD5EAD6FA978AD89AD9AAD0E940A
+S1131890F2030E94A4010E94EF06A2019101C60175
+S11318A0B5010E946C1618163CF575CF81E0809343
+S11318B0700122C0109270011FC0820171012BAD12
+S11318C03CAD4DAD5EAD6FA978AD89AD9AAD0E94CA
+S11318D0CF0312C060E071E08FE792E00E948010B5
+S11318E04B815C81662757FD6095762F2AE030E0B6
+S11318F08FE792E00E94621029813A8121FFA1C002
+S11319008D819E818936910509F44AC08A369105F4
+S1131910B4F48636910569F18736910544F400974D
+S113192009F48FC08536910509F079C020C0873647
+S1131930910539F18836910509F071C024C08C36BF
+S1131940910509F441C08D36910544F48A36910518
+S1131950A9F18B36910509F062C032C08E3791052A
+S113196009F43FC08F37910509F059C048C081E0A0
+S113197001C080E00E94150480916B010E946209FD
+S113198060C080E0FBCF32FF5CC06BA17CA18DA165
+S11319909EA10E948915DC01CB010E94A20051C0C6
+S11319A067E071E08FE792E00E9480100E94C90610
+S11319B0BC018FE792E00E94751043C08FEF01C015
+S11319C080E00E944E063DC032FF3BC06BA17CA16B
+S11319D08DA19EA10E94891570936C0160936B0187
+S11319E030C020E030E040E05FE36F817885898596
+S11319F09A850E94B9140E94891581E00DC020E0E7
+S1131A0030E040E05FE36F81788589859A850E94A4
+S1131A10B9140E94891580E00E946F0912C06AE01F
+S1131A2071E08FE792E00E9480104D815E8166270D
+S1131A3057FD6095762F2AE030E08FE792E00E9410
+S1131A406210CD5BDF4F0FB6F894DEBF0FBECDBF83
+S1131A50DF91CF911F910F91FF90EF90DF90CF9086
+S1131A60BF90AF909F908F907F906F905F904F90BA
+S1131A703F902F9008950F931F938FEF0E948C0631
+S1131A80AC01EEE1F1E0A1E0B0E0608171814617C4
+S1131A9057071CF5AA0FBB1FAA0FBB1FFD01EA5E67
+S1131AA0FE4F0281138120813181421B530BA65EBC
+S1131AB0BE4FFD0182819381801B910B621B730BCE
+S1131AC09C01429FC001439F900D529F900D112491
+S1131AD00E943817600F711F10C08A2F8F5F1196F4
+S1131AE03496A431B10589F6843119F060E070E0D0
+S1131AF00BC060916801709169016F3F710521F01D
+S1131B001CF06FEF70E004C077FF02C060E070E08B
+S1131B10CB011F910F9108950E94CC068FE792E0AC
+S1131B200E949510882311F18FE792E00E94921091
+S1131B3080936A018D3019F48AE080936A01909150
+S1131B406A0190329CF09B3319F481E08093070280
+S1131B5080910702882351F480910602E82FFF2721
+S1131B60EA57FE4F90838F5F8093060280910602AE
+S1131B7087FF04C0109206021092070260910602C9
+S1131B806623B9F080916A018A3099F47727FB01C2
+S1131B90EA57FE4F108286E891E00E94980910925D
+S1131BA006021092070261E171E08FE792E00E9461
+S1131BB0841008950F931F930FE712E040E05BE455
+S1131BC060E070E0C8010E94991064E171E0C8010E
+S1131BD00E94841010920602109207020E945B0475
+S1131BE00E9454061F910F910895CFEFD4E0DEBFF9
+S1131BF0CDBF0E946C0E0E94DA0D0E948C0DFDCFA9
+S1131C001F920F920FB60F9211248F939F93AF934D
+S1131C10BF938091840290918502A0918602B09135
+S1131C2087020196A11DB11D8093840290938502C1
+S1131C30A0938602B0938702BF91AF919F918F9139
+S1131C400F900FBE0F901F901895609184027091B1
+S1131C508502809186029091870227E0660F771FA4
+S1131C60881F991F2A95D1F72DE730E040E050E016
+S1131C700E944B17CA01B9010895AF92BF92CF9247
+S1131C80DF92EF92FF920F931F935B016C010E940E
+S1131C90250E7B018C010E94250E6E197F09800B95
+S1131CA0910B6A157B058C059D05A8F31F910F9177
+S1131CB0FF90EF90DF90CF90BF90AF900895019781
+S1131CC051F0880F991F880F991F02972FB7F89426
+S1131CD00197F1F72FBF089578941092840210921F
+S1131CE08502109286021092870284B5826084BDB8
+S1131CF084B5816084BD85B5826085BD85B581600C
+S1131D0085BDEEE6F0E0808181608083E1E8F0E06B
+S1131D10808182608083808181608083E0E8F0E05C
+S1131D20808181608083E1EBF0E080818460808346
+S1131D30E0EBF0E0808181608083ECE7F0E080817B
+S1131D408F778083808180648083EAE7F0E08081FC
+S1131D5084608083808182608083808181608083CD
+S1131D608081806880831092C1000895282F3327D2
+S1131D70C90185579F4FFC01949129583F4FF901A0
+S1131D808491882381F0E82FFF27E859FF4FE491DD
+S1131D90FF27662329F48081909589238083089501
+S1131DA08081892B80830895482F5527CA01815645
+S1131DB09F4FFC012491CA0185579F4FFC019491C8
+S1131DC049585F4FFA013491332319F480E090E0CD
+S1131DD00895222331F1233021F4809180008F77FC
+S1131DE005C0243031F4809180008F7D8093800081
+S1131DF018C0213019F484B58F7704C0223021F43F
+S1131E0084B58F7D84BD0DC0263021F48091B0004F
+S1131E108F7705C0273029F48091B0008F7D80939F
+S1131E20B000E32FFF27EE58FF4FE491FF27808196
+S1131E3020E030E0892311F021E030E0C901089569
+S1131E40482F5527CA0181569F4FFC012491CA018E
+S1131E5085579F4FFC01949149585F4FFA01349183
+S1131E603323C1F1222331F1233021F48091800006
+S1131E708F7705C0243031F4809180008F7D80936A
+S1131E80800018C0213019F484B58F7704C0223043
+S1131E9021F484B58F7D84BD0DC0263021F480915A
+S1131EA0B0008F7705C0273029F48091B0008F7D72
+S1131EB08093B000E32FFF27E359FF4FE491FF27FE
+S1131EC0662329F4808190958923808308958081F5
+S1131ED0892B8083089590917C008F70907F892B4B
+S1131EE080937C0080917A00806480937A00809152
+S1131EF07A0086FDFCCF20917800809179009927A3
+S1131F00982F88273327822B932B08951F93CF93E1
+S1131F10DF93182FEB0161E00E94B60EE12FFF273B
+S1131F20E156FF4F8491833051F4809180008068A2
+S1131F3080938000D0938900C093880037C0843098
+S1131F4051F480918000806280938000D0938B0054
+S1131F50C0938A002BC0813029F484B5806884BD85
+S1131F60C7BD24C0823029F484B5806284BDC8BD55
+S1131F701DC0863041F48091B00080688093B00029
+S1131F80C093B30013C0873041F48091B0008062E5
+S1131F908093B000C093B40009C0C038D10514F4D4
+S1131FA060E001C061E0812F0E94200FDF91CF919A
+S1131FB01F91089508950895CB01BA01332744274A
+S1131FC055270E94601108952AE00E94DC0F0895AD
+S1131FD0AB01662777270E94E40F0895862F0E949D
+S1131FE058110895862F0E94581108950F931F9336
+S1131FF08C016DE00E94F20F6AE0C8010E94F20FAA
+S11320001F910F9108950F931F938C010E94E40F69
+S1132010C8010E94F60F1F910F9108950F931F930B
+S11320208C010E94EE0FC8010E94F60F1F910F91C0
+S113203008950F931F938C010E94F20FC8010E9410
+S1132040F60F1F910F910895EF92FF920F931F9334
+S1132050CF93DF93EC017A018B0177FF0BC06DE224
+S11320600E94F20F10950095F094E094E11CF11C8D
+S1132070011D111D2AE0B801A701CE010E94DC0F49
+S1132080DF91CF911F910F91FF90EF9008950F93DF
+S11320901F938C010E942410C8010E94F60F1F9107
+S11320A00F9108952115310521F4642F0E94F20F38
+S11320B008952A30310519F40E94241008950E94CD
+S11320C0DC0F08950F931F938C010E945210C801D6
+S11320D00E94F60F1F910F910895AB01662757FDDB
+S11320E06095762F0E94241008950F931F938C01FE
+S11320F00E946D10C8010E94F60F1F910F91089560
+S1132100CB010E94301208950F931F938C010E94FB
+S11321108010C8010E94F60F1F910F9108950E942C
+S1132120111108950E94F21008950E94E110992758
+S11321300895CB01BA010E94A0100895089508954E
+S1132140EF92FF920F931F937B018C0122E030E00A
+S113215040E050E00E946D17205C3D4B404F5F4FC4
+S1132160CA01B901A80197010E946D17215030409E
+S113217040405040BB2757FDBA95A52F942F832F7D
+S11321802F5F3F4F4F4F5F4F8093C50021502093E7
+S1132190C400E1ECF0E0808180618083808188600C
+S11321A080838081806880831F910F91FF90EF90DE
+S11321B00895982F8091C00085FFFCCF9093C600AE
+S11321C00895809180029091810280589F4F2091C0
+S11321D0820230918302821B930B60E870E00E94BC
+S11321E038170895409182025091830280918002B1
+S11321F0909181028417950719F48FEF9FEF08954A
+S1132200FA01E857FD4F2081CA01019660E870E0A9
+S11322100E9438179093830280938202822F992719
+S11322200895809182029091830290938102809319
+S1132230800208951F920F920FB60F9211242F93CC
+S11322403F934F935F936F937F938F939F93AF933A
+S1132250BF93EF93FF934091C600E0918002F09109
+S11322608102CF01019660E870E00E9438179C015A
+S113227080918202909183022817390739F0E85738
+S1132280FD4F40833093810220938002FF91EF91B0
+S1132290BF91AF919F918F917F916F915F914F917A
+S11322A03F912F910F900FBE0F901F901895089596
+S11322B0982F8091C00085FFFCCF9093C6000895AD
+S11322C02F923F924F925F926F927F928F929F9242
+S11322D0AF92BF92CF92DF92EF92FF920F931F9330
+S11322E0CF93DF93CDB7DEB7A0970FB6F894DEBFD8
+S11322F00FBECDBF6B017C0129013A016115710547
+S11323008105910541F48091C00085FFFCCF80E3F5
+S11323108093C6004BC08824992454011E0108945C
+S1132320211C311C8101080D191DC701B601A3012F
+S113233092010E944B17F80160830894811C911C40
+S1132340A11CB11CC701B601A30192010E944B1745
+S113235069017A01211531054105510519F70894E0
+S113236081089108A108B108F101E80DF91D08944C
+S1132370811C911CA11CB11C14C0089481089108F3
+S1132380A108B10880818A3018F4982F905D02C0AA
+S1132390982F995C8091C00085FFFCCF9093C60074
+S11323A0319781149104A104B10439F7A0960FB6B2
+S11323B0F894DEBF0FBECDBFDF91CF911F910F9177
+S11323C0FF90EF90DF90CF90BF90AF909F908F9051
+S11323D07F906F905F904F903F902F90089520E1F1
+S11323E030E040E050E00E946011089528E030E0C1
+S11323F040E050E00E946011089522E030E040E0A7
+S113240050E00E94601108958091C00085FFFCCFC8
+S11324108AE08093C6000895EF92FF920F931F9372
+S11324207B018C0197FF0FC08091C00085FFFCCF1A
+S11324308DE28093C60010950095F094E094E11C21
+S1132440F11C011D111D2AE030E040E050E0C801FC
+S1132450B7010E9460111F910F91FF90EF900895B2
+S1132460FC0107C08091C00085FFFCCF319690939A
+S1132470C60090819923B1F70895A0E0B0E0E3E4A9
+S1132480F2E10C94D017EC015B016115710519F0B0
+S1132490FB0191838083D9908D2D99270E94A217E7
+S11324A0892BC9F7FDE2DF1621F4D990CC24C3941B
+S11324B005C08BE2D81609F4D990CC248E010150C2
+S11324C0104043E050E063EB70E0C8010E94A014A8
+S11324D0892B09F58E010E5F1F4F45E050E066EB36
+S11324E070E0C8010E94A014892B19F48E01095FC1
+S11324F01F4FA114B10419F0F50111830083C0FE2C
+S113250005C060E070E080E89FEFFFC060E070E02D
+S113251080E89FE7FAC043E050E06BEB70E0C8014D
+S11325200E94A014892B61F4A114B10421F0229615
+S1132530F501D183C08360E070E080EC9FE7E5C0E3
+S113254088249924EE24FF2487014D2D40534A30DA
+S1132550A8F5F2E0CF2A8C2D99279C0128703070C1
+S113256082FF06C0232B81F50894811C911C2CC08A
+S1132570232B19F0089481089108D801C701E2E0DF
+S1132580880F991FAA1FBB1FEA95D1F7E80EF91E01
+S11325900A1F1B1FEE0CFF1C001F111FE40EF11C71
+S11325A0011D111D88E9E81689E9F80689E908077B
+S11325B089E1180748F0E4E0CE2A06C04E3F31F422
+S11325C0C3FC3AC0F8E0CF2AD990BFCF453311F00D
+S11325D0453191F589918D3219F480E1C82A05C0FD
+S11325E08B3219F021E030E003C0899122E030E021
+S11325F0482F40534A3018F420E030E007C0C21B93
+S1132600D30B1AC0ECE020383E075CF4C901880FF4
+S1132610991F880F991F280F391F220F331F240F6A
+S1132620311D499140534A3068F3C4FE03C03095CC
+S113263021953F4F820E931EDD2492E0692E712C6A
+S11326406C207D20C1FE07C0A114B10421F02197A4
+S1132650F501D183C083C801B7010E94BA157B017B
+S11326608C01C0FE06C0672821F017FB109517F9EE
+S113267010955701680120E030E040E050E0C801C7
+S1132680B7010E941D15882309F43DC097FE09C0B7
+S1132690C2EDD0E0909481949108939400E210E00C
+S11326A010C0CAEED0E0FACFFE01259135914591D4
+S11326B05491C601B5010E9470165B016C01801A29
+S11326C0910A8016910684F7159507950115110551
+S11326D011F02497F6CF860175018C2D880F8D2D6E
+S11326E0881F8F3F51F020E030E040E050E0C60109
+S11326F0B5010E941D15882331F482E290E0909385
+S1132700090380930803C801B701EEE0CDB7DEB733
+S11327100C94EC17A0E0B0E0E0E9F3E10C94CD17E1
+S11327208C012B01EA016115710519F0FB019183FC
+S11327308083209749F0CE010297839728F060E0C8
+S113274070E080E090E0F7C0F801E1908F018E2DF9
+S113275099270E94A217892BB9F7FDE2EF1631F4ED
+S1132760F801E1908F013324339407C0FBE2EF16A4
+S113277019F4F801E1908F013324209719F0C03146
+S1132780D105E1F4F0E3EF1679F4F801808188379C
+S113279011F0883549F4F801E1800E5F1F4FF2E033
+S11327A03F2AC0E1D0E00AC0209741F480E3E81654
+S11327B019F4C8E0D0E002C0CAE0D0E0C830D105C6
+S11327C071F0C930D10524F4C230D10519F50DC01A
+S11327D0CA30D10581F0C031D105E1F415C0A12C76
+S11327E0B12CC12CB0E1DB2E22C0A12CB12CC12C08
+S11327F0A0E4DA2E1CC0FCECAF2EFCECBF2EFCECEB
+S1132800CF2EFCE0DF2E13C0A12CB12CC12CE8E0AC
+S1132810DE2E0DC09E01442737FD4095542F60E005
+S113282070E080E090E80E944B1759016A0120E0B3
+S113283030E040E050E060E03E01882477FC809482
+S1132840982C70EDF72EFE0CE9E0EF1570F48E2D48
+S113285081548A3118F499ECF92E06C08E2D8156D4
+S11328608A3150F589EAF82EFE0C8F2D99278C17A2
+S11328709D0714F567FD1CC0A216B306C406D50651
+S1132880B0F0CA01B901A40193010E94AD179B01E4
+S1132890AC012F0D311D411D511D2130F0E03F07CA
+S11328A0F0E04F07F0E85F0710F461E001C06FEF5C
+S11328B0F801E1908F01C5CF4114510481F06623E2
+S11328C031F001501040F2011183008308C031FE41
+S11328D01AC002501040F2011183008314C067FF34
+S11328E012C030FE05C020E030E040E050E804C0F3
+S11328F02FEF3FEF4FEF5FE782E290E09093090301
+S11329008093080316C030FE08C05095409530955A
+S113291021953F4F4F4F5F4F0CC057FF0AC082E2D3
+S113292090E090930903809308032FEF3FEF4FEF5C
+S11329305FE7CA01B901E1E1CDB7DEB70C94E9174D
+S1132940FB01DC014150504088F08D9181341CF032
+S11329508B350CF4805E659161341CF06B350CF49E
+S1132960605E861B611171F3990B0895881BFCCF7F
+S11329705058BB27AA270ED075C166D130F06BD151
+S113298020F031F49F3F11F41EF45BC10EF4E09586
+S1132990E7FB51C1E92F77D180F3BA1762077307B8
+S11329A08407950718F071F49EF58FC10EF4E09535
+S11329B00B2EBA2FA02D0B01B90190010C01CA01F5
+S11329C0A0011124FF27591B99F0593F50F4503EA0
+S11329D068F11A16F040A22F232F342F4427585F92
+S11329E0F3CF469537952795A795F0405395C9F7AA
+S11329F07EF41F16BA0B620B730B840BBAF0915062
+S1132A00A1F0FF0FBB1F661F771F881FC2F70EC000
+S1132A10BA0F621F731F841F48F4879577956795D3
+S1132A20B795F7959E3F08F0B3CF9395880F08F0BC
+S1132A309927EE0F979587950895D9D008F481E0EA
+S1132A4008950CD00FC107D140F0FED030F021F42E
+S1132A505F3F19F0F0C0511139C1F3C014D198F39C
+S1132A609923C9F35523B1F3951B550BBB27AA270B
+S1132A7062177307840738F09F5F5F4F220F331F7D
+S1132A80441FAA1FA9F333D00E2E3AF0E0E830D049
+S1132A9091505040E695001CCAF729D0FE2F27D04C
+S1132AA0660F771F881FBB1F261737074807AB071A
+S1132AB0B0E809F0BB0B802DBF01FF2793585F4F8F
+S1132AC02AF09E3F510568F0B6C000C15F3FECF3A9
+S1132AD0983EDCF3869577956795B795F7959F5F54
+S1132AE0C9F7880F911D9695879597F90895E1E0A8
+S1132AF0660F771F881FBB1F621773078407BA0707
+S1132B0020F0621B730B840BBA0BEE1F88F7E09561
+S1132B10089504D06894B111D9C00895BCD088F048
+S1132B209F5790F0B92F9927B751A0F0D1F0660FB5
+S1132B30771F881F991F1AF0BA95C9F712C0B130D0
+S1132B4081F0C3D0B1E00895C0C0672F782F8827E3
+S1132B50B85F39F0B93FCCF3869577956795B3950F
+S1132B60D9F73EF490958095709561957F4F8F4F7E
+S1132B709F4F0895E89409C097FB3EF49095809583
+S1132B80709561957F4F8F4F9F4F9923A9F0F92F2F
+S1132B9096E9BB279395F695879577956795B795AD
+S1132BA0F111F8CFFAF4BB0F11F460FF1BC06F5F93
+S1132BB07F4F8F4F9F4F16C0882311F096E911C0A5
+S1132BC0772321F09EE8872F762F05C0662371F0C6
+S1132BD096E8862F70E060E02AF09A95660F771FDA
+S1132BE0881FDAF7880F9695879597F90895990FB6
+S1132BF00008550FAA0BE0E8FEEF16161706E807C3
+S1132C00F907C0F012161306E407F50798F0621BE3
+S1132C10730B840B950B39F40A2661F0232B242BB8
+S1132C20252B21F408950A2609F4A140A6958FEFD7
+S1132C30811D811D089597F99F6780E870E060E029
+S1132C4008959FEF80EC089500240A941616170641
+S1132C5018060906089500240A9412161306140689
+S1132C6005060895092E0394000C11F4882352F0EC
+S1132C70BB0F40F4BF2B11F460FF04C06F5F7F4FA4
+S1132C808F4F9F4F089557FD9058440F551F59F08B
+S1132C905F3F71F04795880F97FB991F61F09F3F45
+S1132CA079F087950895121613061406551FF2CF6E
+S1132CB04695F1DF08C0161617061806991FF1CFBE
+S1132CC086957105610508940895E894BB276627E5
+S1132CD07727CB0197F908958ADF08F48FEF0895D9
+S1132CE00BD0C0CFB1DF28F0B6DF18F0952309F080
+S1132CF0A2CFA7CF1124EACFC6DFA0F3959FD1F3CB
+S1132D00950F50E0551F629FF001729FBB27F00D95
+S1132D10B11D639FAA27F00DB11DAA1F649F6627EA
+S1132D20B00DA11D661F829F2227B00DA11D621F39
+S1132D30739FB00DA11D621F839FA00D611D221FF3
+S1132D40749F3327A00D611D231F849F600D211DD7
+S1132D50822F762F6A2F11249F5750408AF0E1F07A
+S1132D6088234AF0EE0FFF1FBB1F661F771F881FC3
+S1132D7091505040A9F79E3F510570F05CCFA6CF0B
+S1132D805F3FECF3983EDCF3869577956795B795AE
+S1132D90F795E7959F5FC1F7FE2B880F911D9695D8
+S1132DA0879597F9089511F40EF44BCF4AC073DF59
+S1132DB0D0F39923D9F3CEF39F57550B87FF51D006
+S1132DC056959795B0E020F4660F771F881FBB1FB8
+S1132DD01F930F9300249001A0018001F001A0E84B
+S1132DE00E0F1F1F0A1E511D601B710B8009B50BAE
+S1132DF048F4600F711F801DB51F0E1B1F0B0A0ABC
+S1132E00510907C02E0F3F1F4A1F0E0F1F1F0A1E16
+S1132E10511D660F771F881FBB1FA695F795E79571
+S1132E20F8F60617170708065B07211D311D411D1B
+S1132E300F911F91B901842F9158880F969587950A
+S1132E4008959F3F49F0915028F4869577956795AA
+S1132E50B7959F5F80389F4F880F9695879597F910
+S1132E60089591505040660F771F881FD2F7089538
+S1132E7097FB092E07260AD077FD04D049D006D047
+S1132E8000201AF4709561957F4F0895F6F7909598
+S1132E9081959F4F0895A1E21A2EAA1BBB1BFD0129
+S1132EA00DC0AA1FBB1FEE1FFF1FA217B307E40725
+S1132EB0F50720F0A21BB30BE40BF50B661F771F7D
+S1132EC0881F991F1A9469F760957095809590955D
+S1132ED09B01AC01BD01CF01089597FB092E052686
+S1132EE00ED057FD04D0D7DF0AD0001C38F450951B
+S1132EF04095309521953F4F4F4F5F4F0895F6F71A
+S1132F0090958095709561957F4F8F4F9F4F089551
+S1132F10AA1BBB1B51E107C0AA1FBB1FA617B707FB
+S1132F2010F0A61BB70B881F991F5A95A9F7809517
+S1132F309095BC01CD010895EE0FFF1F0590F4910B
+S1132F40E02D0994911106C0803219F08950855002
+S1132F50D0F70895992788270895629FD001739F19
+S1132F60F001829FE00DF11D649FE00DF11D929F21
+S1132F70F00D839FF00D749FF00D659FF00D992760
+S1132F80729FB00DE11DF91F639FB00DE11DF91F84
+S1132F90BD01CF01112408952F923F924F925F9269
+S1132FA06F927F928F929F92AF92BF92CF92DF9255
+S1132FB0EF92FF920F931F93CF93DF93CDB7DEB7BA
+S1132FC0CA1BDB0B0FB6F894DEBF0FBECDBF09944E
+S1132FD02A88398848885F846E847D848C849B84A5
+S1132FE0AA84B984C884DF80EE80FD800C811B81B3
+S1132FF0AA81B981CE0FD11D0FB6F894DEBF0FBEE2
+S10B3000CDBFED010895FFCFDF
+S11330086875683F204700543A004875683F204D6A
+S1133018006F6B0073746172740001004903360019
+S1133028FF006B00D100A000B800D500A6000A017B
+S113303899003F018E0074018400A9017C00DE011F
+S1133048740013026C00480265007D025D00B20240
+S11330585600E7024E001C03460051033D00860358
+S11330683200BB032200F00303003F800040FF014D
+S1133078014BEAFF404BEAFF400000A04300000078
+S10930883F010101FFFFFE
+S9030000FC
diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/ThermistorTable.h b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/ThermistorTable.h new file mode 100644 index 00000000..07a35377 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/ThermistorTable.h @@ -0,0 +1,36 @@ +#ifndef THERMISTORTABLE_H_ +#define THERMISTORTABLE_H_ + +// 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=4066 --max-adc=1023 +// r0: 100000 +// t0: 25 +// r1: 0 +// r2: 4700 +// beta: 4066 +// max adc: 1023 +#define NUMTEMPS 20 +short temptable[NUMTEMPS][2] = { + {1, 841}, + {54, 255}, + {107, 209}, + {160, 184}, + {213, 166}, + {266, 153}, + {319, 142}, + {372, 132}, + {425, 124}, + {478, 116}, + {531, 108}, + {584, 101}, + {637, 93}, + {690, 86}, + {743, 78}, + {796, 70}, + {849, 61}, + {902, 50}, + {955, 34}, + {1008, 3} +}; +#endif diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/_init.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/_init.pde index 1db13f72..1db13f72 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/_init.pde +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/_init.pde diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/core.a b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/core.a Binary files differnew file mode 100644 index 00000000..f3dae0a6 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/core.a diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/extruder.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/extruder.pde index 6cb0311d..b14fbf18 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/extruder.pde +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/extruder.pde @@ -64,6 +64,7 @@ void valve_set(bool open, int millis) digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 1); delay(millis); digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 0); + digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, 0); } diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/parameters.h b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/parameters.h new file mode 100644 index 00000000..1b14eaed --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/parameters.h @@ -0,0 +1,27 @@ +// define the parameters of our machine. +#define X_STEPS_PER_MM 7.99735 +#define X_STEPS_PER_INCH (X_STEPS_PER_MM*25.4) +#define X_MOTOR_STEPS 400 + +#define Y_STEPS_PER_MM 7.99735 +#define Y_STEPS_PER_INCH (Y_STEPS_PER_MM*25.4) +#define Y_MOTOR_STEPS 400 + +#define Z_STEPS_PER_MM 320 +#define Z_STEPS_PER_INCH (Z_STEPS_PER_MM*25.4) +#define Z_MOTOR_STEPS 400 + +//our maximum feedrates +#define FAST_XY_FEEDRATE 1600.0 +#define FAST_Z_FEEDRATE 50.0 + +// Units in curve section +#define CURVE_SECTION_INCHES 0.019685 +#define CURVE_SECTION_MM 0.5 + +// Set to one if sensor outputs inverting (ie: 1 means open, 0 means closed) +// RepRap opto endstops are *not* inverting. +#define SENSORS_INVERTING 0 + +// How many temperature samples to take. each sample takes about 100 usecs. +#define TEMPERATURE_SAMPLES 3 diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/pins.h b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/pins.h new file mode 100644 index 00000000..638281bb --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/pins.h @@ -0,0 +1,77 @@ +//#define SANGUINO +#ifdef SANGUINO +/**************************************************************************************** +* Sanguino digital i/o pin assignment +* +****************************************************************************************/ + +//cartesian bot pins +#define X_STEP_PIN 15 +#define X_DIR_PIN 18 +#define X_MIN_PIN 20 +#define X_MAX_PIN 21 +#define X_ENABLE_PIN 19 + +#define Y_STEP_PIN 22 +#define Y_DIR_PIN 23 +#define Y_MIN_PIN 25 +#define Y_MAX_PIN 26 +#define Y_ENABLE_PIN 19 + +#define Z_STEP_PIN 29 +#define Z_DIR_PIN 30 +#define Z_MIN_PIN 1 +#define Z_MAX_PIN 2 +#define Z_ENABLE_PIN 31 + +//extruder pins +#define EXTRUDER_0_MOTOR_SPEED_PIN 12 +#define EXTRUDER_0_MOTOR_DIR_PIN 16 +#define EXTRUDER_0_HEATER_PIN 14 +#define EXTRUDER_0_FAN_PIN 3 +#define EXTRUDER_0_THERMISTOR_PIN -1 //a -1 disables thermistor readings +#define EXTRUDER_0_THERMOCOUPLE_PIN 4 //a -1 disables thermocouple readings +#define EXTRUDER_0_VALVE_DIR_PIN 17 +#define EXTRUDER_0_VALVE_ENABLE_PIN 13 // Valve needs to be redesigned not to need this + +/* +#define EXTRUDER_1_MOTOR_SPEED_PIN 99 +#define EXTRUDER_1_MOTOR_DIR_PIN 99 +#define EXTRUDER_1_HEATER_PIN 99 +#define EXTRUDER_1_FAN_PIN 99 +#define EXTRUDER_1_THERMISTOR_PIN 99 //a -1 disables thermistor readings +#define EXTRUDER_1_THERMOCOUPLE_PIN 99 //a -1 disables thermocouple readings +#define EXTRUDER_1_VALVE_DIR_PIN 99 +#define EXTRUDER_1_VALVE_ENABLE_PIN 99 +*/ + +#else + +// Arduino cartesian bot pins +#define X_STEP_PIN 2 +#define X_DIR_PIN 3 +#define X_MIN_PIN 4 +#define X_MAX_PIN 9 +//#define X_ENABLE_PIN 15 +#define Y_STEP_PIN 10 +#define Y_DIR_PIN 7 +#define Y_MIN_PIN 8 +#define Y_MAX_PIN 13 +//#define Y_ENABLE_PIN 15 +#define Z_STEP_PIN 19 +#define Z_DIR_PIN 18 +#define Z_MIN_PIN 17 +#define Z_MAX_PIN 16 +//#define Z_ENABLE_PIN 15 + +//extruder pins +#define EXTRUDER_0_MOTOR_SPEED_PIN 11 +#define EXTRUDER_0_MOTOR_DIR_PIN 12 +#define EXTRUDER_0_HEATER_PIN 6 +#define EXTRUDER_0_FAN_PIN 5 +#define EXTRUDER_0_THERMISTOR_PIN -1 //a -1 disables thermistor readings +#define EXTRUDER_0_THERMOCOUPLE_PIN 0 //a -1 disables thermocouple readings +#define EXTRUDER_0_VALVE_ENABLE_PIN 15 +#define EXTRUDER_0_VALVE_DIR_PIN 16 //NB: Conflicts with Max Z!!!! + +#endif diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/process_string.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/process_string.pde index c22d83c8..c22d83c8 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/process_string.pde +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/process_string.pde diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/stepper_control.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/stepper_control.pde index 5d59fa6c..46040eb8 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/stepper_control.pde +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/applet/stepper_control.pde @@ -21,7 +21,9 @@ int milli_delay; void init_steppers() { //turn them off to start. +#ifdef SANGUINO disable_steppers(); +#endif //init our points. current_units.x = 0.0; @@ -33,13 +35,16 @@ void init_steppers() pinMode(X_STEP_PIN, OUTPUT); pinMode(X_DIR_PIN, OUTPUT); - pinMode(X_ENABLE_PIN, OUTPUT); pinMode(Y_STEP_PIN, OUTPUT); pinMode(Y_DIR_PIN, OUTPUT); - pinMode(Y_ENABLE_PIN, OUTPUT); pinMode(Z_STEP_PIN, OUTPUT); pinMode(Z_DIR_PIN, OUTPUT); + +#ifdef SANGUINO + pinMode(X_ENABLE_PIN, OUTPUT); + pinMode(Y_ENABLE_PIN, OUTPUT); pinMode(Z_ENABLE_PIN, OUTPUT); +#endif #if ENDSTOPS_MIN_ENABLED == 1 pinMode(X_MIN_PIN, INPUT); @@ -59,7 +64,9 @@ void init_steppers() void dda_move(long micro_delay) { //turn on steppers to start moving =) +#ifdef SANGUINO enable_steppers(); +#endif //figure out our deltas max_delta = max(delta_steps.x, delta_steps.y); @@ -299,6 +306,7 @@ long getMaxSpeed() return calculate_feedrate_delay(FAST_XY_FEEDRATE); } +#ifdef SANGUINO void enable_steppers() { // Enable steppers only for axes which are moving @@ -347,6 +355,7 @@ void disable_steppers() digitalWrite(Y_ENABLE_PIN, !ENABLE_ON); digitalWrite(Z_ENABLE_PIN, !ENABLE_ON); } +#endif void delayMicrosecondsInterruptible(unsigned int us) { diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/extruder.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/extruder.pde new file mode 100644 index 00000000..b14fbf18 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/extruder.pde @@ -0,0 +1,267 @@ +// Yep, this is actually -*- c++ -*- + +#include "ThermistorTable.h" + +#define EXTRUDER_0_FORWARD true +#define EXTRUDER_0_REVERSE false + +//these our the default values for the extruder. +int extruder_speed = 128; +int extruder_target_celsius = 0; +int extruder_max_celsius = 0; +byte extruder_heater_low = 64; +byte extruder_heater_high = 255; +byte extruder_heater_current = 0; + +//this is for doing encoder based extruder control +int extruder_rpm = 0; +long extruder_delay = 0; +int extruder_error = 0; +int last_extruder_error = 0; +int extruder_error_delta = 0; +bool extruder_direction = EXTRUDER_0_FORWARD; +bool valve_open = false; + +void init_extruder() +{ + //default to cool... + extruder_set_temperature(-273); + + //setup our pins + pinMode(EXTRUDER_0_MOTOR_DIR_PIN, OUTPUT); + pinMode(EXTRUDER_0_MOTOR_SPEED_PIN, OUTPUT); + pinMode(EXTRUDER_0_HEATER_PIN, OUTPUT); + pinMode(EXTRUDER_0_FAN_PIN, OUTPUT); + pinMode(EXTRUDER_0_VALVE_DIR_PIN, OUTPUT); + pinMode(EXTRUDER_0_VALVE_ENABLE_PIN, OUTPUT); + + //initialize values + digitalWrite(EXTRUDER_0_MOTOR_DIR_PIN, EXTRUDER_0_FORWARD); + analogWrite(EXTRUDER_0_FAN_PIN, 0); + analogWrite(EXTRUDER_0_HEATER_PIN, 0); + analogWrite(EXTRUDER_0_MOTOR_SPEED_PIN, 0); + digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, false); + digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 0); +} + +void wait_for_heater() +{ + //warmup if we're too cold. + while (extruder_get_temperature() < (extruder_target_celsius - 5)) + { + extruder_manage_temperature(); + //Serial.print("T: "); + //Serial.println(extruder_get_temperature()); + delay(1000); + } +} + +void valve_set(bool open, int millis) +{ + wait_for_heater(); + valve_open = open; + digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, open); + digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 1); + delay(millis); + digitalWrite(EXTRUDER_0_VALVE_ENABLE_PIN, 0); + digitalWrite(EXTRUDER_0_VALVE_DIR_PIN, 0); +} + + +void extruder_set_direction(bool direction) +{ + extruder_direction = direction; + digitalWrite(EXTRUDER_0_MOTOR_DIR_PIN, direction); +} + +void extruder_set_speed(byte speed) +{ + if(speed > 0) + wait_for_heater(); + analogWrite(EXTRUDER_0_MOTOR_SPEED_PIN, speed); +} + +void extruder_set_cooler(byte speed) +{ + analogWrite(EXTRUDER_0_FAN_PIN, speed); +} + +void extruder_set_temperature(int temp) +{ + extruder_target_celsius = temp; + extruder_max_celsius = (int)((float)temp * 1.1); +} + +/** +* Samples the temperature and converts it to degrees celsius. +* Returns degrees celsius. +*/ +int extruder_get_temperature() +{ + if (EXTRUDER_0_THERMISTOR_PIN > -1) + return extruder_read_thermistor(); + else if (EXTRUDER_0_THERMOCOUPLE_PIN > -1) + return extruder_read_thermocouple(); +} + +/* +* This function gives us the temperature from the thermistor in Celsius +*/ + +int extruder_read_thermistor() +{ + int raw = extruder_sample_temperature(EXTRUDER_0_THERMISTOR_PIN); + + int celsius = 0; + byte i; + + for (i=1; i<NUMTEMPS; i++) + { + if (temptable[i][0] > raw) + { + celsius = temptable[i-1][1] + + (raw - temptable[i-1][0]) * + (temptable[i][1] - temptable[i-1][1]) / + (temptable[i][0] - temptable[i-1][0]); + + break; + } + } + + // Overflow: Set to last value in the table + if (i == NUMTEMPS) celsius = temptable[i-1][1]; + // Clamp to byte + if (celsius > 255) celsius = 255; + else if (celsius < 0) celsius = 0; + + return celsius; +} + +/* +* This function gives us the temperature from the thermocouple in Celsius +*/ +int extruder_read_thermocouple() +{ + return ( 5.0 * extruder_sample_temperature(EXTRUDER_0_THERMOCOUPLE_PIN) * 100.0) / 1024.0; +} + +/* +* This function gives us an averaged sample of the analog temperature pin. +*/ +int extruder_sample_temperature(byte pin) +{ + int raw = 0; + + //read in a certain number of samples + for (byte i=0; i<TEMPERATURE_SAMPLES; i++) + raw += analogRead(pin); + + //average the samples + raw = raw/TEMPERATURE_SAMPLES; + + //send it back. + return raw; +} + +/*! + Manages motor and heater based on measured temperature: + o If temp is too low, don't start the motor + o Adjust the heater power to keep the temperature at the target + */ +void extruder_manage_temperature() +{ + //make sure we know what our temp is. + int current_celsius = extruder_get_temperature(); + byte newheat = 0; + + //put the heater into high mode if we're not at our target. + if (current_celsius < extruder_target_celsius) + newheat = extruder_heater_high; + //put the heater on low if we're at our target. + else if (current_celsius < extruder_max_celsius) + newheat = extruder_heater_low; + + // Only update heat if it changed + if (extruder_heater_current != newheat) { + extruder_heater_current = newheat; + analogWrite(EXTRUDER_0_HEATER_PIN, extruder_heater_current); + } +} + +#ifdef TEST_MACHINE + +bool heat_on; + +void extruder_heater_test() +{ + int t = extruder_get_temperature(); + if(t < 50 && !heat_on) + { + Serial.println("\n *** Turning heater on.\n"); + heat_on = true; + analogWrite(EXTRUDER_0_HEATER_PIN, extruder_heater_high); + } + + if(t > 100 && heat_on) + { + Serial.println("\n *** Turning heater off.\n"); + heat_on = false; + analogWrite(EXTRUDER_0_HEATER_PIN, 0); + } + + Serial.print("Temperature: "); + Serial.print(t); + Serial.print(" deg C. The heater is "); + if(heat_on) + Serial.println("on."); + else + Serial.println("off."); + + delay(2000); +} + +void extruder_drive_test() +{ + Serial.println("Turning the extruder motor on forwards for 5 seconds."); + extruder_set_direction(true); + extruder_set_speed(200); + delay(5000); + extruder_set_speed(0); + Serial.println("Pausing for 2 seconds."); + delay(2000); + Serial.println("Turning the extruder motor on backwards for 5 seconds."); + extruder_set_direction(false); + extruder_set_speed(200); + delay(5000); + extruder_set_speed(0); + Serial.println("Pausing for 2 seconds."); + delay(2000); +} + +void extruder_valve_test() +{ + Serial.println("Opening the valve."); + valve_set(true, 500); + Serial.println("Pausing for 2 seconds."); + delay(2000); + Serial.println("Closing the valve."); + valve_set(false, 500); + Serial.println("Pausing for 2 seconds."); + delay(2000); +} + +void extruder_fan_test() +{ + Serial.println("Fan on."); + extruder_set_cooler(255); + Serial.println("Pausing for 2 seconds."); + delay(2000); + Serial.println("Fan off."); + extruder_set_cooler(0); + Serial.println("Pausing for 2 seconds."); + delay(2000); +} + + + +#endif diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/parameters.h.dist b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/parameters.h.dist index 5f0f76f0..5f0f76f0 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/parameters.h.dist +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/parameters.h.dist diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/pins.h.dist b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/pins.h.dist index 6156c11a..6156c11a 100644 --- a/trunk/reprap/firmware/Sanguino/GCode_Interpreter/pins.h.dist +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/pins.h.dist diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/process_string.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/process_string.pde new file mode 100644 index 00000000..c22d83c8 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/process_string.pde @@ -0,0 +1,579 @@ +// Yep, this is actually -*- c++ -*- + +// our point structure to make things nice. +struct LongPoint +{ + long x; + long y; + long z; +}; + +struct FloatPoint +{ + float x; + float y; + float z; +}; + +/* gcode line parse results */ +struct GcodeParser +{ + unsigned int seen; + int G; + int M; + float P; + float X; + float Y; + float Z; + float I; + float J; + float F; + float S; + float R; + float Q; +}; + +FloatPoint current_units; +FloatPoint target_units; +FloatPoint delta_units; + +FloatPoint current_steps; +FloatPoint target_steps; +FloatPoint delta_steps; + +boolean abs_mode = true; //0 = incremental; 1 = absolute + +//default to mm for units +float x_units = X_STEPS_PER_MM; +float y_units = Y_STEPS_PER_MM; +float z_units = Z_STEPS_PER_MM; +float curve_section = CURVE_SECTION_MM; + +//our direction vars +byte x_direction = 1; +byte y_direction = 1; +byte z_direction = 1; + +int scan_int(char *str, int *valp); +int scan_float(char *str, float *valp); + +//init our string processing +void init_process_string() +{ + //init our command + //for (byte i=0; i<COMMAND_SIZE; i++) + // word[i] = 0; + serial_count = 0; + comment = false; +} + +//our feedrate variables. +float feedrate = 0.0; +long feedrate_micros = 0; + +/* keep track of the last G code - this is the command mode to use + * if there is no command in the current string + */ +int last_gcode_g = -1; + +/* bit-flags for commands and parameters */ +#define GCODE_G (1<<0) +#define GCODE_M (1<<1) +#define GCODE_P (1<<2) +#define GCODE_X (1<<3) +#define GCODE_Y (1<<4) +#define GCODE_Z (1<<5) +#define GCODE_I (1<<6) +#define GCODE_J (1<<7) +#define GCODE_K (1<<8) +#define GCODE_F (1<<9) +#define GCODE_S (1<<10) +#define GCODE_Q (1<<11) +#define GCODE_R (1<<12) + +#define TYPE_INT 1 +#define TYPE_FLOAT 2 + + +#define PARSE_INT(ch, str, len, val, seen, flag) \ + case ch: \ + len = scan_int(str, &val, &seen, flag); \ + break; + +#define PARSE_FLOAT(ch, str, len, val, seen, flag) \ + case ch: \ + len = scan_float(str, &val, &seen, flag); \ + break; + +int parse_string(struct GcodeParser * gc, char instruction[], int size) +{ + int ind; + int len; /* length of parameter argument */ + + gc->seen = 0; + + len=0; + /* scan the string for commands and parameters, recording the arguments for each, + * and setting the seen flag for each that is seen + */ + for (ind=0; ind<size; ind += (1+len)) + { + len = 0; + switch (instruction[ind]) + { + PARSE_INT('G', &instruction[ind+1], len, gc->G, gc->seen, GCODE_G); + PARSE_INT('M', &instruction[ind+1], len, gc->M, gc->seen, GCODE_M); + PARSE_FLOAT('S', &instruction[ind+1], len, gc->S, gc->seen, GCODE_S); + PARSE_FLOAT('P', &instruction[ind+1], len, gc->P, gc->seen, GCODE_P); + PARSE_FLOAT('X', &instruction[ind+1], len, gc->X, gc->seen, GCODE_X); + PARSE_FLOAT('Y', &instruction[ind+1], len, gc->Y, gc->seen, GCODE_Y); + PARSE_FLOAT('Z', &instruction[ind+1], len, gc->Z, gc->seen, GCODE_Z); + PARSE_FLOAT('I', &instruction[ind+1], len, gc->I, gc->seen, GCODE_I); + PARSE_FLOAT('J', &instruction[ind+1], len, gc->J, gc->seen, GCODE_J); + PARSE_FLOAT('F', &instruction[ind+1], len, gc->F, gc->seen, GCODE_F); + PARSE_FLOAT('R', &instruction[ind+1], len, gc->R, gc->seen, GCODE_R); + PARSE_FLOAT('Q', &instruction[ind+1], len, gc->Q, gc->seen, GCODE_Q); + default: + break; + } + } +} + + +//Read the string and execute instructions +void process_string(char instruction[], int size) +{ + + GcodeParser gc; /* string parse result */ + + //the character / means delete block... used for comments and stuff. + if (instruction[0] == '/') + return; + + //init baby! + FloatPoint fp; + fp.x = 0.0; + fp.y = 0.0; + fp.z = 0.0; + + //get all our parameters! + parse_string(&gc, instruction, size); + /* if no command was seen, but parameters were, then use the last G code as + * the current command + */ + if ((!(gc.seen & (GCODE_G | GCODE_M))) && + ((gc.seen != 0) && + (last_gcode_g >= 0)) + ) + { + /* yes - so use the previous command with the new parameters */ + gc.G = last_gcode_g; + gc.seen |= GCODE_G; + } + //did we get a gcode? + if (gc.seen & GCODE_G) + { + last_gcode_g = gc.G; /* remember this for future instructions */ + fp = current_units; + if (abs_mode) + { + if (gc.seen & GCODE_X) + fp.x = gc.X; + if (gc.seen & GCODE_Y) + fp.y = gc.Y; + if (gc.seen & GCODE_Z) + fp.z = gc.Z; + } + else + { + if (gc.seen & GCODE_X) + fp.x += gc.X; + if (gc.seen & GCODE_Y) + fp.y += gc.Y; + if (gc.seen & GCODE_Z) + fp.z += gc.Z; + } + + // Get feedrate if supplied + if ( gc.seen & GCODE_F ) + feedrate = gc.F; + + //do something! + switch (gc.G) + { + //Rapid Positioning + //Linear Interpolation + //these are basically the same thing. + case 0: + case 1: + //set our target. + set_target(fp.x, fp.y, fp.z); + + // Use currently set feedrate if doing a G1 + if (gc.G == 1) + feedrate_micros = calculate_feedrate_delay(feedrate); + // Use our max for G0 + else + feedrate_micros = getMaxSpeed(); + //finally move. + dda_move(feedrate_micros); + break; +#ifdef SANGUINO +// No room for this in the Arduino + //Clockwise arc + case 2: + //Counterclockwise arc + case 3: + { + FloatPoint cent; + + // Centre coordinates are always relative + if (gc.seen & GCODE_I) cent.x = current_units.x + gc.I; + else cent.x = current_units.x; + if (gc.seen & GCODE_J) cent.y = current_units.y + gc.J; + + float angleA, angleB, angle, radius, length, aX, aY, bX, bY; + + aX = (current_units.x - cent.x); + aY = (current_units.y - cent.y); + bX = (fp.x - cent.x); + bY = (fp.y - cent.y); + + // Clockwise + if (gc.G == 2) + { + angleA = atan2(bY, bX); + angleB = atan2(aY, aX); + } + // Counterclockwise + else + { + angleA = atan2(aY, aX); + angleB = atan2(bY, bX); + } + + // Make sure angleB is always greater than angleA + // and if not add 2PI so that it is (this also takes + // care of the special case of angleA == angleB, + // ie we want a complete circle) + if (angleB <= angleA) + angleB += 2 * M_PI; + angle = angleB - angleA; + + radius = sqrt(aX * aX + aY * aY); + length = radius * angle; + int steps, s, step; + + // Maximum of either 2.4 times the angle in radians or the length of the curve divided by the constant specified in _init.pde + steps = (int) ceil(max(angle * 2.4, length / curve_section)); + + FloatPoint newPoint; + float arc_start_z = current_units.z; + for (s = 1; s <= steps; s++) + { + step = (gc.G == 3) ? s : steps - s; // Work backwards for CW + newPoint.x = cent.x + radius * cos(angleA + angle + * ((float) step / steps)); + newPoint.y = cent.y + radius * sin(angleA + angle + * ((float) step / steps)); + set_target(newPoint.x, newPoint.y, arc_start_z + (fp.z + - arc_start_z) * s / steps); + + // Need to calculate rate for each section of curve + if (feedrate > 0) + feedrate_micros = calculate_feedrate_delay(feedrate); + else + feedrate_micros = getMaxSpeed(); + + // Make step + dda_move(feedrate_micros); + } + } + break; +#endif + + case 4: //Dwell + delay((int)(gc.P + 0.5)); // Changed by AB from 1000*gc.P + break; + + //Inches for Units + case 20: + x_units = X_STEPS_PER_INCH; + y_units = Y_STEPS_PER_INCH; + z_units = Z_STEPS_PER_INCH; + curve_section = CURVE_SECTION_INCHES; + + calculate_deltas(); + break; + + //mm for Units + case 21: + x_units = X_STEPS_PER_MM; + y_units = Y_STEPS_PER_MM; + z_units = Z_STEPS_PER_MM; + curve_section = CURVE_SECTION_MM; + + calculate_deltas(); + break; + + //go home. + case 28: + set_target(0.0, 0.0, 0.0); + dda_move(getMaxSpeed()); + break; + + //go home via an intermediate point. + case 30: + //set our target. + set_target(fp.x, fp.y, fp.z); + + //go there. + dda_move(getMaxSpeed()); + + //go home. + set_target(0.0, 0.0, 0.0); + dda_move(getMaxSpeed()); + break; + + // Drilling canned cycles + case 81: // Without dwell + case 82: // With dwell + case 83: // Peck drilling + { + float retract = gc.R; + + if (!abs_mode) + retract += current_units.z; + + // Retract to R position if Z is currently below this + if (current_units.z < retract) + { + set_target(current_units.x, current_units.y, retract); + dda_move(getMaxSpeed()); + } + + // Move to start XY + set_target(fp.x, fp.y, current_units.z); + dda_move(getMaxSpeed()); + + // Do the actual drilling + float target_z = retract; + float delta_z; + + // For G83 move in increments specified by Q code, otherwise do in one pass + if (gc.G == 83) + delta_z = gc.Q; + else + delta_z = retract - fp.z; + + do { + // Move rapidly to bottom of hole drilled so far (target Z if starting hole) + set_target(fp.x, fp.y, target_z); + dda_move(getMaxSpeed()); + + // Move with controlled feed rate by delta z (or to bottom of hole if less) + target_z -= delta_z; + if (target_z < fp.z) + target_z = fp.z; + set_target(fp.x, fp.y, target_z); + if (feedrate > 0) + feedrate_micros = calculate_feedrate_delay(feedrate); + else + feedrate_micros = getMaxSpeed(); + dda_move(feedrate_micros); + + // Dwell if doing a G82 + if (gc.G == 82) + delay((int)(gc.P * 1000)); + + // Retract + set_target(fp.x, fp.y, retract); + dda_move(getMaxSpeed()); + } while (target_z > fp.z); + } + break; + + + case 90: //Absolute Positioning + abs_mode = true; + break; + + + case 91: //Incremental Positioning + abs_mode = false; + break; + + + case 92: //Set position as fp + set_position(fp.x, fp.y, fp.z); + break; + + /* + //Inverse Time Feed Mode + case 93: + + break; //TODO: add this + + //Feed per Minute Mode + case 94: + + break; //TODO: add this + */ + + default: + Serial.print("huh? G"); + Serial.println(gc.G, DEC); + } + } + + //find us an m code. + if (gc.seen & GCODE_M) + { + switch (gc.M) + { + //TODO: this is a bug because search_string returns 0. gotta fix that. + case 0: + true; + break; + /* + case 0: + //todo: stop program + break; + + case 1: + //todo: optional stop + break; + + case 2: + //todo: program end + break; + */ + //turn extruder on, forward + case 101: + extruder_set_direction(1); + extruder_set_speed(extruder_speed); + break; + + //turn extruder on, reverse + case 102: + extruder_set_direction(0); + extruder_set_speed(extruder_speed); + break; + + //turn extruder off + case 103: + extruder_set_speed(0); + break; + + //custom code for temperature control + case 104: + if (gc.seen & GCODE_S) + { + extruder_set_temperature((int)gc.S); + +// //warmup if we're too cold. +// while (extruder_get_temperature() < extruder_target_celsius) +// { +// extruder_manage_temperature(); +// Serial.print("T: "); +// Serial.println(extruder_get_temperature()); +// delay(1000); +// } + } + break; + + //custom code for temperature reading + case 105: + Serial.print("T:"); + Serial.println(extruder_get_temperature()); + break; + + //turn fan on + case 106: + extruder_set_cooler(255); + break; + + //turn fan off + case 107: + extruder_set_cooler(0); + break; + + //set max extruder speed, 0-255 PWM + case 108: + if (gc.seen & GCODE_S) + extruder_speed = (int)gc.S; + break; + + // Open the valve + case 126: + valve_set(true, (int)(gc.P + 0.5)); + break; + + // Close the valve + case 127: + valve_set(false, (int)(gc.P + 0.5)); + break; + + + default: + Serial.print("Huh? M"); + Serial.println(gc.M, DEC); + } + } + +} + +int scan_float(char *str, float *valp, unsigned int *seen, unsigned int flag) +{ + float res; + int len; + char *end; + + res = (float)strtod(str, &end); + + len = end - str; + + if (len > 0) + { + *valp = res; + *seen |= flag; + } + else + *valp = 0; + + return len; /* length of number */ +} + +int scan_int(char *str, int *valp, unsigned int *seen, unsigned int flag) +{ + int res; + int len; + char *end; + + res = (int)strtol(str, &end, 10); + len = end - str; + + if (len > 0) + { + *valp = res; + *seen |= flag; + } + else + *valp = 0; + + return len; /* length of number */ +} + +#ifdef TEST_MACHINE + +// Read and echo bytes. + +void comms_test() +{ + if (Serial.available() > 0) + Serial.print((char)Serial.read()); +} + +#endif + + diff --git a/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/stepper_control.pde b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/stepper_control.pde new file mode 100644 index 00000000..46040eb8 --- /dev/null +++ b/trunk/reprap/firmware/Sanguino/GCode_Interpreter.old-version/stepper_control.pde @@ -0,0 +1,466 @@ +// Yep, this is actually -*- c++ -*- + +//init our variables +long max_delta; +long x_counter; +long y_counter; +long z_counter; +bool x_can_step; +bool y_can_step; +bool z_can_step; +int milli_delay; + +#if INVERT_ENABLE_PINS == 1 +#define ENABLE_ON LOW +#else +#define ENABLE_ON HIGH +#endif + +#define ENDSTOPS_MIN_ENABLED 1 + +void init_steppers() +{ + //turn them off to start. +#ifdef SANGUINO + disable_steppers(); +#endif + + //init our points. + current_units.x = 0.0; + current_units.y = 0.0; + current_units.z = 0.0; + target_units.x = 0.0; + target_units.y = 0.0; + target_units.z = 0.0; + + pinMode(X_STEP_PIN, OUTPUT); + pinMode(X_DIR_PIN, OUTPUT); + pinMode(Y_STEP_PIN, OUTPUT); + pinMode(Y_DIR_PIN, OUTPUT); + pinMode(Z_STEP_PIN, OUTPUT); + pinMode(Z_DIR_PIN, OUTPUT); + +#ifdef SANGUINO + pinMode(X_ENABLE_PIN, OUTPUT); + pinMode(Y_ENABLE_PIN, OUTPUT); + pinMode(Z_ENABLE_PIN, OUTPUT); +#endif + +#if ENDSTOPS_MIN_ENABLED == 1 + pinMode(X_MIN_PIN, INPUT); + pinMode(Y_MIN_PIN, INPUT); + pinMode(Z_MIN_PIN, INPUT); +#endif +#if ENDSTOPS_MAX_ENABLED == 1 + pinMode(X_MAX_PIN, INPUT); + pinMode(Y_MAX_PIN, INPUT); + pinMode(Z_MAX_PIN, INPUT); +#endif + + //figure our stuff. + calculate_deltas(); +} + +void dda_move(long micro_delay) +{ + //turn on steppers to start moving =) +#ifdef SANGUINO + enable_steppers(); +#endif + + //figure out our deltas + max_delta = max(delta_steps.x, delta_steps.y); + max_delta = max(delta_steps.z, max_delta); + + //init stuff. + long x_counter = -max_delta/2; + long y_counter = -max_delta/2; + long z_counter = -max_delta/2; + + //our step flags + bool x_can_step = 0; + bool y_can_step = 0; + bool z_can_step = 0; + + //how long do we delay for? + if (micro_delay >= 16383) + milli_delay = micro_delay / 1000; + else + milli_delay = 0; + + //do our DDA line! + do + { + x_can_step = can_step(X_MIN_PIN, X_MAX_PIN, current_steps.x, target_steps.x, x_direction); + y_can_step = can_step(Y_MIN_PIN, Y_MAX_PIN, current_steps.y, target_steps.y, y_direction); + z_can_step = can_step(Z_MIN_PIN, Z_MAX_PIN, current_steps.z, target_steps.z, z_direction); + + if (x_can_step) + { + x_counter += delta_steps.x; + + if (x_counter > 0) + { + do_step(X_STEP_PIN); + x_counter -= max_delta; + + if (x_direction) + current_steps.x++; + else + current_steps.x--; + } + } + + if (y_can_step) + { + y_counter += delta_steps.y; + + if (y_counter > 0) + { + do_step(Y_STEP_PIN); + y_counter -= max_delta; + + if (y_direction) + current_steps.y++; + else + current_steps.y--; + } + } + + if (z_can_step) + { + z_counter += delta_steps.z; + + if (z_counter > 0) + { + do_step(Z_STEP_PIN); + z_counter -= max_delta; + + if (z_direction) + current_steps.z++; + else + current_steps.z--; + } + } + + //keep it hot =) + extruder_manage_temperature(); + + //wait for next step. + if (milli_delay > 0) + delay(milli_delay); + else + delayMicrosecondsInterruptible(micro_delay); + } + while (x_can_step || y_can_step || z_can_step); + + //set our points to be the same + current_units.x = target_units.x; + current_units.y = target_units.y; + current_units.z = target_units.z; + calculate_deltas(); +} + +bool can_step(byte min_pin, byte max_pin, long current, long target, byte direction) +{ + //stop us if we're on target + if (target == current) + return false; +#if ENDSTOPS_MIN_ENABLED == 1 + //stop us if we're at home and still going + else if (read_switch(min_pin) && !direction) + return false; +#endif +#if ENDSTOPS_MAX_ENABLED == 1 + //stop us if we're at max and still going + else if (read_switch(max_pin) && direction) + return false; +#endif + + //default to being able to step + return true; +} + +void do_step(byte step_pin) +{ + digitalWrite(step_pin, HIGH); + delayMicroseconds(5); + digitalWrite(step_pin, LOW); +} + +bool read_switch(byte pin) +{ + //dual read as crude debounce + #if ENDSTOPS_INVERTING == 1 + return !digitalRead(pin) && !digitalRead(pin); + #else + return digitalRead(pin) && digitalRead(pin); + #endif +} + +long to_steps(float steps_per_unit, float units) +{ + return steps_per_unit * units; +} + +void set_target(float x, float y, float z) +{ + target_units.x = x; + target_units.y = y; + target_units.z = z; + + calculate_deltas(); +} + +void set_position(float x, float y, float z) +{ + current_units.x = x; + current_units.y = y; + current_units.z = z; + + calculate_deltas(); +} + +void calculate_deltas() +{ + //figure our deltas. + delta_units.x = abs(target_units.x - current_units.x); + delta_units.y = abs(target_units.y - current_units.y); + delta_units.z = abs(target_units.z - current_units.z); + + //set our steps current, target, and delta + current_steps.x = to_steps(x_units, current_units.x); + current_steps.y = to_steps(y_units, current_units.y); + current_steps.z = to_steps(z_units, current_units.z); + + target_steps.x = to_steps(x_units, target_units.x); + target_steps.y = to_steps(y_units, target_units.y); + target_steps.z = to_steps(z_units, target_units.z); + + delta_steps.x = abs(target_steps.x - current_steps.x); + delta_steps.y = abs(target_steps.y - current_steps.y); + delta_steps.z = abs(target_steps.z - current_steps.z); + + //what is our direction + x_direction = (target_units.x >= current_units.x); + y_direction = (target_units.y >= current_units.y); + z_direction = (target_units.z >= current_units.z); + + //set our direction pins as well +#if INVERT_X_DIR == 1 + digitalWrite(X_DIR_PIN, !x_direction); +#else + digitalWrite(X_DIR_PIN, x_direction); +#endif +#if INVERT_Y_DIR == 1 + digitalWrite(Y_DIR_PIN, !y_direction); +#else + digitalWrite(Y_DIR_PIN, y_direction); +#endif +#if INVERT_Z_DIR == 1 + digitalWrite(Z_DIR_PIN, !z_direction); +#else + digitalWrite(Z_DIR_PIN, z_direction); +#endif +} + + +long calculate_feedrate_delay(float feedrate) +{ + //how long is our line length? + float distance = sqrt(delta_units.x*delta_units.x + + delta_units.y*delta_units.y + + delta_units.z*delta_units.z); + long master_steps = 0; + + //find the dominant axis. + if (delta_steps.x > delta_steps.y) + { + if (delta_steps.z > delta_steps.x) + master_steps = delta_steps.z; + else + master_steps = delta_steps.x; + } + else + { + if (delta_steps.z > delta_steps.y) + master_steps = delta_steps.z; + else + master_steps = delta_steps.y; + } + + //calculate delay between steps in microseconds. this is sort of tricky, but not too bad. + //the formula has been condensed to save space. here it is in english: + // (feedrate is in mm/minute) + // distance / feedrate * 60000000.0 = move duration in microseconds + // move duration / master_steps = time between steps for master axis. + + return ((distance * 60000000.0) / feedrate) / master_steps; +} + +long getMaxSpeed() +{ + if (delta_steps.z > 0) + return calculate_feedrate_delay(FAST_Z_FEEDRATE); + else + return calculate_feedrate_delay(FAST_XY_FEEDRATE); +} + +#ifdef SANGUINO +void enable_steppers() +{ + // Enable steppers only for axes which are moving + // taking account of the fact that some or all axes + // may share an enable line (check using macros at + // compile time to avoid needless code) + if ( target_units.x == current_units.x + #if X_ENABLE_PIN == Y_ENABLE_PIN + && target_units.y == current_units.y + #endif + #if X_ENABLE_PIN == Z_ENABLE_PIN + && target_units.z == current_units.z + #endif + ) + digitalWrite(X_ENABLE_PIN, !ENABLE_ON); + else + digitalWrite(X_ENABLE_PIN, ENABLE_ON); + if ( target_units.y == current_units.y + #if Y_ENABLE_PIN == X_ENABLE_PIN + && target_units.x == current_units.x + #endif + #if Y_ENABLE_PIN == Z_ENABLE_PIN + && target_units.z == current_units.z + #endif + ) + digitalWrite(Y_ENABLE_PIN, !ENABLE_ON); + else + digitalWrite(Y_ENABLE_PIN, ENABLE_ON); + if ( target_units.z == current_units.z + #if Z_ENABLE_PIN == X_ENABLE_PIN + && target_units.x == current_units.x + #endif + #if Z_ENABLE_PIN == Y_ENABLE_PIN + && target_units.y == current_units.y + #endif + ) + digitalWrite(Z_ENABLE_PIN, !ENABLE_ON); + else + digitalWrite(Z_ENABLE_PIN, ENABLE_ON); +} + +void disable_steppers() +{ + //disable our steppers + digitalWrite(X_ENABLE_PIN, !ENABLE_ON); + digitalWrite(Y_ENABLE_PIN, !ENABLE_ON); + digitalWrite(Z_ENABLE_PIN, !ENABLE_ON); +} +#endif + +void delayMicrosecondsInterruptible(unsigned int us) +{ + +#if F_CPU >= 16000000L + // for the 16 MHz clock on most Arduino boards + + // for a one-microsecond delay, simply return. the overhead + // of the function call yields a delay of approximately 1 1/8 us. + if (--us == 0) + return; + + // the following loop takes a quarter of a microsecond (4 cycles) + // per iteration, so execute it four times for each microsecond of + // delay requested. + us <<= 2; + + // account for the time taken in the preceeding commands. + us -= 2; +#else + // for the 8 MHz internal clock on the ATmega168 + + // for a one- or two-microsecond delay, simply return. the overhead of + // the function calls takes more than two microseconds. can't just + // subtract two, since us is unsigned; we'd overflow. + if (--us == 0) + return; + if (--us == 0) + return; + + // the following loop takes half of a microsecond (4 cycles) + // per iteration, so execute it twice for each microsecond of + // delay requested. + us <<= 1; + + // partially compensate for the time taken by the preceeding commands. + // we can't subtract any more than this or we'd overflow w/ small delays. + us--; +#endif + + // busy wait + __asm__ __volatile__ ( + "1: sbiw %0,1" "\n\t" // 2 cycles + "brne 1b" : "=w" (us) : "0" (us) // 2 cycles + ); +} + +#ifdef TEST_MACHINE + +void X_motor_test() +{ + Serial.println("Moving X forward by 100 mm at half maximum speed."); + set_target(100, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); + + Serial.println("Moving X back to the start."); + set_target(0, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); +} + +void Y_motor_test() +{ + + Serial.println("Moving Y forward by 100 mm at half maximum speed."); + set_target(0, 100, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); + + Serial.println("Moving Y back to the start."); + set_target(0, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_XY_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); +} + +void Z_motor_test() +{ + Serial.println("Moving Z down by 5 mm at half maximum speed."); + set_target(0, 0, 5); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_Z_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); + + Serial.println("Moving Z back to the start."); + set_target(0, 0, 0); + enable_steppers(); + dda_move(calculate_feedrate_delay(FAST_Z_FEEDRATE/2)); + + Serial.println("Pause for 2 seconds."); + delay(2000); +} + +#endif diff --git a/trunk/reprap/firmware/sketch_081010a/sketch_081010a.pde b/trunk/reprap/firmware/sketch_081010a/sketch_081010a.pde index 2086374c..c7a058c6 100644 --- a/trunk/reprap/firmware/sketch_081010a/sketch_081010a.pde +++ b/trunk/reprap/firmware/sketch_081010a/sketch_081010a.pde @@ -1,20 +1,19 @@ #include <HardwareSerial.h> -char* fp="12.345"; -char* end; -float res=-1.123; +char c; +long count; void setup() { Serial.begin(19200); - Serial.println("start"); - // Uncomment next line to cause crash... - res = (float)strtod(fp, &end); - Serial.print(((int)(res*1000 + 0.5))/1000); - Serial.print("."); - Serial.println(((int)abs(res*1000 + 0.5))%1000); + Serial.println("Type a character: "); + while(!Serial.available()); + c = Serial.read(); } void loop() { + Serial.println(count); + count++; + delay(1000); } |