From 73724a4b9a588d4bae6c9a50ec4c6eb61a68edb4 Mon Sep 17 00:00:00 2001 From: David Crocker Date: Wed, 4 Jun 2014 17:39:36 +0100 Subject: [PATCH] Merged RepRapRro's 0.65e version in Merged changes (mostly to handle multiple tools i.e. extruders) from RRP's 0.65e version. --- Configuration.h | 20 +- GCodes.cpp | 462 ++++++++++++++---- GCodes.h | 229 +++++---- Heat.h | 75 +-- .../Lwip/lwip/src/sam/netif/ethernetif.c | 13 + Move.cpp | 28 +- Move.h | 271 +++++----- Network.cpp | 3 + Platform.cpp | 66 ++- Platform.h | 181 ++++--- Release/RepRapFirmware-065e-dc42.bin | Bin 0 -> 259832 bytes RepRapFirmware.cpp | 106 +++- RepRapFirmware.h | 10 +- Reprap.h | 10 +- Tool.cpp | 107 ++++ Tool.h | 78 +++ 16 files changed, 1190 insertions(+), 469 deletions(-) create mode 100644 Release/RepRapFirmware-065e-dc42.bin create mode 100644 Tool.cpp create mode 100644 Tool.h diff --git a/Configuration.h b/Configuration.h index 4d63c49..314e9df 100644 --- a/Configuration.h +++ b/Configuration.h @@ -24,9 +24,9 @@ Licence: GPL #define CONFIGURATION_H #define NAME "RepRapFirmware" -#define VERSION "0.59e-dc42" -#define DATE "2014-06-01" -#define LAST_AUTHOR "dc42" +#define VERSION "0.65e-dc42" +#define DATE "2014-06-04" +#define LAST_AUTHOR "reprappro & dc42" // Other firmware that we might switch to be compatible with. @@ -48,19 +48,19 @@ enum Compatibility #define HEAT_SAMPLE_TIME (0.5) // Seconds -#define TEMPERATURE_CLOSE_ENOUGH (2.5) // Celsius +#define TEMPERATURE_CLOSE_ENOUGH (2.0) // Celsius #define TEMPERATURE_LOW_SO_DONT_CARE (40.0) // Celsius // If temperatures fall outside this range, something nasty has happened. -#define BAD_LOW_TEMPERATURE -30.0 -#define BAD_HIGH_TEMPERATURE 300.0 #define MAX_BAD_TEMPERATURE_COUNT 6 +#define BAD_LOW_TEMPERATURE -10.0 +#define BAD_HIGH_TEMPERATURE 300.0 #define STANDBY_INTERRUPT_RATE 2.0e-4 // Seconds #define NUMBER_OF_PROBE_POINTS 4 -#define Z_DIVE 5.0 // Height from which to probe the bed (mm) +#define Z_DIVE 8.0 // Height from which to probe the bed (mm) #define SILLY_Z_VALUE -9999.0 @@ -77,6 +77,12 @@ enum Compatibility #define HOME_Z_G "homez.g" #define HOME_ALL_G "homeall.g" +#define LIST_SEPARATOR ':' // Lists in G Codes +#define FILE_LIST_SEPARATOR ',' // Put this between file names when listing them +#define FILE_LIST_BRACKET '"' // Put these round file names when listing them + +#define GCODE_LETTERS { 'X', 'Y', 'Z', 'E', 'F' } // The drives and feedrate in a GCode + #define LONG_TIME 300.0 // Seconds #define EOF_STRING "" diff --git a/GCodes.cpp b/GCodes.cpp index 5d9bebb..7227720 100644 --- a/GCodes.cpp +++ b/GCodes.cpp @@ -78,10 +78,6 @@ void GCodes::Reset() fileGCode->Init(); serialGCode->Init(); cannedCycleGCode->Init(); - webGCode->SetFinished(true); - fileGCode->SetFinished(true); - serialGCode->SetFinished(true); - cannedCycleGCode->SetFinished(true); moveAvailable = false; fileBeingPrinted.Close(); fileToPrint.Close(); @@ -99,7 +95,7 @@ void GCodes::Reset() extrusionFactor = 1.0; } -void GCodes::doFilePrint(GCodeBuffer* gb) +void GCodes::DoFilePrint(GCodeBuffer* gb) { char b; @@ -240,7 +236,7 @@ void GCodes::Spin() } } - doFilePrint(fileGCode); + DoFilePrint(fileGCode); platform->ClassReport("GCodes", longWait); } @@ -336,6 +332,8 @@ bool GCodes::Pop() // Move expects all axis movements to be absolute, and all // extruder drive moves to be relative. This function serves that. // If applyLimits is true and we have homed the relevant axes, then we don't allow movement beyond the bed. +// Note that if no tool is active (i.e. a Tn command hasn't previously been sent) then no E values will +// be acted upon as there is nothing to apply them to. void GCodes::LoadMoveBufferFromGCode(GCodeBuffer *gb, bool doingG92, bool applyLimits) { @@ -371,32 +369,94 @@ void GCodes::LoadMoveBufferFromGCode(GCodeBuffer *gb, bool doingG92, bool applyL } else { - if (gb->Seen(gCodeLetters[i])) - { - // Doing an extruder. We need to store the relative distance for this move in moveBuffer and the resulting new position in lastPos. - float moveArg = gb->GetFValue() * distanceScale * extrusionFactor; - if (doingG92) + /*Fixed to work with multiple concurrent extruder drives: + * Default or M160 S1 (set use only one extruder drive) + * "G1 En.n" adds the float n.n to the move buffer for the selected head + * There is no change in behaviour for one extruder drive setups, or multiple extruder + * setups where only one drive is used at any one time. + * + * M160 Sn (set to use "n" extruder drives) eg + * "M160 S3" + * "G1 En.n:m.m:o.o" adds the floats to the move buffer in the following way: + * moveBuffer[AXES+selectedHead) = n.n + * moveBuffer[AXES+selectedHead+1) = m.m + * moveBuffer[AXES+selectedHead+2) = o.o + * so if selectedHead=1 move buffer ends up looking like this for a 5 extruder drive setup: + * {x.x, y.y, z.z, n.n, m.m, o.o, 0.0,0.0, f.f} + * where x,y,z are the axes and f is the feedrate. + * If selected head > 0 then there is the possibility that more drives can be set than + * exist, in that case the last values are discarded e.g: + * "T3" + * "M160 S3" + * "G1 En.n:m.m:o.o" + * would leave the move buffer on a 4 extruder drive setup looking like this: + * {x.x, y.y, z.z, 0.0, 0.0, 0.0, n.n,m.m, f.f} + */ + if(gb->Seen('E')&& ((i-AXES) == selectedHead-1)) + { + //the number of mixing drives set (by M160) + int numDrives = platform->GetMixingDrives(); + const char* extruderString = gb->GetString(); + float eArg[numDrives]; + uint8_t sp = 0; //string pointer + uint8_t fp = 0; //float pointer for the start of each floating point number in turn + uint8_t hp = 0; //index of the head currently referred to for eArg + while(extruderString[sp]) + { + //first check to confirm we have not got to the feedrate setting part of the string + if(extruderString[sp] == 'F') + { + break; + } + if(extruderString[sp] == ':') + { + eArg[hp] = (atoff(&extruderString[fp]))*distanceScale; + hp++; + if(hp >= numDrives) + { + platform->Message(HOST_MESSAGE, "More mixing extruder drives required in G1 string than set with M160: "); + platform->Message(HOST_MESSAGE, gb->Buffer()); + platform->Message(HOST_MESSAGE, "\n"); + return; + } + sp++; + fp = sp; + } + else + { + sp++; + } + } + //capture the last drive step amount in the string (or the only one in the case of only one extruder) + eArg[hp] = (atoff(&extruderString[fp]))*distanceScale; + + //set the move buffer for each extruder drive + for(int j=0;jSeen(gCodeLetters[DRIVES])) + if(gb->Seen(FEEDRATE_LETTER)) { gFeedRate = gb->GetFValue() * distanceScale * speedFactor; } @@ -415,10 +475,11 @@ int GCodes::SetUpMove(GCodeBuffer *gb) if (moveAvailable) return 0; - // Load the last position; if Move can't accept more, return 0 + // Load the last position into moveBuffer; If Move can't accept more, return false if (!reprap.GetMove()->GetCurrentState(moveBuffer)) return 0; + //check to see if the move is a 'homing' move that endstops are checked on. checkEndStops = false; if (gb->Seen('S')) { @@ -427,8 +488,10 @@ int GCodes::SetUpMove(GCodeBuffer *gb) checkEndStops = true; } } - - LoadMoveBufferFromGCode(gb, false, !checkEndStops && limitAxes); + //loads the movebuffer with either the absolute movement required or the + //relative movement required + LoadMoveBufferFromGCode(gb, false, !checkEndStops && limitAxes); + //There is a new move in the move buffer moveAvailable = true; return (checkEndStops) ? 2 : 1; } @@ -499,7 +562,7 @@ bool GCodes::DoFileCannedCycles(const char* fileName) return false; } - doFilePrint(cannedCycleGCode); + DoFilePrint(cannedCycleGCode); return false; } @@ -601,7 +664,7 @@ bool GCodes::OffsetAxes(GCodeBuffer* gb) } } - if (gb->Seen(gCodeLetters[DRIVES])) // Has the user specified a feedrate? + if(gb->Seen(FEEDRATE_LETTER)) // Has the user specified a feedrate? { moveToDo[DRIVES] = gb->GetFValue(); activeDrive[DRIVES] = true; @@ -628,7 +691,7 @@ bool GCodes::OffsetAxes(GCodeBuffer* gb) // booleans homeX, homeY and homeZ. // Returns true if completed, false if needs to be called again. // 'reply' is only written if there is an error. -// 'error' is false on entry, gets changed to true iff there is an error. +// 'error' is false on entry, gets changed to true if there is an error. bool GCodes::DoHome(char* reply, bool& error) //pre(reply.upb == STRING_LENGTH) { @@ -961,15 +1024,18 @@ bool GCodes::SetPrintZProbe(GCodeBuffer* gb, char* reply) // are updated at the end of each movement, so this won't tell you // where you are mid-movement. -// FIXME - needs to deal with multiple extruders +//Fixed to deal with multiple extruders char* GCodes::GetCurrentCoordinates() { float liveCoordinates[DRIVES + 1]; reprap.GetMove()->LiveCoordinates(liveCoordinates); - snprintf(scratchString, STRING_LENGTH, "X:%f Y:%f Z:%f E:%f", liveCoordinates[X_AXIS], liveCoordinates[Y_AXIS], - liveCoordinates[Z_AXIS], liveCoordinates[AXES]); + snprintf(scratchString, STRING_LENGTH, "X:%f Y:%f Z:%f ", liveCoordinates[X_AXIS], liveCoordinates[Y_AXIS], liveCoordinates[Z_AXIS]); + for(int i = AXES; i< DRIVES; i++) + { + sncatf(scratchString, STRING_LENGTH, "E%d:%f ",i-AXES,liveCoordinates[i]); + } return scratchString; } @@ -979,6 +1045,7 @@ bool GCodes::OpenFileToWrite(const char* directory, const char* fileName, GCodeB eofStringCounter = 0; if (fileBeingWritten == NULL) { + platform->Message(HOST_MESSAGE, "Can't open GCode file for writing.\n"); return false; } else @@ -1087,13 +1154,13 @@ void GCodes::QueueFileToPrint(const char* fileName) void GCodes::DeleteFile(const char* fileName) { - if (!platform->GetMassStorage()->Delete(platform->GetGCodeDir(), fileName)) - { - platform->Message(HOST_MESSAGE, "Unsuccessful attempt to delete: "); - platform->Message(HOST_MESSAGE, fileName); - platform->Message(HOST_MESSAGE, "\n"); - webserver->HandleReply("Failed to delete file", true); - } + if(!platform->GetMassStorage()->Delete(platform->GetGCodeDir(), fileName)) + { + platform->Message(HOST_MESSAGE, "Unsuccessful attempt to delete: "); + platform->Message(HOST_MESSAGE, fileName); + platform->Message(HOST_MESSAGE, "\n"); + webserver->HandleReply("Failed to delete file", true); + } } // Send the config file to USB in response to an M503 command. @@ -1130,7 +1197,7 @@ bool GCodes::SendConfigToLine() bool GCodes::DoDwell(GCodeBuffer *gb) { - if (!gb->Seen('P')) + if(!gb->Seen('P')) return true; // No time given - throw it away float dwell = 0.001 * (float) gb->GetLValue(); // P values are in milliseconds; we need seconds @@ -1173,7 +1240,7 @@ bool GCodes::SetOffsets(GCodeBuffer *gb) int8_t head; if (gb->Seen('P')) { - head = gb->GetIValue() + 1; // 0 is the Bed + head = gb->GetIValue(); // 0 is the Bed if (gb->Seen('R')) reprap.GetHeat()->SetStandbyTemperature(head, gb->GetFValue()); @@ -1203,7 +1270,7 @@ bool GCodes::StandbyHeaters() return false; for (int8_t heater = 0; heater < HEATERS; heater++) reprap.GetHeat()->Standby(heater); - selectedHead = -1; + selectedHead = -1; //FIXME check this does not mess up setters (eg M906) when they are used after this command is called return true; } @@ -1260,9 +1327,47 @@ void GCodes::SetEthernetAddress(GCodeBuffer *gb, int mCode) } } + +void GCodes::SetMACAddress(GCodeBuffer *gb) +{ + uint8_t mac[6]; + const char* ipString = gb->GetString(); + uint8_t sp = 0; + uint8_t spp = 0; + uint8_t ipp = 0; + while(ipString[sp]) + { + if(ipString[sp] == ':') + { + mac[ipp] = strtol(&ipString[spp], NULL, 0); + ipp++; + if(ipp > 5) + { + platform->Message(HOST_MESSAGE, "Dud MAC address: "); + platform->Message(HOST_MESSAGE, gb->Buffer()); + platform->Message(HOST_MESSAGE, "\n"); + return; + } + sp++; + spp = sp; + }else + sp++; + } + mac[ipp] = strtol(&ipString[spp], NULL, 0); + if(ipp == 5) + { + platform->SetMACAddress(mac); + } else + { + platform->Message(HOST_MESSAGE, "Dud MAC address: "); + platform->Message(HOST_MESSAGE, gb->Buffer()); + platform->Message(HOST_MESSAGE, "\n"); + } +} + void GCodes::HandleReply(bool error, bool fromLine, const char* reply, char gMOrT, int code, bool resend) { - if (gMOrT != 'M' || code != 111) // web server reply for M111 is handled before we get here + if (gMOrT != 'M' || code != 111) // web server reply for M111 is handled before we get here { webserver->HandleReply(reply, error); } @@ -1418,7 +1523,6 @@ void GCodes::SetHeaterParameters(GCodeBuffer *gb, char reply[STRING_LENGTH]) { r25 = pp.GetThermistorR25(); } - if (gb->Seen('B')) { beta = gb->GetFValue(); @@ -1727,20 +1831,40 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) bool seen = false; for (int8_t drive = 0; drive < DRIVES; drive++) { - if (gb->Seen(gCodeLetters[drive])) + //Do AXES first + if(gb->Seen(gCodeLetters[drive])&& driveSetDriveStepsPerUnit(drive, gb->GetFValue()); seen = true; } + else if(selectedHead < 0) + { + // If no head selected, set the first extruder steps - best we can do + if(gb->Seen('E')) + { + platform->SetDriveStepsPerUnit(AXES, gb->GetFValue()); + seen=true; + } + } + else if(gb->Seen('E')&& ((drive-AXES) == selectedHead - 1))//then do active extruder + { + platform->SetDriveStepsPerUnit(AXES+selectedHead - 1, gb->GetFValue()); + seen=true; + } } reprap.GetMove()->SetStepHypotenuse(); if (!seen) { - snprintf(reply, STRING_LENGTH, "Steps/mm: X:%f, Y:%f, Z:%f, E:%f", + snprintf(reply, STRING_LENGTH, "Steps/mm: X: %f, Y: %f, Z: %f, E: ", platform->DriveStepsPerUnit(X_AXIS), platform->DriveStepsPerUnit(Y_AXIS), - platform->DriveStepsPerUnit(Z_AXIS), platform->DriveStepsPerUnit(AXES)); // FIXME - needs to do multiple extruders + platform->DriveStepsPerUnit(Z_AXIS)); + // Fixed to do multiple extruders. + for(int8_t drive = AXES; drive < DRIVES; drive++) + { + sncatf(reply, STRING_LENGTH, "%.2f:", platform->DriveStepsPerUnit(drive)); + } } - } + } break; case 98: @@ -1755,16 +1879,18 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) break; case 104: // Deprecated - if (gb->Seen('S')) + if(gb->Seen('S') && selectedHead >= 0) { - reprap.GetHeat()->SetActiveTemperature(1, gb->GetFValue()); // 0 is the bed - reprap.GetHeat()->Activate(1); + //only sets the selected head (As set by T#) + reprap.GetHeat()->SetActiveTemperature(selectedHead, gb->GetFValue()); // 0 is the bed + reprap.GetHeat()->Activate(selectedHead); } break; case 105: // Deprecated... strncpy(reply, "T:", STRING_LENGTH); - for (int8_t heater = HEATERS - 1; heater > 0; heater--) + //FIXME - why did this decrement rather than increment through the heaters (odd behaviour) + for(int8_t heater = 1; heater < HEATERS; heater++) { sncatf(reply, STRING_LENGTH, "%.1f ", reprap.GetHeat()->GetTemperature(heater)); } @@ -1797,28 +1923,23 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) break; case 109: // Set extruder temperature and wait - deprecated - case 190: // Set bed temperature and wait - deprecated - { - int8_t heater = (code == 190) ? 0 : 1; - if (gb->Seen('S')) - { - reprap.GetHeat()->SetActiveTemperature(heater, gb->GetFValue()); - reprap.GetHeat()->Activate(heater); - } - if (!AllMovesAreFinishedAndMoveBufferIsLoaded()) - { - return false; - } - result = reprap.GetHeat()->HeaterAtSetTemperature(heater); - } - break; + if(gb->Seen('S') && selectedHead >= 0) + { + reprap.GetHeat()->SetActiveTemperature(selectedHead, gb->GetFValue()); // 0 is the bed + reprap.GetHeat()->Activate(selectedHead); + } + //check here rather than falling through to M116, we want to just wait for the extruder we specified (otherwise use M116 not M109) + result = reprap.GetHeat()->HeaterAtSetTemperature(selectedHead); + break; case 110: // Set line numbers - line numbers are dealt with in the GCodeBuffer class break; case 111: // Debug level if (gb->Seen('S')) + { reprap.SetDebug(gb->GetIValue()); + } break; case 112: // Emergency stop - acted upon in Webserver, but also here in case it comes from USB etc. @@ -1852,7 +1973,10 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) result = reprap.GetHeat()->AllHeatersAtSetTemperatures(); break; - // case 117 is handled later because it falls through to the default case + //TODO M119 + case 119: + platform->Message(HOST_MESSAGE, "M119 - endstop status not yet implemented\n"); + break; case 120: result = Push(); @@ -1889,15 +2013,47 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) platform->Message(HOST_MESSAGE, "M141 - heated chamber not yet implemented\n"); break; - // case 190 is with case 109 because it used the same code + case 160: //number of mixing filament drives + if(gb->Seen('S')) + { + int iValue=gb->GetIValue(); + platform->SetMixingDrives(iValue); + } + break; + + case 190: // Deprecated... + if(gb->Seen('S')) + { + float value=gb->GetFValue(); + reprap.GetHeat()->SetActiveTemperature(0, value); + reprap.GetHeat()->SetStandbyTemperature(0, value); // FIXME have to set both?not sure as the bed should always be selected + reprap.GetHeat()->Activate(0); + } + result = reprap.GetHeat()->HeaterAtSetTemperature(0); + break; case 201: // Set axis accelerations for (int8_t drive = 0; drive < DRIVES; drive++) { - if (gb->Seen(gCodeLetters[drive])) + //Do AXES first + if(gb->Seen(gCodeLetters[drive]) && driveGetFValue(); - platform->SetAcceleration(drive, value); + platform->SetAcceleration(drive, gb->GetFValue()); + } + else if(selectedHead < 0) + { + if(gb->Seen('E')) // Do first one - best we can do + { + platform->SetAcceleration(AXES, gb->GetFValue()); + } + }//then do active extruder + else if(gb->Seen('E') && ((drive-AXES) == selectedHead-1)) + { + platform->SetAcceleration(AXES+selectedHead-1, gb->GetFValue()); //Set the E acceleration for the currently selected tool + } + else + { + platform->SetAcceleration(drive, -1); } } break; @@ -1905,11 +2061,25 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) case 203: // Set maximum feed rates for (int8_t drive = 0; drive < DRIVES; drive++) { - if (gb->Seen(gCodeLetters[drive])) + //Do AXES first + if(gb->Seen(gCodeLetters[drive]) && driveGetFValue() * distanceScale * 0.016666667; // G Code feedrates are in mm/minute; we need mm/sec; platform->SetMaxFeedrate(drive, value); - } + } + else if(selectedHead < 0) + { + if(gb->Seen('E')) + { + float value = gb->GetFValue()*distanceScale*0.016666667; // G Code feedrates are in mm/minute; we need mm/sec; + platform->SetMaxFeedrate(AXES, value); //Set the E Steps for the first E - best we can do + } + } + else if(gb->Seen('E') && ((drive-AXES) == selectedHead-1))//then do active extruder + { + float value = gb->GetFValue()*distanceScale*0.016666667; // G Code feedrates are in mm/minute; we need mm/sec; + platform->SetMaxFeedrate(AXES+selectedHead-1, value); //Set the E Steps for the currently selected tool + } } break; @@ -2005,6 +2175,13 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) result = SendConfigToLine(); break; + case 540: + if(gb->Seen('P')) + { + SetMACAddress(gb); + } + break; + case 550: // Set machine name if (gb->Seen('P')) reprap.GetWebserver()->SetName(gb->GetString()); @@ -2012,12 +2189,16 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) case 551: // Set password if (gb->Seen('P')) + { reprap.GetWebserver()->SetPassword(gb->GetString()); + } break; case 552: // Set/Get IP address if (gb->Seen('P')) + { SetEthernetAddress(gb, code); + } else { const byte *ip = platform->IPAddress(); @@ -2027,7 +2208,9 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) case 553: // Set/Get netmask if (gb->Seen('P')) + { SetEthernetAddress(gb, code); + } else { const byte *nm = platform->NetMask(); @@ -2037,7 +2220,9 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) case 554: // Set/Get gateway if (gb->Seen('P')) + { SetEthernetAddress(gb, code); + } else { const byte *gw = platform->GateWay(); @@ -2047,7 +2232,9 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) case 555: // Set firmware type to emulate if (gb->Seen('P')) + { platform->SetEmulating((Compatibility) gb->GetIValue()); + } break; case 556: // Axis compensation @@ -2055,8 +2242,12 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) { float value = gb->GetFValue(); for (int8_t axis = 0; axis < AXES; axis++) + { if (gb->Seen(gCodeLetters[axis])) + { reprap.GetMove()->SetAxisCompensation(axis, gb->GetFValue() / value); + } + } } break; @@ -2142,20 +2333,41 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) } break; - case 564: // Think outside the box? - if(gb->Seen('S')) - { - limitAxes = (gb->GetIValue() != 0); - } + case 563: // Define tool + + break; + + case 564: // Think outside the box? + if(gb->Seen('S')) + { + limitAxes = (gb->GetIValue() != 0); + } break; case 906: // Set Motor currents for (uint8_t i = 0; i < DRIVES; i++) { - if (gb->Seen(gCodeLetters[i])) + //Do AXES first + if(gb->Seen(gCodeLetters[i])&& iGetFValue(); // mA + float value = gb->GetFValue(); // mA platform->SetMotorCurrent(i, value); + } + else if(selectedHead < 0) + { + if(gb->Seen('E')) + { + float value = gb->GetFValue(); // mA + platform->SetMotorCurrent(AXES, value); // Set first one - best we can do + } + } + else //do for selected extruder + { + if(gb->Seen(gCodeLetters[i])) + { + float value = gb->GetFValue(); // mA + platform->SetMotorCurrent(AXES+selectedHead-1, value); + } } } break; @@ -2195,41 +2407,43 @@ bool GCodes::HandleMcode(GCodeBuffer* gb) bool GCodes::HandleTcode(GCodeBuffer* gb) { - bool error = false; char reply[STRING_LENGTH]; reply[0] = 0; int code = gb->GetIValue(); if (code == selectedHead) { - HandleReply(error, gb == serialGCode, reply, 'T', code, false); + HandleReply(false, gb == serialGCode, reply, 'T', code, false); return true; } - error = true; for (int8_t i = AXES; i < DRIVES; i++) { - if (selectedHead == i - AXES) - { - reprap.GetHeat()->Standby(selectedHead + 1); // + 1 because 0 is the Bed + if(selectedHead == i - AXES + 1) + { + reprap.GetHeat()->Standby(selectedHead); } } + + bool toolNotFound = true; for (int8_t i = AXES; i < DRIVES; i++) { - if (code == i - AXES) + if(code == i - AXES + 1) { selectedHead = code; - reprap.GetHeat()->Activate(selectedHead + 1); // 0 is the Bed - error = false; + reprap.GetHeat()->Activate(selectedHead); + toolNotFound = false; } } - if (error) - { - snprintf(reply, STRING_LENGTH, "Invalid T Code: %s", gb->Buffer()); - } + if(toolNotFound) + { + selectedHead = -1; + } - HandleReply(error, gb == serialGCode, reply, 'T', code, false); +// snprintf(reply, STRING_LENGTH, "Invalid T Code: %s", gb->Buffer()); + + HandleReply(false, gb == serialGCode, reply, 'T', code, false); return true; } @@ -2387,6 +2601,7 @@ float GCodeBuffer::GetFValue() if (readPointer < 0) { platform->Message(HOST_MESSAGE, "GCodes: Attempt to read a GCode float before a search.\n"); + readPointer = -1; return 0.0; } float result = (float) strtod(&gcodeBuffer[readPointer + 1], 0); @@ -2394,6 +2609,66 @@ float GCodeBuffer::GetFValue() return result; } +// Get a :-separated list of floats after a key letter + +const void GCodeBuffer::GetFloatArray(float a[], int& length) +{ + length = 0; + if(readPointer < 0) + { + platform->Message(HOST_MESSAGE, "GCodes: Attempt to read a GCode float array before a search.\n"); + readPointer = -1; + return; + } + + bool inList = true; + while(inList) + { + a[length] = (float)strtod(&gcodeBuffer[readPointer + 1], 0); + length++; + readPointer++; + while(gcodeBuffer[readPointer] && (gcodeBuffer[readPointer] != ' ') && (gcodeBuffer[readPointer] != LIST_SEPARATOR)) + { + readPointer++; + } + if(gcodeBuffer[readPointer] != LIST_SEPARATOR) + { + inList = false; + } + } + readPointer = -1; +} + +// Get a :-separated list of longs after a key letter + +const void GCodeBuffer::GetLongArray(long l[], int& length) +{ + length = 0; + if(readPointer < 0) + { + platform->Message(HOST_MESSAGE, "GCodes: Attempt to read a GCode long array before a search.\n"); + readPointer = -1; + return; + } + + bool inList = true; + while(inList) + { + l[length] = strtol(&gcodeBuffer[readPointer + 1], 0, 0); + length++; + readPointer++; + while(gcodeBuffer[readPointer] && (gcodeBuffer[readPointer] != ' ') && (gcodeBuffer[readPointer] != LIST_SEPARATOR)) + { + readPointer++; + } + if(gcodeBuffer[readPointer] != LIST_SEPARATOR) + { + inList = false; + } + } + readPointer = -1; +} + // Get a string after a G Code letter found by a call to Seen(). // It will be the whole of the rest of the GCode string, so strings // should always be the last parameter. @@ -2403,6 +2678,7 @@ const char* GCodeBuffer::GetString() if (readPointer < 0) { platform->Message(HOST_MESSAGE, "GCodes: Attempt to read a GCode string before a search.\n"); + readPointer = -1; return ""; } const char* result = &gcodeBuffer[readPointer + 1]; @@ -2425,11 +2701,14 @@ const char* GCodeBuffer::GetUnprecedentedString() { readPointer = 0; while (gcodeBuffer[readPointer] && gcodeBuffer[readPointer] != ' ') + { readPointer++; + } if (!gcodeBuffer[readPointer]) { platform->Message(HOST_MESSAGE, "GCodes: String expected but not seen.\n"); + readPointer = -1; return gcodeBuffer; // Good idea? } @@ -2445,6 +2724,7 @@ long GCodeBuffer::GetLValue() if (readPointer < 0) { platform->Message(HOST_MESSAGE, "GCodes: Attempt to read a GCode int before a search.\n"); + readPointer = -1; return 0; } long result = strtol(&gcodeBuffer[readPointer + 1], 0, 0); diff --git a/GCodes.h b/GCodes.h index 9474a5f..673aadf 100644 --- a/GCodes.h +++ b/GCodes.h @@ -25,7 +25,8 @@ Licence: GPL #define STACK 5 #define GCODE_LENGTH 100 // Maximum length of internally-generated G Code string -#define GCODE_LETTERS { 'X', 'Y', 'Z', 'E', 'F' } // The drives and feedrate in a GCode +#define GCODE_LETTERS { 'X', 'Y', 'Z', 'E', 'F' } // The drives and feedrate in a GCode //FIXME when working with multiple extruders GCODE_LETTERS[DRIVES] is out of scope +#define FEEDRATE_LETTER 'F'//FIX to work with multiple extruders without having to re-define GCODE_LETTERS array // Small class to hold an individual GCode and provide functions to allow it to be parsed @@ -33,34 +34,36 @@ class GCodeBuffer { public: GCodeBuffer(Platform* p, const char* id); - void Init(); - bool Put(char c); - bool Seen(char c); - float GetFValue(); - int GetIValue(); - long GetLValue(); - const char* GetUnprecedentedString(); - const char* GetString(); + void Init(); // Set it up + bool Put(char c); // Add a character to the end + bool Seen(char c); // Is a character present? + float GetFValue(); // Get a float after a key letter + int GetIValue(); // Get an integer after a key letter + long GetLValue(); // Get a long integer after a key letter + const char* GetUnprecedentedString(); // Get a string with no preceding key letter + const char* GetString(); // Get a string after a key letter + const void GetFloatArray(float a[], int& length); // Get a :-separated list of floats after a key letter + const void GetLongArray(long l[], int& length); // Get a :-separated list of longs after a key letter const char* Buffer(); bool Active() const; - void SetFinished(bool f); + void SetFinished(bool f); // Set the G Code executed (or not) void Pause(); void CancelPause(); - const char* WritingFileDirectory() const; - void SetWritingFileDirectory(const char* wfd); + const char* WritingFileDirectory() const; // If we are writing the G Code to a file, where that file is + void SetWritingFileDirectory(const char* wfd); // Set the directory for the file to write the GCode in private: enum State { idle, executing, paused }; - int CheckSum(); - Platform* platform; - char gcodeBuffer[GCODE_LENGTH]; - const char* identity; - int gcodePointer; - int readPointer; - bool inComment; - State state; - const char* writingFileDirectory; + int CheckSum(); // Compute the checksum (if any) at the end of the G Code + Platform* platform; // Pointer to the RepRap's controlling class + char gcodeBuffer[GCODE_LENGTH]; // The G Code + const char* identity; // Where we are from (web, file, serial line etc) + int gcodePointer; // Index in the buffer + int readPointer; // Where in the buffer to read next + bool inComment; // Are we after a ';' character? + State state; // Idle, executing or paused + const char* writingFileDirectory; // If the G Code is going into a file, where that is }; //**************************************************************************************************** @@ -72,113 +75,118 @@ class GCodes public: GCodes(Platform* p, Webserver* w); - void Spin(); - void Init(); - void Exit(); + void Spin(); // Called in a tight loop to make this class work + void Init(); // Set it up + void Exit(); // Shut it down void Reset(); - bool RunConfigurationGCodes(); - 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); - char* GetCurrentCoordinates(); - bool PrintingAFile() const; - void Diagnostics(); - bool HaveIncomingData() const; - bool GetAxisIsHomed(uint8_t axis) const { return axisIsHomed[axis]; } + bool RunConfigurationGCodes(); // Run the configuration G Code file on reboot + bool ReadMove(float* m, bool& ce); // Called by the Move class to get a movement set by the last G Code + void QueueFileToPrint(const char* fileName); // Open a file of G Codes to run + void DeleteFile(const char* fileName); // Does what it says + bool GetProbeCoordinates(int count, float& x, float& y, float& z); // Get pre-recorded probe coordinates + char* GetCurrentCoordinates(); // Get where we are as a string + bool PrintingAFile() const; // Are we in the middle of printing a file? + void Diagnostics(); // Send helpful information out + int8_t GetSelectedHead() const; // return which tool is selected + bool HaveIncomingData() const; // Is there something that we have to do? + bool GetAxisIsHomed(uint8_t axis) const { return axisIsHomed[axis]; } // Is the axis at 0? void SetAxisIsHomed(uint8_t axis) { axisIsHomed[axis] = true; } float GetExtruderPosition(uint8_t extruder) const; void PauseSDPrint(); private: - void doFilePrint(GCodeBuffer* gb); - bool AllMovesAreFinishedAndMoveBufferIsLoaded(); - bool DoCannedCycleMove(bool ce); - bool DoFileCannedCycles(const char* fileName); - bool FileCannedCyclesReturn(); - bool ActOnGcode(GCodeBuffer* gb); + void DoFilePrint(GCodeBuffer* gb); // Get G Codes from a file and print them + bool AllMovesAreFinishedAndMoveBufferIsLoaded(); // Wait for move queue to exhaust and the current position is loaded + bool DoCannedCycleMove(bool ce); // Do a move from an internally programmed canned cycle + bool DoFileCannedCycles(const char* fileName); // Run a GCode macro in a file + bool FileCannedCyclesReturn(); // End a macro + bool ActOnGcode(GCodeBuffer* gb); // Do the G Code bool HandleGcode(GCodeBuffer* gb); bool HandleMcode(GCodeBuffer* gb); bool HandleTcode(GCodeBuffer* gb); int SetUpMove(GCodeBuffer* gb); - bool DoDwell(GCodeBuffer *gb); + bool DoDwell(GCodeBuffer *gb); // Wait for a bit bool DoDwellTime(float dwell); - bool DoHome(char *reply, bool& error); - bool DoSingleZProbeAtPoint(); - bool DoSingleZProbe(); - bool SetSingleZProbeAtAPosition(GCodeBuffer *gb); - bool DoMultipleZProbe(); - bool SetPrintZProbe(GCodeBuffer *gb, char *reply); - bool SetOffsets(GCodeBuffer *gb); - bool SetPositions(GCodeBuffer *gb); - void LoadMoveBufferFromGCode(GCodeBuffer *gb, bool doingG92, bool applyLimits); - bool NoHome() const; - bool Push(); - bool Pop(); - bool DisableDrives(); - bool StandbyHeaters(); - void SetEthernetAddress(GCodeBuffer *gb, int mCode); - void HandleReply(bool error, bool fromLine, const char* reply, char gMOrT, int code, bool resend); - bool OpenFileToWrite(const char* directory, const char* fileName, GCodeBuffer *gb); - void WriteGCodeToFile(GCodeBuffer *gb); - bool SendConfigToLine(); - void WriteHTMLToFile(char b, GCodeBuffer *gb); - bool OffsetAxes(GCodeBuffer *gb); + bool DoHome(char *reply, bool& error); // Home some axes + bool DoSingleZProbeAtPoint(); // Probe at a given point + bool DoSingleZProbe(); // Probe where we are + bool SetSingleZProbeAtAPosition(GCodeBuffer *gb); // Probes at a given position - see the comment at the head of the function itself + bool DoMultipleZProbe(); // Probes a series of points and sets the bed equation + bool SetPrintZProbe(GCodeBuffer *gb, char *reply); // Either return the probe value, or set its threshold + bool SetOffsets(GCodeBuffer *gb); // Deal with a G10 + bool SetPositions(GCodeBuffer *gb); // Deal with a G92 + void LoadMoveBufferFromGCode(GCodeBuffer *gb, // Set up a move for the Move class + bool doingG92, bool applyLimits); + bool NoHome() const; // Are we homing and not finished? + bool Push(); // Push feedrate etc on the stack + bool Pop(); // Pop feedrate etc + bool DisableDrives(); // Turn the motors off + bool StandbyHeaters(); // Set all heaters to standby temperatures + void SetEthernetAddress(GCodeBuffer *gb, int mCode); // Does what it says + void SetMACAddress(GCodeBuffer *gb); // Deals with an M540 + void HandleReply(bool error, bool fromLine, const char* reply, // If the GCode is from the serial interface, reply to it + char gMOrT, int code, bool resend); + bool OpenFileToWrite(const char* directory, // Start saving GCodes in a file + const char* fileName, GCodeBuffer *gb); + void WriteGCodeToFile(GCodeBuffer *gb); // Write this GCode into a file + bool SendConfigToLine(); // Deal with M503 + void WriteHTMLToFile(char b, GCodeBuffer *gb); // Save an HTML file (usually to upload a new web interface) + bool OffsetAxes(GCodeBuffer *gb); // Set offsets - deprecated, use G10 void SetPidParameters(GCodeBuffer *gb, int heater, char reply[STRING_LENGTH]); void SetHeaterParameters(GCodeBuffer *gb, char reply[STRING_LENGTH]); int8_t Heater(int8_t head) const; - - Platform* platform; - bool active; - Webserver* webserver; - float dwellTime; - bool dwellWaiting; - GCodeBuffer* webGCode; - GCodeBuffer* fileGCode; - GCodeBuffer* serialGCode; - GCodeBuffer* cannedCycleGCode; - bool moveAvailable; - float moveBuffer[DRIVES+1]; // Last is feed rate - bool checkEndStops; - bool drivesRelative; // All except X, Y and Z - bool axesRelative; // X, Y and Z - bool drivesRelativeStack[STACK]; - bool axesRelativeStack[STACK]; - float feedrateStack[STACK]; + Platform* platform; // The RepRap machine + bool active; // Live and running? + Webserver* webserver; // The webserver class + float dwellTime; // How long a pause for a dwell (seconds)? + bool dwellWaiting; // We are in a dwell + GCodeBuffer* webGCode; // The sources... + GCodeBuffer* fileGCode; // ... + GCodeBuffer* serialGCode; // ... + GCodeBuffer* cannedCycleGCode; // ... of G Codes + bool moveAvailable; // Have we seen a move G Code and set it up? + float moveBuffer[DRIVES+1]; // Move coordinates; last is feed rate + bool checkEndStops; // Should we check them on the next move? + bool drivesRelative; // Are movements relative - all except X, Y and Z + bool axesRelative; // Are movements relative - X, Y and Z + bool drivesRelativeStack[STACK]; // For dealing with Push and Pop + bool axesRelativeStack[STACK]; // For dealing with Push and Pop + float feedrateStack[STACK]; // For dealing with Push and Pop FileData fileStack[STACK]; - int8_t stackPointer; - char gCodeLetters[DRIVES + 1]; // Extra is for F - float lastPos[DRIVES - AXES]; // Just needed for relative moves. - float record[DRIVES+1]; - float moveToDo[DRIVES+1]; - bool activeDrive[DRIVES+1]; - bool offSetSet; - float distanceScale; + int8_t stackPointer; // Push and Pop stack pointer + char gCodeLetters[DRIVES + 1]; // 'X', 'Y' etc. Extra is for F + float lastPos[DRIVES - AXES]; // Just needed for relative moves; i.e. not X, Y and Z + float record[DRIVES+1]; // Temporary store for move positions + float moveToDo[DRIVES+1]; // Where to go set by G1 etc + bool activeDrive[DRIVES+1]; // Is this drive involved in a move? + bool offSetSet; // Are any axis offsets non-zero? + float distanceScale; // MM or inches FileData fileBeingPrinted; FileData fileToPrint; - FileStore* fileBeingWritten; - FileStore* configFile; - bool doingCannedCycleFile; - char* eofString; - uint8_t eofStringCounter; - uint8_t eofStringLength; - int8_t selectedHead; - bool homeX; - bool homeY; - bool homeZ; - float gFeedRate; - int probeCount; - int8_t cannedCycleMoveCount; - bool cannedCycleMoveQueued; - bool zProbesSet; - float longWait; - bool limitAxes; // Don't think outside the box. - bool axisIsHomed[3]; // these record which of the axes have been homed + FileStore* fileBeingWritten; // A file to write G Codes (or sometimes HTML) in + FileStore* configFile; // A file containing a macro + bool doingCannedCycleFile; // Are we executing a macro file? + char* eofString; // What's at the end of an HTML file? + uint8_t eofStringCounter; // Check the... + uint8_t eofStringLength; // ... EoF string as we read. + int8_t selectedHead; // Which extruder is in use + bool homeX; // True to home the X axis this move + bool homeY; // True to home the Y axis this move + bool homeZ; // True to home the Z axis this move + int8_t homeAxisMoveCount; // Counts homing moves + float gFeedRate; // Store for the current feedrate + int probeCount; // Counts multiple probe points + int8_t cannedCycleMoveCount; // Counts through internal (i.e. not macro) canned cycle moves + bool cannedCycleMoveQueued; // True if a canned cycle move has been set + bool zProbesSet; // True if all Z probing is done and we can set the bed equation + float longWait; // Timer for things that happen occasionally (seconds) + bool limitAxes; // Don't think outside the box. + bool axisIsHomed[3]; // These record which of the axes have been homed bool waitingForMoveToComplete; bool coolingInverted; - float speedFactor; // speed factor, including the conversion from mm/min to mm/sec, normally 1/60 - float extrusionFactor; // extrusion factor, normally 1.0 + float speedFactor; // speed factor, including the conversion from mm/min to mm/sec, normally 1/60 + float extrusionFactor; // extrusion factor, normally 1.0 }; //***************************************************************************************************** @@ -262,4 +270,9 @@ inline bool GCodes::RunConfigurationGCodes() return !DoFileCannedCycles(platform->GetConfigFile()); } +inline int8_t GCodes::GetSelectedHead() const +{ + return selectedHead; +} + #endif diff --git a/Heat.h b/Heat.h index 9225310..399c9f9 100644 --- a/Heat.h +++ b/Heat.h @@ -21,68 +21,78 @@ Licence: GPL #ifndef HEAT_H #define HEAT_H +/** + * This class implements a PID controller for the heaters + */ + class PID { - public: + friend class Heat; + private: + //public: PID(Platform* p, int8_t h); - void Init(); - void Spin(); + void Init(); // (Re)Set everything to start + void Spin(); // Called in a tight loop to keep things running void SetActiveTemperature(float t); float GetActiveTemperature() const; void SetStandbyTemperature(float t); float GetStandbyTemperature() const; - void Activate(); - void Standby(); + void Activate(); // Switch from idle to active + void Standby(); // Switch from active to idle bool Active() const; - void ResetFault(); + void ResetFault(); // Reset a fault condition - only call this if you know what you are doing float GetTemperature() const; + + // private: - private: - - Platform* platform; - float activeTemperature; - float standbyTemperature; - float temperature; - float lastTemperature; - float temp_iState; - bool active; - int8_t heater; - int8_t badTemperatureCount; - bool temperatureFault; + Platform* platform; // The instance of the class that is the RepRap hardware + float activeTemperature; // The required active temperature + float standbyTemperature; // The required standby temperature + float temperature; // The current temperature + float lastTemperature; // The previous current temperature + float temp_iState; // The integral PID component + bool active; // Are we active or standby? + int8_t heater; // The index of our heater + int8_t badTemperatureCount; // Count of sequential dud readings + bool temperatureFault; // Has our heater developed a fault? }; +/** + * The master class that controls all the heaters in the RepRap machine + */ + class Heat { public: Heat(Platform* p, GCodes* g); - void Spin(); - void Init(); - void Exit(); + void Spin(); // Called in a tight loop to keep everything going + void Init(); // Set everything up + void Exit(); // Shut everything down void SetActiveTemperature(int8_t heater, float t); float GetActiveTemperature(int8_t heater) const; void SetStandbyTemperature(int8_t heater, float t); float GetStandbyTemperature(int8_t heater) const; - void Activate(int8_t heater); - void Standby(int8_t heater); + void Activate(int8_t heater); // Turn on a heater + void Standby(int8_t heater); // Set a heater idle float GetTemperature(int8_t heater) const; - void ResetFault(int8_t heater); + void ResetFault(int8_t heater); // Reset a heater fault - oly call this if you know what you are doing bool AllHeatersAtSetTemperatures() const; bool HeaterAtSetTemperature(int8_t heater) const; // Is a specific heater at temperature within tolerance? - void Diagnostics(); + void Diagnostics(); // Output useful information private: - Platform* platform; - GCodes* gCodes; - bool active; - PID* pids[HEATERS]; - float lastTime; - float longWait; + Platform* platform; // The instance of the RepRap hardware class + GCodes* gCodes; // The instance of the G Code interpreter class + bool active; // Are we active? + PID* pids[HEATERS]; // A PID controller for each heater + float lastTime; // The last time our Spin() was called + float longWait; // Long time for things that happen occasionally }; - + //*********************************************************************************************************** @@ -189,5 +199,4 @@ inline void Heat::ResetFault(int8_t heater) } - #endif diff --git a/Libraries/Lwip/lwip/src/sam/netif/ethernetif.c b/Libraries/Lwip/lwip/src/sam/netif/ethernetif.c index 4d58942..11fb6ab 100644 --- a/Libraries/Lwip/lwip/src/sam/netif/ethernetif.c +++ b/Libraries/Lwip/lwip/src/sam/netif/ethernetif.c @@ -513,6 +513,9 @@ err_t ethernetif_init(struct netif *netif) netif->output = etharp_output; netif->linkoutput = low_level_output; +#if 1 + // We now require the user to configure the MAC address if the default one is unsuitable, instead of selecting it automatically +#else // Patch the last 4 bytes of the MAC address to be the IP address, so that we can support multiple Duets on the same subnet { size_t i; @@ -521,9 +524,19 @@ err_t ethernetif_init(struct netif *netif) gs_uc_mac_address[i + 2] = ((uint8_t*)&(netif->ip_addr))[i]; } } +#endif /* Initialize the hardware */ low_level_init(netif); return ERR_OK; } + +void RepRapNetworkSetMACAddress(const u8_t macAddress[]) +{ + size_t i; + for (i = 0; i < 8; ++i) + { + gs_uc_mac_address[i] = macAddress[i]; + } +} diff --git a/Move.cpp b/Move.cpp index 9773726..a99a4c3 100644 --- a/Move.cpp +++ b/Move.cpp @@ -271,7 +271,8 @@ bool Move::GetCurrentState(float m[]) if(i < AXES) m[i] = lastMove->MachineToEndPoint(i); else - m[i] = 0.0; + m[i] = 0.0; //FIXME This resets extruders to 0.0, even the inactive ones (is this behaviour desired?) + //m[i] = lastMove->MachineToEndPoint(i); //FIXME TEST alternative that does not reset extruders to 0 } if(currentFeedrate >= 0.0) m[DRIVES] = currentFeedrate; @@ -364,7 +365,7 @@ void Move::SetStepHypotenuse() // We don't want 0. If no axes/extruders are moving these should never be used. // But try to be safe. - stepDistances[0] = 1.0/platform->DriveStepsPerUnit(AXES); + stepDistances[0] = 1.0/platform->DriveStepsPerUnit(AXES); //FIXME this is not multi extruder safe (but we should never get here) extruderStepDistances[0] = stepDistances[0]; } @@ -520,7 +521,7 @@ void Move::DoLookAhead() else if (mt & zMove) c = platform->InstantDv(Z_AXIS); else - c = platform->InstantDv(AXES); // value for first extruder FIXME?? + c = platform->InstantDv((AXES+gCodes->GetSelectedHead())); // value for current extruder } n1->SetV(c); n1->SetProcessed(vCosineSet); @@ -571,7 +572,7 @@ void Move::Interrupt() dda = NULL; } - +// creates a new lookahead object adds it to the lookahead ring, returns false if its full bool Move::LookAheadRingAdd(const long ep[], float feedRate, float vv, bool ce, int8_t mt) { if(LookAheadRingFull()) @@ -614,7 +615,7 @@ void Move::SetIdentityTransform() secondDegreeCompensation = false; } -void Move::Transform(float xyzPoint[]) +void Move::Transform(float xyzPoint[]) const { xyzPoint[X_AXIS] = xyzPoint[X_AXIS] + tanXY*xyzPoint[Y_AXIS] + tanXZ*xyzPoint[Z_AXIS]; xyzPoint[Y_AXIS] = xyzPoint[Y_AXIS] + tanYZ*xyzPoint[Z_AXIS]; @@ -624,7 +625,7 @@ void Move::Transform(float xyzPoint[]) xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] + aX*xyzPoint[X_AXIS] + aY*xyzPoint[Y_AXIS] + aC; } -void Move::InverseTransform(float xyzPoint[]) +void Move::InverseTransform(float xyzPoint[]) const { if(secondDegreeCompensation) xyzPoint[Z_AXIS] = xyzPoint[Z_AXIS] - SecondDegreeTransformZ(xyzPoint[X_AXIS], xyzPoint[Y_AXIS]); @@ -973,15 +974,18 @@ MovementProfile DDA::Init(LookAhead* lookAhead, float& u, float& v) // by a velocity later. int8_t mt = myLookAheadEntry->GetMovementType(); - - if(mt & xyMove) // X or Y involved? - { - // If XY (or Z) are moving, then the extruder won't be considered in the // acceleration calculation. Usually this is OK. But check that we are not asking // the extruder to accelerate, decelerate, or move too fast. The common place // for this to happen is when it is moving back from a previous retraction during // an XY move. + if(mt & xyMove) // X or Y involved? + { + // If XY (or Z) are moving, then the extruder won't be considered in the + // acceleration calculation. Usually this is OK. But check that we are not asking + // the extruder to accelerate, decelerate, or move too fast. The common place + // for this to happen is when it is moving back from a previous retraction during + // an XY move. if((mt & eMove) && eDistance > distance) { SetEAcceleration(eDistance); @@ -990,7 +994,7 @@ MovementProfile DDA::Init(LookAhead* lookAhead, float& u, float& v) { SetXYAcceleration(); } - } else if (mt & zMove) // Z involved? + } else if (mt & zMove) // Z involved? { acceleration = platform->Acceleration(Z_AXIS); instantDv = platform->InstantDv(Z_AXIS); @@ -1240,11 +1244,13 @@ float LookAhead::Cosine() return cosine; } +//Returns units (mm) from steps for a particular drive float LookAhead::MachineToEndPoint(int8_t drive, long coord) { return ((float)coord)/reprap.GetPlatform()->DriveStepsPerUnit(drive); } +//Returns steps from units (mm) for a particular drive long LookAhead::EndPointToMachine(int8_t drive, float coord) { return (long)roundf(coord*reprap.GetPlatform()->DriveStepsPerUnit(drive)); diff --git a/Move.h b/Move.h index 6b3e1b6..cd2b9b0 100644 --- a/Move.h +++ b/Move.h @@ -60,188 +60,204 @@ enum PointCoordinateSet zSet = 4 }; - +/** + * This class implements a look-ahead buffer for moves. It allows colinear + * moves not to decelerate between them, sets velocities at ends and beginnings + * for angled moves, and so on. Entries are joined in a doubly-linked list + * to form a ring buffer. + */ class LookAhead { -public: - friend class Move; friend class DDA; protected: + LookAhead(Move* m, Platform* p, LookAhead* n); - void Init(const long ep[], float feedRate, float vv, bool ce, int8_t mt); - LookAhead* Next(); - LookAhead* Previous(); + void Init(const long ep[], float feedRate, float vv, bool ce, int8_t mt); // Set up this move + LookAhead* Next(); // Next one in the ring + LookAhead* Previous(); // Previous one in the ring const long* MachineEndPoints() const; - float MachineToEndPoint(int8_t drive); - static float MachineToEndPoint(int8_t drive, long coord); - static long EndPointToMachine(int8_t drive, float coord); - int8_t GetMovementType() const; - float FeedRate() const; - float V() const; - void SetV(float vv); - void SetFeedRate(float f); - int8_t Processed() const; - void SetProcessed(MovementState ms); - void SetDriveCoordinateAndZeroEndSpeed(float a, int8_t drive); - bool CheckEndStops() const; - void Release(); + float MachineToEndPoint(int8_t drive); // Convert a move endpoint to real mm coordinates + static float MachineToEndPoint(int8_t drive, long coord); // Convert any number to a real coordinate + static long EndPointToMachine(int8_t drive, float coord); // Convert real mm to a machine coordinate + int8_t GetMovementType() const; // What sort of move is this? + float FeedRate() const; // How fast is the maximum speed for this move + float V() const; // The speed at the end of the move + void SetV(float vv); // Set the end speed + void SetFeedRate(float f); // Set the desired feedrate + int8_t Processed() const; // Where we are in the look-ahead prediction sequence + void SetProcessed(MovementState ms); // Set where we are the the look ahead processing + void SetDriveCoordinateAndZeroEndSpeed(float a, int8_t drive); // Force an end ppoint and st its speed to stopped + bool CheckEndStops() const; // Are we checking endstops on this move? + void Release(); // This move has been processed and executed private: - Move* move; - Platform* platform; - LookAhead* next; - LookAhead* previous; - long endPoint[DRIVES+1]; // Should never use the +1, but safety first - int8_t movementType; - float Cosine(); - bool checkEndStops; - float cosine; - float v; // The feedrate we can actually do - float feedRate; // The requested feedrate - float instantDv; - volatile int8_t processed; + Move* move; // The main movement control class + Platform* platform; // The RepRap machine + LookAhead* next; // Next entry in the ring + LookAhead* previous; // Previous entry in the ring + long endPoint[DRIVES+1]; // Machine coordinates of the endpoint. Should never use the +1, but safety first + int8_t movementType; // XY move, Z move, extruder only etc + float Cosine(); // The angle between the previous move and this one + bool checkEndStops; // Check endstops for this move + float cosine; // Store for the cosine value - the function uses lazy evaluation + float v; // The feedrate we can actually do + float feedRate; // The requested feedrate + float instantDv; // The slowest speed we can move at. > 0 + volatile int8_t processed; // The stage in the look ahead process that this move is at. }; - +/** + * This implements an integer space machine coordinates Bressenham-style DDA to step the drives. + * DDAs are stored in a linked list forming a ring buffer. + */ class DDA { -public: - friend class Move; friend class LookAhead; protected: + DDA(Move* m, Platform* p, DDA* n); - MovementProfile Init(LookAhead* lookAhead, float& u, float& v); - void Start(bool noTest); - void Step(); + MovementProfile Init(LookAhead* lookAhead, float& u, float& v); // Set up the DDA. Also used experimentally in look ahead. + void Start(bool noTest); // Start executing the DDA. I.e. move the move. + void Step(); // Take one step of the DDA. Called by timed interrupt. bool Active() const; - DDA* Next(); + DDA* Next(); // Next entry in the ring float InstantDv() const; private: - MovementProfile AccelerationCalculation(float& u, float& v, MovementProfile result); - void SetXYAcceleration(); - void SetEAcceleration(float eDistance); - Move* move; - Platform* platform; - DDA* next; - LookAhead* myLookAheadEntry; - long counter[DRIVES]; - long delta[DRIVES]; - bool directions[DRIVES]; - long totalSteps; - long stepCount; - bool checkEndStops; - float timeStep; - float velocity; - long stopAStep; - long startDStep; - float distance; - float acceleration; - float instantDv; + + MovementProfile AccelerationCalculation(float& u, float& v, // Compute acceleration profiles + MovementProfile result); + void SetXYAcceleration(); // Compute an XY acceleration + void SetEAcceleration(float eDistance); // Compute an extruder acceleration + + Move* move; // The main movement control class + Platform* platform; // The RepRap machine + DDA* next; // The next one in the ring + LookAhead* myLookAheadEntry; // The look-ahead entry corresponding to this DDA + long counter[DRIVES]; // Step counters + long delta[DRIVES]; // How far to move each drive + bool directions[DRIVES]; // Forwards or backwards? + long totalSteps; // Total number of steps for this move + long stepCount; // How many steps we have already taken + bool checkEndStops; // Are we checking endstops? + float timeStep; // The current timestep (seconds) + float velocity; // The current velocity + long stopAStep; // The stepcount at which we stop accelerating + long startDStep; // The stepcount at which we start decelerating + float distance; // How long is the move in real distance + float acceleration; // The acceleration to use + float instantDv; // The lowest possible velocity float feedRate; - volatile bool active; + volatile bool active; // Is the DDA running? }; - +/** + * This is the master movement class. It controls all movement in the machine. + */ class Move { + friend class DDA; + public: Move(Platform* p, GCodes* g); - void Init(); - void Spin(); - void Exit(); - bool GetCurrentState(float m[]); // takes account of all the rings and delays - void LiveCoordinates(float m[]); // Just gives the last point at the end of the last DDA - void Interrupt(); - void InterruptTime(); - bool AllMovesAreFinished(); - void ResumeMoving(); - void DoLookAhead(); - void HitLowStop(int8_t drive, LookAhead* la, DDA* hitDDA); - void HitHighStop(int8_t drive, LookAhead* la, DDA* hitDDA); - void SetPositions(float move[]); - void SetLiveCoordinates(float coords[]); - void SetXBedProbePoint(int index, float x); - void SetYBedProbePoint(int index, float y); - void SetZBedProbePoint(int index, float z); - float xBedProbePoint(int index) const; - float yBedProbePoint(int index) const; - float zBedProbePoint(int index) const; - int NumberOfProbePoints() const; - int NumberOfXYProbePoints() const; - bool AllProbeCoordinatesSet(int index) const; - bool XYProbeCoordinatesSet(int index) const; - void SetZProbing(bool probing); - void SetProbedBedEquation(); - float SecondDegreeTransformZ(float x, float y) const; - float GetLastProbedZ() const; - void SetAxisCompensation(int8_t axis, float tangent); - void SetIdentityTransform(); - void Transform(float move[]); - void InverseTransform(float move[]); - void Diagnostics(); - float ComputeCurrentCoordinate(int8_t drive, LookAhead* la, DDA* runningDDA); - void SetStepHypotenuse(); - - - friend class DDA; + void Init(); // Start me up + void Spin(); // Called in a tight loop to keep the class going + void Exit(); // Shut down + bool GetCurrentState(float m[]); // Return the current position if possible. Send false otherwise + void LiveCoordinates(float m[]); // Gives the last point at the end of the last complete DDA + void Interrupt(); // The hardware's (i.e. platform's) interrupt should call this. + void InterruptTime(); // Test function - not used + bool AllMovesAreFinished(); // Is the look-ahead ring empty? Stops more moves being added as well. + void ResumeMoving(); // Allow moves to be added after a call to AllMovesAreFinished() + void DoLookAhead(); // Run the look-ahead procedure + void HitLowStop(int8_t drive, // What to do when a low endstop is hit + LookAhead* la, DDA* hitDDA); + void HitHighStop(int8_t drive, // What to do when a high endstop is hit + LookAhead* la, DDA* hitDDA); + void SetPositions(float move[]); // Force the coordinates to be these + void SetLiveCoordinates(float coords[]); // Force the live coordinates (see above) to be these + void SetXBedProbePoint(int index, float x); // Record the X coordinate of a probe point + void SetYBedProbePoint(int index, float y); // Record the Y coordinate of a probe point + void SetZBedProbePoint(int index, float z); // Record the Z coordinate of a probe point + float xBedProbePoint(int index) const; // Get the X coordinate of a probe point + float yBedProbePoint(int index) const; // Get the Y coordinate of a probe point + float zBedProbePoint(int index)const ; // Get the Z coordinate of a probe point + int NumberOfProbePoints() const; // How many points to probe have been set? 0 if incomplete + int NumberOfXYProbePoints() const; // How many XY coordinates of probe points have been set (Zs may not have been probed yet) + bool AllProbeCoordinatesSet(int index) const; // XY, and Z all set for this one? + bool XYProbeCoordinatesSet(int index) const; // Just XY set for this one? + void SetZProbing(bool probing); // Set the Z probe live + void SetProbedBedEquation(); // When we have a full set of probed points, work out the bed's equation + float SecondDegreeTransformZ(float x, float y) const; // Used for second degree bed equation + float GetLastProbedZ() const; // What was the Z when the probe last fired? + void SetAxisCompensation(int8_t axis, float tangent); // Set an axis-pair compensation angle + void SetIdentityTransform(); // Cancel the bed equation; does not reset axis angle compensation + void Transform(float move[]) const; // Take a position and apply the bed and the axis-angle compensations + void InverseTransform(float move[]) const; // Go from a transformed point back to user coordinates + void Diagnostics(); // Report useful stuff + float ComputeCurrentCoordinate(int8_t drive,// Turn a DDA value back into a real world coordinate + LookAhead* la, DDA* runningDDA); + void SetStepHypotenuse(); // Set up the hypotenuse lengths for multiple axis steps, like step both X and Y at once private: - bool DDARingAdd(LookAhead* lookAhead); - DDA* DDARingGet(); + bool DDARingAdd(LookAhead* lookAhead); // Add a processed look-ahead entry to the DDA ring + DDA* DDARingGet(); // Get the next DDA ring entry to be run bool DDARingEmpty() const; bool NoLiveMovement() const; bool DDARingFull() const; - bool GetDDARingLock(); - void ReleaseDDARingLock(); + bool GetDDARingLock(); // Lock the ring so only this function may access it + void ReleaseDDARingLock(); // Release the DDA ring lock bool LookAheadRingEmpty() const; bool LookAheadRingFull() const; 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; + LookAhead* LookAheadRingGet(); // Get the next entry from the look-ahead ring + int8_t GetMovementType(const long sp[], const long ep[]) const; // XY? Z? extruder only? - float liveCoordinates[DRIVES + 1]; + Platform* platform; // The RepRap machine + GCodes* gCodes; // The G Codes processing class - Platform* platform; - GCodes* gCodes; + // These implement the DDA ring DDA* dda; DDA* ddaRingAddPointer; DDA* ddaRingGetPointer; volatile bool ddaRingLocked; + // These implement the look-ahead ring + LookAhead* lookAheadRingAddPointer; LookAhead* lookAheadRingGetPointer; LookAhead* lastMove; DDA* lookAheadDDA; int lookAheadRingCount; - float lastTime; - bool addNoMoreMoves; - bool active; - float currentFeedrate; - float nextMove[DRIVES + 1]; // Extra is for feedrate - float stepDistances[(1< dx, dy, dz <- msb - float extruderStepDistances[(1<<(DRIVES-AXES))]; // NB - limits us to 5 extruders - long nextMachineEndPoints[DRIVES+1]; - float xBedProbePoints[NUMBER_OF_PROBE_POINTS]; - float yBedProbePoints[NUMBER_OF_PROBE_POINTS]; - float zBedProbePoints[NUMBER_OF_PROBE_POINTS]; - uint8_t probePointSet[NUMBER_OF_PROBE_POINTS]; - float aX, aY, aC; // Bed plane explicit equation z' = z + aX*x + aY*y + aC - float tanXY, tanYZ, tanXZ; // 90 degrees + angle gives angle between axes - float xRectangle, yRectangle; - float lastZHit; - bool zProbing; - bool secondDegreeCompensation; - float longWait; + float lastTime; // The last time we were called (secs) + bool addNoMoreMoves; // If true, allow no more moves to be added to the look-ahead + bool active; // Are we live and running? + float currentFeedrate; // Err... the current feed rate... + float liveCoordinates[DRIVES + 1]; // The last endpoint that the machine moved to + float nextMove[DRIVES + 1]; // The endpoint of the next move to processExtra entry is for feedrate + float stepDistances[(1< dx, dy, dz <- msb + float extruderStepDistances[(1<<(DRIVES-AXES))];// Same as above for the extruders. NB - may limit us to 5 extruders + long nextMachineEndPoints[DRIVES+1]; // The next endpoint in machine coordinates (i.e. steps) + float xBedProbePoints[NUMBER_OF_PROBE_POINTS]; // The X coordinates of the points on the bed at which to probe + float yBedProbePoints[NUMBER_OF_PROBE_POINTS]; // The X coordinates of the points on the bed at which to probe + float zBedProbePoints[NUMBER_OF_PROBE_POINTS]; // The X coordinates of the points on the bed at which to probe + uint8_t probePointSet[NUMBER_OF_PROBE_POINTS]; // Has the XY of this point been set? Has the Z been probed? + float aX, aY, aC; // Bed plane explicit equation z' = z + aX*x + aY*y + aC + float tanXY, tanYZ, tanXZ; // Axis compensation - 90 degrees + angle gives angle between axes + float xRectangle, yRectangle; // The side lengths of the rectangle used for second-degree bed compensation + float lastZHit; // The last Z value hit by the probe + bool zProbing; // Are we bed probing as well as moving? + bool secondDegreeCompensation; // Are we using second degree bed compensation. If not, linear + float longWait; // A long time for things that need to be done occasionally }; //******************************************************************************************************** @@ -274,7 +290,6 @@ inline float LookAhead::MachineToEndPoint(int8_t drive) return ((float)(endPoint[drive]))/platform->DriveStepsPerUnit(drive); } - inline float LookAhead::FeedRate() const { return feedRate; diff --git a/Network.cpp b/Network.cpp index f1828d2..d44c016 100644 --- a/Network.cpp +++ b/Network.cpp @@ -50,6 +50,8 @@ extern "C" #include "lwip/src/include/lwip/stats.h" #include "lwip/src/include/lwip/tcp.h" +void RepRapNetworkSetMACAddress(const u8_t macAddress[]); + } const int httpStateSize = MEMP_NUM_TCP_PCB + 1; // the +1 is in case of recovering from network errors @@ -317,6 +319,7 @@ void Network::AppendTransaction(RequestState* volatile* list, RequestState *r) void Network::Init() { + RepRapNetworkSetMACAddress(reprap.GetPlatform()->MACAddress()); init_ethernet(); } diff --git a/Platform.cpp b/Platform.cpp index b4b2113..bdd1ced 100644 --- a/Platform.cpp +++ b/Platform.cpp @@ -43,7 +43,6 @@ void setup() } reprap.Init(); - //reprap.GetMove()->InterruptTime(); // Uncomment this line to time the interrupt routine on startup } void loop() @@ -122,6 +121,7 @@ void Platform::Init() nvData.ipAddress = IP_ADDRESS; nvData.netMask = NET_MASK; nvData.gateWay = GATE_WAY; + nvData.macAddress = MAC_ADDRESS; nvData.zProbeType = 0; // Default is to use the switch nvData.switchZProbeParameters.Init(0.0); @@ -160,8 +160,8 @@ void Platform::Init() fileStructureInitialised = true; - mcp.begin(); - + mcpDuet.begin(); //only call begin once in the entire execution, this begins the I2C comms on that channel for all objects + mcpExpansion.setMCP4461Address(0x2E); //not required for mcpDuet, as this uses the default address sysDir = SYS_DIR; configFile = CONFIG_FILE; @@ -180,6 +180,7 @@ void Platform::Init() potWipes = POT_WIPES; senseResistor = SENSE_RESISTOR; maxStepperDigipotVoltage = MAX_STEPPER_DIGIPOT_VOLTAGE; + numMixingDrives = NUM_MIXING_DRIVES; // Z PROBE @@ -207,26 +208,30 @@ void Platform::Init() webDir = WEB_DIR; gcodeDir = GCODE_DIR; tempDir = TEMP_DIR; - + /* + FIXME Nasty having to specify individually if a pin is arduino or not. + requires a unified variant file. If implemented this would be much better + to allow for different hardware in the future + */ for (size_t i = 0; i < DRIVES; i++) { if (stepPins[i] >= 0) { - if (i > Z_AXIS) + if(i == E0_DRIVE || i == E3_DRIVE) //STEP_PINS {14, 25, 5, X2, 41, 39, X4, 49} pinModeNonDue(stepPins[i], OUTPUT); else pinMode(stepPins[i], OUTPUT); } if (directionPins[i] >= 0) { - if (i > Z_AXIS) + if(i == E0_DRIVE) //DIRECTION_PINS {15, 26, 4, X3, 35, 53, 51, 48} pinModeNonDue(directionPins[i], OUTPUT); else pinMode(directionPins[i], OUTPUT); } if (enablePins[i] >= 0) { - if (i >= Z_AXIS) + if(i == Z_AXIS || i==E0_DRIVE || i==E2_DRIVE) //ENABLE_PINS {29, 27, X1, X0, 37, X8, 50, 47} pinModeNonDue(enablePins[i], OUTPUT); else pinMode(enablePins[i], OUTPUT); @@ -234,8 +239,7 @@ void Platform::Init() Disable(i); driveEnabled[i] = false; } - - for (size_t i = 0; i < AXES; i++) + for(size_t i = 0; i < DRIVES; i++) { if (lowStopPins[i] >= 0) { @@ -253,7 +257,7 @@ void Platform::Init() { if (heatOnPins[i] >= 0) { - if (i == 0) // heater 0 (bed heater) is a standard Arduino PWM pin + if(i == E0_HEATER || i==E1_HEATER) //HEAT_ON_PINS {6, X5, X7, 7, 8, 9} { pinMode(heatOnPins[i], OUTPUT); } @@ -262,7 +266,6 @@ void Platform::Init() pinModeNonDue(heatOnPins[i], OUTPUT); } } - thermistorFilters[i].Init(); heaterAdcChannels[i] = PinToAdcChannel(tempSensePins[i]); @@ -276,8 +279,8 @@ void Platform::Init() if (coolingFanPin >= 0) { - pinMode(coolingFanPin, OUTPUT); - analogWrite(coolingFanPin, (HEAT_ON == 0) ? 255 : 0); // turn auxiliary cooling fan off + //pinModeNonDue(coolingFanPin, OUTPUT); //not required as analogwrite does this automatically + analogWriteNonDue(coolingFanPin, 255); //inverse logic for Duet v0.6 this turns it off } InitialiseInterrupts(); @@ -540,9 +543,6 @@ void Platform::Spin() line->Spin(); - if (Time() - lastTime < 0.006) - return; - lastTime = Time(); ClassReport("Platform", longWait); } @@ -722,7 +722,6 @@ void Platform::SetDebug(int d) case DiagnosticTest::TestSpinLockup: debugCode = d; // tell the Spin function to loop break; - default: break; } @@ -898,11 +897,17 @@ void Platform::SetHeater(size_t heater, const float& power) byte p = (byte) (255.0 * min(1.0, max(0.0, power))); if (HEAT_ON == 0) + { p = 255 - p; - if (heater == 0) - analogWrite(heatOnPins[heater], p); - else - analogWriteNonDue(heatOnPins[heater], p); + if(heater == E0_HEATER || heater == E1_HEATER) //HEAT_ON_PINS {6, X5, X7, 7, 8, 9} + { + analogWriteNonDue(heatOnPins[heater], p); + } + else + { + analogWrite(heatOnPins[heater], p); + } + } } EndStopHit Platform::Stopped(int8_t drive) @@ -982,6 +987,7 @@ void Platform::Step(byte drive) } // current is in mA + void Platform::SetMotorCurrent(byte drive, float current) { unsigned short pot = (unsigned short)(0.256*current*8.0*senseResistor/maxStepperDigipotVoltage); @@ -989,18 +995,28 @@ void Platform::SetMotorCurrent(byte drive, float current) // snprintf(scratchString, STRING_LENGTH, "%d", pot); // Message(HOST_MESSAGE, scratchString); // Message(HOST_MESSAGE, "\n"); - mcp.setNonVolatileWiper(potWipes[drive], pot); - mcp.setVolatileWiper(potWipes[drive], pot); + if(drive < 4) + { + mcpDuet.setNonVolatileWiper(potWipes[drive], pot); + mcpDuet.setVolatileWiper(potWipes[drive], pot); + } + else + { + mcpExpansion.setNonVolatileWiper(potWipes[drive], pot); + mcpExpansion.setVolatileWiper(potWipes[drive], pot); + } } + //Changed to be compatible with existing gcode norms // M106 S0 = fully off M106 S255 = fully on void Platform::CoolingFan(float speed) { - if(coolingFanPin > 0) + if(coolingFanPin >= 0) { + byte p =(byte)speed; // The cooling fan output pin gets inverted if HEAT_ON == 0 - analogWriteNonDue(coolingFanPin, (uint32_t)( (HEAT_ON == 0) ? (255.0 - speed) : speed)); + analogWriteNonDue(coolingFanPin, (HEAT_ON == 0) ? (255 - p) : p); } } diff --git a/Platform.h b/Platform.h index 5defd70..632172c 100644 --- a/Platform.h +++ b/Platform.h @@ -1,8 +1,8 @@ /**************************************************************************************************** -RepRapFirmware - Platform: RepRapPro Mendel with Duet controller +RepRapFirmware - Platform: RepRapPro Ormerod with Duet controller -Platform contains all the code and definitons to deal with machine-dependent things such as control +Platform contains all the code and definitions to deal with machine-dependent things such as control pins, bed area, number of extruders, tolerable accelerations and speeds and so on. No definitions that are system-independent should go in here. Put them in Configuration.h. Note that @@ -57,9 +57,9 @@ Licence: GPL // Some numbers... -#define STRING_LENGTH 1029 // needs to be long enough to receive web data +#define STRING_LENGTH 1029 // needs to be long enough to receive web data #define SHORT_STRING_LENGTH 40 -#define TIME_TO_REPRAP 1.0e6 // Convert seconds to the units used by the machine (usually microseconds) +#define TIME_TO_REPRAP 1.0e6 // Convert seconds to the units used by the machine (usually microseconds) #define TIME_FROM_REPRAP 1.0e-6 // Convert the units used by the machine (usually microseconds) to seconds /**************************************************************************************************/ @@ -70,53 +70,64 @@ Licence: GPL #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; 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. +// The numbers of entries in each {} array definition must correspond with the values of DRIVES, +// AXES, or HEATERS. Set values to -1 to flag unavailability. Pins are the microcontroller pin numbers. // DRIVES -#define STEP_PINS {14, 25, 5, X2} -#define DIRECTION_PINS {15, 26, 4, X3} -#define FORWARDS true // What to send to go... -#define BACKWARDS false // ...in each direction -#define ENABLE_PINS {29, 27, X1, X0} -#define ENABLE false // What to send to enable... -#define DISABLE true // ...and disable a drive +#define STEP_PINS {14, 25, 5, X2} // Full array for Duet + Duex4 is {14, 25, 5, X2, 41, 39, X4, 49} +#define DIRECTION_PINS {15, 26, 4, X3} // Full array for Duet + Duex4 is {15, 26, 4, X3, 35, 53, 51, 48} +#define FORWARDS true // What to send to go... +#define BACKWARDS false // ...in each direction +#define ENABLE_PINS {29, 27, X1, X0} // Full array for Duet + Duex4 is {29, 27, X1, X0, 37, X8, 50, 47} +#define ENABLE false // What to send to enable... +#define DISABLE true // ...and disable a drive #define DISABLE_DRIVES {false, false, true, false} // Set true to disable a drive when it becomes idle -#define LOW_STOP_PINS {11, -1, 60, 31} +#define LOW_STOP_PINS {11, -1, 60, 31} // Full array endstop pins for Duet + Duex4 is {11, 28, 60, 31, 24, 46, 45, 44} #define HIGH_STOP_PINS {-1, 28, -1, -1} -#define ENDSTOP_HIT 1 // when a stop == this it is hit -#define POT_WIPES {1, 3, 2, 0} // Indices for motor current digipots (if any) -#define SENSE_RESISTOR 0.1 // Stepper motor current sense resistor +#define ENDSTOP_HIT 1 // when a stop == this it is hit + +// Indices for motor current digipots (if any) +// first 4 are for digipot 1,(on duet) +// second 4 for digipot 2(on expansion board) +// Full order is {1, 3, 2, 0, 1, 3, 2, 0}, only include as many as you have DRIVES defined +#define POT_WIPES {1, 3, 2, 0} // Indices for motor current digipots (if any) +#define SENSE_RESISTOR 0.1 // Stepper motor current sense resistor (ohms) #define MAX_STEPPER_DIGIPOT_VOLTAGE ( 3.3*2.5/(2.7+2.5) ) // Stepper motor current reference voltage -#define Z_PROBE_AD_VALUE (400) -#define Z_PROBE_STOP_HEIGHT (0.7) // mm -#define Z_PROBE_PIN (0) // Analogue pin number -#define Z_PROBE_MOD_PIN (61) // Digital pin number to turn the IR LED on (high) or off (low) +#define Z_PROBE_AD_VALUE (400) // Default for the Z probe - should be overwritten by experiment +#define Z_PROBE_STOP_HEIGHT (0.7) // mm +#define Z_PROBE_PIN (0) // Analogue pin number +#define Z_PROBE_MOD_PIN (61) // Digital pin number to turn the IR LED on (high) or off (low) const unsigned int numZProbeReadingsAveraged = 8; // we average this number of readings with IR on, and the same number with IR off -#define MAX_FEEDRATES {50.0, 50.0, 3.0, 16.0} // mm/sec +#define MAX_FEEDRATES {50.0, 50.0, 3.0, 16.0} // mm/sec #define ACCELERATIONS {800.0, 800.0, 10.0, 250.0} // mm/sec^2 #define DRIVE_STEPS_PER_UNIT {87.4890, 87.4890, 4000.0, 420.0} #define INSTANT_DVS {10.0, 10.0, 0.2, 2.0} // (mm/sec) these are also the minimum feed rates which is why I (dc42) decreased X/Y from 15 to 10 +#define NUM_MIXING_DRIVES 1; //number of mixing drives // AXES #define AXIS_MAXIMA {220, 200, 200} // mm #define AXIS_MINIMA {0, 0, 0} // mm -#define HOME_FEEDRATES {50.0, 50.0, 1.0} // mm/sec -#define HEAD_OFFSETS {0.0, 0.0, 0.0} +#define HOME_FEEDRATES {50.0, 50.0, 1.0} // mm/sec +#define HEAD_OFFSETS {0.0, 0.0, 0.0} // mm -#define X_AXIS 0 // The index of the X axis +#define X_AXIS 0 // The index of the X axis in the arrays #define Y_AXIS 1 // The index of the Y axis #define Z_AXIS 2 // The index of the Z axis +#define E0_DRIVE 3 //the index of the first Extruder drive +#define E1_DRIVE 4 //the index of the second Extruder drive +#define E2_DRIVE 5 //the index of the third Extruder drive +#define E3_DRIVE 6 //the index of the fourth Extruder drive +#define E4_DRIVE 7 //the index of the fifth Extruder drive -// HEATERS - The bed is assumed to be the first +// HEATERS - The bed is assumed to be the at index 0 -#define TEMP_SENSE_PINS {5, 4} // Analogue pin numbers -#define HEAT_ON_PINS {6, X5} +#define TEMP_SENSE_PINS {5, 4} // Analogue pin numbers (full array for Duet+Duex4 = {5, 4, 0, 7, 8, 9} ) +#define HEAT_ON_PINS {6, X5} // PWM pins (full array for Duet+Duex4 = {6, X5, X7, 7, 8, 9} ) // Bed thermistor: http://uk.farnell.com/epcos/b57863s103f040/sensor-miniature-ntc-10k/dp/1299930?Ntt=129-9930 // Hot end thermistor: http://www.digikey.co.uk/product-search/en?x=20&y=11&KeyWords=480-3137-ND @@ -159,8 +170,8 @@ const float defaultPidMax[HEATERS] = {255, 180}; // maximum value of I-term, mus #define STANDBY_TEMPERATURES {ABS_ZERO, ABS_ZERO} // We specify one for the bed, though it's not needed #define ACTIVE_TEMPERATURES {ABS_ZERO, ABS_ZERO} -#define COOLING_FAN_PIN X6 -#define HEAT_ON 0 // 0 for inverted heater (e.g. Duet v0.6) 1 for not (e.g. Duet v0.4) +#define COOLING_FAN_PIN X6 //pin D34 is PWM capable but not an Arduino PWM pin - use X6 instead +#define HEAT_ON 0 // 0 for inverted heater (eg Duet v0.6) 1 for not (e.g. Duet v0.4) // For the theory behind ADC oversampling, see http://www.atmel.com/Images/doc8003.pdf const unsigned int adOversampleBits = 1; // number of bits we oversample when reading temperatures @@ -174,6 +185,11 @@ const unsigned int adDisconnectedReal = adRangeReal - 3; // we consider an ADC r const unsigned int adDisconnectedVirtual = adDisconnectedReal << adOversampleBits; #define HOT_BED 0 // The index of the heated bed; set to -1 if there is no heated bed +#define E0_HEATER 1 //the index of the first extruder heater +#define E1_HEATER 2 //the index of the first extruder heater +#define E2_HEATER 3 //the index of the first extruder heater +#define E3_HEATER 4 //the index of the first extruder heater +#define E4_HEATER 5 //the index of the first extruder heater /****************************************************************************************************/ @@ -182,40 +198,39 @@ const unsigned int adDisconnectedVirtual = adDisconnectedReal << adOversampleBit #define MAX_FILES (10) // must be large enough to handle the max number of simultaneous web requests + file being printed #define FILE_BUF_LEN (256) #define SD_SPI (4) //Pin -#define WEB_DIR "0:/www/" // Place to find web files on the server -#define GCODE_DIR "0:/gcodes/" // Ditto - g-codes -#define SYS_DIR "0:/sys/" // Ditto - system files -#define TEMP_DIR "0:/tmp/" // Ditto - temporary files -#define FILE_LIST_SEPARATOR ',' -#define FILE_LIST_BRACKET '"' -#define FILE_LIST_LENGTH (1000) // Maximum length of file list - can't make it much longer unless we also make jsonResponse longer +#define WEB_DIR "0:/www/" // Place to find web files on the SD card +#define GCODE_DIR "0:/gcodes/" // Ditto - g-codes +#define SYS_DIR "0:/sys/" // Ditto - system files +#define TEMP_DIR "0:/tmp/" // Ditto - temporary files +#define FILE_LIST_LENGTH (1000) // Maximum length of file list -#define FLASH_LED 'F' // Type byte of a message that is to flash an LED; the next two bytes define the frequency and M/S ratio. -#define DISPLAY_MESSAGE 'L' // Type byte of a message that is to appear on a local display; the L is not displayed; \f and \n should be supported. -#define HOST_MESSAGE 'H' // Type byte of a message that is to be sent to the host; the H is not sent. +#define FLASH_LED 'F' // Type byte of a message that is to flash an LED; the next two bytes define + // the frequency and M/S ratio. +#define DISPLAY_MESSAGE 'L' // Type byte of a message that is to appear on a local display; the L is + // not displayed; \f and \n should be supported. +#define HOST_MESSAGE 'H' // Type byte of a message that is to be sent to the host; the H is not sent. #define DEBUG_MESSAGE 'D' // Type byte of a message that is to be sent for debugging; the D is not sent. +#define MAC_ADDRESS {0xBE, 0xEF, 0xDE, 0xAD, 0xFE, 0xED} + /****************************************************************************************************/ // Miscellaneous... -//#define LED_PIN 13 // Indicator LED - -#define BAUD_RATE 115200 // Communication speed of the USB if needed. +#define BAUD_RATE 115200 // Communication speed of the USB if needed. const int atxPowerPin = 12; // Arduino Due pin number that controls the ATX power on/off const uint16_t lineInBufsize = 256; // use a power of 2 for good performance const uint16_t lineOutBufSize = 2048; // ideally this should be large enough to hold the results of an M503 command, // but could be reduced if we ever need the memory -const uint16_t NumZProbeReadingsAveraged = 8; // must be an even number, preferably a power of 2 for performance, and no greater than 64 /****************************************************************************************************/ enum EndStopHit { noStop = 0, // no endstop hit - lowHit = 1, // low switch hit, or Z-probe in use and above threshold + lowHit = 1, // low switch hit, or Z-probe in use and above threshold highHit = 2, // high stop hit lowNear = 3 // approaching Z-probe threshold }; @@ -254,6 +269,7 @@ namespace DiagnosticTest { TestWatchdog = 1001, // test that we get a watchdog reset if the tick interrupt stops TestSpinLockup = 1002 // test that we get a software reset if a Spin() function takes too long + }; } @@ -515,14 +531,14 @@ public: void SetDebug(int d); void SoftwareReset(uint16_t reason); void SetAtxPower(bool on); - + // Timing float Time(); // Returns elapsed seconds since some arbitrary time void SetInterrupt(float s); // Set a regular interrupt going every s seconds; if s is -ve turn interrupt off void DisableInterrupts(); void Tick(); - + // Communications and data storage Line* GetLine() const; @@ -532,6 +548,8 @@ public: const byte* NetMask() const; void SetGateWay(byte gw[]); const byte* GateWay() const; + void SetMACAddress(uint8_t mac[]); + const uint8_t* MACAddress() const; friend class FileStore; @@ -544,7 +562,7 @@ public: const char* GetConfigFile() const; // Where the configuration is stored (in the system dir). void Message(char type, const char* message); // Send a message. Messages may simply flash an LED, or, - // say, display the messages on an LCD. This may also transmit the messages to the host. + // say, display the messages on an LCD. This may also transmit the messages to the host. void PushMessageIndent(); void PopMessageIndent(); @@ -582,6 +600,11 @@ public: bool GetZProbeParameters(struct ZProbeParameters& params) const; bool SetZProbeParameters(const struct ZProbeParameters& params); bool MustHomeXYBeforeZ() const; + + // Mixing support + + void SetMixingDrives(int); + int GetMixingDrives(); // Heat and temperature @@ -619,6 +642,7 @@ private: byte ipAddress[4]; byte netMask[4]; byte gateWay[4]; + uint8_t macAddress[6]; Compatibility compatibility; }; @@ -650,7 +674,10 @@ private: float accelerations[DRIVES]; float driveStepsPerUnit[DRIVES]; float instantDvs[DRIVES]; - MCP4461 mcp; + MCP4461 mcpDuet; + MCP4461 mcpExpansion; + + int8_t potWipes[DRIVES]; float senseResistor; float maxStepperDigipotVoltage; @@ -660,6 +687,7 @@ private: volatile ZProbeAveragingFilter zProbeOnFilter; // Z probe readings we took with the IR turned on volatile ZProbeAveragingFilter zProbeOffFilter; // Z probe readings we took with the IR turned off volatile ThermistorAveragingFilter thermistorFilters[HEATERS]; // bed and extruder thermistor readings + int8_t numMixingDrives; // AXES @@ -671,7 +699,7 @@ private: float axisMinima[AXES]; float homeFeedrates[AXES]; float headOffsets[AXES]; // FIXME - needs a 2D array - + // HEATERS - Bed is assumed to be the first int GetRawTemperature(byte heater) const; @@ -809,7 +837,7 @@ inline const char* Platform::GetWebDir() const // Where the gcodes are inline const char* Platform::GetGCodeDir() const -{ + { return gcodeDir; } @@ -819,7 +847,7 @@ inline const char* Platform::GetSysDir() const { return sysDir; } - + // Where the temporary files are inline const char* Platform::GetTempDir() const @@ -832,7 +860,7 @@ inline const char* Platform::GetConfigFile() const { return configFile; } - + //***************************************************************************************************************** @@ -840,15 +868,15 @@ inline const char* Platform::GetConfigFile() const // Drive the RepRap machine - Movement inline float Platform::DriveStepsPerUnit(int8_t drive) const -{ + { return driveStepsPerUnit[drive]; -} - + } + inline void Platform::SetDriveStepsPerUnit(int8_t drive, float value) { driveStepsPerUnit[drive] = value; } - + inline float Platform::Acceleration(int8_t drive) const { return accelerations[drive]; @@ -916,6 +944,21 @@ inline void Platform::SetMaxFeedrate(int8_t drive, float value) maxFeedrates[drive] = value; } +inline void Platform::SetMixingDrives(int num_drives) +{ + if(num_drives>(DRIVES-AXES)) + { + Message(HOST_MESSAGE, "More mixing extruder drives set with M160 than exist in firmware configuration\n"); + return; + } + numMixingDrives = num_drives; +} + +inline int Platform::GetMixingDrives() +{ + return numMixingDrives; +} + //******************************************************************************************************** // Drive the RepRap machine - Heat and temperature @@ -932,8 +975,6 @@ inline float Platform::HeatSampleTime() const return heatSampleTime; } -//**************************************************************************************************************** - inline const byte* Platform::IPAddress() const { return nvData.ipAddress; @@ -949,6 +990,28 @@ inline const byte* Platform::GateWay() const return nvData.gateWay; } +inline void Platform::SetMACAddress(uint8_t mac[]) +{ + bool changed = false; + for(int8_t i = 0; i < 6; i++) + { + if (nvData.macAddress[i] != mac[i]) + { + nvData.macAddress[i] = mac[i]; + changed = true; + } + } + if (changed) + { + WriteNvData(); + } +} + +inline const byte* Platform::MACAddress() const +{ + return nvData.macAddress; +} + inline Line* Platform::GetLine() const { return line; diff --git a/Release/RepRapFirmware-065e-dc42.bin b/Release/RepRapFirmware-065e-dc42.bin new file mode 100644 index 0000000000000000000000000000000000000000..a0771fcca73fdc667758bef3a60e5b3510acc251 GIT binary patch literal 259832 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%0DP8u`@=+Z8zUmZLhlRwEctI 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 K``QWSu;3ph5Ywjs literal 0 HcmV?d00001 diff --git a/RepRapFirmware.cpp b/RepRapFirmware.cpp index 27a9c74..0ec3644 100644 --- a/RepRapFirmware.cpp +++ b/RepRapFirmware.cpp @@ -165,6 +165,7 @@ RepRap::RepRap() : active(false), debug(false), stopped(false), spinState(0), ti gCodes = new GCodes(platform, webserver); move = new Move(platform, gCodes); heat = new Heat(platform, gCodes); + toolList = NULL; } void RepRap::Init() @@ -177,7 +178,7 @@ void RepRap::Init() webserver->Init(); move->Init(); heat->Init(); - + currentTool = NULL; const uint32_t wdtTicks = 256; // number of watchdog ticks @ 32768Hz/128 before the watchdog times out (max 4095) WDT_Enable(WDT, (wdtTicks << WDT_MR_WDV_Pos) | (wdtTicks << WDT_MR_WDD_Pos) | WDT_MR_WDRSTEN); // enable watchdog, reset the mcu if it times out active = true; // must do this before we start the network, else the watchdog may time out @@ -199,6 +200,9 @@ void RepRap::Init() platform->Message(HOST_MESSAGE, "\n"); platform->Message(HOST_MESSAGE, NAME); platform->Message(HOST_MESSAGE, " is up and running.\n"); + fastLoop = FLT_MAX; + slowLoop = 0.0; + lastTime = platform->Time(); } void RepRap::Exit() @@ -243,6 +247,15 @@ void RepRap::Spin() spinState = 0; ticksInSpinState = 0; + // Keep track of the loop time + + double t = platform->Time(); + double dt = t - lastTime; + if(dt < fastLoop) + fastLoop = dt; + if(dt > slowLoop) + slowLoop = dt; + lastTime = t; } void RepRap::Diagnostics() @@ -252,6 +265,10 @@ void RepRap::Diagnostics() heat->Diagnostics(); gCodes->Diagnostics(); webserver->Diagnostics(); + snprintf(scratchString, STRING_LENGTH, "Slow loop secs: %f; fast: %f\n", slowLoop, fastLoop); + platform->Message(HOST_MESSAGE, scratchString); + fastLoop = FLT_MAX; + slowLoop = 0.0; } // Turn off the heaters, disable the motors, and @@ -265,6 +282,13 @@ void RepRap::EmergencyStop() //platform->DisableInterrupts(); + Tool* t = toolList; + while(t) + { + t->Standby(); + t = t->Next(); + } + heat->Exit(); for(int8_t i = 0; i < HEATERS; i++) { @@ -290,6 +314,84 @@ void RepRap::EmergencyStop() webserver->HandleReply("Emergency Stop! Reset the controller to continue.", false); } +void RepRap::AddTool(Tool* t) +{ + if(toolList == NULL) + { + toolList = t; + return; + } + + toolList->AddTool(t); +} + +void RepRap::SelectTool(int toolNumber) +{ + Tool* t = toolList; + + while(t) + { + if(t->Number() == toolNumber) + { + t->Activate(currentTool); + currentTool = t; + return; + } + t = t->Next(); + } + + platform->Message(HOST_MESSAGE, "Attempt to select and activate a non-existent tool.\n"); +} + +void RepRap::StandbyTool(int toolNumber) +{ + Tool* t = toolList; + + while(t) + { + if(t->Number() == toolNumber) + { + t->Standby(); + if(currentTool == t) + currentTool = NULL; + return; + } + t = t->Next(); + } + + platform->Message(HOST_MESSAGE, "Attempt to standby a non-existent tool.\n"); +} + +void RepRap::SetToolVariables(int toolNumber, float x, float y, float z, float* standbyTemperatures, float* activeTemperatures) +{ + Tool* t = toolList; + + while(t) + { + if(t->Number() == toolNumber) + { + t->SetVariables(x, y, z, standbyTemperatures, activeTemperatures); + return; + } + t = t->Next(); + } + platform->Message(HOST_MESSAGE, "Attempt to set-up a non-existent tool.\n"); +} + +void RepRap::GetCurrentToolOffset(float& x, float& y, float& z) +{ + if(currentTool == NULL) + { + platform->Message(HOST_MESSAGE, "Attempt to get offset when no tool selected.\n"); + x = 0.0; + y = 0.0; + z = 0.0; + return; + } + currentTool->GetOffset(x, y, z); +} + + void RepRap::Tick() { if (active) @@ -306,7 +408,6 @@ void RepRap::Tick() { platform->SetHeater(i, 0.0); } - for(uint8_t i = 0; i < DRIVES; i++) { platform->Disable(i); @@ -324,6 +425,7 @@ void RepRap::Tick() // 1 = debug on // other = print stats and run code-specific tests void RepRap::SetDebug(int d) + { switch(d) { diff --git a/RepRapFirmware.h b/RepRapFirmware.h index b8dccc5..3612156 100644 --- a/RepRapFirmware.h +++ b/RepRapFirmware.h @@ -35,15 +35,16 @@ class Webserver; class GCodes; class Move; class Heat; +class Tool; class RepRap; class FileStore; // A single instance of the RepRap class contains all the others - + extern RepRap reprap; - + // Functions and globals not part of any class - + void debugPrintf(const char* fmt, ...); int sncatf(char *dst, size_t len, const char* fmt, ...); #if 0 // no longer used @@ -53,7 +54,7 @@ bool StringEndsWith(const char* string, const char* ending); bool StringStartsWith(const char* string, const char* starting); bool StringEquals(const char* s1, const char* s2); 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])) // Macro to give us the highest valid index into an array i.e. one less than the size @@ -69,6 +70,7 @@ extern char scratchString[]; #include "GCodes.h" #include "Move.h" #include "Heat.h" +#include "Tool.h" #include "Reprap.h" // std::min and std::max don't seem to work with this variant of gcc, so define our own ones here diff --git a/Reprap.h b/Reprap.h index d3ef66c..6fa153e 100644 --- a/Reprap.h +++ b/Reprap.h @@ -34,6 +34,11 @@ class RepRap void Diagnostics(); bool Debug() const; void SetDebug(int d); + void AddTool(Tool* t); + void SelectTool(int toolNumber); + void StandbyTool(int toolNumber); + void SetToolVariables(int toolNumber, float x, float y, float z, float* standbyTemperatures, float* activeTemperatures); + void GetCurrentToolOffset(float& x, float& y, float& z); Platform* GetPlatform() const; Move* GetMove() const; Heat* GetHeat() const; @@ -52,9 +57,13 @@ class RepRap Heat* heat; GCodes* gCodes; Webserver* webserver; + Tool* toolList; + Tool* currentTool; uint16_t ticksInSpinState; uint8_t spinState; bool debug; + float fastLoop, slowLoop; + float lastTime; bool stopped; bool active; bool resetting; @@ -71,7 +80,6 @@ inline void RepRap::Interrupt() { move->Interrupt(); } inline bool RepRap::IsStopped() const { return stopped; } inline uint16_t RepRap::GetTicksInSpinState() const { return ticksInSpinState; } - #endif diff --git a/Tool.cpp b/Tool.cpp new file mode 100644 index 0000000..1988db5 --- /dev/null +++ b/Tool.cpp @@ -0,0 +1,107 @@ +/**************************************************************************************************** + +RepRapFirmware - Tool + +This class implements a tool in the RepRap machine, usually (though not necessarily) an extruder. + +Tools may have zero or more drives associated with them and zero or more heaters. There are a fixed number +of tools in a given RepRap, with fixed heaters and drives. All this is specified on reboot, and cannot +be altered dynamically. This restriction may be lifted in the future. Tool descriptions are stored in +GCode macros that are loaded on reboot. + +----------------------------------------------------------------------------------------------------- + +Version 0.1 + +Created on: Apr 11, 2014 + +Adrian Bowyer +RepRap Professional Ltd +http://reprappro.com + +Licence: GPL + +****************************************************************************************************/ + +#include "RepRapFirmware.h" + +Tool::Tool(int tNum, int d[], int h[]) +{ + myNumber = tNum; + next = NULL; + active = false; + + for(driveCount = 0; driveCount < DRIVES; driveCount++) + if(d[driveCount] < 0) + break; + if(driveCount > 0) + { + drives = new int[driveCount]; + for(int8_t drive = 0; drive < driveCount; drive++) + drives[drive] = d[drive]; + } + + for(heaterCount = 0; heaterCount < HEATERS; heaterCount++) + if(h[heaterCount] < 0) + break; + if(heaterCount > 0) + { + heaters = new int[heaterCount]; + for(int8_t heater = 0; heater < heaterCount; heater++) + heaters[heater] = h[heater]; + } + + x = 0.0; + y = 0.0; + z = 0.0; +} + +// Add a tool to the end of the linked list. +// (We must already be in it.) + +void Tool::AddTool(Tool* t) +{ + Tool* last = this; + Tool* n = next; + while(n) + { + last = n; + n = Next(); + } + t->next = NULL; // Defensive... + last->next = t; +} + +void Tool::Activate(Tool* currentlyActive) +{ + if(active) + return; + if(currentlyActive) + currentlyActive->Standby(); + for(int8_t heater = 0; heater < heaterCount; heater++) + reprap.GetHeat()->Activate(heaters[heater]); + active = true; +} + +void Tool::Standby() +{ + if(!active) + return; + for(int8_t heater = 0; heater < heaterCount; heater++) + reprap.GetHeat()->Standby(heaters[heater]); + active = false; +} + +void Tool::SetVariables(float xx, float yy, float zz, float* standbyTemperatures, float* activeTemperatures) +{ + x = xx; + y = yy; + z = zz; + for(int8_t heater = 0; heater < heaterCount; heater++) + { + reprap.GetHeat()->SetActiveTemperature(heaters[heater], activeTemperatures[heater]); + reprap.GetHeat()->SetStandbyTemperature(heaters[heater], standbyTemperatures[heater]); + } +} + + diff --git a/Tool.h b/Tool.h new file mode 100644 index 0000000..adad081 --- /dev/null +++ b/Tool.h @@ -0,0 +1,78 @@ +/**************************************************************************************************** + +RepRapFirmware - Tool + +This class implements a tool in the RepRap machine, usually (though not necessarily) an extruder. + +Tools may have zero or more drives associated with them and zero or more heaters. There are a fixed number +of tools in a given RepRap, with fixed heaters and drives. All this is specified on reboot, and cannot +be altered dynamically. This restriction may be lifted in the future. Tool descriptions are stored in +GCode macros that are loaded on reboot. + +----------------------------------------------------------------------------------------------------- + +Version 0.1 + +Created on: Apr 11, 2014 + +Adrian Bowyer +RepRap Professional Ltd +http://reprappro.com + +Licence: GPL + +****************************************************************************************************/ + +#ifndef TOOL_H_ +#define TOOL_H_ + +class Tool +{ +public: + + Tool(int tNum, int d[], int h[]); + + friend class RepRap; + +protected: + + Tool* Next(); + int Number(); + void Activate(Tool* currentlyActive); + void Standby(); + void AddTool(Tool* t); + void SetVariables(float xx, float yy, float zz, float* standbyTemperatures, float* activeTemperatures); + void GetOffset(float& xx, float& yy, float& zz); + +private: + + int myNumber; + int* drives; + int driveCount; + int* heaters; + int heaterCount; + Tool* next; + float x, y, z; + bool active; +}; + +inline Tool* Tool::Next() +{ + return next; +} + +inline int Tool::Number() +{ + return myNumber; +} + +inline void Tool::GetOffset(float& xx, float& yy, float& zz) +{ + xx = x; + yy = y; + zz = z; +} + + + +#endif /* TOOL_H_ */