Version 0.78h

Added a few more improvements from RRP's dev branch
Corrected M201 output
Added a few more minor fixes
This commit is contained in:
David Crocker 2014-08-03 11:17:48 +01:00
parent 30b67ff40a
commit 2a818bcfc0
12 changed files with 583 additions and 329 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H #define CONFIGURATION_H
#define NAME "RepRapFirmware" #define NAME "RepRapFirmware"
#define VERSION "0.78g-dc42" #define VERSION "0.78h-dc42"
#define DATE "2014-07-30" #define DATE "2014-08-01"
#define AUTHORS "reprappro, dc42. zpl" #define AUTHORS "reprappro, dc42. zpl"
// Other firmware that we might switch to be compatible with. // Other firmware that we might switch to be compatible with.
@ -50,6 +50,8 @@ enum Compatibility
#define TEMPERATURE_CLOSE_ENOUGH (2.5) // Celsius #define TEMPERATURE_CLOSE_ENOUGH (2.5) // Celsius
#define TEMPERATURE_LOW_SO_DONT_CARE (40.0) // Celsius #define TEMPERATURE_LOW_SO_DONT_CARE (40.0) // Celsius
#define HOT_ENOUGH_TO_EXTRUDE (160.0) // Celsius
#define TIME_TO_HOT (120.0) // Seconds
// If temperatures fall outside this range, something nasty has happened. // If temperatures fall outside this range, something nasty has happened.

View file

@ -246,18 +246,15 @@ void GCodes::Diagnostics()
bool GCodes::AllMovesAreFinishedAndMoveBufferIsLoaded() bool GCodes::AllMovesAreFinishedAndMoveBufferIsLoaded()
{ {
// Last one gone? // Last one gone?
if(moveAvailable) if(moveAvailable)
return false; return false;
// Wait for all the queued moves to stop so we get the actual last position and feedrate // Wait for all the queued moves to stop so we get the actual last position and feedrate
if(!reprap.GetMove()->AllMovesAreFinished()) if(!reprap.GetMove()->AllMovesAreFinished())
return false; return false;
reprap.GetMove()->ResumeMoving(); reprap.GetMove()->ResumeMoving();
// Load the last position; If Move can't accept more, return false - should never happen // Load the last position; If Move can't accept more, return false - should never happen
if(!reprap.GetMove()->GetCurrentUserPosition(moveBuffer)) if(!reprap.GetMove()->GetCurrentUserPosition(moveBuffer))
return false; return false;
@ -346,8 +343,8 @@ bool GCodes::LoadMoveBufferFromGCode(GCodeBuffer *gb, bool doingG92, bool applyL
platform->Message(BOTH_ERROR_MESSAGE, "Attempting to extrude with no tool selected.\n"); platform->Message(BOTH_ERROR_MESSAGE, "Attempting to extrude with no tool selected.\n");
return false; return false;
} }
float eMovement[DRIVES-AXES];
int eMoveCount = tool->DriveCount(); int eMoveCount = tool->DriveCount();
float eMovement[DRIVES-AXES];
gb->GetFloatArray(eMovement, eMoveCount); gb->GetFloatArray(eMovement, eMoveCount);
if(tool->DriveCount() != eMoveCount) if(tool->DriveCount() != eMoveCount)
{ {
@ -386,7 +383,7 @@ bool GCodes::LoadMoveBufferFromGCode(GCodeBuffer *gb, bool doingG92, bool applyL
{ {
if(gb->Seen(axisLetters[axis])) if(gb->Seen(axisLetters[axis]))
{ {
float moveArg = gb->GetFValue()*distanceScale; float moveArg = gb->GetFValue() * distanceScale;
if (axesRelative && !doingG92) if (axesRelative && !doingG92)
{ {
moveArg += moveBuffer[axis]; moveArg += moveBuffer[axis];
@ -550,7 +547,7 @@ bool GCodes::FileCannedCyclesReturn()
// To execute any move, call this until it returns true. // To execute any move, call this until it returns true.
// moveToDo[] entries corresponding with false entries in action[] will // moveToDo[] entries corresponding with false entries in action[] will
// be ignored. Recall that moveToDo[DRIVES] should contain the feed rate // be ignored. Recall that moveToDo[DRIVES] should contain the feedrate
// you want (if action[DRIVES] is true). // you want (if action[DRIVES] is true).
bool GCodes::DoCannedCycleMove(EndstopChecks ce) bool GCodes::DoCannedCycleMove(EndstopChecks ce)
@ -1661,13 +1658,13 @@ void GCodes::SetToolHeaters(Tool *tool, float temperature)
bool GCodes::ActOnCode(GCodeBuffer *gb) bool GCodes::ActOnCode(GCodeBuffer *gb)
{ {
// M-code parameters might contain letters T and G, e.g. in filenames. // M-code parameters might contain letters T and G, e.g. in filenames.
// I assume that G-and T-code parameters never contain the letter M. // dc42 assumes that G-and T-code parameters never contain the letter M.
// Therefore we must check for an M-code first. // Therefore we must check for an M-code first.
if (gb->Seen('M')) if (gb->Seen('M'))
{ {
return HandleMcode(gb); return HandleMcode(gb);
} }
// I don't think a G-code parameter ever contains letter T, or a T-code ever contains letter G. // dc42 doesn't think a G-code parameter ever contains letter T, or a T-code ever contains letter G.
// So it doesn't matter in which order we look for them. // So it doesn't matter in which order we look for them.
if (gb->Seen('G')) if (gb->Seen('G'))
{ {
@ -1913,7 +1910,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
break; break;
case 82: // Use absolute extruder positioning case 82: // Use absolute extruder positioning
if (drivesRelative) if (drivesRelative) // don't reset the absolute extruder position if it was already absolute
{ {
for (int8_t extruder = AXES; extruder < DRIVES; extruder++) for (int8_t extruder = AXES; extruder < DRIVES; extruder++)
{ {
@ -2048,7 +2045,8 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
f = max<float>(f, 0.0); f = max<float>(f, 0.0);
if (coolingInverted) if (coolingInverted)
{ {
platform->CoolingFan(255.0 - f); // Check if 1.0 or 255.0 may be used as the maximum value
platform->CoolingFan((f <= 1.0 ? 1.0 : 255.0) - f);
} }
else else
{ {
@ -2153,7 +2151,6 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
} }
break; break;
//TODO M119
case 119: case 119:
{ {
snprintf(reply, STRING_LENGTH, "Endstops - "); snprintf(reply, STRING_LENGTH, "Endstops - ");
@ -2311,16 +2308,16 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
if(!seen) if(!seen)
{ {
snprintf(reply, STRING_LENGTH, "Axis limits - "); snprintf(reply, STRING_LENGTH, "Accelerations: X: %f, Y: %f, Z: %f, E: ",
char comma = ','; platform->Acceleration(X_AXIS)/distanceScale, platform->Acceleration(Y_AXIS)/distanceScale,
for(int8_t axis = 0; axis < AXES; axis++) platform->Acceleration(Z_AXIS)/distanceScale);
for(int8_t drive = AXES; drive < DRIVES; drive++)
{ {
if(axis == AXES - 1) sncatf(reply, STRING_LENGTH, "%f", platform->Acceleration(drive)/distanceScale);
if(drive < DRIVES-1)
{ {
comma = ' '; sncatf(reply, STRING_LENGTH, ":");
} }
sncatf(reply, STRING_LENGTH, "%c: %.1f min, %.1f max%c ", axisLetters[axis],
platform->AxisMinimum(axis), platform->AxisMaximum(axis), comma);
} }
} }
} }
@ -2383,7 +2380,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
result = OffsetAxes(gb); result = OffsetAxes(gb);
break; break;
case 208: // Set/print maximum axis lengths. If there is an S parameter with value 1 then we set the min value, alse we set the max value. case 208: // Set/print maximum axis lengths. If there is an S parameter with value 1 then we set the min value, else we set the max value.
{ {
bool setMin = (gb->Seen('S') ? (gb->GetIValue() == 1): false); bool setMin = (gb->Seen('S') ? (gb->GetIValue() == 1): false);
bool seen = false; bool seen = false;
@ -2406,11 +2403,17 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
if (!seen) if (!seen)
{ {
snprintf(reply, STRING_LENGTH, "X:%.1f Y:%.1f Z:%.1f", snprintf(reply, STRING_LENGTH, "Axis limits - ");
(setMin) ? platform->AxisMinimum(X_AXIS) : platform->AxisMaximum(X_AXIS), char comma = ',';
(setMin) ? platform->AxisMinimum(Y_AXIS) : platform->AxisMaximum(Y_AXIS), for(int8_t axis = 0; axis < AXES; axis++)
(setMin) ? platform->AxisMinimum(Z_AXIS) : platform->AxisMaximum(Z_AXIS) {
); if(axis == AXES - 1)
{
comma = ' ';
}
sncatf(reply, STRING_LENGTH, "%c: %.1f min, %.1f max%c ", axisLetters[axis],
platform->AxisMinimum(axis), platform->AxisMaximum(axis), comma);
}
} }
} }
break; break;
@ -2494,7 +2497,23 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
SetPidParameters(gb, 1, reply); SetPidParameters(gb, 1, reply);
break; break;
case 302: // Allow cold extrudes case 302: // Allow, deny or report cold extrudes
if (gb->Seen('P'))
{
if (gb->GetIValue() > 0)
{
reprap.AllowColdExtrude();
}
else
{
reprap.DenyColdExtrude();
}
}
else
{
snprintf(reply, STRING_LENGTH, "Cold extrudes are %s, use M302 P[1/0] to allow or deny them",
reprap.ColdExtrude() ? "enabled" : "disabled");
}
break; break;
case 304: // Set/report heated bed PID values case 304: // Set/report heated bed PID values
@ -2661,28 +2680,47 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
} }
break; break;
case 558: // Set Z probe type case 558: // Set or report Z probe type and for which axes it is used
{
bool seen = false;
if(gb->Seen('P')) if(gb->Seen('P'))
{ {
platform->SetZProbeType(gb->GetIValue()); platform->SetZProbeType(gb->GetIValue());
seen = true;
}
bool zProbeAxes[AXES];
platform->GetZProbeAxes(zProbeAxes);
for(int axis=0; axis<AXES; axis++)
{
if (gb->Seen(axisLetters[axis]))
{
zProbeAxes[axis] = (gb->GetIValue() > 0);
seen = true;
}
}
if (seen)
{
platform->SetZProbeAxes(zProbeAxes);
} }
else else
{ {
snprintf(reply, STRING_LENGTH, "Z Probe: %d", platform->GetZProbeType()); snprintf(reply, STRING_LENGTH, "Z Probe type is %d and it is used for these axes:", platform->GetZProbeType());
for(int axis=0; axis<AXES; axis++)
{
if (zProbeAxes[axis])
{
sncatf(reply, STRING_LENGTH, " %c", axisLetters[axis]);
}
}
}
} }
break; break;
case 559: // Upload config.g or another gcode file to put in the sys directory case 559: // Upload config.g or another gcode file to put in the sys directory
{ {
const char* str; const char* str = (gb->Seen('P') ? gb->GetString() : platform->GetConfigFile());
if (gb->Seen('P'))
{
str = gb->GetString();
}
else
{
str = platform->GetConfigFile();
}
bool ok = OpenFileToWrite(platform->GetSysDir(), str, gb); bool ok = OpenFileToWrite(platform->GetSysDir(), str, gb);
if (ok) if (ok)
{ {
@ -2698,15 +2736,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
case 560: // Upload reprap.htm or another web interface file case 560: // Upload reprap.htm or another web interface file
{ {
const char* str; const char* str = (gb->Seen('P') ? gb->GetString() : INDEX_PAGE);
if (gb->Seen('P'))
{
str = gb->GetString();
}
else
{
str = INDEX_PAGE;
}
bool ok = OpenFileToWrite(platform->GetWebDir(), str, gb); bool ok = OpenFileToWrite(platform->GetWebDir(), str, gb);
if (ok) if (ok)
{ {
@ -2899,7 +2929,8 @@ bool GCodes::ChangeTool(int newToolNumber)
{ {
toolChangeSequence++; toolChangeSequence++;
} }
} else }
else
{ {
toolChangeSequence++; toolChangeSequence++;
} }
@ -2921,7 +2952,8 @@ bool GCodes::ChangeTool(int newToolNumber)
{ {
toolChangeSequence++; toolChangeSequence++;
} }
} else }
else
{ {
toolChangeSequence++; toolChangeSequence++;
} }
@ -2940,7 +2972,8 @@ bool GCodes::ChangeTool(int newToolNumber)
{ {
toolChangeSequence++; toolChangeSequence++;
} }
} else }
else
{ {
toolChangeSequence++; toolChangeSequence++;
} }
@ -3057,7 +3090,9 @@ bool GCodeBuffer::Put(char c)
// Strip out the line number and checksum // Strip out the line number and checksum
while (gcodeBuffer[gcodePointer] != ' ' && gcodeBuffer[gcodePointer]) while (gcodeBuffer[gcodePointer] != ' ' && gcodeBuffer[gcodePointer])
{
gcodePointer++; gcodePointer++;
}
// Anything there? // Anything there?
@ -3181,7 +3216,8 @@ const void GCodeBuffer::GetFloatArray(float a[], int& returnedLength)
{ {
a[i] = a[0]; a[i] = a[0];
} }
} else }
else
{ {
returnedLength = length; returnedLength = length;
} }

View file

@ -32,7 +32,9 @@ Heat::Heat(Platform* p, GCodes* g)
void Heat::Init() void Heat::Init()
{ {
for(int8_t heater=0; heater < HEATERS; heater++) for(int8_t heater=0; heater < HEATERS; heater++)
{
pids[heater]->Init(); pids[heater]->Init();
}
lastTime = platform->Time(); lastTime = platform->Time();
longWait = lastTime; longWait = lastTime;
active = true; active = true;
@ -41,7 +43,9 @@ void Heat::Init()
void Heat::Exit() void Heat::Exit()
{ {
for(int8_t heater=0; heater < HEATERS; heater++) for(int8_t heater=0; heater < HEATERS; heater++)
{
pids[heater]->SwitchOff(); pids[heater]->SwitchOff();
}
platform->Message(HOST_MESSAGE, "Heat class exited.\n"); platform->Message(HOST_MESSAGE, "Heat class exited.\n");
active = false; active = false;
} }
@ -116,6 +120,7 @@ void PID::Init()
temperatureFault = false; temperatureFault = false;
active = false; // Default to standby temperature active = false; // Default to standby temperature
switchedOff = true; switchedOff = true;
heatingUp = false;
} }
void PID::SwitchOn() void PID::SwitchOn()
@ -147,7 +152,8 @@ void PID::Spin()
return; return;
} }
// We are switched on. Check for faults. // We are switched on. Check for faults. Temperature silly-low or silly-high mean open-circuit
// or shorted thermistor respectively.
if(temperature < BAD_LOW_TEMPERATURE || temperature > BAD_HIGH_TEMPERATURE) if(temperature < BAD_LOW_TEMPERATURE || temperature > BAD_HIGH_TEMPERATURE)
{ {
@ -157,8 +163,9 @@ void PID::Spin()
platform->SetHeater(heater, 0.0); platform->SetHeater(heater, 0.0);
temperatureFault = true; temperatureFault = true;
switchedOff = true; switchedOff = true;
snprintf(scratchString, STRING_LENGTH, "Temperature measurement fault on heater %d, T = %.1f\n", heater, temperature); snprintf(scratchString, STRING_LENGTH, "Temperature fault on heater %d, T = %.1f\n", heater, temperature);
platform->Message(BOTH_MESSAGE, scratchString); platform->Message(BOTH_MESSAGE, scratchString);
reprap.FlagTemperatureFault(heater);
} }
} }
else else
@ -166,6 +173,36 @@ void PID::Spin()
badTemperatureCount = 0; badTemperatureCount = 0;
} }
// Now check how long it takes to warm up. If too long, maybe the thermistor is not in contact with the heater
if(heatingUp && heater != HOT_BED) // FIXME - also check bed warmup time?
{
float tmp = standbyTemperature;
if(active)
{
tmp = activeTemperature;
}
tmp -= TEMPERATURE_CLOSE_ENOUGH;
if(temperature < tmp)
{
float tim = platform->Time() - timeSetHeating;
if(tim > TIME_TO_HOT)
{
platform->SetHeater(heater, 0.0);
temperatureFault = true;
switchedOff = true;
snprintf(scratchString, STRING_LENGTH, "Heating fault on heater %d, T = %.1f C; still not at temperature after %f seconds.\n",
heater, temperature, tim);
platform->Message(BOTH_MESSAGE, scratchString);
reprap.FlagTemperatureFault(heater);
}
}
else
{
heatingUp = false;
}
}
float targetTemperature = (active) ? activeTemperature : standbyTemperature; float targetTemperature = (active) ? activeTemperature : standbyTemperature;
float error = targetTemperature - temperature; float error = targetTemperature - temperature;
const PidParameters& pp = platform->GetPidParameters(heater); const PidParameters& pp = platform->GetPidParameters(heater);

13
Heat.h
View file

@ -60,6 +60,8 @@ class PID
int8_t heater; // The index of our heater int8_t heater; // The index of our heater
int8_t badTemperatureCount; // Count of sequential dud readings int8_t badTemperatureCount; // Count of sequential dud readings
bool temperatureFault; // Has our heater developed a fault? bool temperatureFault; // Has our heater developed a fault?
float timeSetHeating; // When we were switched on
bool heatingUp; // Are we heating up?
}; };
/** /**
@ -139,12 +141,22 @@ inline void PID::Activate()
{ {
SwitchOn(); SwitchOn();
active = true; active = true;
if(!heatingUp)
{
timeSetHeating = platform->Time();
}
heatingUp = activeTemperature > temperature;
} }
inline void PID::Standby() inline void PID::Standby()
{ {
SwitchOn(); SwitchOn();
active = false; active = false;
if(!heatingUp)
{
timeSetHeating = platform->Time();
}
heatingUp = standbyTemperature > temperature;
} }
inline void PID::ResetFault() inline void PID::ResetFault()
@ -158,6 +170,7 @@ inline void PID::SwitchOff()
platform->SetHeater(heater, 0.0); platform->SetHeater(heater, 0.0);
active = false; active = false;
switchedOff = true; switchedOff = true;
heatingUp = false;
} }

View file

@ -134,6 +134,7 @@ void Platform::Init()
nvData.macAddress = MAC_ADDRESS; nvData.macAddress = MAC_ADDRESS;
nvData.zProbeType = 0; // Default is to use the switch nvData.zProbeType = 0; // Default is to use the switch
nvData.zProbeAxes = Z_PROBE_AXES;
nvData.switchZProbeParameters.Init(0.0); nvData.switchZProbeParameters.Init(0.0);
nvData.irZProbeParameters.Init(Z_PROBE_STOP_HEIGHT); nvData.irZProbeParameters.Init(Z_PROBE_STOP_HEIGHT);
nvData.alternateZProbeParameters.Init(Z_PROBE_STOP_HEIGHT); nvData.alternateZProbeParameters.Init(Z_PROBE_STOP_HEIGHT);
@ -232,21 +233,21 @@ void Platform::Init()
{ {
if (stepPins[i] >= 0) if (stepPins[i] >= 0)
{ {
if(i == E0_DRIVE || i == E3_DRIVE) //STEP_PINS {14, 25, 5, X2, 41, 39, X4, 49} if(i == E0_DRIVE || i == E3_DRIVE) // STEP_PINS {14, 25, 5, X2, 41, 39, X4, 49}
pinModeNonDue(stepPins[i], OUTPUT); pinModeNonDue(stepPins[i], OUTPUT);
else else
pinMode(stepPins[i], OUTPUT); pinMode(stepPins[i], OUTPUT);
} }
if (directionPins[i] >= 0) if (directionPins[i] >= 0)
{ {
if(i == E0_DRIVE) //DIRECTION_PINS {15, 26, 4, X3, 35, 53, 51, 48} if(i == E0_DRIVE) // DIRECTION_PINS {15, 26, 4, X3, 35, 53, 51, 48}
pinModeNonDue(directionPins[i], OUTPUT); pinModeNonDue(directionPins[i], OUTPUT);
else else
pinMode(directionPins[i], OUTPUT); pinMode(directionPins[i], OUTPUT);
} }
if (enablePins[i] >= 0) if (enablePins[i] >= 0)
{ {
if(i == Z_AXIS || i==E0_DRIVE || i==E2_DRIVE) //ENABLE_PINS {29, 27, X1, X0, 37, X8, 50, 47} if(i == Z_AXIS || i == E0_DRIVE || i == E2_DRIVE) // ENABLE_PINS {29, 27, X1, X0, 37, X8, 50, 47}
pinModeNonDue(enablePins[i], OUTPUT); pinModeNonDue(enablePins[i], OUTPUT);
else else
pinMode(enablePins[i], OUTPUT); pinMode(enablePins[i], OUTPUT);
@ -272,7 +273,7 @@ void Platform::Init()
{ {
if (heatOnPins[i] >= 0) if (heatOnPins[i] >= 0)
{ {
if(i == E0_HEATER || i==E1_HEATER) //HEAT_ON_PINS {6, X5, X7, 7, 8, 9} if(i == E0_HEATER || i == E1_HEATER) // HEAT_ON_PINS {6, X5, X7, 7, 8, 9}
{ {
digitalWriteNonDue(heatOnPins[i], HIGH); // turn the heater off digitalWriteNonDue(heatOnPins[i], HIGH); // turn the heater off
pinModeNonDue(heatOnPins[i], OUTPUT); pinModeNonDue(heatOnPins[i], OUTPUT);
@ -391,6 +392,23 @@ int Platform::GetZProbeType() const
return nvData.zProbeType; return nvData.zProbeType;
} }
void Platform::SetZProbeAxes(const bool axes[AXES])
{
for(int axis=0; axis<AXES; axis++)
{
nvData.zProbeAxes[axis] = axes[axis];
}
WriteNvData();
}
void Platform::GetZProbeAxes(bool (&axes)[AXES])
{
for(int axis=0; axis<AXES; axis++)
{
axes[axis] = nvData.zProbeAxes[axis];
}
}
float Platform::ZProbeStopHeight() const float Platform::ZProbeStopHeight() const
{ {
switch (nvData.zProbeType) switch (nvData.zProbeType)
@ -793,11 +811,13 @@ void Platform::Diagnostics()
AppendMessage(BOTH_MESSAGE, scratchString); AppendMessage(BOTH_MESSAGE, scratchString);
reprap.Timing(); reprap.Timing();
#if LWIP_STATS
// Normally we should NOT try to display LWIP stats here, because it uses debugPrintf(), which will hang the system is no USB cable is connected. // Normally we should NOT try to display LWIP stats here, because it uses debugPrintf(), which will hang the system is no USB cable is connected.
if (reprap.Debug()) if (reprap.Debug())
{ {
stats_display(); stats_display();
} }
#endif
} }
void Platform::DiagnosticTest(int d) void Platform::DiagnosticTest(int d)
@ -930,9 +950,7 @@ void Platform::SetHeater(size_t heater, const float& power)
EndStopHit Platform::Stopped(int8_t drive) EndStopHit Platform::Stopped(int8_t drive)
{ {
if (nvData.zProbeType > 0) if (nvData.zProbeType > 0 && drive < AXES && nvData.zProbeAxes[drive])
{ // Z probe is used for both X and Z.
if (drive != Y_AXIS)
{ {
int zProbeVal = ZProbe(); int zProbeVal = ZProbe();
int zProbeADValue = int zProbeADValue =
@ -945,7 +963,6 @@ EndStopHit Platform::Stopped(int8_t drive)
else else
return noStop; return noStop;
} }
}
if (lowStopPins[drive] >= 0) if (lowStopPins[drive] >= 0)
{ {
@ -965,9 +982,13 @@ void Platform::SetDirection(byte drive, bool direction)
if(directionPins[drive] < 0) if(directionPins[drive] < 0)
return; return;
if(drive == E0_DRIVE) //DIRECTION_PINS {15, 26, 4, X3, 35, 53, 51, 48} if(drive == E0_DRIVE) //DIRECTION_PINS {15, 26, 4, X3, 35, 53, 51, 48}
{
digitalWriteNonDue(directionPins[drive], direction); digitalWriteNonDue(directionPins[drive], direction);
}
else else
{
digitalWrite(directionPins[drive], direction); digitalWrite(directionPins[drive], direction);
}
} }
void Platform::Disable(byte drive) void Platform::Disable(byte drive)
@ -1041,13 +1062,28 @@ float Platform::MotorCurrent(byte drive)
return (float)pot * maxStepperDigipotVoltage / (0.256 * 8.0 * senseResistor); return (float)pot * maxStepperDigipotVoltage / (0.256 * 8.0 * senseResistor);
} }
//Changed to be compatible with existing gcode norms // This is a bit of a compromise - old RepRaps used fan speeds in the range
// M106 S0 = fully off M106 S255 = fully on // [0, 255], which is very hardware dependent. It makes much more sense
// to specify speeds in [0.0, 1.0]. This looks at the value supplied (which
// the G Code reader will get right for a float or an int) and attempts to
// do the right thing whichever the user has done. This will only not work
// for an old-style fan speed of 1/255...
void Platform::CoolingFan(float speed) void Platform::CoolingFan(float speed)
{ {
if(coolingFanPin >= 0) if(coolingFanPin >= 0)
{ {
byte p =(byte)speed; byte p;
if(speed <= 1.0)
{
p = (byte)(255.0 * max<float>(0.0, speed));
}
else
{
p = (byte)speed;
}
// The cooling fan output pin gets inverted if HEAT_ON == 0 // The cooling fan output pin gets inverted if HEAT_ON == 0
analogWriteNonDue(coolingFanPin, (HEAT_ON == 0) ? (255 - p) : p); analogWriteNonDue(coolingFanPin, (HEAT_ON == 0) ? (255 - p) : p);
} }

View file

@ -99,6 +99,7 @@ Licence: GPL
#define Z_PROBE_STOP_HEIGHT (0.7) // mm #define Z_PROBE_STOP_HEIGHT (0.7) // mm
#define Z_PROBE_PIN (10) // Analogue pin number #define Z_PROBE_PIN (10) // Analogue pin number
#define Z_PROBE_MOD_PIN (52) // Digital pin number to turn the IR LED on (high) or off (low) #define Z_PROBE_MOD_PIN (52) // Digital pin number to turn the IR LED on (high) or off (low)
#define Z_PROBE_AXES {true, false, true} // Axes for which the Z-probe is normally used
const unsigned int numZProbeReadingsAveraged = 8; // we average this number of readings with IR on, and the same number with IR off const unsigned int numZProbeReadingsAveraged = 8; // we average this number of readings with IR on, and the same number with IR off
#define MAX_FEEDRATES {100.0, 100.0, 3.0, 20.0, 20.0, 20.0, 20.0, 20.0} // mm/sec #define MAX_FEEDRATES {100.0, 100.0, 3.0, 20.0, 20.0, 20.0, 20.0, 20.0} // mm/sec
@ -107,6 +108,12 @@ const unsigned int numZProbeReadingsAveraged = 8; // we average this number of r
#define INSTANT_DVS {15.0, 15.0, 0.2, 2.0, 2.0, 2.0, 2.0, 2.0} // (mm/sec) #define INSTANT_DVS {15.0, 15.0, 0.2, 2.0, 2.0, 2.0, 2.0, 2.0} // (mm/sec)
#define NUM_MIXING_DRIVES 1; //number of mixing drives #define NUM_MIXING_DRIVES 1; //number of mixing drives
#define E0_DRIVE 3 //the index of the first Extruder drive
#define E1_DRIVE 4 //the index of the second Extruder drive
#define E2_DRIVE 5 //the index of the third Extruder drive
#define E3_DRIVE 6 //the index of the fourth Extruder drive
#define E4_DRIVE 7 //the index of the fifth Extruder drive
// AXES // AXES
#define AXIS_MAXIMA {220, 200, 200} // mm #define AXIS_MAXIMA {220, 200, 200} // mm
@ -118,12 +125,6 @@ const unsigned int numZProbeReadingsAveraged = 8; // we average this number of r
#define Y_AXIS 1 // The index of the Y axis #define Y_AXIS 1 // The index of the Y axis
#define Z_AXIS 2 // The index of the Z axis #define Z_AXIS 2 // The index of the Z axis
#define E0_DRIVE 3 //the index of the first Extruder drive
#define E1_DRIVE 4 //the index of the second Extruder drive
#define E2_DRIVE 5 //the index of the third Extruder drive
#define E3_DRIVE 6 //the index of the fourth Extruder drive
#define E4_DRIVE 7 //the index of the fifth Extruder drive
// HEATERS - The bed is assumed to be the at index 0 // HEATERS - The bed is assumed to be the at index 0
#define TEMP_SENSE_PINS {5, 4, 0, 7, 8, 9} // Analogue pin numbers #define TEMP_SENSE_PINS {5, 4, 0, 7, 8, 9} // Analogue pin numbers
@ -168,11 +169,6 @@ const float defaultFullBand[HEATERS] = {5.0, 30.0, 30.0, 30.0, 30.0, 30.0}; //
const float defaultPidMin[HEATERS] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // minimum value of I-term const float defaultPidMin[HEATERS] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // minimum value of I-term
const float defaultPidMax[HEATERS] = {255, 180, 180, 180, 180, 180}; // maximum value of I-term, must be high enough to reach 245C for ABS printing const float defaultPidMax[HEATERS] = {255, 180, 180, 180, 180, 180}; // maximum value of I-term, must be high enough to reach 245C for ABS printing
#define STANDBY_TEMPERATURES {ABS_ZERO, ABS_ZERO} // We specify one for the bed, though it's not needed
#define ACTIVE_TEMPERATURES {ABS_ZERO, ABS_ZERO}
#define COOLING_FAN_PIN X6 // pin D34 is PWM capable but not an Arduino PWM pin - use X6 instead
#define HEAT_ON 0 // 0 for inverted heater (eg Duet v0.6) 1 for not (e.g. Duet v0.4)
#define STANDBY_TEMPERATURES {ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO} // We specify one for the bed, though it's not needed #define STANDBY_TEMPERATURES {ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO} // We specify one for the bed, though it's not needed
#define ACTIVE_TEMPERATURES {ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO} #define ACTIVE_TEMPERATURES {ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO, ABS_ZERO}
#define COOLING_FAN_PIN X6 //pin D34 is PWM capable but not an Arduino PWM pin - use X6 instead #define COOLING_FAN_PIN X6 //pin D34 is PWM capable but not an Arduino PWM pin - use X6 instead
@ -191,10 +187,10 @@ const unsigned int adDisconnectedVirtual = adDisconnectedReal << adOversampleBit
#define HOT_BED 0 // The index of the heated bed; set to -1 if there is no heated bed #define HOT_BED 0 // The index of the heated bed; set to -1 if there is no heated bed
#define E0_HEATER 1 //the index of the first extruder heater #define E0_HEATER 1 //the index of the first extruder heater
#define E1_HEATER 2 //the index of the first extruder heater #define E1_HEATER 2 //the index of the second extruder heater
#define E2_HEATER 3 //the index of the first extruder heater #define E2_HEATER 3 //the index of the third extruder heater
#define E3_HEATER 4 //the index of the first extruder heater #define E3_HEATER 4 //the index of the fourth extruder heater
#define E4_HEATER 5 //the index of the first extruder heater #define E4_HEATER 5 //the index of the fifth extruder heater
/****************************************************************************************************/ /****************************************************************************************************/
@ -346,17 +342,17 @@ class FileStore //: public InputOutput
public: public:
int8_t Status(); // Returns OR of IOStatus int8_t Status(); // Returns OR of IOStatus
bool Read(char& b); bool Read(char& b); // Read 1 byte
int Read(char* buf, unsigned int nBytes); int Read(char* buf, unsigned int nBytes); // Read a block of nBytes length
bool Write(char b); bool Write(char b); // Write 1 byte
bool Write(const char *s, unsigned int len); bool Write(const char *s, unsigned int len); // Write a block of len bytes
bool Write(const char* s); bool Write(const char* s); // Write a string
bool Close(); bool Close(); // Shut the file and tidy up
bool Seek(unsigned long pos); bool Seek(unsigned long pos); // Jump to pos in the file
bool GoToEnd(); // Position the file at the end (so you can write on the end). bool GoToEnd(); // Position the file at the end (so you can write on the end).
unsigned long Length(); // File size in bytes unsigned long Length(); // File size in bytes
void Duplicate(); void Duplicate(); // Create a second reference to this file
bool Flush(); bool Flush(); // Write remaining buffer data
friend class Platform; friend class Platform;
@ -610,6 +606,8 @@ public:
int GetZProbeSecondaryValues(int& v1, int& v2); int GetZProbeSecondaryValues(int& v1, int& v2);
void SetZProbeType(int iZ); void SetZProbeType(int iZ);
int GetZProbeType() const; int GetZProbeType() const;
void SetZProbeAxes(const bool axes[AXES]);
void GetZProbeAxes(bool (&axes)[AXES]);
void SetZProbing(bool starting); void SetZProbing(bool starting);
bool GetZProbeParameters(struct ZProbeParameters& params) const; bool GetZProbeParameters(struct ZProbeParameters& params) const;
bool SetZProbeParameters(const struct ZProbeParameters& params); bool SetZProbeParameters(const struct ZProbeParameters& params);
@ -617,8 +615,8 @@ public:
// Mixing support // Mixing support
void SetMixingDrives(int); // void SetMixingDrives(int);
int GetMixingDrives(); // int GetMixingDrives();
int8_t SlowestDrive() const; int8_t SlowestDrive() const;
@ -655,6 +653,7 @@ private:
ZProbeParameters irZProbeParameters; // Z probe values for the IR sensor ZProbeParameters irZProbeParameters; // Z probe values for the IR sensor
ZProbeParameters alternateZProbeParameters; // Z probe values for the alternate sensor ZProbeParameters alternateZProbeParameters; // Z probe values for the alternate sensor
int zProbeType; // the type of Z probe we are currently using int zProbeType; // the type of Z probe we are currently using
bool zProbeAxes[AXES]; // Z probe is used for these axes
PidParameters pidParams[HEATERS]; PidParameters pidParams[HEATERS];
byte ipAddress[4]; byte ipAddress[4];
byte netMask[4]; byte netMask[4];
@ -991,21 +990,6 @@ inline float Platform::AxisTotalLength(int8_t axis) const
return axisMaxima[axis] - axisMinima[axis]; return axisMaxima[axis] - axisMinima[axis];
} }
inline void Platform::SetMixingDrives(int num_drives)
{
if(num_drives>(DRIVES-AXES))
{
Message(HOST_MESSAGE, "More mixing extruder drives set with M160 than exist in firmware configuration\n");
return;
}
numMixingDrives = num_drives;
}
inline int Platform::GetMixingDrives()
{
return numMixingDrives;
}
//******************************************************************************************************** //********************************************************************************************************
// Drive the RepRap machine - Heat and temperature // Drive the RepRap machine - Heat and temperature

View file

@ -189,13 +189,12 @@ void RepRap::Init()
currentTool = NULL; currentTool = NULL;
const uint32_t wdtTicks = 256; // number of watchdog ticks @ 32768Hz/128 before the watchdog times out (max 4095) const uint32_t wdtTicks = 256; // number of watchdog ticks @ 32768Hz/128 before the watchdog times out (max 4095)
WDT_Enable(WDT, (wdtTicks << WDT_MR_WDV_Pos) | (wdtTicks << WDT_MR_WDD_Pos) | WDT_MR_WDRSTEN); // enable watchdog, reset the mcu if it times out WDT_Enable(WDT, (wdtTicks << WDT_MR_WDV_Pos) | (wdtTicks << WDT_MR_WDD_Pos) | WDT_MR_WDRSTEN); // enable watchdog, reset the mcu if it times out
coldExtrude = true; // DC42 changed default to true for compatibility because for now we are aiming for copatibility with RRP 0.78
active = true; // must do this before we start the network, else the watchdog may time out active = true; // must do this before we start the network, else the watchdog may time out
platform->Message(HOST_MESSAGE, NAME); snprintf(scratchString, STRING_LENGTH, "%s Version %s dated %s\n", NAME, VERSION, DATE);
platform->Message(HOST_MESSAGE, " Version "); platform->Message(HOST_MESSAGE, scratchString);
platform->Message(HOST_MESSAGE, VERSION);
platform->Message(HOST_MESSAGE, ", dated ");
platform->Message(HOST_MESSAGE, DATE);
platform->Message(HOST_MESSAGE, ".\n\nExecuting "); platform->Message(HOST_MESSAGE, ".\n\nExecuting ");
platform->Message(HOST_MESSAGE, platform->GetConfigFile()); platform->Message(HOST_MESSAGE, platform->GetConfigFile());
platform->Message(HOST_MESSAGE, "...\n\n"); platform->Message(HOST_MESSAGE, "...\n\n");

View file

@ -41,7 +41,12 @@ class RepRap
Tool* GetCurrentTool(); Tool* GetCurrentTool();
Tool* GetTool(int toolNumber); Tool* GetTool(int toolNumber);
void SetToolVariables(int toolNumber, float* standbyTemperatures, float* activeTemperatures); void SetToolVariables(int toolNumber, float* standbyTemperatures, float* activeTemperatures);
void AllowColdExtrude();
void DenyColdExtrude();
bool ColdExtrude() const;
void PrintTool(int toolNumber, char* reply) const; void PrintTool(int toolNumber, char* reply) const;
void FlagTemperatureFault(int8_t dudHeater);
void ClearTemperatureFault(int8_t wasDudHeater);
Platform* GetPlatform() const; Platform* GetPlatform() const;
Move* GetMove() const; Move* GetMove() const;
Heat* GetHeat() const; Heat* GetHeat() const;
@ -74,6 +79,7 @@ class RepRap
bool resetting; bool resetting;
uint16_t activeExtruders; uint16_t activeExtruders;
uint16_t activeHeaters; uint16_t activeHeaters;
bool coldExtrude;
}; };
inline Platform* RepRap::GetPlatform() const { return platform; } inline Platform* RepRap::GetPlatform() const { return platform; }
@ -86,6 +92,26 @@ inline bool RepRap::Debug() const { return debug; }
inline Tool* RepRap::GetCurrentTool() { return currentTool; } inline Tool* RepRap::GetCurrentTool() { return currentTool; }
inline uint16_t RepRap::GetExtrudersInUse() const { return activeExtruders; } inline uint16_t RepRap::GetExtrudersInUse() const { return activeExtruders; }
inline uint16_t RepRap::GetHeatersInUse() const { return activeHeaters; } inline uint16_t RepRap::GetHeatersInUse() const { return activeHeaters; }
inline bool RepRap::ColdExtrude() const { return coldExtrude; }
inline void RepRap::AllowColdExtrude() { coldExtrude = true; }
inline void RepRap::DenyColdExtrude() { coldExtrude = false; }
inline void RepRap::FlagTemperatureFault(int8_t dudHeater)
{
if(toolList != NULL)
{
toolList->FlagTemperatureFault(dudHeater);
}
}
inline void RepRap::ClearTemperatureFault(int8_t wasDudHeater)
{
reprap.GetHeat()->ResetFault(wasDudHeater);
if(toolList != NULL)
{
toolList->ClearTemperatureFault(wasDudHeater);
}
}
inline void RepRap::SetDebug(bool d) inline void RepRap::SetDebug(bool d)
{ {

View file

@ -32,6 +32,8 @@ Tool::Tool(int toolNumber, long d[], int dCount, long h[], int hCount)
active = false; active = false;
driveCount = dCount; driveCount = dCount;
heaterCount = hCount; heaterCount = hCount;
heaterFault = false;
mixing = false;
if(driveCount > 0) if(driveCount > 0)
{ {
@ -43,9 +45,12 @@ Tool::Tool(int toolNumber, long d[], int dCount, long h[], int hCount)
return; return;
} }
drives = new int[driveCount]; drives = new int[driveCount];
mix = new float[driveCount];
float r = 1.0/(float)driveCount;
for(int8_t drive = 0; drive < driveCount; drive++) for(int8_t drive = 0; drive < driveCount; drive++)
{ {
drives[drive] = d[drive]; drives[drive] = d[drive];
mix[drive] = r;
} }
} }
@ -70,7 +75,7 @@ Tool::Tool(int toolNumber, long d[], int dCount, long h[], int hCount)
} }
} }
void Tool::Print(char* reply) const void Tool::Print(char* reply)
{ {
snprintf(reply, STRING_LENGTH, "Tool %d - drives: ", myNumber); snprintf(reply, STRING_LENGTH, "Tool %d - drives: ", myNumber);
char comma = ','; char comma = ',';
@ -97,6 +102,7 @@ void Tool::Print(char* reply) const
sncatf(reply, STRING_LENGTH, " status: %s", active ? "selected" : "standby"); sncatf(reply, STRING_LENGTH, " status: %s", active ? "selected" : "standby");
} }
float Tool::MaxFeedrate() const float Tool::MaxFeedrate() const
{ {
if(driveCount <= 0) if(driveCount <= 0)
@ -138,17 +144,83 @@ float Tool::InstantDv() const
// Add a tool to the end of the linked list. // Add a tool to the end of the linked list.
// (We must already be in it.) // (We must already be in it.)
void Tool::AddTool(Tool* t) void Tool::AddTool(Tool* tool)
{ {
Tool* last = this; Tool* t = this;
Tool* n = next; Tool* last;
while(t != NULL)
{
if(t->Number() == tool->Number())
{
reprap.GetPlatform()->Message(HOST_MESSAGE, "Add tool: tool number already in use.\n");
return;
}
last = t;
t = t->Next();
}
tool->next = NULL; // Defensive...
last->next = tool;
}
// There is a temperature fault on a heater.
// Disable all tools using that heater.
// This function must be called for the first
// entry in the linked list.
void Tool::FlagTemperatureFault(int8_t heater)
{
Tool* n = this;
while(n != NULL) while(n != NULL)
{ {
last = n; n->SetTemperatureFault(heater);
n = n->Next(); n = n->Next();
} }
t->next = NULL; // Defensive... }
last->next = t;
void Tool::ClearTemperatureFault(int8_t heater)
{
Tool* n = this;
while(n != NULL)
{
n->ResetTemperatureFault(heater);
n = n->Next();
}
}
void Tool::SetTemperatureFault(int8_t dudHeater)
{
for(int8_t heater = 0; heater < heaterCount; heater++)
{
if(dudHeater == heaters[heater])
{
heaterFault = true;
return;
}
}
}
void Tool::ResetTemperatureFault(int8_t wasDudHeater)
{
for(int8_t heater = 0; heater < heaterCount; heater++)
{
if(wasDudHeater == heaters[heater])
{
heaterFault = false;
return;
}
}
}
bool Tool::AllHeatersAtHighTemperature() const
{
for(int8_t heater = 0; heater < heaterCount; heater++)
{
if(reprap.GetHeat()->GetTemperature(heaters[heater]) < HOT_ENOUGH_TO_EXTRUDE)
{
return false;
}
}
return true;
} }
void Tool::Activate(Tool* currentlyActive) void Tool::Activate(Tool* currentlyActive)
@ -200,6 +272,17 @@ void Tool::GetVariables(float* standby, float* active) const
} }
} }
bool Tool::ToolCanDrive() const
{
if(heaterFault)
return false;
if(reprap.ColdExtrude() || AllHeatersAtHighTemperature())
return true;
return false;
}
// Update the number of active drives and extruders in use to reflect what this tool uses // Update the number of active drives and extruders in use to reflect what this tool uses
void Tool::UpdateExtruderAndHeaterCount(uint16_t &numExtruders, uint16_t &numHeaters) const void Tool::UpdateExtruderAndHeaterCount(uint16_t &numExtruders, uint16_t &numHeaters) const
{ {

53
Tool.h
View file

@ -34,14 +34,20 @@ public:
void GetOffset(float& xx, float& yy, float& zz) const; void GetOffset(float& xx, float& yy, float& zz) const;
int DriveCount() const; int DriveCount() const;
int Drive(int driveNumber) const; int Drive(int driveNumber) const;
bool ToolCanDrive() const;
int HeaterCount() const; int HeaterCount() const;
int Heater(int heaterNumber) const; int Heater(int heaterNumber) const;
int Number() const; int Number() const;
void SetVariables(float* standby, float* active); void SetVariables(float* standby, float* active);
void GetVariables(float* standby, float* active) const; void GetVariables(float* standby, float* active) const;
void DefineMix(float* m);
float* GetMix() const;
void TurnMixingOn();
void TurnMixingOff();
bool Mixing() const;
float MaxFeedrate() const; float MaxFeedrate() const;
float InstantDv() const; float InstantDv() const;
void Print(char* reply) const; void Print(char* reply);
friend class RepRap; friend class RepRap;
@ -50,13 +56,20 @@ protected:
Tool* Next() const; Tool* Next() const;
void Activate(Tool* currentlyActive); void Activate(Tool* currentlyActive);
void Standby(); void Standby();
void AddTool(Tool* t); void AddTool(Tool* tool);
void FlagTemperatureFault(int8_t dudHeater);
void ClearTemperatureFault(int8_t wasDudHeater);
void UpdateExtruderAndHeaterCount(uint16_t &extruders, uint16_t &heaters) const; void UpdateExtruderAndHeaterCount(uint16_t &extruders, uint16_t &heaters) const;
private: private:
void SetTemperatureFault(int8_t dudHeater);
void ResetTemperatureFault(int8_t wasDudHeater);
bool AllHeatersAtHighTemperature() const;
int myNumber; int myNumber;
int* drives; int* drives;
float* mix;
bool mixing;
int driveCount; int driveCount;
int* heaters; int* heaters;
float* activeTemperatures; float* activeTemperatures;
@ -64,13 +77,9 @@ private:
int heaterCount; int heaterCount;
Tool* next; Tool* next;
bool active; bool active;
bool heaterFault;
}; };
inline int Tool::DriveCount() const
{
return driveCount;
}
inline int Tool::Drive(int driveNumber) const inline int Tool::Drive(int driveNumber) const
{ {
return drives[driveNumber]; return drives[driveNumber];
@ -96,7 +105,37 @@ inline int Tool::Number() const
return myNumber; return myNumber;
} }
inline void Tool::DefineMix(float* m)
{
for(int8_t drive = 0; drive < driveCount; drive++)
{
mix[drive] = m[drive];
}
}
inline float* Tool::GetMix() const
{
return mix;
}
inline void Tool::TurnMixingOn()
{
mixing = true;
}
inline void Tool::TurnMixingOff()
{
mixing = false;
}
inline bool Tool::Mixing() const
{
return mixing;
}
inline int Tool::DriveCount() const
{
return driveCount;
}
#endif /* TOOL_H_ */ #endif /* TOOL_H_ */

View file

@ -495,7 +495,6 @@ void Webserver::ConnectionLost(const ConnectionState *cs)
if (interpreter->DebugEnabled()) if (interpreter->DebugEnabled())
{ {
debugPrintf("Webserver: ConnectionLost called with port %d\n", local_port); debugPrintf("Webserver: ConnectionLost called with port %d\n", local_port);
platform->Message(DEBUG_MESSAGE, scratchString);
} }
interpreter->ConnectionLost(local_port); interpreter->ConnectionLost(local_port);