Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/FilamentMonitors/FilamentMonitor.cpp')
-rw-r--r--src/FilamentMonitors/FilamentMonitor.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/src/FilamentMonitors/FilamentMonitor.cpp b/src/FilamentMonitors/FilamentMonitor.cpp
new file mode 100644
index 00000000..4d370bea
--- /dev/null
+++ b/src/FilamentMonitors/FilamentMonitor.cpp
@@ -0,0 +1,182 @@
+/*
+ * FilamentSensor.cpp
+ *
+ * Created on: 20 Jul 2017
+ * Author: David
+ */
+
+#include "FilamentMonitor.h"
+#include "SimpleFilamentMonitor.h"
+#include "RotatingMagnetFilamentMonitor.h"
+#include "LaserFilamentMonitor.h"
+#include "PulsedFilamentMonitor.h"
+#include "RepRap.h"
+#include "Platform.h"
+#include "GCodes/GCodeBuffer.h"
+#include "Movement/Move.h"
+#include "PrintMonitor.h"
+
+// Static data
+FilamentMonitor *FilamentMonitor::filamentSensors[MaxExtruders] = { 0 };
+
+// Default destructor
+FilamentMonitor::~FilamentMonitor()
+{
+ if (pin != NoPin)
+ {
+ detachInterrupt(pin);
+ }
+}
+
+// Try to get the pin number from the GCode command in the buffer, setting Seen if a pin number was provided and returning true if error.
+// Also attaches the ISR.
+bool FilamentMonitor::ConfigurePin(GCodeBuffer& gb, StringRef& reply, uint32_t interruptMode, bool& seen)
+{
+ if (gb.Seen('C'))
+ {
+ seen = true;
+ // The C parameter is an endstop number in RRF
+ const int endstop = gb.GetIValue();
+ const Pin p = reprap.GetPlatform().GetEndstopPin(endstop);
+ if (p == NoPin)
+ {
+ reply.copy("bad endstop number");
+ return true;
+ }
+ endstopNumber = endstop;
+ pin = p;
+ attachInterrupt(pin, InterruptEntry, interruptMode, this);
+ }
+ else if (seen)
+ {
+ // We already had a P parameter, therefore it is an error not to have a C parameter too
+ reply.copy("no endstop number given");
+ return true;
+ }
+ return false;
+}
+
+// Factory function
+/*static*/ FilamentMonitor *FilamentMonitor::Create(int type)
+{
+ switch (type)
+ {
+ case 1: // active high switch
+ case 2: // active low switch
+ return new SimpleFilamentMonitor(type);
+ break;
+
+ case 3: // duet3d rotating magnet, no switch
+ case 4: // duet3d rotating magnet + switch
+ return new RotatingMagnetFilamentMonitor(type);
+
+ case 5: // duet3d laser, no switch
+ case 6: // duet3d laser + switch
+ return new LaserFilamentMonitor(type);
+
+ case 7: // simple pulse output sensor
+ return new PulsedFilamentMonitor(type);
+ break;
+
+ default: // no sensor, or unknown sensor
+ return nullptr;
+ }
+}
+
+// Return an error message corresponding to a status code
+/*static*/ const char *FilamentMonitor::GetErrorMessage(FilamentSensorStatus f)
+{
+ switch(f)
+ {
+ case FilamentSensorStatus::ok: return "no error";
+ case FilamentSensorStatus::noFilament: return "no filament";
+ case FilamentSensorStatus::tooLittleMovement: return "too little movement";
+ case FilamentSensorStatus::tooMuchMovement: return "too much movement";
+ case FilamentSensorStatus::sensorError: return "sensor not working";
+ default: return "unknown error";
+ }
+}
+
+// ISR
+/*static*/ void FilamentMonitor::InterruptEntry(CallbackParameter param)
+{
+ static_cast<FilamentMonitor*>(param.vp)->Interrupt();
+}
+
+/*static*/ void FilamentMonitor::Spin(bool full)
+{
+ // Filament sensors
+ for (size_t extruder = 0; extruder < MaxExtruders; ++extruder)
+ {
+ if (filamentSensors[extruder] != nullptr)
+ {
+ GCodes& gCodes = reprap.GetGCodes();
+ bool wasNonPrinting;
+ const int32_t extruderStepsCommanded = reprap.GetMove().GetAccumulatedExtrusion(extruder, wasNonPrinting); // get and clear the net extrusion commanded
+ if (gCodes.IsReallyPrinting() && !gCodes.IsSimulating())
+ {
+ const float extrusionCommanded = (float)extruderStepsCommanded/reprap.GetPlatform().DriveStepsPerUnit(extruder + gCodes.GetTotalAxes());
+ const FilamentSensorStatus fstat = filamentSensors[extruder]->Check(full, wasNonPrinting, extrusionCommanded);
+ if (full && fstat != FilamentSensorStatus::ok && extrusionCommanded > 0.0)
+ {
+ if (reprap.Debug(moduleFilamentSensors))
+ {
+ debugPrintf("Filament error: extruder %u reports %s\n", extruder, FilamentMonitor::GetErrorMessage(fstat));
+ }
+ else
+ {
+ gCodes.FilamentError(extruder, fstat);
+ }
+ }
+ }
+ else
+ {
+ filamentSensors[extruder]->Clear(full);
+ }
+ }
+ }
+}
+
+// Return the filament sensor associated with a particular extruder
+/*static*/ FilamentMonitor *FilamentMonitor::GetFilamentSensor(unsigned int extruder)
+{
+ return (extruder < MaxExtruders) ? filamentSensors[extruder] : nullptr;
+}
+
+// Set the filament sensor associated with a particular extruder
+/*static*/ bool FilamentMonitor::SetFilamentSensorType(unsigned int extruder, int newSensorType)
+{
+ if (extruder < MaxExtruders)
+ {
+ FilamentMonitor*& sensor = filamentSensors[extruder];
+ const int oldSensorType = (sensor == nullptr) ? 0 : sensor->GetType();
+ if (newSensorType != oldSensorType)
+ {
+ delete sensor;
+ sensor = Create(newSensorType);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Send diagnostics info
+/*static*/ void FilamentMonitor::Diagnostics(MessageType mtype)
+{
+ bool first = true;
+ for (size_t i = 0; i < MaxExtruders; ++i)
+ {
+ if (filamentSensors[i] != nullptr)
+ {
+ if (first)
+ {
+ reprap.GetPlatform().Message(mtype, "=== Filament sensors ===\n");
+ first = false;
+ }
+ filamentSensors[i]->Diagnostics(mtype, i);
+ }
+ }
+}
+
+// End