First working version. Horay!
This commit is contained in:
parent
b94bff107c
commit
874e6e0baf
14 changed files with 7730 additions and 42 deletions
2
GCodes.h
2
GCodes.h
|
@ -24,6 +24,7 @@ Licence: GPL
|
|||
|
||||
#define STACK 5
|
||||
|
||||
#define GCODE_LETTERS { 'X', 'Y', 'Z', 'E', 'F' } // The drives and feedrate in a GCode
|
||||
|
||||
// Small class to hold an individual GCode
|
||||
|
||||
|
@ -64,6 +65,7 @@ class GCodes
|
|||
boolean ReadHeat(float* h);
|
||||
void QueueFileToPrint(char* fileName);
|
||||
boolean PrintingAFile();
|
||||
void Diagnostics();
|
||||
|
||||
private:
|
||||
|
||||
|
|
11
GCodes.ino
11
GCodes.ino
|
@ -106,6 +106,11 @@ void GCodes::Spin()
|
|||
}
|
||||
}
|
||||
|
||||
void GCodes::Diagnostics()
|
||||
{
|
||||
platform->Message(HOST_MESSAGE, "GCodes Diagnostics:\n");
|
||||
}
|
||||
|
||||
boolean GCodes::AllMovesAreFinishedAndMoveBufferIsLoaded()
|
||||
{
|
||||
// Last one gone?
|
||||
|
@ -221,7 +226,7 @@ boolean GCodes::SetUpMove(GCodeBuffer *gb)
|
|||
// Deal with feedrate
|
||||
|
||||
if(gb->Seen(gCodeLetters[DRIVES]))
|
||||
moveBuffer[DRIVES] = gb->GetFValue()*distanceScale/60.0; // Feedrates are in mm/minute; we need mm/sec
|
||||
moveBuffer[DRIVES] = gb->GetFValue()*distanceScale*0.016666667; // Feedrates are in mm/minute; we need mm/sec
|
||||
|
||||
// Remember for next time if we are switched
|
||||
// to absolute drive moves
|
||||
|
@ -527,6 +532,10 @@ boolean GCodes::ActOnGcode(GCodeBuffer *gb)
|
|||
result = Pop();
|
||||
break;
|
||||
|
||||
case 122:
|
||||
reprap.Diagnostics();
|
||||
break;
|
||||
|
||||
case 126: // Valve open
|
||||
platform->Message(HOST_MESSAGE, "M126 - valves not yet implemented\n");
|
||||
break;
|
||||
|
|
1
Heat.h
1
Heat.h
|
@ -61,6 +61,7 @@ class Heat
|
|||
void Activate(int8_t heater);
|
||||
void Standby(int8_t heater);
|
||||
float GetTemperature(int8_t heater);
|
||||
void Diagnostics();
|
||||
|
||||
private:
|
||||
|
||||
|
|
5
Heat.ino
5
Heat.ino
|
@ -55,6 +55,11 @@ void Heat::Spin()
|
|||
pids[heater]->Spin();
|
||||
}
|
||||
|
||||
void Heat::Diagnostics()
|
||||
{
|
||||
platform->Message(HOST_MESSAGE, "Heat Diagnostics:\n");
|
||||
}
|
||||
|
||||
//******************************************************************************************************
|
||||
|
||||
PID::PID(Platform* p, int8_t h)
|
||||
|
|
8
Move.h
8
Move.h
|
@ -77,6 +77,7 @@ class LookAhead
|
|||
boolean checkEndStops;
|
||||
float cosine;
|
||||
float v;
|
||||
float instantDv;
|
||||
volatile int8_t processed;
|
||||
};
|
||||
|
||||
|
@ -90,6 +91,7 @@ class DDA
|
|||
void Step(boolean noTest);
|
||||
boolean Active();
|
||||
DDA* Next();
|
||||
float InstantDv();
|
||||
|
||||
friend class Move;
|
||||
|
||||
|
@ -134,6 +136,7 @@ class Move
|
|||
void DoLookAhead();
|
||||
void HitLowStop(int8_t drive, LookAhead* la);
|
||||
void HitHighStop(int8_t drive, LookAhead* la);
|
||||
void Diagnostics();
|
||||
|
||||
friend class DDA;
|
||||
|
||||
|
@ -248,6 +251,11 @@ inline DDA* DDA::Next()
|
|||
return next;
|
||||
}
|
||||
|
||||
inline float DDA::InstantDv()
|
||||
{
|
||||
return instantDv;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************************
|
||||
|
||||
|
|
85
Move.ino
85
Move.ino
|
@ -45,7 +45,7 @@ Move::Move(Platform* p, GCodes* g)
|
|||
lookAheadRingGetPointer = new LookAhead(this, platform, lookAheadRingGetPointer);
|
||||
lookAheadRingAddPointer->next = lookAheadRingGetPointer;
|
||||
|
||||
// Set the backwards pointers
|
||||
// Set the lookahead backwards pointers
|
||||
|
||||
lookAheadRingGetPointer = lookAheadRingAddPointer;
|
||||
for(i = 0; i <= LOOK_AHEAD_RING_LENGTH; i++)
|
||||
|
@ -82,7 +82,7 @@ void Move::Init()
|
|||
|
||||
addNoMoreMoves = false;
|
||||
|
||||
// Put the origin on the lookahead ring with zero velocity in the previous
|
||||
// Put the origin on the lookahead ring with default velocity in the previous
|
||||
// position to the first one that will be used.
|
||||
|
||||
lastMove = lookAheadRingAddPointer->Previous();
|
||||
|
@ -173,22 +173,80 @@ void Move::Spin()
|
|||
if(addNoMoreMoves || LookAheadRingFull())
|
||||
return;
|
||||
|
||||
// boolean waitForThisToFinish;
|
||||
|
||||
// If there's a G Code move available, add it to the look-ahead
|
||||
// ring for proicessing.
|
||||
// ring for processing.
|
||||
|
||||
if(gCodes->ReadMove(nextMove, checkEndStopsOnNextMove))
|
||||
{
|
||||
currentFeedrate = nextMove[DRIVES]; // Might be G1 with just an F field
|
||||
if(GetMovementType(lastMove->EndPoint(), nextMove) == noMove) // Throw it away if there's no real movement.
|
||||
|
||||
int8_t mt = GetMovementType(lastMove->EndPoint(), nextMove);
|
||||
|
||||
// Throw it away if there's no real movement.
|
||||
|
||||
if(mt == noMove)
|
||||
return;
|
||||
currentFeedrate = -1.0; // Real move - record its feedrate with it, not here.
|
||||
|
||||
// Real move - record its feedrate with it, not here.
|
||||
|
||||
currentFeedrate = -1.0;
|
||||
|
||||
// Promote minimum feedrates
|
||||
|
||||
if(mt & xyMove)
|
||||
nextMove[DRIVES] = fmax(nextMove[DRIVES], platform->InstantDv(X_AXIS));
|
||||
else if(mt & eMove)
|
||||
nextMove[DRIVES] = fmax(nextMove[DRIVES], platform->InstantDv(AXES));
|
||||
else
|
||||
nextMove[DRIVES] = fmax(nextMove[DRIVES], platform->InstantDv(Z_AXIS));
|
||||
|
||||
// Restrict maximum feedrates; assumes z < e < xy FIXME??
|
||||
|
||||
if(mt & zMove)
|
||||
nextMove[DRIVES] = fmin(nextMove[DRIVES], platform->MaxFeedrate(Z_AXIS));
|
||||
else if(mt & eMove)
|
||||
nextMove[DRIVES] = fmin(nextMove[DRIVES], platform->MaxFeedrate(AXES)); // Picks up the value for the first extruder. FIXME?
|
||||
else // Must be xy
|
||||
nextMove[DRIVES] = fmin(nextMove[DRIVES], platform->MaxFeedrate(X_AXIS)); // Assumes X and Y are equal. FIXME?
|
||||
|
||||
if(!LookAheadRingAdd(nextMove, 0.0, checkEndStopsOnNextMove))
|
||||
platform->Message(HOST_MESSAGE, "Can't add to non-full look ahead ring!\n"); // Should never happen...
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Move::Diagnostics()
|
||||
{
|
||||
platform->Message(HOST_MESSAGE, "Move Diagnostics:\n");
|
||||
/* if(active)
|
||||
platform->Message(HOST_MESSAGE, " active\n");
|
||||
else
|
||||
platform->Message(HOST_MESSAGE, " not active\n");
|
||||
|
||||
platform->Message(HOST_MESSAGE, " look ahead ring count: ");
|
||||
sprintf(scratchString, "%d\n", lookAheadRingCount);
|
||||
platform->Message(HOST_MESSAGE, scratchString);
|
||||
if(dda == NULL)
|
||||
platform->Message(HOST_MESSAGE, " dda: NULL\n");
|
||||
else
|
||||
{
|
||||
if(dda->Active())
|
||||
platform->Message(HOST_MESSAGE, " dda: active\n");
|
||||
else
|
||||
platform->Message(HOST_MESSAGE, " dda: not active\n");
|
||||
|
||||
}
|
||||
if(ddaRingLocked)
|
||||
platform->Message(HOST_MESSAGE, " dda ring is locked\n");
|
||||
else
|
||||
platform->Message(HOST_MESSAGE, " dda ring is not locked\n");
|
||||
if(addNoMoreMoves)
|
||||
platform->Message(HOST_MESSAGE, " addNoMoreMoves is true\n\n");
|
||||
else
|
||||
platform->Message(HOST_MESSAGE, " addNoMoreMoves is false\n\n");
|
||||
*/
|
||||
}
|
||||
|
||||
// This returns false if it is not possible
|
||||
// to use the result as the basis for the
|
||||
// next move because the look ahead ring
|
||||
|
@ -388,7 +446,7 @@ void Move::DoLookAhead()
|
|||
else if (mt & xyMove)
|
||||
c = platform->InstantDv(X_AXIS);
|
||||
else
|
||||
c = platform->InstantDv(AXES); // value for first extruder - slight hack
|
||||
c = platform->InstantDv(AXES); // value for first extruder FIXME??
|
||||
}
|
||||
n1->SetV(c);
|
||||
n1->SetProcessed(vCosineSet);
|
||||
|
@ -649,10 +707,12 @@ MovementProfile DDA::Init(LookAhead* lookAhead, float& u, float& v)
|
|||
|
||||
// If velocities requested are (almost) zero, set them to instantDv
|
||||
|
||||
if(v < 0.01) // Set change here?
|
||||
if(v < instantDv) // Set change here?
|
||||
v = instantDv;
|
||||
if(u < 0.01)
|
||||
if(u < instantDv)
|
||||
u = instantDv;
|
||||
if(targetPosition[DRIVES] < instantDv)
|
||||
targetPosition[DRIVES] = instantDv;
|
||||
|
||||
// At which DDA step should we stop accelerating? targetPosition[DRIVES] contains
|
||||
// the desired feedrate.
|
||||
|
@ -801,6 +861,11 @@ void DDA::Step(boolean noTest)
|
|||
if(stepCount >= startDStep)
|
||||
velocity -= acceleration*timeStep;
|
||||
|
||||
// Euler is only approximate.
|
||||
|
||||
if(velocity < instantDv)
|
||||
velocity = instantDv;
|
||||
|
||||
stepCount++;
|
||||
active = stepCount < totalSteps;
|
||||
|
||||
|
|
23
Platform.h
23
Platform.h
|
@ -58,7 +58,7 @@ Licence: GPL
|
|||
|
||||
#define DRIVES 4 // The number of drives in the machine, including X, Y, and Z plus extruder drives
|
||||
#define AXES 3 // The number of movement axes in the machine, usually just X, Y and Z. <= DRIVES
|
||||
#define HEATERS 2 // The number of heaters in the machine, including the heated bed if any.
|
||||
#define HEATERS 2 // The number of heaters in the machine; 0 is the heated bed even if there isn't one.
|
||||
|
||||
// The numbers of entries in each array must correspond with the values of DRIVES,
|
||||
// AXES, or HEATERS. Set values to -1 to flag unavailability.
|
||||
|
@ -80,12 +80,11 @@ Licence: GPL
|
|||
#define ACCELERATIONS {800.0, 800.0, 30.0, 250.0} // mm/sec^2??
|
||||
//#define ACCELERATIONS {80, 80, 3, 25}
|
||||
#define DRIVE_STEPS_PER_UNIT {91.4286, 91.4286, 4000.0, 948.0}
|
||||
#define INSTANT_DVS {15.0, 15.0, 0.4, 15.0} // (mm/sec)
|
||||
#define GCODE_LETTERS { 'X', 'Y', 'Z', 'E', 'F' } // The drives and feedrate in a GCode
|
||||
#define INSTANT_DVS {1.0, 1.0, 0.3, 1.0} // (mm/sec) - Bit high? AB
|
||||
|
||||
// AXES
|
||||
|
||||
#define START_FEED_RATE 200.0
|
||||
#define START_FEED_RATE 200.0 // Default. mm/min
|
||||
|
||||
#define AXIS_LENGTHS {210, 200, 120} // mm
|
||||
#define HOME_FEEDRATES {50.0*60.0, 50.0*60.0, 1.0*60.0} // mm/min
|
||||
|
@ -96,7 +95,7 @@ Licence: GPL
|
|||
#define Z_AXIS 2 // The index of the Z axis
|
||||
|
||||
|
||||
// HEATERS - Bed is assumed to be the first
|
||||
// HEATERS - The bed is assumed to be the first
|
||||
|
||||
#define TEMP_SENSE_PINS {10, 9} // Analogue pin numbers
|
||||
#define HEAT_ON_PINS {8, 9}
|
||||
|
@ -207,6 +206,8 @@ class Platform
|
|||
|
||||
void Exit(); // Shut down tidily. Calling Init after calling this should reset to the beginning
|
||||
|
||||
void Diagnostics();
|
||||
|
||||
// Timing
|
||||
|
||||
float Time(); // Returns elapsed seconds since some arbitrary time
|
||||
|
@ -247,6 +248,7 @@ class Platform
|
|||
void Disable(byte drive); // There is no drive enable; drives get enabled automatically the first time they are used.
|
||||
float DriveStepsPerUnit(int8_t drive);
|
||||
float Acceleration(int8_t drive);
|
||||
float MaxFeedrate(int8_t drive);
|
||||
float InstantDv(int8_t drive);
|
||||
float HomeFeedRate(int8_t drive);
|
||||
EndStopHit Stopped(int8_t drive);
|
||||
|
@ -449,6 +451,12 @@ inline float Platform::AxisLength(int8_t drive)
|
|||
return axisLengths[drive];
|
||||
}
|
||||
|
||||
inline float Platform::MaxFeedrate(int8_t drive)
|
||||
{
|
||||
return maxFeedrates[drive];
|
||||
}
|
||||
|
||||
|
||||
//********************************************************************************************************
|
||||
|
||||
// Drive the RepRap machine - Heat and temperature
|
||||
|
@ -524,8 +532,9 @@ inline void Platform::SetInterrupt(float s) // Seconds
|
|||
{
|
||||
if(s <= 0.0)
|
||||
{
|
||||
NVIC_DisableIRQ(TC3_IRQn);
|
||||
return;
|
||||
//NVIC_DisableIRQ(TC3_IRQn);
|
||||
Message(HOST_MESSAGE, "Negative interrupt!\n");
|
||||
s = STANDBY_INTERRUPT_RATE;
|
||||
}
|
||||
uint32_t rc = (uint32_t)( (((long)(TIME_TO_REPRAP*s))*84l)/128l );
|
||||
TC_SetRA(TC1, 0, rc/2); //50% high, 50% low
|
||||
|
|
23
Platform.ino
23
Platform.ino
|
@ -198,13 +198,10 @@ void Platform::Init()
|
|||
active = true;
|
||||
}
|
||||
|
||||
/*
|
||||
char* Platform::PrependRoot(char* result, char* root, char* fileName)
|
||||
void Platform::Diagnostics()
|
||||
{
|
||||
strcpy(result, root);
|
||||
return strcat(result, fileName);
|
||||
Message(HOST_MESSAGE, "Platform Diagnostics:\n");
|
||||
}
|
||||
*/
|
||||
|
||||
// Load settings from local storage; return true if successful, false otherwise
|
||||
|
||||
|
@ -233,26 +230,10 @@ bool Platform::LoadFromStore()
|
|||
|
||||
// Result is in degrees celsius
|
||||
|
||||
/*
|
||||
#define A 100000.0
|
||||
#define B 150000.0
|
||||
#define RS 4700
|
||||
#define VLOW 3.362
|
||||
#define VT 4.65
|
||||
*/
|
||||
|
||||
float Platform::GetTemperature(int8_t heater)
|
||||
{
|
||||
float r = (float)GetRawTemperature(heater);
|
||||
//Serial.println(r);
|
||||
return ABS_ZERO + thermistorBetas[heater]/log( (r*thermistorSeriesRs[heater]/(AD_RANGE - r))/thermistorInfRs[heater] );
|
||||
/* float v = VLOW*(float)GetRawTemperature(heater)/AD_RANGE;
|
||||
Serial.print(v); Serial.print(' ');
|
||||
float k = (A + B)*v/(B*VT);
|
||||
float rp = RS*k/(1 - k);
|
||||
float r = rp*(A+B)/(A + B - rp);
|
||||
Serial.println(r);
|
||||
return ABS_ZERO + thermistorBetas[heater]/log( r/thermistorInfRs[heater] );*/
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ General design principles:
|
|||
* Don't abhor floats - they work fast enough if you're clever,
|
||||
* Don't avoid arrays and structs/classes,
|
||||
* Don't avoid pointers,
|
||||
* Use operator and function overloading where appropriate, particularly for vector algebra.
|
||||
* Use operator and function overloading where appropriate.
|
||||
|
||||
|
||||
Naming conventions:
|
||||
|
@ -200,6 +200,15 @@ void RepRap::Spin()
|
|||
heat->Spin();
|
||||
}
|
||||
|
||||
void RepRap::Diagnostics()
|
||||
{
|
||||
platform->Diagnostics();
|
||||
move->Diagnostics();
|
||||
heat->Diagnostics();
|
||||
gCodes->Diagnostics();
|
||||
webserver->Diagnostics();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*************************************************************************************************
|
||||
|
|
2
Reprap.h
2
Reprap.h
|
@ -30,6 +30,7 @@ class RepRap
|
|||
void Spin();
|
||||
void Exit();
|
||||
void Interrupt();
|
||||
void Diagnostics();
|
||||
// void InterruptTime();
|
||||
boolean debug();
|
||||
void debug(boolean d);
|
||||
|
@ -59,6 +60,7 @@ inline boolean RepRap::debug() { return dbg; }
|
|||
inline void RepRap::debug(boolean d) { dbg = d; }
|
||||
inline void RepRap::Interrupt() { move->Interrupt(); }
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
7591
SD-image/gcodes/crocclip.g
Normal file
7591
SD-image/gcodes/crocclip.g
Normal file
File diff suppressed because it is too large
Load diff
|
@ -436,7 +436,7 @@ function viewModel()
|
|||
self.extrudeFilament = function(length, data, event)
|
||||
{
|
||||
if(self.extrudeButton() == 'Extrude:')
|
||||
$.get('/rr_gcode', {gcode: "M120\nM83\nG1 E" + length + " F200\nM121"}, self.dummy);
|
||||
$.get('/rr_gcode', {gcode: "M120\nM83\nG1 E" + length + " F60\nM121"}, self.dummy);
|
||||
else
|
||||
$.get('/rr_gcode', {gcode: "M120\nM83\nG1 E-" + length + " F800\nM121"}, self.dummy);
|
||||
};
|
||||
|
|
|
@ -49,6 +49,7 @@ class Webserver
|
|||
void Init();
|
||||
void Spin();
|
||||
void Exit();
|
||||
void Diagnostics();
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -679,5 +679,10 @@ void Webserver::Exit()
|
|||
active = false;
|
||||
}
|
||||
|
||||
void Webserver::Diagnostics()
|
||||
{
|
||||
platform->Message(HOST_MESSAGE, "Webserver Diagnostics:\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Reference in a new issue