Version 0.78d-dc42
M116 now accepts a P parameter so that you can wait just for the heaters associated with a particular tool M220 and M221 commands report the current override factor if no S parameter is provided Multiple "Filament used" values from gcode files are reported to the web interface Active and standby temperatures for all heaters are reported to the web interface Bug fix: defining a tool with no drives or no extruders would cause it to use a collection of drives or extruders depending on the values of un-initialised array elements Bug fix: running a macro file would reset the extruder position to a value depending on what extrusion (if any) was requested by the last movement command in the macro file
This commit is contained in:
parent
8f1dd9c315
commit
8bab7ab035
6 changed files with 155 additions and 45 deletions
|
@ -48,6 +48,18 @@ Additional functionality in 0.78a-dc42 release compared to RRP 0.78:
|
|||
|
||||
* M0 and M1 commands now turn all heaters off instead of setting them to their standby temperatures
|
||||
|
||||
* When using a Z probe, Z homing and bed probing are done in two stages (a fast stage followed by a slow stage) for better accuracy.
|
||||
|
||||
* M116 takes an optional P parameter to specify which tool to wait for. If no P parameter is given, it waits for all tools and the bed as before. The main purpose of this is that on a tool change, you can wait for the new tool to heat up to operating temperature but not wait for the old tool to cool down to standby temperature.
|
||||
|
||||
* When fetching file info, if the gcode file contains more than one 'filament used' comment, the filament lengths in all of them are returned to the web interface
|
||||
|
||||
* The active and standby temperatures of all heaters are included in the status poll response
|
||||
|
||||
* The default initial Z homing and bed probing speed has been increased. This is possible because Z homing and bed probing slow down when the probe reading is approaching the target value.
|
||||
|
||||
* The M220 and M221 commands now return the override factors if no S parameter is provided
|
||||
|
||||
* FTP server supported (thanks zombiepantslol)
|
||||
|
||||
* Telnet server supported (thanks zombiepantslol)
|
||||
|
@ -64,6 +76,10 @@ Additional functionality in 0.78a-dc42 release compared to RRP 0.78:
|
|||
|
||||
* Bug fix: if bed compensation or axis compensation was in use, then a G1 S1 command to home an axis could be prematurely terminated if the head was already at the endstop position for a different axis.
|
||||
|
||||
* Bug fix: if a tool was defined as using zero drives or zero extruders, it would be treated as assuming a collection of drives or extruders according to the vales in an uninitialised array
|
||||
|
||||
* Bug fix: the cumulative extruder positions were getting reset (typically to zero) on a tool change or other macro file execution
|
||||
|
||||
|
||||
Additional functionality in web interface 0.95 compared to RRP 0.65:
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ Licence: GPL
|
|||
#define CONFIGURATION_H
|
||||
|
||||
#define NAME "RepRapFirmware"
|
||||
#define VERSION "0.78c-dc42"
|
||||
#define DATE "2014-07-15"
|
||||
#define VERSION "0.78d-dc42"
|
||||
#define DATE "2014-07-16"
|
||||
#define LAST_AUTHOR "reprappro, dc42. zpl"
|
||||
|
||||
// Other firmware that we might switch to be compatible with.
|
||||
|
|
85
GCodes.cpp
85
GCodes.cpp
|
@ -305,15 +305,16 @@ bool GCodes::Pop()
|
|||
axesRelative = axesRelativeStack[stackPointer];
|
||||
fileBeingPrinted.MoveFrom(fileStack[stackPointer]);
|
||||
platform->PopMessageIndent();
|
||||
// Remember for next time if we have just been switched
|
||||
// to absolute drive moves
|
||||
|
||||
// Remember for next time if we have just been switched to absolute drive moves
|
||||
// DC 2014-07-16: the following code is wrong, it messes up the absolute extruder position (typically it resets it to zero) and does nothing useful as far as I can see.
|
||||
// So I am commenting it out.
|
||||
//for(int8_t i = AXES; i < DRIVES; i++)
|
||||
//{
|
||||
// lastPos[i - AXES] = moveBuffer[i];
|
||||
//}
|
||||
|
||||
for(int8_t i = AXES; i < DRIVES; i++)
|
||||
{
|
||||
lastPos[i - AXES] = moveBuffer[i];
|
||||
}
|
||||
|
||||
// Do a null move to set the correct feedrate
|
||||
// Set the correct feedrate
|
||||
|
||||
moveBuffer[DRIVES] = feedrateStack[stackPointer];
|
||||
|
||||
|
@ -644,7 +645,9 @@ bool GCodes::OffsetAxes(GCodeBuffer* gb)
|
|||
{
|
||||
//LoadMoveBufferFromArray(record);
|
||||
for (int drive = 0; drive <= DRIVES; drive++)
|
||||
{
|
||||
moveBuffer[drive] = record[drive];
|
||||
}
|
||||
reprap.GetMove()->SetLiveCoordinates(record); // This doesn't transform record
|
||||
reprap.GetMove()->SetPositions(record); // This does
|
||||
offSetSet = false;
|
||||
|
@ -1258,6 +1261,10 @@ void GCodes::AddNewTool(GCodeBuffer *gb)
|
|||
{
|
||||
gb->GetLongArray(drives, dCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
dCount = 0;
|
||||
}
|
||||
|
||||
long heaters[HEATERS];
|
||||
int hCount = HEATERS;
|
||||
|
@ -1265,6 +1272,10 @@ void GCodes::AddNewTool(GCodeBuffer *gb)
|
|||
{
|
||||
gb->GetLongArray(heaters, hCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
hCount = 0;
|
||||
}
|
||||
|
||||
Tool* tool = new Tool(toolNumber, drives, dCount, heaters, hCount);
|
||||
reprap.AddTool(tool);
|
||||
|
@ -1870,7 +1881,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
|
|||
platform->SetAtxPower(code == 80);
|
||||
break;
|
||||
|
||||
case 82:
|
||||
case 82: // Use absolute extruder positioning
|
||||
for (int8_t extruder = AXES; extruder < DRIVES; extruder++)
|
||||
{
|
||||
lastPos[extruder - AXES] = 0.0;
|
||||
|
@ -1878,12 +1889,15 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
|
|||
drivesRelative = false;
|
||||
break;
|
||||
|
||||
case 83:
|
||||
for (int8_t extruder = AXES; extruder < DRIVES; extruder++)
|
||||
case 83: // Use relative extruder positioning
|
||||
if (!drivesRelative) // don't reset the absolute extruder position if it was already relative
|
||||
{
|
||||
lastPos[extruder - AXES] = 0.0;
|
||||
for (int8_t extruder = AXES; extruder < DRIVES; extruder++)
|
||||
{
|
||||
lastPos[extruder - AXES] = 0.0;
|
||||
}
|
||||
drivesRelative = true;
|
||||
}
|
||||
drivesRelative = true;
|
||||
break;
|
||||
|
||||
case 84: // Motors off - deprecated, use M18
|
||||
|
@ -2060,7 +2074,28 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
result = reprap.GetHeat()->AllHeatersAtSetTemperatures(true);
|
||||
if (gb->Seen('P'))
|
||||
{
|
||||
// Wait for the heaters associated with the specified tool to be ready
|
||||
int toolNumber = gb->GetIValue();
|
||||
Tool* tool = reprap.GetTool(toolNumber);
|
||||
if (tool != NULL)
|
||||
{
|
||||
for (int i = 0; i < tool->HeaterCount(); ++i)
|
||||
{
|
||||
if (!reprap.GetHeat()->HeaterAtSetTemperature(tool->Heater(i)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for all heaters to be ready
|
||||
result = reprap.GetHeat()->AllHeatersAtSetTemperatures(true);
|
||||
}
|
||||
break;
|
||||
|
||||
//TODO M119
|
||||
|
@ -2306,19 +2341,21 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
|
|||
case 220: // set speed factor override percentage
|
||||
if (gb->Seen('S'))
|
||||
{
|
||||
float newSpeedFactor = gb->GetFValue()/(60 * 100.0); // include the conversion from mm/minute to mm/second
|
||||
float newSpeedFactor = gb->GetFValue()/(60.0 * 100.0); // include the conversion from mm/minute to mm/second
|
||||
if (newSpeedFactor > 0)
|
||||
{
|
||||
speedFactorChange *= newSpeedFactor/speedFactor;
|
||||
speedFactor = newSpeedFactor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(reply, STRING_LENGTH, "Speed factor override: %.1f%%\n", speedFactor * (60.0 * 100.0));
|
||||
}
|
||||
break;
|
||||
|
||||
case 221: // set extrusion factor override percentage
|
||||
if (gb->Seen('S')) // S parameter sets the override percentage
|
||||
{
|
||||
float extrusionFactor = gb->GetFValue()/100.0;
|
||||
int drive;
|
||||
if (gb->Seen('D')) // D parameter (if present) selects the extruder drive number
|
||||
{
|
||||
|
@ -2328,9 +2365,19 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
|
|||
{
|
||||
drive = 0; // default to drive 0 if not specified
|
||||
}
|
||||
if (drive >= 0 && drive < DRIVES - AXES && extrusionFactor >= 0)
|
||||
|
||||
if (gb->Seen('S')) // S parameter sets the override percentage
|
||||
{
|
||||
extrusionFactors[drive] = extrusionFactor;
|
||||
float extrusionFactor = gb->GetFValue()/100.0;
|
||||
if (drive >= 0 && drive < DRIVES - AXES && extrusionFactor >= 0)
|
||||
{
|
||||
extrusionFactors[drive] = extrusionFactor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(reply, STRING_LENGTH, "Extrusion factor override for drive %d: %.1f%%\n", drive, extrusionFactors[drive] * 100.0);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -150,9 +150,9 @@ const unsigned int numZProbeReadingsAveraged = 8; // we average this number of r
|
|||
|
||||
// AXES
|
||||
|
||||
#define AXIS_MAXIMA {220, 200, 200} // mm
|
||||
#define AXIS_MINIMA {0, 0, 0} // mm
|
||||
#define HOME_FEEDRATES {50.0, 50.0, 1.0} // mm/sec
|
||||
#define AXIS_MAXIMA {220, 200, 200} // mm
|
||||
#define AXIS_MINIMA {0, 0, 0} // mm
|
||||
#define HOME_FEEDRATES {50.0, 50.0, 100.0/60.0} // mm/sec (increased Z because we slow down z-homing when approaching the target height)
|
||||
#define HEAD_OFFSETS {0.0, 0.0, 0.0} // mm
|
||||
|
||||
#define X_AXIS 0 // The index of the X axis in the arrays
|
||||
|
|
|
@ -888,14 +888,29 @@ bool Webserver::HttpInterpreter::GetJsonResponse(const char* request, const char
|
|||
else if (StringEquals(request, "fileinfo") && StringEquals(key, "name"))
|
||||
{
|
||||
unsigned long length;
|
||||
float height, filament, layerHeight;
|
||||
float height, filament[DRIVES - AXES], layerHeight;
|
||||
unsigned int numFilaments = DRIVES - AXES;
|
||||
char generatedBy[50];
|
||||
bool found = webserver->GetFileInfo(value, length, height, filament, layerHeight, generatedBy, ARRAY_SIZE(generatedBy));
|
||||
bool found = webserver->GetFileInfo(value, length, height, filament, numFilaments, layerHeight, generatedBy, ARRAY_SIZE(generatedBy));
|
||||
if (found)
|
||||
{
|
||||
snprintf(jsonResponse, ARRAY_UPB(jsonResponse),
|
||||
"{\"err\":0,\"size\":%lu,\"height\":%.2f,\"filament\":%.1f,\"layerHeight\":%.2f,\"generatedBy\":\"%s\"}",
|
||||
length, height, filament, layerHeight, generatedBy);
|
||||
"{\"err\":0,\"size\":%lu,\"height\":%.2f,\"layerHeight\":%.2f,\"filament\":",
|
||||
length, height, layerHeight);
|
||||
char ch = '[';
|
||||
if (numFilaments == 0)
|
||||
{
|
||||
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c", ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int i = 0; i < numFilaments; ++i)
|
||||
{
|
||||
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c%.1f", ch, filament[i]);
|
||||
ch = ',';
|
||||
}
|
||||
}
|
||||
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "],\"generatedBy\":\"%s\"}", generatedBy);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -968,7 +983,7 @@ void Webserver::HttpInterpreter::GetStatusResponse(uint8_t type)
|
|||
char ch = (reprap.IsStopped()) ? 'S' : (gc->PrintingAFile()) ? 'P' : 'I';
|
||||
snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"status\":\"%c\",\"heaters\":", ch);
|
||||
|
||||
// Send the heater temperatures
|
||||
// Send the heater actual temperatures
|
||||
ch = '[';
|
||||
for (int8_t heater = 0; heater < reprap.GetHeatersInUse(); heater++)
|
||||
{
|
||||
|
@ -976,7 +991,25 @@ void Webserver::HttpInterpreter::GetStatusResponse(uint8_t type)
|
|||
ch = ',';
|
||||
}
|
||||
|
||||
// Send XYZ and extruder positions
|
||||
// Send the heater active temperatures
|
||||
strncat(jsonResponse, "],\"active\":", ARRAY_UPB(jsonResponse));
|
||||
ch = '[';
|
||||
for (int8_t heater = 0; heater < reprap.GetHeatersInUse(); heater++)
|
||||
{
|
||||
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c\%.1f", ch, reprap.GetHeat()->GetActiveTemperature(heater));
|
||||
ch = ',';
|
||||
}
|
||||
|
||||
// Send the heater standby temperatures
|
||||
strncat(jsonResponse, "],\"standby\":", ARRAY_UPB(jsonResponse));
|
||||
ch = '[';
|
||||
for (int8_t heater = 0; heater < reprap.GetHeatersInUse(); heater++)
|
||||
{
|
||||
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c\%.1f", ch, reprap.GetHeat()->GetStandbyTemperature(heater));
|
||||
ch = ',';
|
||||
}
|
||||
|
||||
// Send XYZ positions
|
||||
float liveCoordinates[DRIVES + 1];
|
||||
reprap.GetMove()->LiveCoordinates(liveCoordinates);
|
||||
strncat(jsonResponse, "],\"pos\":", ARRAY_UPB(jsonResponse)); // announce the XYZ position
|
||||
|
@ -986,6 +1019,8 @@ void Webserver::HttpInterpreter::GetStatusResponse(uint8_t type)
|
|||
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c%.2f", ch, liveCoordinates[drive]);
|
||||
ch = ',';
|
||||
}
|
||||
|
||||
// Send extruder total extrusion since power up or last G92
|
||||
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "],\"extr\":"); // announce the extruder positions
|
||||
ch = '[';
|
||||
for (int8_t drive = 0; drive < reprap.GetExtrudersInUse(); drive++) // loop through extruders
|
||||
|
@ -2339,8 +2374,8 @@ void Webserver::TelnetInterpreter::HandleGcodeReply(const char *reply)
|
|||
//
|
||||
//********************************************************************************************
|
||||
|
||||
// Get information for a file on the SD card
|
||||
bool Webserver::GetFileInfo(const char *fileName, unsigned long& length, float& height, float& filamentUsed, float& layerHeight, char* generatedBy, size_t generatedByLength)
|
||||
// Get information for a file on the SD card.
|
||||
bool Webserver::GetFileInfo(const char *fileName, unsigned long& length, float& height, float *filamentUsed, unsigned int& numFilaments, float& layerHeight, char* generatedBy, size_t generatedByLength)
|
||||
{
|
||||
FileStore *f = platform->GetFileStore("0:/", fileName, false);
|
||||
if (f != NULL)
|
||||
|
@ -2348,7 +2383,6 @@ bool Webserver::GetFileInfo(const char *fileName, unsigned long& length, float&
|
|||
// Try to find the object height by looking for the last G1 Zxxx command in the file
|
||||
length = f->Length();
|
||||
height = 0.0;
|
||||
filamentUsed = 0.0;
|
||||
layerHeight = 0.0;
|
||||
generatedBy[0] = 0;
|
||||
|
||||
|
@ -2424,7 +2458,7 @@ bool Webserver::GetFileInfo(const char *fileName, unsigned long& length, float&
|
|||
}
|
||||
unsigned long seekPos = length - sizeToRead; // read on a 512b boundary
|
||||
size_t sizeToScan = sizeToRead;
|
||||
bool foundFilamentUsed = false;
|
||||
unsigned int filamentsFound = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (!f->Seek(seekPos))
|
||||
|
@ -2437,10 +2471,20 @@ bool Webserver::GetFileInfo(const char *fileName, unsigned long& length, float&
|
|||
break; // read failed so give up
|
||||
}
|
||||
buf[sizeToScan] = 0; // add a null terminator
|
||||
if (!foundFilamentUsed)
|
||||
|
||||
// Search for filament used
|
||||
float filaments[DRIVES - AXES];
|
||||
unsigned int nFilaments = FindFilamentUsed(buf, sizeToScan, filaments, DRIVES - AXES);
|
||||
if (nFilaments != 0 && nFilaments >= filamentsFound)
|
||||
{
|
||||
foundFilamentUsed = FindFilamentUsed(buf, sizeToScan, filamentUsed);
|
||||
filamentsFound = min<unsigned int>(nFilaments, numFilaments);
|
||||
for (unsigned int i = 0; i < filamentsFound; ++i)
|
||||
{
|
||||
filamentUsed[i] = filaments[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Search for object height
|
||||
if (FindHeight(buf, sizeToScan, height))
|
||||
{
|
||||
break; // quit if found height
|
||||
|
@ -2454,6 +2498,7 @@ bool Webserver::GetFileInfo(const char *fileName, unsigned long& length, float&
|
|||
sizeToScan = readSize + overlap;
|
||||
memcpy(buf + sizeToRead, buf, overlap);
|
||||
}
|
||||
numFilaments = filamentsFound;
|
||||
}
|
||||
}
|
||||
f->Close();
|
||||
|
@ -2505,11 +2550,13 @@ bool Webserver::FindHeight(const char* buf, size_t len, float& height)
|
|||
}
|
||||
|
||||
// Scan the buffer for the filament used. The buffer is null-terminated.
|
||||
bool Webserver::FindFilamentUsed(const char* buf, size_t len, float& filamentUsed)
|
||||
// Returns the number of filaments found.
|
||||
unsigned int Webserver::FindFilamentUsed(const char* buf, size_t len, float *filamentUsed, unsigned int maxFilaments)
|
||||
{
|
||||
const char* filamentUsedStr = "ilament used"; // comment string used by slic3r, followed by filament used and "mm"
|
||||
const char* p = strstr(buf, filamentUsedStr);
|
||||
if (p != NULL)
|
||||
unsigned int filamentsFound = 0;
|
||||
const char* p = buf;
|
||||
while (filamentsFound < maxFilaments && (p = strstr(p, filamentUsedStr)) != NULL)
|
||||
{
|
||||
p += strlen(filamentUsedStr);
|
||||
while(strchr(" :=\t", *p) != NULL)
|
||||
|
@ -2519,15 +2566,15 @@ bool Webserver::FindFilamentUsed(const char* buf, size_t len, float& filamentUse
|
|||
if (isDigit(*p))
|
||||
{
|
||||
char* q;
|
||||
filamentUsed = strtod(p, &q);
|
||||
filamentUsed[filamentsFound] = strtod(p, &q);
|
||||
if (*q == 'm' && *(q + 1) != 'm')
|
||||
{
|
||||
filamentUsed *= 1000.0; // Cura outputs filament used in metres not mm
|
||||
filamentUsed[filamentsFound] *= 1000.0; // Cura outputs filament used in metres not mm
|
||||
}
|
||||
return true;
|
||||
++filamentsFound;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return filamentsFound;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -292,9 +292,9 @@ class Webserver
|
|||
void StoreGcodeData(const char* data, size_t len);
|
||||
|
||||
// File info methods
|
||||
bool GetFileInfo(const char *fileName, unsigned long& length, float& height, float& filamentUsed, float& layerHeight, char* generatedBy, size_t generatedByLength);
|
||||
bool GetFileInfo(const char *fileName, unsigned long& length, float& height, float *filamentUsed, unsigned int& numFilaments, float& layerHeight, char* generatedBy, size_t generatedByLength);
|
||||
static bool FindHeight(const char* buf, size_t len, float& height);
|
||||
static bool FindFilamentUsed(const char* buf, size_t len, float& filamentUsed);
|
||||
static unsigned int FindFilamentUsed(const char* buf, size_t len, float *filamentUsed, unsigned int maxFilaments);
|
||||
static void CopyParameterText(const char* src, char *dst, size_t length);
|
||||
|
||||
// Buffer to hold gcode that is ready for processing
|
||||
|
|
Reference in a new issue