Version 1.00i
Fixed bug with reading file info Don't return status as Printing if just running a macro Restored Json buffer back to 2000 bytes so as to return more files on SD card Limit the amount of moves we buffer so as to react faster to speed and extrusion rate changes Return print time left estimates in M105 S2 status response if printing a file Show stepper motor currents as integers and do some rounding to get more accurate values
This commit is contained in:
parent
8cc4162b40
commit
2a3cf6c5c9
11 changed files with 95 additions and 91 deletions
|
@ -24,8 +24,8 @@ Licence: GPL
|
|||
#define CONFIGURATION_H
|
||||
|
||||
#define NAME "RepRapFirmware"
|
||||
#define VERSION "1.00h-dc42"
|
||||
#define DATE "2015-02-11"
|
||||
#define VERSION "1.00i-dc42"
|
||||
#define DATE "2015-02-16"
|
||||
#define AUTHORS "reprappro, dc42, zpl"
|
||||
|
||||
#define FLASH_SAVE_ENABLED (1)
|
||||
|
|
14
DDA.cpp
14
DDA.cpp
|
@ -19,8 +19,8 @@ int32_t DDA::GetTimeLeft() const
|
|||
//pre(state == executing || state == frozen || state == completed)
|
||||
{
|
||||
return (state == completed) ? 0
|
||||
: (state == executing) ? (int32_t)(moveStartTime + timeNeeded - Platform::GetInterruptClocks())
|
||||
: (int32_t)timeNeeded;
|
||||
: (state == executing) ? (int32_t)(moveStartTime + clocksNeeded - Platform::GetInterruptClocks())
|
||||
: (int32_t)clocksNeeded;
|
||||
}
|
||||
|
||||
void DDA::DebugPrintVector(const char *name, const float *vec, size_t len) const
|
||||
|
@ -551,14 +551,14 @@ void DDA::Prepare()
|
|||
params.decelStartDistance = totalDistance - decelDistance;
|
||||
|
||||
// Convert the accelerate/decelerate distances to times
|
||||
float accelStopTime = (topSpeed - startSpeed)/acceleration;
|
||||
float decelStartTime = accelStopTime + (params.decelStartDistance - accelDistance)/topSpeed;
|
||||
float totalTime = decelStartTime + (topSpeed - endSpeed)/acceleration;
|
||||
timeNeeded = (uint32_t)(totalTime * stepClockRate);
|
||||
const float accelStopTime = (topSpeed - startSpeed)/acceleration;
|
||||
const float decelStartTime = accelStopTime + (params.decelStartDistance - accelDistance)/topSpeed;
|
||||
const float totalTime = decelStartTime + (topSpeed - endSpeed)/acceleration;
|
||||
clocksNeeded = (uint32_t)(totalTime * stepClockRate);
|
||||
|
||||
params.startSpeedTimesCdivA = (uint32_t)((startSpeed * stepClockRate)/acceleration);
|
||||
params.topSpeedTimesCdivA = (uint32_t)((topSpeed * stepClockRate)/acceleration);
|
||||
params.decelStartClocks = decelStartTime * stepClockRate;
|
||||
params.decelStartClocks = (uint32_t)(decelStartTime * stepClockRate);
|
||||
params.topSpeedTimesCdivAPlusDecelStartClocks = params.topSpeedTimesCdivA + params.decelStartClocks;
|
||||
params.accelClocksMinusAccelDistanceTimesCdivTopSpeed = (uint32_t)((accelStopTime - (accelDistance/topSpeed)) * stepClockRate);
|
||||
params.compFactor = 1.0 - startSpeed/topSpeed;
|
||||
|
|
2
DDA.h
2
DDA.h
|
@ -116,7 +116,7 @@ private:
|
|||
float targetNextSpeed; // The speed that the next move would like to start at
|
||||
|
||||
// These are calculated from the above and used in the ISR, so they are set up by Prepare()
|
||||
uint32_t timeNeeded; // in clocks
|
||||
uint32_t clocksNeeded; // in clocks
|
||||
uint32_t moveStartTime; // clock count at which the move was started
|
||||
uint32_t firstStepTime; // in clocks, relative to the start of the move
|
||||
|
||||
|
|
37
GCodes.cpp
37
GCodes.cpp
|
@ -28,10 +28,8 @@
|
|||
const char GCodes::axisLetters[AXES] = {'X', 'Y', 'Z'};
|
||||
|
||||
GCodes::GCodes(Platform* p, Webserver* w)
|
||||
: active(false), platform(p), webserver(w), stackPointer(0)
|
||||
{
|
||||
active = false;
|
||||
platform = p;
|
||||
webserver = w;
|
||||
webGCode = new GCodeBuffer(platform, "web: ");
|
||||
fileGCode = new GCodeBuffer(platform, "file: ");
|
||||
serialGCode = new GCodeBuffer(platform, "serial: ");
|
||||
|
@ -81,7 +79,6 @@ void GCodes::Reset()
|
|||
fileBeingWritten = NULL;
|
||||
endStopsToCheck = 0;
|
||||
doingFileMacro = false;
|
||||
fractionOfFilePrinted = -1.0;
|
||||
dwellWaiting = false;
|
||||
stackPointer = 0;
|
||||
state = GCodeState::normal;
|
||||
|
@ -103,6 +100,19 @@ void GCodes::Reset()
|
|||
filePos = moveFilePos = noFilePosition;
|
||||
}
|
||||
|
||||
float GCodes::FractionOfFilePrinted() const
|
||||
{
|
||||
if (isPaused)
|
||||
{
|
||||
return (fileToPrint.IsLive()) ? fileToPrint.FractionRead() : -1.0;
|
||||
}
|
||||
if (stackPointer == 0)
|
||||
{
|
||||
return (fileBeingPrinted.IsLive() && !doingFileMacro) ? fileBeingPrinted.FractionRead() : -1.0;
|
||||
}
|
||||
return (stack[0].fileState.IsLive() && !stack[0].doingFileMacro) ? stack[0].fileState.FractionRead() : -1.0;
|
||||
}
|
||||
|
||||
void GCodes::DoFilePrint(GCodeBuffer* gb, StringRef& reply)
|
||||
{
|
||||
for (int i = 0; i < 50 && fileBeingPrinted.IsLive(); ++i)
|
||||
|
@ -306,7 +316,6 @@ void GCodes::Spin()
|
|||
fileBeingPrinted.MoveFrom(fileToPrint);
|
||||
moveBuffer[DRIVES] = pausedMoveBuffer[DRIVES];
|
||||
reprap.GetMove()->SetFeedrate(pausedMoveBuffer[DRIVES]);
|
||||
fractionOfFilePrinted = -1.0;
|
||||
fileGCode->Resume();
|
||||
HandleReply(false, gbCurrent, reply.Pointer(), 'M', 24, false);
|
||||
isPaused = false;
|
||||
|
@ -505,10 +514,6 @@ void GCodes::Push()
|
|||
stack[stackPointer].drivesRelative = drivesRelative;
|
||||
stack[stackPointer].axesRelative = axesRelative;
|
||||
stack[stackPointer].doingFileMacro = doingFileMacro;
|
||||
if (stackPointer == 0)
|
||||
{
|
||||
fractionOfFilePrinted = fileBeingPrinted.FractionRead(); // save this so that we don't return the fraction of the macro file read
|
||||
}
|
||||
stackPointer++;
|
||||
platform->PushMessageIndent();
|
||||
}
|
||||
|
@ -523,10 +528,6 @@ void GCodes::Pop()
|
|||
}
|
||||
|
||||
stackPointer--;
|
||||
if (stackPointer == 0)
|
||||
{
|
||||
fractionOfFilePrinted = -1.0; // restore live updates of fraction read from the file being printed
|
||||
}
|
||||
state = stack[stackPointer].state;
|
||||
gbCurrent = stack[stackPointer].gb;
|
||||
moveBuffer[DRIVES] = stack[stackPointer].feedrate;
|
||||
|
@ -2274,7 +2275,6 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
else
|
||||
{
|
||||
fileBeingPrinted.MoveFrom(fileToPrint);
|
||||
fractionOfFilePrinted = -1.0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2315,7 +2315,6 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
}
|
||||
}
|
||||
pausedFanValue = platform->GetFanValue();
|
||||
fractionOfFilePrinted = fileBeingPrinted.FractionRead();
|
||||
fileToPrint.MoveFrom(fileBeingPrinted);
|
||||
fileGCode->Pause();
|
||||
state = GCodeState::pausing1;
|
||||
|
@ -3741,12 +3740,12 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
|
|||
}
|
||||
else if (!seen)
|
||||
{
|
||||
reply.printf("Axis currents (mA) - X:%.1f, Y:%.1f, Z:%.1f, E:",
|
||||
platform->MotorCurrent(X_AXIS), platform->MotorCurrent(Y_AXIS),
|
||||
platform->MotorCurrent(Z_AXIS));
|
||||
reply.printf("Axis currents (mA) - X:%d, Y:%d, Z:%d, E:",
|
||||
(int)platform->MotorCurrent(X_AXIS), (int)platform->MotorCurrent(Y_AXIS),
|
||||
(int)platform->MotorCurrent(Z_AXIS));
|
||||
for(int8_t drive = AXES; drive < DRIVES; drive++)
|
||||
{
|
||||
reply.catf("%.1f%c", platform->MotorCurrent(drive), (drive < DRIVES - 1) ? ':' : '\n');
|
||||
reply.catf("%d%c", (int)platform->MotorCurrent(drive), (drive < DRIVES - 1) ? ':' : '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
GCodes.h
16
GCodes.h
|
@ -192,7 +192,6 @@ class GCodes
|
|||
uint16_t toBeHomed; // Bitmap of axes still to be homed
|
||||
bool doingFileMacro; // Are we executing a macro file?
|
||||
int oldToolNumber, newToolNumber; // Tools being changed
|
||||
float fractionOfFilePrinted; // Only used to record the main file when a macro is being printed
|
||||
const char* eofString; // What's at the end of an HTML file?
|
||||
uint8_t eofStringCounter; // Check the...
|
||||
uint8_t eofStringLength; // ... EoF string as we read.
|
||||
|
@ -219,21 +218,6 @@ class GCodes
|
|||
|
||||
//*****************************************************************************************************
|
||||
|
||||
inline float GCodes::FractionOfFilePrinted() const
|
||||
{
|
||||
if (fractionOfFilePrinted < 0.0)
|
||||
{
|
||||
return fileBeingPrinted.FractionRead();
|
||||
}
|
||||
|
||||
if (!fileBeingPrinted.IsLive())
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
return fractionOfFilePrinted;
|
||||
}
|
||||
|
||||
inline bool GCodes::PrintingAFile() const
|
||||
{
|
||||
return FractionOfFilePrinted() >= 0.0;
|
||||
|
|
47
Move.cpp
47
Move.cpp
|
@ -199,26 +199,47 @@ void Move::Spin()
|
|||
// See if we can add another move to the ring
|
||||
if (!addNoMoreMoves && ddaRingAddPointer->GetState() == DDA::empty)
|
||||
{
|
||||
DDA *dda = ddaRingAddPointer;
|
||||
if (reprap.Debug(moduleMove))
|
||||
{
|
||||
ddaRingAddPointer->PrintIfHasStepError();
|
||||
dda->PrintIfHasStepError();
|
||||
}
|
||||
// If there's a G Code move available, add it to the DDA ring for processing.
|
||||
float nextMove[DRIVES + 1];
|
||||
EndstopChecks endStopsToCheck;
|
||||
bool noDeltaMapping;
|
||||
FilePosition filePos;
|
||||
if (reprap.GetGCodes()->ReadMove(nextMove, endStopsToCheck, noDeltaMapping, filePos))
|
||||
|
||||
// In order to react faster to speed and extrusion rate changes, only add more moves if the total duration of
|
||||
// all un-frozen moves is less than 2 seconds, or the total duration of all but the first un-frozen move is
|
||||
// less than 0.5 seconds.
|
||||
float unPreparedTime = 0.0;
|
||||
float prevMoveTime = 0.0;
|
||||
for(;;)
|
||||
{
|
||||
currentFeedrate = nextMove[DRIVES]; // might be G1 with just an F field
|
||||
if (!noDeltaMapping || !IsDeltaMode())
|
||||
dda = dda->GetPrevious();
|
||||
if (dda->GetState() != DDA::provisional)
|
||||
{
|
||||
Transform(nextMove);
|
||||
break;
|
||||
}
|
||||
if (ddaRingAddPointer->Init(nextMove, endStopsToCheck, IsDeltaMode() && !noDeltaMapping, filePos))
|
||||
unPreparedTime += prevMoveTime;
|
||||
prevMoveTime = dda->CalcTime();
|
||||
}
|
||||
|
||||
if (unPreparedTime < 0.5 || unPreparedTime + prevMoveTime < 2.0)
|
||||
{
|
||||
// If there's a G Code move available, add it to the DDA ring for processing.
|
||||
float nextMove[DRIVES + 1];
|
||||
EndstopChecks endStopsToCheck;
|
||||
bool noDeltaMapping;
|
||||
FilePosition filePos;
|
||||
if (reprap.GetGCodes()->ReadMove(nextMove, endStopsToCheck, noDeltaMapping, filePos))
|
||||
{
|
||||
ddaRingAddPointer = ddaRingAddPointer->GetNext();
|
||||
idleCount = 0;
|
||||
currentFeedrate = nextMove[DRIVES]; // might be G1 with just an F field
|
||||
if (!noDeltaMapping || !IsDeltaMode())
|
||||
{
|
||||
Transform(nextMove);
|
||||
}
|
||||
if (ddaRingAddPointer->Init(nextMove, endStopsToCheck, IsDeltaMode() && !noDeltaMapping, filePos))
|
||||
{
|
||||
ddaRingAddPointer = ddaRingAddPointer->GetNext();
|
||||
idleCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
39
Platform.cpp
39
Platform.cpp
|
@ -1251,7 +1251,7 @@ void Platform::Disable(size_t drive)
|
|||
|
||||
void Platform::SetMotorCurrent(byte drive, float current)
|
||||
{
|
||||
unsigned short pot = (unsigned short)(0.256*current*8.0*senseResistor/maxStepperDigipotVoltage);
|
||||
unsigned short pot = (unsigned short)((0.256*current*8.0*senseResistor + maxStepperDigipotVoltage/2)/maxStepperDigipotVoltage);
|
||||
// Message(HOST_MESSAGE, "Set pot to: ");
|
||||
// snprintf(scratchString, STRING_LENGTH, "%d", pot);
|
||||
// Message(HOST_MESSAGE, scratchString);
|
||||
|
@ -1880,7 +1880,7 @@ bool FileStore::Open(const char* directory, const char* fileName, bool write)
|
|||
? platform->GetMassStorage()->CombineName(directory, fileName)
|
||||
: fileName;
|
||||
writing = write;
|
||||
lastBufferEntry = FILE_BUF_LEN - 1;
|
||||
lastBufferEntry = FILE_BUF_LEN;
|
||||
|
||||
FRESULT openReturn = f_open(&file, location, (writing) ? FA_CREATE_ALWAYS | FA_WRITE : FA_OPEN_EXISTING | FA_READ);
|
||||
if (openReturn != FR_OK)
|
||||
|
@ -1944,45 +1944,32 @@ bool FileStore::Seek(FilePosition pos)
|
|||
if (writing)
|
||||
{
|
||||
WriteBuffer();
|
||||
FRESULT fr = f_lseek(&file, pos);
|
||||
if (fr == FR_OK)
|
||||
{
|
||||
bufferPointer = 0;
|
||||
lastBufferEntry = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep file reads aligned on a 256-byte boundary
|
||||
FRESULT fr = f_lseek(&file, pos & ~(FilePosition)(FILE_BUF_LEN - 1));
|
||||
if (fr == FR_OK)
|
||||
{
|
||||
bool ok = ReadBuffer();
|
||||
if (ok)
|
||||
{
|
||||
bufferPointer = pos & (FilePosition)(FILE_BUF_LEN - 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
FRESULT fr = f_lseek(&file, pos);
|
||||
bufferPointer = (writing) ? 0 : FILE_BUF_LEN;
|
||||
return fr == FR_OK;
|
||||
}
|
||||
|
||||
FilePosition FileStore::GetPosition() const
|
||||
{
|
||||
FilePosition pos = file.fptr;
|
||||
if (!writing && bufferPointer < lastBufferEntry)
|
||||
if (writing)
|
||||
{
|
||||
pos += bufferPointer;
|
||||
}
|
||||
else if (bufferPointer < lastBufferEntry)
|
||||
{
|
||||
pos -= (lastBufferEntry - bufferPointer);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
#if 0 // not currently used
|
||||
bool FileStore::GoToEnd()
|
||||
{
|
||||
return Seek(Length());
|
||||
}
|
||||
#endif
|
||||
|
||||
FilePosition FileStore::Length() const
|
||||
{
|
||||
|
@ -1996,7 +1983,7 @@ FilePosition FileStore::Length() const
|
|||
|
||||
float FileStore::FractionRead() const
|
||||
{
|
||||
uint32_t len = Length();
|
||||
FilePosition len = Length();
|
||||
if (len == 0)
|
||||
{
|
||||
return 0.0;
|
||||
|
|
13
Platform.h
13
Platform.h
|
@ -75,8 +75,13 @@ Licence: GPL
|
|||
|
||||
// DRIVES
|
||||
|
||||
#if 0 // swap X with E0
|
||||
#define STEP_PINS {X2, 25, 5, 14, 41, 39, X4, 49}
|
||||
#define DIRECTION_PINS {X3, 26, 4, 15, 35, 53, 51, 48}
|
||||
#else
|
||||
#define STEP_PINS {14, 25, 5, X2, 41, 39, X4, 49}
|
||||
#define DIRECTION_PINS {15, 26, 4, X3, 35, 53, 51, 48}
|
||||
#endif
|
||||
#define FORWARDS true // What to send to go...
|
||||
#define BACKWARDS (!FORWARDS) // ...in each direction
|
||||
#define DIRECTIONS {BACKWARDS, FORWARDS, FORWARDS, FORWARDS, FORWARDS, FORWARDS, FORWARDS, FORWARDS} // What each axis needs to make it go forwards - defaults
|
||||
|
@ -373,7 +378,9 @@ public:
|
|||
bool Close(); // Shut the file and tidy up
|
||||
bool Seek(FilePosition pos); // Jump to pos in the file
|
||||
FilePosition GetPosition() const; // Return the current position in the file, assuming we are reading the file
|
||||
#if 0 // not currently used
|
||||
bool GoToEnd(); // Position the file at the end (so you can write on the end).
|
||||
#endif
|
||||
FilePosition Length() const; // File size in bytes
|
||||
float FractionRead() const; // How far in we are
|
||||
void Duplicate(); // Create a second reference to this file
|
||||
|
@ -900,12 +907,12 @@ public:
|
|||
return f->Flush();
|
||||
}
|
||||
|
||||
uint32_t GetPosition() const
|
||||
FilePosition GetPosition() const
|
||||
{
|
||||
return f->GetPosition();
|
||||
}
|
||||
|
||||
bool Seek(uint32_t position)
|
||||
bool Seek(FilePosition position)
|
||||
{
|
||||
return f->Seek(position);
|
||||
}
|
||||
|
@ -915,7 +922,7 @@ public:
|
|||
return (f == NULL ? -1.0 : f->FractionRead());
|
||||
}
|
||||
|
||||
uint32_t Length() const
|
||||
FilePosition Length() const
|
||||
{
|
||||
return f->Length();
|
||||
}
|
||||
|
|
BIN
Release/RepRapFirmware-1.00i-dc42.bin
Normal file
BIN
Release/RepRapFirmware-1.00i-dc42.bin
Normal file
Binary file not shown.
|
@ -243,13 +243,13 @@ void RepRap::Init()
|
|||
while (initialisingInProgress)
|
||||
{
|
||||
Spin();
|
||||
if(gCodes->PrintingAFile())
|
||||
if(gCodes->DoingFileMacro())
|
||||
{
|
||||
runningTheFile = true;
|
||||
}
|
||||
if(runningTheFile)
|
||||
{
|
||||
if(!gCodes->PrintingAFile())
|
||||
if(!gCodes->DoingFileMacro())
|
||||
{
|
||||
initialisingInProgress = false;
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ void RepRap::GetStatusResponse(StringRef& response, uint8_t type, bool forWebser
|
|||
// Paused / Stopped
|
||||
ch = 'S';
|
||||
}
|
||||
else if (gCodes->PrintingAFile())
|
||||
else if (gCodes->PrintingAFile() && !gCodes->DoingFileMacro())
|
||||
{
|
||||
// Printing
|
||||
ch = 'P';
|
||||
|
@ -1106,6 +1106,12 @@ void RepRap::GetLegacyStatusResponse(StringRef& response, uint8_t type, int seq)
|
|||
response.catf(",\"buff\":%u", webserver->GetGcodeBufferSpace()); // send the amount of buffer space available for gcodes
|
||||
}
|
||||
|
||||
if (type == 2 && gCodes->PrintingAFile())
|
||||
{
|
||||
// Send estimated times left bBased on file progress, filament usage, and layers
|
||||
response.catf(",\"timesLeft\":[%.1f,%.1f,%.1f]", EstimateTimeLeft(0), EstimateTimeLeft(1), EstimateTimeLeft(2));
|
||||
}
|
||||
|
||||
if (type < 2 || (seq != -1 && replySeq > seq))
|
||||
{
|
||||
response.catf(",\"seq\":%u", replySeq); // send the response sequence number
|
||||
|
|
|
@ -44,7 +44,7 @@ const unsigned int maxCommandWords = 4; // max number of space-separated words
|
|||
const unsigned int maxQualKeys = 5; // max number of key/value pairs in the qualifier
|
||||
const unsigned int maxHeaders = 10; // max number of key/value pairs in the headers
|
||||
|
||||
const unsigned int jsonReplyLength = 1024; // size of buffer used to hold JSON reply
|
||||
const unsigned int jsonReplyLength = 2000; // size of buffer used to hold JSON reply
|
||||
|
||||
const unsigned int maxSessions = 8; // maximum number of simultaneous HTTP sessions
|
||||
const unsigned int httpSessionTimeout = 30; // HTTP session timeout in seconds
|
||||
|
|
Reference in a new issue