diff --git a/Changes in dc42 fork.txt b/Changes in dc42 fork.txt index 6fd343a..ee3eb94 100644 --- a/Changes in dc42 fork.txt +++ b/Changes in dc42 fork.txt @@ -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: diff --git a/Configuration.h b/Configuration.h index 484f94a..73d1216 100644 --- a/Configuration.h +++ b/Configuration.h @@ -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. diff --git a/GCodes.cpp b/GCodes.cpp index 7441845..a377e84 100644 --- a/GCodes.cpp +++ b/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; diff --git a/Platform.h b/Platform.h index ab444d3..d266fc6 100644 --- a/Platform.h +++ b/Platform.h @@ -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 diff --git a/Webserver.cpp b/Webserver.cpp index 526c376..6982f5d 100644 --- a/Webserver.cpp +++ b/Webserver.cpp @@ -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(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; } diff --git a/Webserver.h b/Webserver.h index 49947c4..c661340 100644 --- a/Webserver.h +++ b/Webserver.h @@ -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