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:
David Crocker 2015-02-17 00:37:47 +00:00
parent 8cc4162b40
commit 2a3cf6c5c9
11 changed files with 95 additions and 91 deletions

View file

@ -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
View file

@ -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
View file

@ -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

View file

@ -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');
}
}
}

View file

@ -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;

View file

@ -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;
}
}
}
}

View file

@ -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;

View file

@ -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();
}

Binary file not shown.

View file

@ -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

View file

@ -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