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
This commit is contained in:
parent
d5e7dfba41
commit
120987ff63
12 changed files with 275 additions and 79 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace FirmwareUpdater
|
|||
switch(module)
|
||||
{
|
||||
case WifiExternalFirmwareModule:
|
||||
Network::ResetWiFiForExternalUpload();
|
||||
Network::ResetWiFiForUpload(true);
|
||||
break;
|
||||
|
||||
case WifiFirmwareModule:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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 (segmentsLeft != 0)
|
||||
if (LoadExtrusionAndFeedrateFromGCode(gb, moveBuffer.moveType))
|
||||
{
|
||||
// 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)
|
||||
segmentsLeft = LoadMoveBufferFromGCode(gb, moveBuffer.moveType);
|
||||
if (segmentsLeft != 0)
|
||||
{
|
||||
if (axis != Z_AXIS && moveBuffer.coords[axis] != moveBuffer.initialCoords[axis])
|
||||
// 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)
|
||||
{
|
||||
moveBuffer.usePressureAdvance = true;
|
||||
break;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// The Move class calls this function to find what to do next.
|
||||
// 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]));
|
||||
|
||||
// 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'))
|
||||
{
|
||||
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 ((arcAxesMoving & (1 << axis)) != 0)
|
||||
{
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = ':';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Reference in a new issue