#include "configuration.h" #include "pins.h" #include "intercom.h" #include "extruder.h" // Select a new extruder void newExtruder(byte e) { if(e < 0) return; if(e >= EXTRUDER_COUNT) return; if(e != extruder_in_use) { extruder_in_use = e; setUnits(cdda[0]->get_units()); } } //************************************************************************* // Extruder functions that are the same for all extruders. void extruder::waitForTemperature() { byte seconds = 0; bool warming = true; count = 0; newT = 0; oldT = newT; while (true) { newT += getTemperature(); count++; if(count > 5) { newT = newT/5; if(newT >= targetTemperature - HALF_DEAD_ZONE) { warming = false; if(seconds > WAIT_AT_TEMPERATURE) return; else seconds++; } if(warming) { if(newT > oldT) oldT = newT; else { // Temp isn't increasing - extruder hardware error temperatureError(); return; } } newT = 0; count = 0; } for(int i = 0; i < 1000; i++) { manage(); delay(1); } } } // This is a fatal error - something is wrong with the heater. void extruder::temperatureError() { sprintf(talkToHost.string(), "Extruder temperature not rising - hard fault."); talkToHost.setFatal(); } /*************************************************************************************************************************** * * Darwin-style motherboard */ #if EXTRUDER_CONTROLLER == EXTRUDER_CONTROLLER_DC extruder::extruder(byte md_pin, byte ms_pin, byte h_pin, byte f_pin, byte t_pin, byte vd_pin, byte ve_pin, byte se_pin, float spm) { 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; step_en_pin = se_pin; sPerMM = spm; //setup our pins pinMode(motor_dir_pin, OUTPUT); pinMode(motor_speed_pin, OUTPUT); pinMode(heater_pin, OUTPUT); pinMode(temp_pin, INPUT); pinMode(valve_dir_pin, OUTPUT); pinMode(valve_en_pin, OUTPUT); //initialize values digitalWrite(motor_dir_pin, EXTRUDER_FORWARD); analogWrite(heater_pin, 0); analogWrite(motor_speed_pin, 0); digitalWrite(valve_dir_pin, false); digitalWrite(valve_en_pin, 0); // The step enable pin and the fan pin are the same... // We can have one, or the other, but not both if(step_en_pin >= 0) { pinMode(step_en_pin, OUTPUT); disableStep(); } else { pinMode(fan_pin, OUTPUT); analogWrite(fan_pin, 0); } //these our the default values for the extruder. e_speed = 0; targetTemperature = 0; 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 setTemperature(targetTemperature); } void extruder::shutdown() { analogWrite(heater_pin, 0); digitalWrite(step_en_pin, !ENABLE_ON); valveSet(false, 500); } void extruder::valveSet(bool open, int dTime) { waitForTemperature(); valve_open = open; digitalWrite(valve_dir_pin, open); digitalWrite(valve_en_pin, 1); delay(dTime); digitalWrite(valve_en_pin, 0); } void extruder::setTemperature(int temp) { targetTemperature = temp; max_celsius = (temp*11)/10; // If we've turned the heat off, we might as well disable the extrude stepper // if(target_celsius < 1) // disableStep(); } /** * Samples the temperature and converts it to degrees celsius. * Returns degrees celsius. */ int extruder::getTemperature() { #ifdef USE_THERMISTOR int raw = sampleTemperature(); int celsius = 0; byte i; for (i=1; i 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; #else return ( 5.0 * sampleTemperature() * 100.0) / 1024.0; #endif } /* * This function gives us an averaged sample of the analog temperature pin. */ int extruder::sampleTemperature() { int raw = 0; //read in a certain number of samples for (byte i=0; ipidCalculation(targetTemperature); } void extruder::slowManage() { manageCount = 0; controlTemperature(); } void extruder::manage() { #ifdef PASTE_EXTRUDER valveMonitor(); #endif manageCount++; if(manageCount > SLOW_CLOCK) slowManage(); } // Stop everything void extruder::shutdown() { // Heater off; setTemperature(0); extruderPID->shutdown(); // Motor off digitalWrite(motor_en_pin, !ENABLE_ON); // Close valve #ifdef PASTE_EXTRUDER valveSet(false, 500); #endif } void extruder::setDirection(bool direction) { digitalWrite(motor_dir_pin, direction); } void extruder::setCooler(byte e_speed) { //analogWrite(fan_pin, e_speed); } void extruder::setTemperature(int tp) { extruderPID->reset(); targetTemperature = tp; } int extruder::getTemperature() { return extruderPID->temperature(); } void extruder::enableStep() { digitalWrite(motor_en_pin, ENABLE_ON); } void extruder::disableStep() { #if DISABLE_E digitalWrite(motor_en_pin, !ENABLE_ON); #endif } void extruder::valveSet(bool closed, int dTime) { #ifdef PASTE_EXTRUDER requiredValveState = closed; kickStartValve(); #endif } #ifdef PASTE_EXTRUDER bool extruder::valveTimeCheck(int millisecs) { if(valveAlreadyRunning) { if(millis() >= valveEndTime) { valveAlreadyRunning = false; return true; } return false; } valveEndTime = millis() + millisecs*MILLI_CORRECTION; valveAlreadyRunning = true; return false; } void extruder::valveTurn(bool close) { if(valveAtEnd) return; byte valveRunningState = VALVE_STARTING; if(digitalRead(OPTO_PIN)) { seenHighLow = true; valveRunningState = VALVE_RUNNING; } else { if(!seenHighLow) valveRunningState = VALVE_STARTING; else valveRunningState = VALVE_STOPPING; } switch(valveRunningState) { case VALVE_STARTING: if(close) digitalWrite(H1D, 1); else digitalWrite(H1D, 0); digitalWrite(H1E, HIGH); break; case VALVE_RUNNING: return; case VALVE_STOPPING: if(close) digitalWrite(H1D, 0); else digitalWrite(H1D, 1); if(!valveTimeCheck(10)) return; digitalWrite(H1E, LOW); valveState = close; valveAtEnd = true; seenHighLow = false; break; default: break; } } void extruder::valveMonitor() { if(valveState == requiredValveState) return; valveAtEnd = false; valveTurn(requiredValveState); } void extruder::kickStartValve() { if(digitalRead(OPTO_PIN)) { if(requiredValveState) digitalWrite(H1D, 1); else digitalWrite(H1D, 0); digitalWrite(H1E, HIGH); } } #endif #endif