First working version. Horay!

This commit is contained in:
Adrian Bowyer 2013-07-18 12:15:05 +01:00
parent b94bff107c
commit 874e6e0baf
14 changed files with 7730 additions and 42 deletions

View file

@ -24,6 +24,7 @@ Licence: GPL
#define STACK 5 #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 // Small class to hold an individual GCode
@ -64,6 +65,7 @@ class GCodes
boolean ReadHeat(float* h); boolean ReadHeat(float* h);
void QueueFileToPrint(char* fileName); void QueueFileToPrint(char* fileName);
boolean PrintingAFile(); boolean PrintingAFile();
void Diagnostics();
private: private:

View file

@ -106,6 +106,11 @@ void GCodes::Spin()
} }
} }
void GCodes::Diagnostics()
{
platform->Message(HOST_MESSAGE, "GCodes Diagnostics:\n");
}
boolean GCodes::AllMovesAreFinishedAndMoveBufferIsLoaded() boolean GCodes::AllMovesAreFinishedAndMoveBufferIsLoaded()
{ {
// Last one gone? // Last one gone?
@ -221,7 +226,7 @@ boolean GCodes::SetUpMove(GCodeBuffer *gb)
// Deal with feedrate // Deal with feedrate
if(gb->Seen(gCodeLetters[DRIVES])) 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 // Remember for next time if we are switched
// to absolute drive moves // to absolute drive moves
@ -527,6 +532,10 @@ boolean GCodes::ActOnGcode(GCodeBuffer *gb)
result = Pop(); result = Pop();
break; break;
case 122:
reprap.Diagnostics();
break;
case 126: // Valve open case 126: // Valve open
platform->Message(HOST_MESSAGE, "M126 - valves not yet implemented\n"); platform->Message(HOST_MESSAGE, "M126 - valves not yet implemented\n");
break; break;

1
Heat.h
View file

@ -61,6 +61,7 @@ class Heat
void Activate(int8_t heater); void Activate(int8_t heater);
void Standby(int8_t heater); void Standby(int8_t heater);
float GetTemperature(int8_t heater); float GetTemperature(int8_t heater);
void Diagnostics();
private: private:

View file

@ -55,6 +55,11 @@ void Heat::Spin()
pids[heater]->Spin(); pids[heater]->Spin();
} }
void Heat::Diagnostics()
{
platform->Message(HOST_MESSAGE, "Heat Diagnostics:\n");
}
//****************************************************************************************************** //******************************************************************************************************
PID::PID(Platform* p, int8_t h) PID::PID(Platform* p, int8_t h)

8
Move.h
View file

@ -77,6 +77,7 @@ class LookAhead
boolean checkEndStops; boolean checkEndStops;
float cosine; float cosine;
float v; float v;
float instantDv;
volatile int8_t processed; volatile int8_t processed;
}; };
@ -90,6 +91,7 @@ class DDA
void Step(boolean noTest); void Step(boolean noTest);
boolean Active(); boolean Active();
DDA* Next(); DDA* Next();
float InstantDv();
friend class Move; friend class Move;
@ -134,6 +136,7 @@ class Move
void DoLookAhead(); void DoLookAhead();
void HitLowStop(int8_t drive, LookAhead* la); void HitLowStop(int8_t drive, LookAhead* la);
void HitHighStop(int8_t drive, LookAhead* la); void HitHighStop(int8_t drive, LookAhead* la);
void Diagnostics();
friend class DDA; friend class DDA;
@ -248,6 +251,11 @@ inline DDA* DDA::Next()
return next; return next;
} }
inline float DDA::InstantDv()
{
return instantDv;
}
//*************************************************************************************** //***************************************************************************************

View file

@ -45,7 +45,7 @@ Move::Move(Platform* p, GCodes* g)
lookAheadRingGetPointer = new LookAhead(this, platform, lookAheadRingGetPointer); lookAheadRingGetPointer = new LookAhead(this, platform, lookAheadRingGetPointer);
lookAheadRingAddPointer->next = lookAheadRingGetPointer; lookAheadRingAddPointer->next = lookAheadRingGetPointer;
// Set the backwards pointers // Set the lookahead backwards pointers
lookAheadRingGetPointer = lookAheadRingAddPointer; lookAheadRingGetPointer = lookAheadRingAddPointer;
for(i = 0; i <= LOOK_AHEAD_RING_LENGTH; i++) for(i = 0; i <= LOOK_AHEAD_RING_LENGTH; i++)
@ -82,7 +82,7 @@ void Move::Init()
addNoMoreMoves = false; 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. // position to the first one that will be used.
lastMove = lookAheadRingAddPointer->Previous(); lastMove = lookAheadRingAddPointer->Previous();
@ -173,22 +173,80 @@ void Move::Spin()
if(addNoMoreMoves || LookAheadRingFull()) if(addNoMoreMoves || LookAheadRingFull())
return; return;
// boolean waitForThisToFinish;
// If there's a G Code move available, add it to the look-ahead // 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)) if(gCodes->ReadMove(nextMove, checkEndStopsOnNextMove))
{ {
currentFeedrate = nextMove[DRIVES]; // Might be G1 with just an F field 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.
return; int8_t mt = GetMovementType(lastMove->EndPoint(), nextMove);
currentFeedrate = -1.0; // Real move - record its feedrate with it, not here.
// Throw it away if there's no real movement.
if(mt == noMove)
return;
// 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)) if(!LookAheadRingAdd(nextMove, 0.0, checkEndStopsOnNextMove))
platform->Message(HOST_MESSAGE, "Can't add to non-full look ahead ring!\n"); // Should never happen... 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 // This returns false if it is not possible
// to use the result as the basis for the // to use the result as the basis for the
// next move because the look ahead ring // next move because the look ahead ring
@ -388,7 +446,7 @@ void Move::DoLookAhead()
else if (mt & xyMove) else if (mt & xyMove)
c = platform->InstantDv(X_AXIS); c = platform->InstantDv(X_AXIS);
else else
c = platform->InstantDv(AXES); // value for first extruder - slight hack c = platform->InstantDv(AXES); // value for first extruder FIXME??
} }
n1->SetV(c); n1->SetV(c);
n1->SetProcessed(vCosineSet); 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 velocities requested are (almost) zero, set them to instantDv
if(v < 0.01) // Set change here? if(v < instantDv) // Set change here?
v = instantDv; v = instantDv;
if(u < 0.01) if(u < instantDv)
u = instantDv; u = instantDv;
if(targetPosition[DRIVES] < instantDv)
targetPosition[DRIVES] = instantDv;
// At which DDA step should we stop accelerating? targetPosition[DRIVES] contains // At which DDA step should we stop accelerating? targetPosition[DRIVES] contains
// the desired feedrate. // the desired feedrate.
@ -801,6 +861,11 @@ void DDA::Step(boolean noTest)
if(stepCount >= startDStep) if(stepCount >= startDStep)
velocity -= acceleration*timeStep; velocity -= acceleration*timeStep;
// Euler is only approximate.
if(velocity < instantDv)
velocity = instantDv;
stepCount++; stepCount++;
active = stepCount < totalSteps; active = stepCount < totalSteps;

View file

@ -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 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 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, // The numbers of entries in each array must correspond with the values of DRIVES,
// AXES, or HEATERS. Set values to -1 to flag unavailability. // 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 {800.0, 800.0, 30.0, 250.0} // mm/sec^2??
//#define ACCELERATIONS {80, 80, 3, 25} //#define ACCELERATIONS {80, 80, 3, 25}
#define DRIVE_STEPS_PER_UNIT {91.4286, 91.4286, 4000.0, 948.0} #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 INSTANT_DVS {1.0, 1.0, 0.3, 1.0} // (mm/sec) - Bit high? AB
#define GCODE_LETTERS { 'X', 'Y', 'Z', 'E', 'F' } // The drives and feedrate in a GCode
// AXES // AXES
#define START_FEED_RATE 200.0 #define START_FEED_RATE 200.0 // Default. mm/min
#define AXIS_LENGTHS {210, 200, 120} // mm #define AXIS_LENGTHS {210, 200, 120} // mm
#define HOME_FEEDRATES {50.0*60.0, 50.0*60.0, 1.0*60.0} // mm/min #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 #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 TEMP_SENSE_PINS {10, 9} // Analogue pin numbers
#define HEAT_ON_PINS {8, 9} #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 Exit(); // Shut down tidily. Calling Init after calling this should reset to the beginning
void Diagnostics();
// Timing // Timing
float Time(); // Returns elapsed seconds since some arbitrary time 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. 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 DriveStepsPerUnit(int8_t drive);
float Acceleration(int8_t drive); float Acceleration(int8_t drive);
float MaxFeedrate(int8_t drive);
float InstantDv(int8_t drive); float InstantDv(int8_t drive);
float HomeFeedRate(int8_t drive); float HomeFeedRate(int8_t drive);
EndStopHit Stopped(int8_t drive); EndStopHit Stopped(int8_t drive);
@ -449,6 +451,12 @@ inline float Platform::AxisLength(int8_t drive)
return axisLengths[drive]; return axisLengths[drive];
} }
inline float Platform::MaxFeedrate(int8_t drive)
{
return maxFeedrates[drive];
}
//******************************************************************************************************** //********************************************************************************************************
// Drive the RepRap machine - Heat and temperature // Drive the RepRap machine - Heat and temperature
@ -524,8 +532,9 @@ inline void Platform::SetInterrupt(float s) // Seconds
{ {
if(s <= 0.0) if(s <= 0.0)
{ {
NVIC_DisableIRQ(TC3_IRQn); //NVIC_DisableIRQ(TC3_IRQn);
return; Message(HOST_MESSAGE, "Negative interrupt!\n");
s = STANDBY_INTERRUPT_RATE;
} }
uint32_t rc = (uint32_t)( (((long)(TIME_TO_REPRAP*s))*84l)/128l ); uint32_t rc = (uint32_t)( (((long)(TIME_TO_REPRAP*s))*84l)/128l );
TC_SetRA(TC1, 0, rc/2); //50% high, 50% low TC_SetRA(TC1, 0, rc/2); //50% high, 50% low

View file

@ -198,13 +198,10 @@ void Platform::Init()
active = true; active = true;
} }
/* void Platform::Diagnostics()
char* Platform::PrependRoot(char* result, char* root, char* fileName)
{ {
strcpy(result, root); Message(HOST_MESSAGE, "Platform Diagnostics:\n");
return strcat(result, fileName);
} }
*/
// Load settings from local storage; return true if successful, false otherwise // Load settings from local storage; return true if successful, false otherwise
@ -233,26 +230,10 @@ bool Platform::LoadFromStore()
// Result is in degrees celsius // 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 Platform::GetTemperature(int8_t heater)
{ {
float r = (float)GetRawTemperature(heater); float r = (float)GetRawTemperature(heater);
//Serial.println(r);
return ABS_ZERO + thermistorBetas[heater]/log( (r*thermistorSeriesRs[heater]/(AD_RANGE - r))/thermistorInfRs[heater] ); 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] );*/
} }

View file

@ -24,7 +24,7 @@ General design principles:
* Don't abhor floats - they work fast enough if you're clever, * Don't abhor floats - they work fast enough if you're clever,
* Don't avoid arrays and structs/classes, * Don't avoid arrays and structs/classes,
* Don't avoid pointers, * Don't avoid pointers,
* Use operator and function overloading where appropriate, particularly for vector algebra. * Use operator and function overloading where appropriate.
Naming conventions: Naming conventions:
@ -200,6 +200,15 @@ void RepRap::Spin()
heat->Spin(); heat->Spin();
} }
void RepRap::Diagnostics()
{
platform->Diagnostics();
move->Diagnostics();
heat->Diagnostics();
gCodes->Diagnostics();
webserver->Diagnostics();
}
//************************************************************************************************* //*************************************************************************************************

View file

@ -30,6 +30,7 @@ class RepRap
void Spin(); void Spin();
void Exit(); void Exit();
void Interrupt(); void Interrupt();
void Diagnostics();
// void InterruptTime(); // void InterruptTime();
boolean debug(); boolean debug();
void debug(boolean d); 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::debug(boolean d) { dbg = d; }
inline void RepRap::Interrupt() { move->Interrupt(); } inline void RepRap::Interrupt() { move->Interrupt(); }
#endif #endif

7591
SD-image/gcodes/crocclip.g Normal file

File diff suppressed because it is too large Load diff

View file

@ -436,7 +436,7 @@ function viewModel()
self.extrudeFilament = function(length, data, event) self.extrudeFilament = function(length, data, event)
{ {
if(self.extrudeButton() == 'Extrude:') 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 else
$.get('/rr_gcode', {gcode: "M120\nM83\nG1 E-" + length + " F800\nM121"}, self.dummy); $.get('/rr_gcode', {gcode: "M120\nM83\nG1 E-" + length + " F800\nM121"}, self.dummy);
}; };

View file

@ -49,6 +49,7 @@ class Webserver
void Init(); void Init();
void Spin(); void Spin();
void Exit(); void Exit();
void Diagnostics();
private: private:

View file

@ -679,5 +679,10 @@ void Webserver::Exit()
active = false; active = false;
} }
void Webserver::Diagnostics()
{
platform->Message(HOST_MESSAGE, "Webserver Diagnostics:\n");
}