Fixed G32 auto bed compensation

Fixed bug introduced at version 057o-dc42 that broke the G32 bed
compensation. Added the Z heights of the bed compensation points to the
information displayed by M111 S2. Simplified the code that does
Z-probing in fast and slow stages. Added function sncatf and used it to
simplify the code in several places.
This commit is contained in:
David Crocker 2014-03-26 18:07:49 +00:00
parent aa55c61e1d
commit 92fefbf598
11 changed files with 114 additions and 150 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H
#define NAME "RepRapFirmware"
#define VERSION "0.57w-dc42"
#define DATE "2014-03-25"
#define VERSION "0.57x-dc42"
#define DATE "2014-03-26"
#define LAST_AUTHOR "dc42"
// Other firmware that we might switch to be compatible with.

View file

@ -55,7 +55,7 @@ void GCodes::Init()
moveAvailable = false;
drivesRelative = true;
axesRelative = false;
checkEndStops = noEndstopCheck;
checkEndStops = false;
gCodeLetters = GCODE_LETTERS;
distanceScale = 1.0;
for (int8_t i = 0; i < DRIVES - AXES; i++)
@ -305,7 +305,7 @@ bool GCodes::Pop()
gFeedRate = feedrateStack[stackPointer];
moveBuffer[DRIVES] = gFeedRate;
checkEndStops = noEndstopCheck;
checkEndStops = false;
moveAvailable = true;
return true;
}
@ -394,24 +394,23 @@ int GCodes::SetUpMove(GCodeBuffer *gb)
if (!reprap.GetMove()->GetCurrentState(moveBuffer))
return 0;
bool doEndstopCheck = false;
checkEndStops = false;
if (gb->Seen('S'))
{
if (gb->GetIValue() == 1)
{
doEndstopCheck = true;
checkEndStops = true;
}
}
checkEndStops = (doEndstopCheck) ? checkAtEndstop : noEndstopCheck;
LoadMoveBufferFromGCode(gb, false, !doEndstopCheck);
LoadMoveBufferFromGCode(gb, false, !checkEndStops);
moveAvailable = true;
return (doEndstopCheck) ? 2 : 1;
return (checkEndStops) ? 2 : 1;
}
// The Move class calls this function to find what to do next.
bool GCodes::ReadMove(float m[], EndstopMode& ce)
bool GCodes::ReadMove(float m[], bool& ce)
{
if (!moveAvailable)
return false;
@ -419,7 +418,7 @@ bool GCodes::ReadMove(float m[], EndstopMode& ce)
m[i] = moveBuffer[i];
ce = checkEndStops;
moveAvailable = false;
checkEndStops = noEndstopCheck;
checkEndStops = false;
return true;
}
@ -498,7 +497,7 @@ bool GCodes::FileCannedCyclesReturn()
// be ignored. Recall that moveToDo[DRIVES] should contain the feedrate
// you want (if action[DRIVES] is true).
bool GCodes::DoCannedCycleMove(EndstopMode ce)
bool GCodes::DoCannedCycleMove(bool ce)
{
// Is the move already running?
@ -585,7 +584,7 @@ bool GCodes::OffsetAxes(GCodeBuffer* gb)
offSetSet = true;
}
if (DoCannedCycleMove(noEndstopCheck))
if (DoCannedCycleMove(false))
{
//LoadMoveBufferFromArray(record);
for (int drive = 0; drive <= DRIVES; drive++)
@ -659,7 +658,7 @@ bool GCodes::DoHome(char* reply, bool& error)
// Should never get here
checkEndStops = noEndstopCheck;
checkEndStops = false;
moveAvailable = false;
return true;
@ -680,19 +679,19 @@ bool GCodes::DoSingleZProbeAtPoint()
switch (cannedCycleMoveCount)
{
case 0: // This only does anything on the first move; on all the others Z is already there
case 0: // Raise Z to 5mm. This only does anything on the first move; on all the others Z is already there
moveToDo[Z_AXIS] = Z_DIVE;
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
activeDrive[DRIVES] = true;
if (DoCannedCycleMove(noEndstopCheck))
reprap.GetMove()->SetZProbing(false);
if (DoCannedCycleMove(false))
{
cannedCycleMoveCount++;
reprap.GetMove()->SetZProbing(true); // we only want to call this once
}
return false;
case 1:
case 1: // Move to the correct XY coordinates
GetProbeCoordinates(probeCount, moveToDo[X_AXIS], moveToDo[Y_AXIS], moveToDo[Z_AXIS]);
activeDrive[X_AXIS] = true;
activeDrive[Y_AXIS] = true;
@ -700,48 +699,33 @@ bool GCodes::DoSingleZProbeAtPoint()
moveToDo[DRIVES] = platform->HomeFeedRate(X_AXIS);
activeDrive[DRIVES] = true;
reprap.GetMove()->SetZProbing(false);
if (DoCannedCycleMove(noEndstopCheck))
if (DoCannedCycleMove(false))
{
cannedCycleMoveCount++;
platform->SetZProbing(true); // do this here because we only want to call it once
}
return false;
case 2:
case 2: // Probe the bed
moveToDo[Z_AXIS] = -2.0 * platform->AxisLength(Z_AXIS);
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
activeDrive[DRIVES] = true;
reprap.GetMove()->SetZProbing(true);
if (DoCannedCycleMove(checkApproachingEndstop))
{
cannedCycleMoveCount++;
}
return false;
case 3:
{
float liveCoordinates[DRIVES + 1];
reprap.GetMove()->LiveCoordinates(liveCoordinates);
moveToDo[Z_AXIS] = liveCoordinates[Z_AXIS] - 10.0; // move down at most another 10mm
}
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS) * 0.2;
activeDrive[DRIVES] = true;
reprap.GetMove()->SetZProbing(true);
if (DoCannedCycleMove(checkAtEndstop))
if (DoCannedCycleMove(true))
{
cannedCycleMoveCount++;
platform->SetZProbing(false);
}
return false;
case 4:
case 3: // Raise the head 5mm
moveToDo[Z_AXIS] = Z_DIVE;
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
activeDrive[DRIVES] = true;
reprap.GetMove()->SetZProbing(false);
if (DoCannedCycleMove(noEndstopCheck))
if (DoCannedCycleMove(false))
{
cannedCycleMoveCount++;
}
@ -775,22 +759,7 @@ bool GCodes::DoSingleZProbe()
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
activeDrive[DRIVES] = true;
if (DoCannedCycleMove(checkApproachingEndstop))
{
cannedCycleMoveCount++;
}
return false;
case 2:
{
float liveCoordinates[DRIVES + 1];
reprap.GetMove()->LiveCoordinates(liveCoordinates);
moveToDo[Z_AXIS] = liveCoordinates[Z_AXIS] - 10.0; // move down at most another 10mm
}
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS) * 0.2;
activeDrive[DRIVES] = true;
if (DoCannedCycleMove(checkAtEndstop))
if (DoCannedCycleMove(true))
{
cannedCycleMoveCount++;
probeCount = 0;
@ -1656,11 +1625,9 @@ bool GCodes::ActOnGcode(GCodeBuffer *gb)
strncpy(reply, "T:", STRING_LENGTH);
for (int8_t heater = HEATERS - 1; heater > 0; heater--)
{
strncat(reply, ftoa(0, reprap.GetHeat()->GetTemperature(heater), 1), STRING_LENGTH);
strncat(reply, " ", STRING_LENGTH);
sncatf(reply, STRING_LENGTH, "%.1f ", reprap.GetHeat()->GetTemperature(heater));
}
strncat(reply, "B:", STRING_LENGTH);
strncat(reply, ftoa(0, reprap.GetHeat()->GetTemperature(0), 1), STRING_LENGTH);
sncatf(reply, STRING_LENGTH, "B:%.1f", reprap.GetHeat()->GetTemperature(0));
break;
case 106: // Fan on or off

View file

@ -27,10 +27,6 @@ Licence: GPL
#define GCODE_LETTERS { 'X', 'Y', 'Z', 'E', 'F' } // The drives and feedrate in a GCode
// Enumeration to define the mode in which we check endstops
enum EndstopMode { noEndstopCheck, checkApproachingEndstop, checkAtEndstop};
// Small class to hold an individual GCode and provide functions to allow it to be parsed
@ -77,7 +73,7 @@ class GCodes
void Init();
void Exit();
bool RunConfigurationGCodes();
bool ReadMove(float* m, EndstopMode& ce);
bool ReadMove(float* m, bool& ce);
void QueueFileToPrint(const char* fileName);
void DeleteFile(const char* fileName);
bool GetProbeCoordinates(int count, float& x, float& y, float& z);
@ -92,7 +88,7 @@ class GCodes
void doFilePrint(GCodeBuffer* gb);
bool AllMovesAreFinishedAndMoveBufferIsLoaded();
bool DoCannedCycleMove(EndstopMode ce);
bool DoCannedCycleMove(bool ce);
bool DoFileCannedCycles(const char* fileName);
bool FileCannedCyclesReturn();
bool ActOnGcode(GCodeBuffer* gb);
@ -133,7 +129,7 @@ class GCodes
GCodeBuffer* cannedCycleGCode;
bool moveAvailable;
float moveBuffer[DRIVES+1]; // Last is feed rate
EndstopMode checkEndStops;
bool checkEndStops;
bool drivesRelative; // All except X, Y and Z
bool axesRelative; // X, Y and Z
bool drivesRelativeStack[STACK];

View file

@ -128,12 +128,8 @@ void PID::Spin()
{
platform->SetHeater(heater, 0.0);
temperatureFault = true;
platform->Message(HOST_MESSAGE, "Temperature measurement fault on heater ");
snprintf(scratchString, STRING_LENGTH, "%d", heater);
snprintf(scratchString, STRING_LENGTH, "Temperature measurement fault on heater %d, T = %.1f\n", heater, temperature);
platform->Message(HOST_MESSAGE, scratchString);
platform->Message(HOST_MESSAGE, ", T = ");
platform->Message(HOST_MESSAGE, ftoa(scratchString, temperature, 1));
platform->Message(HOST_MESSAGE, "\n");
}
}
else

View file

@ -94,7 +94,7 @@ void Move::Init()
liveCoordinates[i] = 0.0;
}
lastMove->Init(ep, platform->HomeFeedRate(Z_AXIS), platform->InstantDv(Z_AXIS), noEndstopCheck, zMove); // Typically Z is the slowest Axis
lastMove->Init(ep, platform->HomeFeedRate(Z_AXIS), platform->InstantDv(Z_AXIS), false, zMove); // Typically Z is the slowest Axis
lastMove->Release();
liveCoordinates[DRIVES] = platform->HomeFeedRate(Z_AXIS);
@ -167,7 +167,7 @@ void Move::Spin()
// If there's a G Code move available, add it to the look-ahead
// ring for processing.
EndstopMode checkEndStopsOnNextMove;
bool checkEndStopsOnNextMove;
if(gCodes->ReadMove(nextMove, checkEndStopsOnNextMove))
{
Transform(nextMove);
@ -572,7 +572,7 @@ void Move::Interrupt()
}
bool Move::LookAheadRingAdd(const long ep[], float feedRate, float vv, EndstopMode ce, int8_t mt)
bool Move::LookAheadRingAdd(const long ep[], float feedRate, float vv, bool ce, int8_t mt)
{
if(LookAheadRingFull())
return false;
@ -600,7 +600,7 @@ LookAhead* Move::LookAheadRingGet()
}
// Note that we don't set the tan values to 0 here. This means that the bed probe
// values will be a fraction of a millimeter out in X and Y, which, as the bed should
// values will be a fraction of a millimetre out in X and Y, which, as the bed should
// be nearly flat (and the probe doesn't coincide with the nozzle anyway), won't matter.
// But it means that the tan values can be set for the machine
// at the start in the configuration file and be retained, without having to know and reset
@ -614,7 +614,6 @@ void Move::SetIdentityTransform()
secondDegreeCompensation = false;
}
void Move::Transform(float xyzPoint[])
{
xyzPoint[X_AXIS] = xyzPoint[X_AXIS] + tanXY*xyzPoint[Y_AXIS] + tanXZ*xyzPoint[Z_AXIS];
@ -1099,7 +1098,7 @@ void DDA::Step()
// Hit anything?
if(checkEndStops != noEndstopCheck)
if(checkEndStops)
{
switch(platform->Stopped(drive))
{
@ -1112,11 +1111,7 @@ void DDA::Step()
active = false;
break;
case lowNear:
if (checkEndStops == checkApproachingEndstop)
{
move->NearLowStop(drive, myLookAheadEntry, this);
active = false;
}
velocity = instantDv; // slow down because we are getting close
break;
default:
break;
@ -1180,7 +1175,7 @@ LookAhead::LookAhead(Move* m, Platform* p, LookAhead* n)
next = n;
}
void LookAhead::Init(const long ep[], float f, float vv, EndstopMode ce, int8_t mt)
void LookAhead::Init(const long ep[], float f, float vv, bool ce, int8_t mt)
{
v = vv;
movementType = mt;

18
Move.h
View file

@ -70,7 +70,7 @@ public:
protected:
LookAhead(Move* m, Platform* p, LookAhead* n);
void Init(const long ep[], float feedRate, float vv, EndstopMode ce, int8_t mt);
void Init(const long ep[], float feedRate, float vv, bool ce, int8_t mt);
LookAhead* Next();
LookAhead* Previous();
const long* MachineEndPoints() const;
@ -85,7 +85,7 @@ protected:
int8_t Processed() const;
void SetProcessed(MovementState ms);
void SetDriveCoordinateAndZeroEndSpeed(float a, int8_t drive);
EndstopMode CheckEndStops() const;
bool CheckEndStops() const;
void Release();
private:
@ -97,7 +97,7 @@ private:
long endPoint[DRIVES+1]; // Should never use the +1, but safety first
int8_t movementType;
float Cosine();
EndstopMode checkEndStops;
bool checkEndStops;
float cosine;
float v; // The feedrate we can actually do
float feedRate; // The requested feedrate
@ -135,7 +135,7 @@ private:
bool directions[DRIVES];
long totalSteps;
long stepCount;
EndstopMode checkEndStops;
bool checkEndStops;
float timeStep;
float velocity;
long stopAStep;
@ -164,7 +164,6 @@ class Move
void ResumeMoving();
void DoLookAhead();
void HitLowStop(int8_t drive, LookAhead* la, DDA* hitDDA);
void NearLowStop(int8_t drive, LookAhead* la, DDA* hitDDA);
void HitHighStop(int8_t drive, LookAhead* la, DDA* hitDDA);
void SetPositions(float move[]);
void SetLiveCoordinates(float coords[]);
@ -204,7 +203,7 @@ class Move
void ReleaseDDARingLock();
bool LookAheadRingEmpty() const;
bool LookAheadRingFull() const;
bool LookAheadRingAdd(const long ep[], float feedRate, float vv, EndstopMode ce, int8_t movementType);
bool LookAheadRingAdd(const long ep[], float feedRate, float vv, bool ce, int8_t movementType);
LookAhead* LookAheadRingGet();
int8_t GetMovementType(const long sp[], const long ep[]) const;
@ -304,7 +303,7 @@ inline void LookAhead::Release()
processed = released;
}
inline EndstopMode LookAhead::CheckEndStops() const
inline bool LookAhead::CheckEndStops() const
{
return checkEndStops;
}
@ -583,11 +582,6 @@ inline void Move::HitHighStop(int8_t drive, LookAhead* la, DDA* hitDDA)
gCodes->SetAxisIsHomed(drive);
}
inline void Move::NearLowStop(int8_t drive, LookAhead* la, DDA* hitDDA)
{
la->SetDriveCoordinateAndZeroEndSpeed(1.0, drive); // say we are at 1mm
}
inline float Move::ComputeCurrentCoordinate(int8_t drive, LookAhead* la, DDA* runningDDA)
{
float previous = la->Previous()->MachineToEndPoint(drive);

View file

@ -770,6 +770,16 @@ void Platform::PrintMemoryUsage()
snprintf(scratchString, STRING_LENGTH, "Error status: %u\n", errorCodeBits);
reprap.GetWebserver()->AppendReply(scratchString);
Message(HOST_MESSAGE, scratchString);
// Show the current probe position heights
strncpy(scratchString, "Bed probe heights:", STRING_LENGTH);
for (size_t i = 0; i < NUMBER_OF_PROBE_POINTS; ++i)
{
sncatf(scratchString, STRING_LENGTH, " %.3f", reprap.GetMove()->zBedProbePoint(i));
}
strncat(scratchString, "\n", STRING_LENGTH);
reprap.GetWebserver()->AppendReply(scratchString);
Message(HOST_MESSAGE, scratchString);
}
void Platform::ClassReport(char* className, float &lastTime)

Binary file not shown.

View file

@ -302,11 +302,13 @@ void RepRap::SetDebug(int d)
// Utilities and storage not part of any class
char scratchString[STRING_LENGTH];
#if 0 // no longer used, we use snprinf or sncatf instead
// Float to a string.
static long precision[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
char scratchString[STRING_LENGTH];
char* ftoa(char *a, const float& f, int prec)
{
@ -326,6 +328,23 @@ char* ftoa(char *a, const float& f, int prec)
snprintf(a, STRING_LENGTH, "%0*d", prec, decimal);
return ret;
}
#endif
// This behaves like snprintf but appends to an existing string
// The second parameter is the length of the entire destination buffer, not the length remaining
int sncatf(char *dst, size_t len, const char* fmt, ...)
{
size_t n = strnlen(dst, len);
if (n + 1 < len)
{
va_list p;
va_start(p, fmt);
int ret = vsnprintf(dst + n, len - n, fmt, p);
va_end(p);
return ret;
}
return 0;
}
// String testing

View file

@ -22,6 +22,9 @@ Licence: GPL
#ifndef REPRAPFIRMWARE_H
#define REPRAPFIRMWARE_H
#include <cstddef> // for size_t
#include <cfloat>
// Warn of what's to come, so we can use pointers to classes...
class Platform;
@ -37,7 +40,10 @@ extern RepRap reprap;
// Functions and globals not part of any class
int sncatf(char *dst, size_t len, const char* fmt, ...);
#if 0 // n longer used
char* ftoa(char *a, const float& f, int prec);
#endif
bool StringEndsWith(const char* string, const char* ending);
bool StringStartsWith(const char* string, const char* starting);
bool StringEquals(const char* s1, const char* s2);
@ -46,8 +52,6 @@ int StringContains(const char* string, const char* match);
// Macro to give us the number of elements in an array
#define ARRAY_SIZE(_x) (sizeof(_x)/sizeof(_x[0]))
#include <float.h>
extern char scratchString[];
#include "Configuration.h"
@ -59,7 +63,6 @@ extern char scratchString[];
#include "Reprap.h"
#endif

View file

@ -390,6 +390,7 @@ void Webserver::JsonReport(bool ok, const char* request)
{
if(reprap.Debug())
{
jsonResponse[STRING_LENGTH] = 0;
platform->Message(HOST_MESSAGE, "JSON response: ");
platform->Message(HOST_MESSAGE, jsonResponse);
platform->Message(HOST_MESSAGE, " queued\n");
@ -410,68 +411,65 @@ void Webserver::GetJsonResponse(const char* request)
if(StringStartsWith(request, "poll"))
{
// The poll response lists the status, then all the heater temperatures, then the XYZ positions, then all the extruder positions.
// These are all returned in a single vector called "poll".
// This is a poor choice of format because we can't easily tell which is which unless we already know the number of heaters and extruders,
// but we're stuck with it if we want to retain compatibility with existing web server javascript files.
strncpy(jsonResponse, "{\"poll\":[", STRING_LENGTH);
if(reprap.GetGCodes()->PrintingAFile())
{
strncat(jsonResponse, "\"P\",", STRING_LENGTH); // Printing
}
else
{
strncat(jsonResponse, "\"I\",", STRING_LENGTH); // Idle
}
for(int8_t heater = 0; heater < HEATERS; heater++)
{
strncat(jsonResponse, "\"", STRING_LENGTH);
strncat(jsonResponse, ftoa(0, reprap.GetHeat()->GetTemperature(heater), 1), STRING_LENGTH);
strncat(jsonResponse, "\",", STRING_LENGTH);
sncatf(jsonResponse, STRING_LENGTH, "\"%.1f\",", reprap.GetHeat()->GetTemperature(heater));
}
float liveCoordinates[DRIVES+1];
reprap.GetMove()->LiveCoordinates(liveCoordinates);
for(int8_t drive = 0; drive < AXES; drive++)
{
strncat(jsonResponse, "\"", STRING_LENGTH);
strncat(jsonResponse, ftoa(0, liveCoordinates[drive], 2), STRING_LENGTH);
strncat(jsonResponse, "\",", STRING_LENGTH);
sncatf(jsonResponse, STRING_LENGTH, "\"%.2f\",", liveCoordinates[drive]);
}
// FIXME: should loop through all Es
strncat(jsonResponse, "\"", STRING_LENGTH);
strncat(jsonResponse, ftoa(0, liveCoordinates[AXES], 4), STRING_LENGTH);
strncat(jsonResponse, "\"", STRING_LENGTH);
strncat(jsonResponse, "]", STRING_LENGTH);
for(int8_t drive = AXES; drive < DRIVES; drive++) // loop through extruders
{
char ch = (drive == DRIVES - 1) ? ']' : ','; // append ] to the last one but , to the others
sncatf(jsonResponse, STRING_LENGTH, "\"%.f4\"%c", liveCoordinates[drive], ch);
}
// All the other values we send back are in separate variables.
// Send the Z probe value
char scratch[SHORT_STRING_LENGTH+1];
scratch[SHORT_STRING_LENGTH] = 0;
int v0 = platform->ZProbe();
int v1, v2;
switch(platform->GetZProbeSecondaryValues(v1, v2))
{
case 1:
snprintf(scratch, SHORT_STRING_LENGTH, ",\"probe\":\"%d (%d)\"", v0, v1);
sncatf(jsonResponse, STRING_LENGTH, ",\"probe\":\"%d (%d)\"", v0, v1);
break;
case 2:
snprintf(scratch, SHORT_STRING_LENGTH, ",\"probe\":\"%d (%d, %d)\"", v0, v1, v2);
sncatf(jsonResponse, STRING_LENGTH, ",\"probe\":\"%d (%d, %d)\"", v0, v1, v2);
break;
default:
snprintf(scratch, SHORT_STRING_LENGTH, ",\"probe\":\"%d\"", v0);
sncatf(jsonResponse, STRING_LENGTH, ",\"probe\":\"%d\"", v0);
break;
}
strncat(jsonResponse, scratch, STRING_LENGTH);
// Send the amount of buffer space available for gcodes
snprintf(scratch, SHORT_STRING_LENGTH, ",\"buff\":%u", GetReportedGcodeBufferSpace());
strncat(jsonResponse, scratch, STRING_LENGTH);
sncatf(jsonResponse, STRING_LENGTH, ",\"buff\":%u", GetReportedGcodeBufferSpace());
// Send the home state. To keep the messages short, we send 1 for homed and 0 for not homed, instead of true and false.
strncat(jsonResponse, ",\"hx\":", STRING_LENGTH);
strncat(jsonResponse, (reprap.GetGCodes()->GetAxisIsHomed(0)) ? "1" : "0", STRING_LENGTH);
strncat(jsonResponse, ",\"hy\":", STRING_LENGTH);
strncat(jsonResponse, (reprap.GetGCodes()->GetAxisIsHomed(1)) ? "1" : "0", STRING_LENGTH);
strncat(jsonResponse, ",\"hz\":", STRING_LENGTH);
strncat(jsonResponse, (reprap.GetGCodes()->GetAxisIsHomed(2)) ? "1" : "0", STRING_LENGTH);
sncatf(jsonResponse, STRING_LENGTH, ",\"hx\":%d,\"hy\":%d,\"hz\":%d",
(reprap.GetGCodes()->GetAxisIsHomed(0)) ? 1 : 0,
(reprap.GetGCodes()->GetAxisIsHomed(1)) ? 1 : 0,
(reprap.GetGCodes()->GetAxisIsHomed(2)) ? 1 : 0
);
// Send the response sequence number
strncat(jsonResponse, ",\"seq\":", STRING_LENGTH);
snprintf(scratch, SHORT_STRING_LENGTH, "%u", (unsigned int)seq);
strncat(jsonResponse, scratch, STRING_LENGTH);
sncatf(jsonResponse, STRING_LENGTH, ",\"seq\":%u", (unsigned int)seq);
// Send the response to the last command. Do this last because it is long and may need to be truncated.
strncat(jsonResponse, ",\"resp\":\"", STRING_LENGTH);
@ -510,7 +508,6 @@ void Webserver::GetJsonResponse(const char* request)
}
strncat(jsonResponse, "\"}", STRING_LENGTH);
jsonResponse[STRING_LENGTH] = 0;
JsonReport(true, request);
return;
}
@ -518,10 +515,7 @@ void Webserver::GetJsonResponse(const char* request)
if(StringStartsWith(request, "gcode"))
{
LoadGcodeBuffer(&clientQualifier[6], true);
char scratch[SHORT_STRING_LENGTH+1];
scratch[SHORT_STRING_LENGTH] = 0;
snprintf(scratch, SHORT_STRING_LENGTH, "{\"buff\":%u}", GetReportedGcodeBufferSpace());
strncat(jsonResponse, scratch, STRING_LENGTH);
sncatf(jsonResponse, STRING_LENGTH, "{\"buff\":%u}", GetReportedGcodeBufferSpace());
JsonReport(true, request);
return;
}
@ -529,18 +523,14 @@ void Webserver::GetJsonResponse(const char* request)
if(StringStartsWith(request, "files"))
{
const char* fileList = platform->GetMassStorage()->FileList(platform->GetGCodeDir(), false);
strncpy(jsonResponse, "{\"files\":[", STRING_LENGTH);
strncat(jsonResponse, fileList, STRING_LENGTH);
strncat(jsonResponse, "]}", STRING_LENGTH);
snprintf(jsonResponse, STRING_LENGTH, "{\"files\":[%s]}", fileList);
JsonReport(true, request);
return;
}
if(StringStartsWith(request, "name"))
{
strncpy(jsonResponse, "{\"myName\":\"", STRING_LENGTH);
strncat(jsonResponse, myName, STRING_LENGTH);
strncat(jsonResponse, "\"}", STRING_LENGTH);
snprintf(jsonResponse, STRING_LENGTH, "{\"myName\":\"%s\"}", myName);
JsonReport(true, request);
return;
}
@ -548,12 +538,7 @@ void Webserver::GetJsonResponse(const char* request)
if(StringStartsWith(request, "password"))
{
CheckPassword();
strncpy(jsonResponse, "{\"password\":\"", STRING_LENGTH);
if(gotPassword)
strncat(jsonResponse, "right", STRING_LENGTH);
else
strncat(jsonResponse, "wrong", STRING_LENGTH);
strncat(jsonResponse, "\"}", STRING_LENGTH);
snprintf(jsonResponse, STRING_LENGTH, "{\"password\":\"%s\"}", (gotPassword) ? "right" : "wrong");
JsonReport(true, request);
return;
}
@ -563,12 +548,11 @@ void Webserver::GetJsonResponse(const char* request)
strncpy(jsonResponse, "{\"axes\":[", STRING_LENGTH);
for(int8_t drive = 0; drive < AXES; drive++)
{
strncat(jsonResponse, "\"", STRING_LENGTH);
strncat(jsonResponse, ftoa(0, platform->AxisLength(drive), 1), STRING_LENGTH);
sncatf(jsonResponse, STRING_LENGTH, "\"%.1f\"", platform->AxisLength(drive));
if(drive < AXES-1)
strncat(jsonResponse, "\",", STRING_LENGTH);
else
strncat(jsonResponse, "\"", STRING_LENGTH);
{
strncat(jsonResponse, ",", STRING_LENGTH);
}
}
strncat(jsonResponse, "]}", STRING_LENGTH);
JsonReport(true, request);