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:
parent
aa55c61e1d
commit
92fefbf598
11 changed files with 114 additions and 150 deletions
|
@ -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.
|
||||
|
|
81
GCodes.cpp
81
GCodes.cpp
|
@ -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
|
||||
|
|
10
GCodes.h
10
GCodes.h
|
@ -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];
|
||||
|
|
6
Heat.cpp
6
Heat.cpp
|
@ -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
|
||||
|
|
19
Move.cpp
19
Move.cpp
|
@ -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
18
Move.h
|
@ -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);
|
||||
|
|
10
Platform.cpp
10
Platform.cpp
|
@ -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)
|
||||
|
|
BIN
Release/RepRapFirmware-057x-dc42.bin
Normal file
BIN
Release/RepRapFirmware-057x-dc42.bin
Normal file
Binary file not shown.
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Reference in a new issue