Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2017-01-19 23:11:04 +0300
committerDavid Crocker <dcrocker@eschertech.com>2017-01-19 23:11:04 +0300
commit120987ff6314c3ff0a01d14735794f0b39bdea14 (patch)
tree4d2f30d6f657f3afe822d9aa06bc0b669ad7cda7 /src
parentd5e7dfba417aae0255d12d1eaf934a636a876030 (diff)
Version 1.17c+1
Implemented G2 and G3 Fixed bug: couldn't update WiFi server or DWC on Duet WiFi after sending M997 S3 Disable the uart used to update the WiFi module during normal WiFi operation
Diffstat (limited to 'src')
-rw-r--r--src/Configuration.h2
-rw-r--r--src/Duet/Pins_Duet.h2
-rw-r--r--src/DuetNG/DuetWiFi/Network.cpp31
-rw-r--r--src/DuetNG/DuetWiFi/Network.h3
-rw-r--r--src/DuetNG/DuetWiFi/WifiFirmwareUploader.cpp2
-rw-r--r--src/DuetNG/FirmwareUpdater.cpp2
-rw-r--r--src/GCodes/GCodeMachineState.cpp2
-rw-r--r--src/GCodes/GCodes.cpp216
-rw-r--r--src/GCodes/GCodes.h30
-rw-r--r--src/GCodes/GCodes2.cpp52
-rw-r--r--src/RepRapFirmware.h6
-rw-r--r--src/Version.h4
12 files changed, 274 insertions, 78 deletions
diff --git a/src/Configuration.h b/src/Configuration.h
index 14ecfe0d..4c844ed4 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -165,6 +165,8 @@ const float DefaultFeedrate = 3000.0; // The initial requested feed rate afte
const float DefaultRetractSpeed = 1000.0; // The default firmware retraction and un-retraction speed, in mm
const float DefaultRetractLength = 1.0;
+const float DefaultArcSegmentLength = 0.2; // G2 and G3 arc movement commands get split into segments this long
+
const float DEFAULT_IDLE_TIMEOUT = 30.0; // Seconds
const float DEFAULT_IDLE_CURRENT_FACTOR = 0.3; // Proportion of normal motor current that we use for idle hold
diff --git a/src/Duet/Pins_Duet.h b/src/Duet/Pins_Duet.h
index 4234a869..18096b6d 100644
--- a/src/Duet/Pins_Duet.h
+++ b/src/Duet/Pins_Duet.h
@@ -114,7 +114,7 @@ const Pin COOLING_FAN_RPM_PIN = 23; // Pin PA15
const size_t NumSdCards = 2;
const Pin SdCardDetectPins[NumSdCards] = {13, NoPin};
const Pin SdWriteProtectPins[NumSdCards] = {NoPin, NoPin};
-const Pin SdSpiCSPins[1] = {67}; // Note: this clashes with inkjet support
+const Pin SdSpiCSPins[1] = {67}; // Pin PB16 Note: this clashes with inkjet support
#if SUPPORT_INKJET
// Inkjet control pins
diff --git a/src/DuetNG/DuetWiFi/Network.cpp b/src/DuetNG/DuetWiFi/Network.cpp
index 63720451..316461c4 100644
--- a/src/DuetNG/DuetWiFi/Network.cpp
+++ b/src/DuetNG/DuetWiFi/Network.cpp
@@ -55,7 +55,7 @@ Network::Network(Platform* p) : platform(p), responseCode(0), responseBody(nullp
void Network::Init()
{
// Make sure the ESP8266 is held in the reset state
- pinMode(EspResetPin, OUTPUT_LOW);
+ ResetWiFi();
uploader = new WifiFirmwareUploader(Serial1);
}
@@ -118,7 +118,7 @@ void Network::Start()
// GPIO0 has to be held high for sufficient time:
// - 10ms is not enough
// - 18ms after reset is released, an oscillating signal appears on GPIO0 for 55ms
- // - so 18ms is probably long enough. Use 25ms for safety.
+ // - so 18ms is probably long enough. Use 50ms for safety.
delay(50);
// Relinquish control of our CS pin so that the ESP can take it over
@@ -1120,16 +1120,18 @@ void Network::SpiInterrupt()
// Reset the ESP8266 and leave held in reset
void Network::ResetWiFi()
{
- pinMode(EspResetPin, OUTPUT_LOW);
+ pinMode(EspResetPin, OUTPUT_LOW); // assert ESP8266 /RESET
+ pinMode(APIN_UART1_TXD, INPUT_PULLUP); // just enable pullups on TxD and RxD pins for now to avoid floating pins
+ pinMode(APIN_UART1_RXD, INPUT_PULLUP);
}
-// Reset the ESP8266 to take commands from the UART. The caller must wait for the reset to complete after calling this.
+// Reset the ESP8266 to take commands from the UART or from external input. The caller must wait for the reset to complete after calling this.
// ESP8266 boot modes:
// GPIO0 GPIO2 GPIO15
// 0 1 0 Firmware download from UART
// 1 1 0 Normal boot from flash memory
// 0 0 1 SD card boot (not used in on Duet)
-void Network::ResetWiFiForUpload()
+void Network::ResetWiFiForUpload(bool external)
{
// Make sure the ESP8266 is in the reset state
pinMode(EspResetPin, OUTPUT_LOW);
@@ -1152,17 +1154,18 @@ void Network::ResetWiFiForUpload()
// Make sure it has time to reset - no idea how long it needs, but 50ms should be plenty
delay(50);
+ if (external)
+ {
+ pinMode(APIN_UART1_TXD, INPUT_PULLUP); // just enable pullups on TxD and RxD pins
+ pinMode(APIN_UART1_RXD, INPUT_PULLUP);
+ }
+ else
+ {
+ ConfigurePin(g_APinDescription[APINS_UART1]); // connect the pins to UART1
+ }
+
// Release the reset on the ESP8266
digitalWrite(EspResetPin, HIGH);
}
-// Reset the ESP8266 to take commands from an external input. The caller must wait for the reset to complete after calling this.
-void Network::ResetWiFiForExternalUpload()
-{
- ResetWiFiForUpload();
-
- // Set our TxD pin low to make things easier for the FTDI chip to drive the ESP RxD input
- pinMode(APIN_UART1_TXD, OUTPUT_LOW);
-}
-
// End
diff --git a/src/DuetNG/DuetWiFi/Network.h b/src/DuetNG/DuetWiFi/Network.h
index 66963776..4b13f34e 100644
--- a/src/DuetNG/DuetWiFi/Network.h
+++ b/src/DuetNG/DuetWiFi/Network.h
@@ -76,8 +76,7 @@ public:
WifiFirmwareUploader *GetWifiUploader() { return uploader; }
static void ResetWiFi();
- static void ResetWiFiForUpload();
- static void ResetWiFiForExternalUpload();
+ static void ResetWiFiForUpload(bool external);
const char *GetWiFiServerVersion() const { return wiFiServerVersion; }
diff --git a/src/DuetNG/DuetWiFi/WifiFirmwareUploader.cpp b/src/DuetNG/DuetWiFi/WifiFirmwareUploader.cpp
index cfe108d3..a94518c5 100644
--- a/src/DuetNG/DuetWiFi/WifiFirmwareUploader.cpp
+++ b/src/DuetNG/DuetWiFi/WifiFirmwareUploader.cpp
@@ -586,7 +586,7 @@ void WifiFirmwareUploader::Spin()
}
uploadPort.begin(baud);
uploadPort.setInterruptPriority(1); // we are going to move data at seriously high speeds
- Network::ResetWiFiForUpload();
+ Network::ResetWiFiForUpload(false);
lastAttemptTime = lastResetTime = millis();
state = UploadState::connecting;
}
diff --git a/src/DuetNG/FirmwareUpdater.cpp b/src/DuetNG/FirmwareUpdater.cpp
index 3fd43179..87a9dcaa 100644
--- a/src/DuetNG/FirmwareUpdater.cpp
+++ b/src/DuetNG/FirmwareUpdater.cpp
@@ -62,7 +62,7 @@ namespace FirmwareUpdater
switch(module)
{
case WifiExternalFirmwareModule:
- Network::ResetWiFiForExternalUpload();
+ Network::ResetWiFiForUpload(true);
break;
case WifiFirmwareModule:
diff --git a/src/GCodes/GCodeMachineState.cpp b/src/GCodes/GCodeMachineState.cpp
index e21cddfb..420b2c5b 100644
--- a/src/GCodes/GCodeMachineState.cpp
+++ b/src/GCodes/GCodeMachineState.cpp
@@ -12,7 +12,7 @@ unsigned int GCodeMachineState::numAllocated = 0;
// Create a default initialised GCodeMachineState
GCodeMachineState::GCodeMachineState()
- : previous(nullptr), feedrate(DefaultFeedrate * secondsToMinutes), fileState(), lockedResources(0), state(GCodeState::normal),
+ : previous(nullptr), feedrate(DefaultFeedrate * SecondsToMinutes), fileState(), lockedResources(0), state(GCodeState::normal),
drivesRelative(false), axesRelative(false), doingFileMacro(false), runningM502(false)
{
}
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 97bebd8e..cb83c7d1 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -55,7 +55,7 @@ void GCodes::RestorePoint::Init()
{
moveCoords[i] = 0.0;
}
- feedRate = DefaultFeedrate * secondsToMinutes;
+ feedRate = DefaultFeedrate * SecondsToMinutes;
}
GCodes::GCodes(Platform* p, Webserver* w) :
@@ -82,6 +82,7 @@ void GCodes::Init()
numAxes = MIN_AXES;
numExtruders = MaxExtruders;
distanceScale = 1.0;
+ arcSegmentLength = DefaultArcSegmentLength;
rawExtruderTotal = 0.0;
for (size_t extruder = 0; extruder < MaxExtruders; extruder++)
{
@@ -111,7 +112,7 @@ void GCodes::Init()
retractLength = retractExtra = DefaultRetractLength;
retractHop = 0.0;
- retractSpeed = unRetractSpeed = DefaultRetractSpeed * secondsToMinutes;
+ retractSpeed = unRetractSpeed = DefaultRetractSpeed * SecondsToMinutes;
isRetracted = false;
}
@@ -134,7 +135,7 @@ void GCodes::Reset()
probeCount = 0;
cannedCycleMoveCount = 0;
cannedCycleMoveQueued = false;
- speedFactor = secondsToMinutes; // default is just to convert from mm/minute to mm/second
+ speedFactor = SecondsToMinutes; // default is just to convert from mm/minute to mm/second
for (size_t i = 0; i < MaxExtruders; ++i)
{
extrusionFactors[i] = 1.0;
@@ -362,7 +363,7 @@ void GCodes::Spin()
{
moveBuffer.coords[drive] = 0.0;
}
- moveBuffer.feedRate = DefaultFeedrate * secondsToMinutes; // ask for a good feed rate, we may have paused during a slow move
+ moveBuffer.feedRate = DefaultFeedrate * SecondsToMinutes; // ask for a good feed rate, we may have paused during a slow move
moveBuffer.moveType = 0;
moveBuffer.endStopsToCheck = 0;
moveBuffer.usePressureAdvance = false;
@@ -980,11 +981,10 @@ void GCodes::Pop(GCodeBuffer& gb)
}
}
-// Move expects all axis movements to be absolute, and all extruder drive moves to be relative. This function serves that.
-// 'moveType' is the S parameter in the G0 or G1 command, or -1 if we are doing G92.
-// For regular (type 0) moves, we apply limits and do X axis mapping.
-// Returns the number of segments if we have a legal move, 1 if we are doing G92, or zero if this gcode should be discarded
-unsigned int GCodes::LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType)
+// Set up the extrusion and feed rate of a move for the Move class
+// 'moveType' is the S parameter in the G0 or G1 command, or zero for a G2 or G3 command
+// Returns true if this gcode is valid so far, false if it should be discarded
+bool GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, int moveType)
{
// Zero every extruder drive as some drives may not be changed
for (size_t drive = numAxes; drive < DRIVES; drive++)
@@ -998,7 +998,7 @@ unsigned int GCodes::LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType)
const float rate = gb.GetFValue() * distanceScale;
gb.MachineState().feedrate = (moveType == 0)
? rate * speedFactor
- : rate * secondsToMinutes; // don't apply the speed factor to homing and other special moves
+ : rate * SecondsToMinutes; // don't apply the speed factor to homing and other special moves
}
moveBuffer.feedRate = gb.MachineState().feedrate;
@@ -1009,7 +1009,7 @@ unsigned int GCodes::LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType)
if (tool == nullptr)
{
platform->Message(GENERIC_MESSAGE, "Attempting to extrude with no tool selected.\n");
- return 0;
+ return false;
}
const size_t eMoveCount = tool->DriveCount();
if (eMoveCount > 0)
@@ -1073,8 +1073,16 @@ unsigned int GCodes::LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType)
}
}
}
+ return true;
+}
- // Now the movement axes
+// Set up the axis coordinates of a move for the Move class
+// Move expects all axis movements to be absolute, and all extruder drive moves to be relative. This function serves that.
+// 'moveType' is the S parameter in the G0 or G1 command, or -1 if we are doing G92.
+// For regular (type 0) moves, we apply limits and do X axis mapping.
+// Returns the number of segments if we have a legal move, 1 if we are doing G92, or zero if this gcode should be discarded
+unsigned int GCodes::LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType)
+{
const Tool * const currentTool = reprap.GetCurrentTool();
unsigned int numSegments = 1;
for (size_t axis = 0; axis < numAxes; axis++)
@@ -1216,6 +1224,7 @@ int GCodes::SetUpMove(GCodeBuffer& gb, StringRef& reply)
// Check to see if the move is a 'homing' move that endstops are checked on.
moveBuffer.endStopsToCheck = 0;
moveBuffer.moveType = 0;
+ doingArcMove = false;
moveBuffer.xAxes = reprap.GetCurrentXAxes();
if (gb.Seen('S'))
{
@@ -1279,31 +1288,157 @@ int GCodes::SetUpMove(GCodeBuffer& gb, StringRef& reply)
// Load the move buffer with either the absolute movement required or the relative movement required
memcpy(moveBuffer.initialCoords, moveBuffer.coords, numAxes * sizeof(moveBuffer.initialCoords[0]));
- segmentsLeft = LoadMoveBufferFromGCode(gb, moveBuffer.moveType);
+ if (LoadExtrusionAndFeedrateFromGCode(gb, moveBuffer.moveType))
+ {
+ segmentsLeft = LoadMoveBufferFromGCode(gb, moveBuffer.moveType);
+ if (segmentsLeft != 0)
+ {
+ // Flag whether we should use pressure advance, if there is any extrusion in this move.
+ // We assume it is a normal printing move needing pressure advance if there is forward extrusion and XYU.. movement.
+ // The movement code will only apply pressure advance if there is forward extrusion, so we only need to check for XYU.. movement here.
+ moveBuffer.usePressureAdvance = false;
+ for (size_t axis = 0; axis < numAxes; ++axis)
+ {
+ if (axis != Z_AXIS && moveBuffer.coords[axis] != moveBuffer.initialCoords[axis])
+ {
+ moveBuffer.usePressureAdvance = true;
+ break;
+ }
+ }
+ moveBuffer.filePos = (&gb == fileGCode) ? gb.MachineState().fileState.GetPosition() : noFilePosition;
+ moveBuffer.canPauseAfter = (moveBuffer.endStopsToCheck == 0);
+ //debugPrintf("Queue move pos %u\n", moveFilePos);
+ }
+ }
+ return (moveBuffer.moveType != 0 || moveBuffer.endStopsToCheck != 0) ? 2 : 1;
+}
+
+// Execute an arc move returning true if it was badly-formed
+// We already have the movement lock and the last move has gone
+bool GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
+{
+ memcpy(moveBuffer.initialCoords, moveBuffer.coords, numAxes * sizeof(moveBuffer.initialCoords[0]));
- if (segmentsLeft != 0)
+ // Get the axis parameters. X Y I J are compulsory, Z is optional.
+ if (!gb.Seen('X')) return true;
+ const float xParam = gb.GetFValue();
+ if (!gb.Seen('Y')) return true;
+ const float yParam = gb.GetFValue();
+ if (!gb.Seen('I')) return true;
+ const float iParam = gb.GetFValue();
+ if (!gb.Seen('J')) return true;
+ const float jParam = gb.GetFValue();
+
+ // Adjust them for relative/absolute coordinates, tool offset, and X axis mapping. Also get the optional Z parameter
+ const Tool * const currentTool = reprap.GetCurrentTool();
+ const bool axesRelative = gb.MachineState().axesRelative;
+ if (gb.Seen('Z'))
{
- // Flag whether we should use pressure advance, if there is any extrusion in this move.
- // We assume it is a normal printing move needing pressure advance if there is forward extrusion and XYU.. movement.
- // The movement code will only apply pressure advance if there is forward extrusion, so we only need to check for XYU.. movement here.
- moveBuffer.usePressureAdvance = false;
+ const float zParam = gb.GetFValue();
+ if (axesRelative)
+ {
+ moveBuffer.coords[Z_AXIS] += zParam;
+ }
+ else
+ {
+ moveBuffer.coords[Z_AXIS] = zParam;
+ if (currentTool != nullptr)
+ {
+ moveBuffer.coords[Z_AXIS] -= currentTool->GetOffset()[Z_AXIS];
+ }
+ }
+ }
+
+ float initialDx = 0.0;
+ if (currentTool != nullptr)
+ {
+ // Record which axes behave like an X axis
+ arcAxesMoving = currentTool->GetXAxisMap() & ~((1 << Y_AXIS) | (1 << Z_AXIS));
+
+ // Sort out the Y axis
+ if (axesRelative)
+ {
+ moveBuffer.coords[Y_AXIS] += yParam;
+ arcCentre[Y_AXIS] = moveBuffer.initialCoords[Y_AXIS] + jParam;
+ }
+ else
+ {
+ moveBuffer.coords[Y_AXIS] = yParam - currentTool->GetOffset()[Y_AXIS];
+ arcCentre[Y_AXIS] = jParam - currentTool->GetOffset()[Y_AXIS];
+ }
+
+ // Deal with the X axes
for (size_t axis = 0; axis < numAxes; ++axis)
{
- if (axis != Z_AXIS && moveBuffer.coords[axis] != moveBuffer.initialCoords[axis])
+ if ((arcAxesMoving & (1 << axis)) != 0)
{
- moveBuffer.usePressureAdvance = true;
- break;
+ if (axesRelative)
+ {
+ moveBuffer.coords[axis] += xParam;
+ arcCentre[axis] = moveBuffer.initialCoords[axis] + iParam;
+ initialDx = -iParam;
+ }
+ else
+ {
+ moveBuffer.coords[axis] = xParam - currentTool->GetOffset()[axis];
+ arcCentre[axis] = iParam + currentTool->GetOffset()[axis];
+ initialDx = moveBuffer.initialCoords[axis] - arcCentre[axis];
+ }
}
}
- moveBuffer.filePos = (&gb == fileGCode) ? gb.MachineState().fileState.GetPosition() : noFilePosition;
- moveBuffer.canPauseAfter = (moveBuffer.endStopsToCheck == 0);
- //debugPrintf("Queue move pos %u\n", moveFilePos);
}
- return (moveBuffer.moveType != 0 || moveBuffer.endStopsToCheck != 0) ? 2 : 1;
+ else
+ {
+ arcAxesMoving = (1 << X_AXIS);
+ if (axesRelative)
+ {
+ moveBuffer.coords[X_AXIS] += xParam;
+ arcCentre[X_AXIS] = moveBuffer.initialCoords[X_AXIS] + iParam;
+ moveBuffer.coords[Y_AXIS] += yParam;
+ arcCentre[Y_AXIS] = moveBuffer.initialCoords[Y_AXIS] + jParam;;
+ initialDx = -iParam;
+ }
+ else
+ {
+ moveBuffer.coords[X_AXIS] = xParam;
+ arcCentre[X_AXIS] = iParam;
+ moveBuffer.coords[Y_AXIS] = yParam;
+ arcCentre[Y_AXIS] = jParam;
+ initialDx = moveBuffer.initialCoords[X_AXIS] - arcCentre[X_AXIS];
+ }
+ }
+
+ moveBuffer.endStopsToCheck = 0;
+ moveBuffer.moveType = 0;
+ moveBuffer.xAxes = reprap.GetCurrentXAxes();
+ if (LoadExtrusionAndFeedrateFromGCode(gb, moveBuffer.moveType)) // this reports an error if necessary, so no need to return true if it fails
+ {
+ const float initialDy = moveBuffer.initialCoords[Y_AXIS] - arcCentre[Y_AXIS];
+ arcRadius = sqrtf(initialDx * initialDx + initialDy * initialDy);
+ arcCurrentAngle = atan2(initialDy, initialDx);
+ const float finalTheta = atan2(yParam - jParam, xParam - iParam);
+
+ // Calculate the total angle moved, which depends on which way round we are going
+ float totalArc = (clockwise) ? arcCurrentAngle - finalTheta : finalTheta - arcCurrentAngle;
+ if (totalArc < 0)
+ {
+ totalArc += 2 * PI;
+ }
+ segmentsLeft = max<unsigned int>((unsigned int)((arcRadius * totalArc)/arcSegmentLength + 0.8), 1);
+ arcAngleIncrement = totalArc/segmentsLeft;
+ if (clockwise)
+ {
+ arcAngleIncrement = -arcAngleIncrement;
+ }
+ doingArcMove = true;
+ moveBuffer.usePressureAdvance = true;
+// debugPrintf("Radius %.2f, initial angle %.1f, increment %.1f, segments %u\n",
+// arcRadius, arcCurrentAngle * RadiansToDegrees, arcAngleIncrement * RadiansToDegrees, segmentsLeft);
+ }
+ return false;
}
// The Move class calls this function to find what to do next.
-
bool GCodes::ReadMove(RawMove& m)
{
if (segmentsLeft == 0)
@@ -1314,6 +1449,7 @@ bool GCodes::ReadMove(RawMove& m)
m = moveBuffer;
if (segmentsLeft == 1)
{
+ // If there is just 1 segment left, it doesn't matter if it is an arc move or not, just move to the end position
ClearMove();
}
else
@@ -1322,10 +1458,30 @@ bool GCodes::ReadMove(RawMove& m)
m.canPauseAfter = false;
// Do the axes
+ if (doingArcMove)
+ {
+ arcCurrentAngle += arcAngleIncrement;
+ }
+
for (size_t drive = 0; drive < numAxes; ++drive)
{
- const float movementToDo = (moveBuffer.coords[drive] - moveBuffer.initialCoords[drive])/segmentsLeft;
- moveBuffer.initialCoords[drive] += movementToDo;
+ if (doingArcMove && drive != Z_AXIS)
+ {
+ if (drive == Y_AXIS)
+ {
+ moveBuffer.initialCoords[drive] = arcCentre[drive] + arcRadius * sinf(arcCurrentAngle);
+ }
+ else if ((arcAxesMoving & (1 << drive)) != 0)
+ {
+ // X axis or a substitute X axis
+ moveBuffer.initialCoords[drive] = arcCentre[drive] + arcRadius * cosf(arcCurrentAngle);
+ }
+ }
+ else
+ {
+ const float movementToDo = (moveBuffer.coords[drive] - moveBuffer.initialCoords[drive])/segmentsLeft;
+ moveBuffer.initialCoords[drive] += movementToDo;
+ }
m.coords[drive] = moveBuffer.initialCoords[drive];
}
@@ -1336,6 +1492,7 @@ bool GCodes::ReadMove(RawMove& m)
m.coords[drive] = extrusionToDo;
moveBuffer.coords[drive] -= extrusionToDo;
}
+
--segmentsLeft;
}
return true;
@@ -1344,6 +1501,7 @@ bool GCodes::ReadMove(RawMove& m)
void GCodes::ClearMove()
{
segmentsLeft = 0;
+ doingArcMove = false;
moveBuffer.endStopsToCheck = 0;
moveBuffer.moveType = 0;
moveBuffer.isFirmwareRetraction = false;
@@ -1528,7 +1686,7 @@ bool GCodes::OffsetAxes(GCodeBuffer& gb)
if (gb.Seen(feedrateLetter)) // Has the user specified a feedrate?
{
- cannedFeedRate = gb.GetFValue() * distanceScale * secondsToMinutes;
+ cannedFeedRate = gb.GetFValue() * distanceScale * SecondsToMinutes;
}
else
{
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index 017d98dc..6a32aa87 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -101,7 +101,7 @@ public:
void SetAxisNotHomed(unsigned int axis) // Tell us that the axis is not homed
{ axesHomed &= ~(1 << axis); }
- float GetSpeedFactor() const { return speedFactor * minutesToSeconds; } // Return the current speed factor
+ float GetSpeedFactor() const { return speedFactor * MinutesToSeconds; } // Return the current speed factor
float GetExtrusionFactor(size_t extruder) { return extrusionFactors[extruder]; } // Return the current extrusion factors
float GetRawExtruderPosition(size_t drive) const; // Get the actual extruder position, after adjusting the extrusion factor
float GetRawExtruderTotalByDrive(size_t extruder) const; // Get the total extrusion since start of print, for one drive
@@ -158,8 +158,8 @@ private:
void StartNextGCode(GCodeBuffer& gb, StringRef& reply); // Fetch a new or old GCode and process it
void DoFilePrint(GCodeBuffer& gb, StringRef& reply); // Get G Codes from a file and print them
- bool DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissing, bool runningM502 = false);
- // Run a GCode macro file, optionally report error if not found
+ bool DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissing, bool runningM502 = false);
+ // Run a GCode macro file, optionally report error if not found
bool DoCannedCycleMove(GCodeBuffer& gb, EndstopChecks ce); // Do a move from an internally programmed canned cycle
void FileMacroCyclesReturn(GCodeBuffer& gb); // End a macro
bool ActOnCode(GCodeBuffer& gb, StringRef& reply); // Do a G, M or T Code
@@ -177,9 +177,13 @@ private:
void SetBedEquationWithProbe(int sParam, StringRef& reply); // Probes a series of points and sets the bed equation
bool SetPrintZProbe(GCodeBuffer& gb, StringRef& reply); // Either return the probe value, or set its threshold
bool SetOrReportOffsets(GCodeBuffer& gb, StringRef& reply); // Deal with a G10
+
bool SetPositions(GCodeBuffer& gb); // Deal with a G92
- unsigned int LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType); // Set up a move for the Move class
- bool NoHome() const; // Are we homing and not finished?
+ bool LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, int moveType); // Set up the extrusion and feed rate of a move for the Move class
+ unsigned int LoadMoveBufferFromGCode(GCodeBuffer& gb, int moveType); // Set up the axis coordinates of a move for the Move class
+ bool DoArcMove(GCodeBuffer& gb, bool clockwise) // Execute an arc move returning true if it was badly-formed
+ pre(segmentsLeft == 0; resourceOwners[MoveResource] == &gb);
+
bool Push(GCodeBuffer& gb); // Push feedrate etc on the stack
void Pop(GCodeBuffer& gb); // Pop feedrate etc
void DisableDrives(); // Turn the motors off
@@ -223,8 +227,8 @@ private:
static uint32_t LongArrayToBitMap(const long *arr, size_t numEntries); // Convert an array of longs to a bit map
- Platform* platform; // The RepRap machine
- Webserver* webserver; // The web server class
+ Platform* const platform; // The RepRap machine
+ Webserver* const webserver; // The web server class
GCodeBuffer* gcodeSources[6]; // The various sources of gcodes
@@ -244,9 +248,18 @@ private:
bool runningConfigFile; // We are running config.g during the startup process
bool doingToolChange; // We are running tool change macros
- unsigned int segmentsLeft; // The number of segments left to do in the current move, or 0 if no move available
float dwellTime; // How long a pause for a dwell (seconds)?
+
+ // The following contain the details of moves that the Move module fetches
RawMove moveBuffer; // Move details to pass to Move class
+ unsigned int segmentsLeft; // The number of segments left to do in the current move, or 0 if no move available
+ float arcCentre[MAX_AXES];
+ float arcRadius;
+ float arcCurrentAngle;
+ float arcAngleIncrement;
+ uint32_t arcAxesMoving;
+ bool doingArcMove;
+
RestorePoint simulationRestorePoint; // The position and feed rate when we started a simulation
RestorePoint pauseRestorePoint; // The position and feed rate when we paused the print
RestorePoint toolChangeRestorePoint; // The position and feed rate when we freed a tool
@@ -262,6 +275,7 @@ private:
CannedMoveType cannedMoveType[DRIVES]; // Is this drive involved in a canned cycle move?
bool offSetSet; // Are any axis offsets non-zero?
float distanceScale; // MM or inches
+ float arcSegmentLength; // Length of segments that we split arc moves into
FileData fileToPrint;
FileStore* fileBeingWritten; // A file to write G Codes (or sometimes HTML) to
uint16_t toBeHomed; // Bitmap of axes still to be homed
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 0308fcf9..86690abf 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -108,7 +108,7 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
{
moveBuffer.coords[drive] = 0.0;
}
- moveBuffer.feedRate = (gb.Seen(feedrateLetter)) ? gb.GetFValue() * secondsToMinutes : gb.MachineState().feedrate;
+ moveBuffer.feedRate = (gb.Seen(feedrateLetter)) ? gb.GetFValue() * SecondsToMinutes : gb.MachineState().feedrate;
moveBuffer.filePos = noFilePosition;
moveBuffer.usePressureAdvance = false;
segmentsLeft = 1;
@@ -125,6 +125,24 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
}
break;
+ case 2: // Clockwise arc
+ case 3: // Anti clockwise arc
+ // We only support X and Y axes in these, but you can map them to other axes in the tool definitions
+ if (!LockMovement(gb))
+ {
+ return false;
+ }
+ if (segmentsLeft != 0)
+ {
+ return false;
+ }
+ if (DoArcMove(gb, code == 2))
+ {
+ reply.copy("Invalid G2 or G3 command");
+ error = true;
+ }
+ break;
+
case 4: // Dwell
result = DoDwell(gb);
break;
@@ -1566,7 +1584,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
{
if (gb.Seen(axisLetters[axis]))
{
- platform->SetMaxFeedrate(axis, gb.GetFValue() * distanceScale * secondsToMinutes); // G Code feedrates are in mm/minute; we need mm/sec
+ platform->SetMaxFeedrate(axis, gb.GetFValue() * distanceScale * SecondsToMinutes); // G Code feedrates are in mm/minute; we need mm/sec
seen = true;
}
}
@@ -1579,7 +1597,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
gb.GetFloatArray(eVals, eCount, true);
for (size_t e = 0; e < eCount; e++)
{
- platform->SetMaxFeedrate(numAxes + e, eVals[e] * distanceScale * secondsToMinutes);
+ platform->SetMaxFeedrate(numAxes + e, eVals[e] * distanceScale * SecondsToMinutes);
}
}
@@ -1588,13 +1606,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
reply.copy("Maximum feedrates: ");
for (size_t axis = 0; axis < numAxes; ++axis)
{
- reply.catf("%c: %.1f, ", axisLetters[axis], platform->MaxFeedrate(axis) / (distanceScale * secondsToMinutes));
+ reply.catf("%c: %.1f, ", axisLetters[axis], platform->MaxFeedrate(axis) / (distanceScale * SecondsToMinutes));
}
reply.cat("E:");
char sep = ' ';
for (size_t extruder = 0; extruder < numExtruders; extruder++)
{
- reply.catf("%c%.1f", sep, platform->MaxFeedrate(extruder + numAxes) / (distanceScale * secondsToMinutes));
+ reply.catf("%c%.1f", sep, platform->MaxFeedrate(extruder + numAxes) / (distanceScale * SecondsToMinutes));
sep = ':';
}
}
@@ -1620,12 +1638,12 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
if (gb.Seen('F'))
{
- unRetractSpeed = retractSpeed = max<float>(gb.GetFValue(), 60.0) * secondsToMinutes;
+ unRetractSpeed = retractSpeed = max<float>(gb.GetFValue(), 60.0) * SecondsToMinutes;
seen = true;
}
if (gb.Seen('T')) // must do this one after 'F'
{
- unRetractSpeed = max<float>(gb.GetFValue(), 60.0) * secondsToMinutes;
+ unRetractSpeed = max<float>(gb.GetFValue(), 60.0) * SecondsToMinutes;
seen = true;
}
if (gb.Seen('Z'))
@@ -1636,7 +1654,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
if (!seen)
{
reply.printf("Retraction/un-retraction settings: length %.2f/%.2fmm, speed %d/%dmm/min, Z hop %.2fmm",
- retractLength, retractLength + retractExtra, (int)(retractSpeed * minutesToSeconds), (int)(unRetractSpeed * minutesToSeconds), retractHop);
+ retractLength, retractLength + retractExtra, (int)(retractSpeed * MinutesToSeconds), (int)(unRetractSpeed * MinutesToSeconds), retractHop);
}
}
break;
@@ -1683,7 +1701,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
case 220: // Set/report speed factor override percentage
if (gb.Seen('S'))
{
- float newSpeedFactor = (gb.GetFValue() * 0.01) * secondsToMinutes; // include the conversion from mm/minute to mm/second
+ float newSpeedFactor = (gb.GetFValue() * 0.01) * SecondsToMinutes; // include the conversion from mm/minute to mm/second
if (newSpeedFactor > 0.0)
{
// Update the feed rate for ALL input sources, and all feed rates on the stack
@@ -1712,7 +1730,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
else
{
- reply.printf("Speed factor override: %.1f%%", speedFactor * minutesToSeconds * 100.0);
+ reply.printf("Speed factor override: %.1f%%", speedFactor * MinutesToSeconds * 100.0);
}
break;
@@ -2366,13 +2384,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
if (gb.Seen('F')) // feed rate i.e. probing speed
{
- params.probeSpeed = gb.GetFValue() * secondsToMinutes;
+ params.probeSpeed = gb.GetFValue() * SecondsToMinutes;
seenParam = true;
}
if (gb.Seen('T')) // travel speed to probe point
{
- params.travelSpeed = gb.GetFValue() * secondsToMinutes;
+ params.travelSpeed = gb.GetFValue() * SecondsToMinutes;
seenParam = true;
}
@@ -2394,7 +2412,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
{
reply.printf("Z Probe type %d, invert %s, dive height %.1fmm, probe speed %dmm/min, travel speed %dmm/min, recovery time %.2f sec",
platform->GetZProbeType(), (params.invertReading) ? "yes" : "no", params.diveHeight,
- (int)(params.probeSpeed * minutesToSeconds), (int)(params.travelSpeed * minutesToSeconds), params.recoveryTime);
+ (int)(params.probeSpeed * MinutesToSeconds), (int)(params.travelSpeed * MinutesToSeconds), params.recoveryTime);
if (platform->GetZProbeType() == ZProbeTypeDelta)
{
reply.catf(", extra parameter %.2f", params.extraParam);
@@ -2485,7 +2503,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
{
if (gb.Seen(axisLetters[axis]))
{
- platform->SetInstantDv(axis, gb.GetFValue() * distanceScale * secondsToMinutes); // G Code feedrates are in mm/minute; we need mm/sec
+ platform->SetInstantDv(axis, gb.GetFValue() * distanceScale * SecondsToMinutes); // G Code feedrates are in mm/minute; we need mm/sec
seen = true;
}
}
@@ -2498,7 +2516,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
gb.GetFloatArray(eVals, eCount, true);
for (size_t e = 0; e < eCount; e++)
{
- platform->SetInstantDv(numAxes + e, eVals[e] * distanceScale * secondsToMinutes);
+ platform->SetInstantDv(numAxes + e, eVals[e] * distanceScale * SecondsToMinutes);
}
}
else if (!seen)
@@ -2506,13 +2524,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
reply.copy("Maximum jerk rates: ");
for (size_t axis = 0; axis < numAxes; ++axis)
{
- reply.catf("%c: %.1f, ", axisLetters[axis], platform->ConfiguredInstantDv(axis) / (distanceScale * secondsToMinutes));
+ reply.catf("%c: %.1f, ", axisLetters[axis], platform->ConfiguredInstantDv(axis) / (distanceScale * SecondsToMinutes));
}
reply.cat("E:");
char sep = ' ';
for (size_t extruder = 0; extruder < numExtruders; extruder++)
{
- reply.catf("%c%.1f", sep, platform->ConfiguredInstantDv(extruder + numAxes) / (distanceScale * secondsToMinutes));
+ reply.catf("%c%.1f", sep, platform->ConfiguredInstantDv(extruder + numAxes) / (distanceScale * SecondsToMinutes));
sep = ':';
}
}
diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h
index 1b866008..6e596092 100644
--- a/src/RepRapFirmware.h
+++ b/src/RepRapFirmware.h
@@ -89,11 +89,13 @@ const size_t CART_AXES = 3; // The number of Cartesian axes
const size_t X_AXIS = 0, Y_AXIS = 1, Z_AXIS = 2, E0_AXIS = 3; // The indices of the Cartesian axes in drive arrays
// Common conversion factors
-const float minutesToSeconds = 60.0;
-const float secondsToMinutes = 1.0/minutesToSeconds;
+const float MinutesToSeconds = 60.0;
+const float SecondsToMinutes = 1.0/MinutesToSeconds;
const float SecondsToMillis = 1000.0;
const float MillisToSeconds = 0.001;
const float InchToMm = 25.4;
+const float DegreesToRadians = PI/180.0;
+const float RadiansToDegrees = 180.0/PI;
// Type of an offset in a file
typedef uint32_t FilePosition;
diff --git a/src/Version.h b/src/Version.h
index 6bf69967..d3cf2f3b 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -9,11 +9,11 @@
#define SRC_VERSION_H_
#ifndef VERSION
-# define VERSION "1.17c"
+# define VERSION "1.17c+1"
#endif
#ifndef DATE
-# define DATE "2017-01-14"
+# define DATE "2017-01-19"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman"