diff options
author | David Crocker <dcrocker@eschertech.com> | 2017-08-14 21:41:49 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2017-08-14 21:41:49 +0300 |
commit | f8507434bd770432a2b424af28dd42057996cdf3 (patch) | |
tree | e299a71367bca733f79b34f1b6765c8359462ca8 | |
parent | ba7778b3e6f278fed1f5d30d31ed2a2a8be7369c (diff) |
Version 1.19 releasev1.19
Fixed some filament sensor issues
43 files changed, 457 insertions, 287 deletions
diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19RC5.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19RC5.bin Binary files differdeleted file mode 100644 index e2d0fa87..00000000 --- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19RC5.bin +++ /dev/null diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19RC6.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19RC6.bin Binary files differdeleted file mode 100644 index c5887fd6..00000000 --- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19RC6.bin +++ /dev/null diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19beta11.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19beta11.bin Binary files differdeleted file mode 100644 index 1960fe9e..00000000 --- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.19beta11.bin +++ /dev/null diff --git a/Release/Duet-0.6-0.8.5/Stable/DuetWebControl-1.15a.zip b/Release/Duet-0.6-0.8.5/Stable/DuetWebControl-1.15a.zip Binary files differdeleted file mode 100644 index ae0e45b0..00000000 --- a/Release/Duet-0.6-0.8.5/Stable/DuetWebControl-1.15a.zip +++ /dev/null diff --git a/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.19-RC1.zip b/Release/Duet-0.6-0.8.5/Stable/DuetWebControl-1.19.zip Binary files differindex 06ffd580..c229a53d 100644 --- a/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.19-RC1.zip +++ b/Release/Duet-0.6-0.8.5/Stable/DuetWebControl-1.19.zip diff --git a/Release/Duet-0.6-0.8.5/Stable/RepRapFirmware-1.18.1.bin b/Release/Duet-0.6-0.8.5/Stable/RepRapFirmware-1.18.1.bin Binary files differdeleted file mode 100644 index 380e50a4..00000000 --- a/Release/Duet-0.6-0.8.5/Stable/RepRapFirmware-1.18.1.bin +++ /dev/null diff --git a/Release/Duet-0.6-0.8.5/Stable/RepRapFirmware-1.19.bin b/Release/Duet-0.6-0.8.5/Stable/RepRapFirmware-1.19.bin Binary files differnew file mode 100644 index 00000000..26c9f89d --- /dev/null +++ b/Release/Duet-0.6-0.8.5/Stable/RepRapFirmware-1.19.bin diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC5.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC5.bin Binary files differdeleted file mode 100644 index 67201339..00000000 --- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC5.bin +++ /dev/null diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC6.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC6.bin Binary files differdeleted file mode 100644 index adef2b0b..00000000 --- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC6.bin +++ /dev/null diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19beta11.bin b/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19beta11.bin Binary files differdeleted file mode 100644 index 3a3ac15c..00000000 --- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19beta11.bin +++ /dev/null diff --git a/Release/Duet-Ethernet/Stable/DuetEthernetFirmware-1.18.1.bin b/Release/Duet-Ethernet/Stable/DuetEthernetFirmware-1.18.1.bin Binary files differdeleted file mode 100644 index 8bc491cd..00000000 --- a/Release/Duet-Ethernet/Stable/DuetEthernetFirmware-1.18.1.bin +++ /dev/null diff --git a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC7.bin b/Release/Duet-Ethernet/Stable/DuetEthernetFirmware-1.19.bin Binary files differindex bdf220f2..65a4cf94 100644 --- a/Release/Duet-Ethernet/Edge/DuetEthernetFirmware-1.19RC7.bin +++ b/Release/Duet-Ethernet/Stable/DuetEthernetFirmware-1.19.bin diff --git a/Release/Duet-Ethernet/Stable/DuetWebControl-1.15a.zip b/Release/Duet-Ethernet/Stable/DuetWebControl-1.15a.zip Binary files differdeleted file mode 100644 index ae0e45b0..00000000 --- a/Release/Duet-Ethernet/Stable/DuetWebControl-1.15a.zip +++ /dev/null diff --git a/Release/Duet-Ethernet/Edge/DuetWebControl-1.19-RC1.zip b/Release/Duet-Ethernet/Stable/DuetWebControl-1.19.zip Binary files differindex 06ffd580..c229a53d 100644 --- a/Release/Duet-Ethernet/Edge/DuetWebControl-1.19-RC1.zip +++ b/Release/Duet-Ethernet/Stable/DuetWebControl-1.19.zip diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC5.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC5.bin Binary files differdeleted file mode 100644 index 4bb34293..00000000 --- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC5.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC6.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC6.bin Binary files differdeleted file mode 100644 index 0cb0566e..00000000 --- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC6.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19beta11.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19beta11.bin Binary files differdeleted file mode 100644 index a0e9ea01..00000000 --- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19beta11.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Stable/DuetWebControl-1.15a.bin b/Release/Duet-WiFi/Stable/DuetWebControl-1.15a.bin Binary files differdeleted file mode 100644 index 80327997..00000000 --- a/Release/Duet-WiFi/Stable/DuetWebControl-1.15a.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWebControl-1.19-RC1.zip b/Release/Duet-WiFi/Stable/DuetWebControl-1.19.zip Binary files differindex 06ffd580..c229a53d 100644 --- a/Release/Duet-WiFi/Edge/DuetWebControl-1.19-RC1.zip +++ b/Release/Duet-WiFi/Stable/DuetWebControl-1.19.zip diff --git a/Release/Duet-WiFi/Stable/DuetWiFiFirmware-1.18.1.bin b/Release/Duet-WiFi/Stable/DuetWiFiFirmware-1.18.1.bin Binary files differdeleted file mode 100644 index b8c37593..00000000 --- a/Release/Duet-WiFi/Stable/DuetWiFiFirmware-1.18.1.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC7.bin b/Release/Duet-WiFi/Stable/DuetWiFiFirmware-1.19.bin Binary files differindex 85c76f85..236b696f 100644 --- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.19RC7.bin +++ b/Release/Duet-WiFi/Stable/DuetWiFiFirmware-1.19.bin diff --git a/Release/Duet-WiFi/Stable/DuetWiFiServer-1.03-ch.bin b/Release/Duet-WiFi/Stable/DuetWiFiServer-1.03-ch.bin Binary files differdeleted file mode 100644 index 5c8270b9..00000000 --- a/Release/Duet-WiFi/Stable/DuetWiFiServer-1.03-ch.bin +++ /dev/null diff --git a/Release/Duet-WiFi/Edge/DuetWiFiServer-1.19beta10.bin b/Release/Duet-WiFi/Stable/DuetWiFiServer-1.19.bin Binary files differindex fe287ffa..ce9dccc7 100644 --- a/Release/Duet-WiFi/Edge/DuetWiFiServer-1.19beta10.bin +++ b/Release/Duet-WiFi/Stable/DuetWiFiServer-1.19.bin diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17d.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17d.bin Binary files differdeleted file mode 100644 index ac2a728c..00000000 --- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.17d.bin +++ /dev/null diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19.bin Binary files differnew file mode 100644 index 00000000..c089d2c0 --- /dev/null +++ b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19.bin diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19RC5.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19RC5.bin Binary files differdeleted file mode 100644 index c6bdda81..00000000 --- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19RC5.bin +++ /dev/null diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19RC6.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19RC6.bin Binary files differdeleted file mode 100644 index 4106443e..00000000 --- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19RC6.bin +++ /dev/null diff --git a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19beta11.bin b/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19beta11.bin Binary files differdeleted file mode 100644 index 32b69381..00000000 --- a/Release/RADDS/Edge/RepRapFirmware-RADDS-1.19beta11.bin +++ /dev/null diff --git a/src/FilamentSensors/Duet3DFilamentSensor.cpp b/src/FilamentSensors/Duet3DFilamentSensor.cpp index 29e65c65..e5874bd0 100644 --- a/src/FilamentSensors/Duet3DFilamentSensor.cpp +++ b/src/FilamentSensors/Duet3DFilamentSensor.cpp @@ -13,10 +13,21 @@ // Constructors Duet3DFilamentSensor::Duet3DFilamentSensor(int type) : FilamentSensor(type), mmPerRev(DefaultMmPerRev), - tolerance(DefaultTolerance), absTolerance(DefaultAbsTolerance), minimumExtrusionCheckLength(DefaultMinimumExtrusionCheckLength), withSwitch(type == 4), - sensorValue(0), accumulatedExtrusionCommanded(0.0), accumulatedExtrusionMeasured(0.0), extrusionCommandedAtLastMeasurement(0.0),tentativeExtrusionCommanded(0.0), - numberOfEdgesCaptured(0), lastMeasurementTime(0), state(RxdState::waitingForStartBit), samplesReceived(0) + tolerance(DefaultTolerance), minimumExtrusionCheckLength(DefaultMinimumExtrusionCheckLength), withSwitch(type == 4) { + Init(); +} + +void Duet3DFilamentSensor::Init() +{ + samplesReceived = 0; + sensorValue = 0; + calibrationStarted = comparisonStarted = dataReceived = false; + edgeCaptureReadPointer = edgeCaptureWritePointer = 1; + edgeCaptures[0] = Platform::GetInterruptClocks(); // assume we just had a high-to-low transition + lastMeasurementTime = 0; + accumulatedExtrusionCommanded = accumulatedRevsMeasured = extrusionCommandedAtLastMeasurement = tentativeExtrusionCommanded = 0.0; + state = RxdState::waitingForStartBit; } // Configure this sensor, returning true if error and setting 'seen' if we processed any configuration parameters @@ -28,32 +39,22 @@ bool Duet3DFilamentSensor::Configure(GCodeBuffer& gb, StringRef& reply, bool& se } gb.TryGetFValue('S', mmPerRev, seen); - gb.TryGetFValue('T', absTolerance, seen); gb.TryGetFValue('E', minimumExtrusionCheckLength, seen); if (gb.Seen('R')) { seen = true; - const float tol = gb.GetFValue(); - if (tolerance < 0.0 || tolerance >= 100.0) - { - reply.copy("Relative tolerance must be between 0 and 100%"); - return true; - } - tolerance = tol * 0.01; + tolerance = gb.GetFValue() * 0.01; } if (seen) { - samplesReceived = 0; - numberOfEdgesCaptured = 0; - lastMeasurementTime = 0; - accumulatedExtrusionCommanded = accumulatedExtrusionMeasured = extrusionCommandedAtLastMeasurement = tentativeExtrusionCommanded = 0.0; + Init(); } else { - reply.printf("Duet3D filament sensor on endstop %u, %s microswitch, %.1fmm per rev, check every %.1fmm, tolerance %.1f%% + %.1fmm, current angle %.1f", - GetEndstopNumber(), (withSwitch) ? "with" : "no", mmPerRev, minimumExtrusionCheckLength, tolerance * 100.0, absTolerance, GetCurrentAngle()); + reply.printf("Duet3D filament sensor on endstop %u, %s microswitch, %.1fmm per rev, check every %.1fmm, tolerance %.1f%%, current angle %.1f", + GetEndstopNumber(), (withSwitch) ? "with" : "no", mmPerRev, minimumExtrusionCheckLength, tolerance * 100.0, GetCurrentAngle()); } return false; @@ -62,12 +63,29 @@ bool Duet3DFilamentSensor::Configure(GCodeBuffer& gb, StringRef& reply, bool& se // ISR for when the pin state changes void Duet3DFilamentSensor::Interrupt() { - const size_t numEdgesCaptured = numberOfEdgesCaptured; // capture volatile variable - if (numEdgesCaptured < MaxEdgeCaptures && (numEdgesCaptured % 2u) != (unsigned int)Platform::ReadPin(GetPin())) // low-to-high transitions must be stored at even indices + uint32_t now = Platform::GetInterruptClocks(); + const size_t writePointer = edgeCaptureWritePointer; // capture volatile variable + if ((writePointer + 1) % EdgeCaptureBufferSize != edgeCaptureReadPointer) { - edgeCaptures[numEdgesCaptured] = Platform::GetInterruptClocks(); // record the time at which this edge was detected - numberOfEdgesCaptured = numEdgesCaptured + 1; + if (Platform::ReadPin(GetPin())) + { + if ((writePointer & 1) == 0) // low-to-high transitions should occur on odd indices + { + return; + } + } + else + { + if ((writePointer & 1) != 0) // high-to-low transitions should occur on even indices + { + return; + } + now -= 40; // partial correction for skew caused by debounce filter on Duet endstop inputs (measured skew = 74) + } } + + edgeCaptures[writePointer] = now; // record the time at which this edge was detected + edgeCaptureWritePointer = (writePointer + 1) % EdgeCaptureBufferSize; } // Call the following regularly to keep the status up to date @@ -77,105 +95,161 @@ void Duet3DFilamentSensor::Poll() static const uint32_t NominalBitLength = DDA::stepClockRate/BitsPerSecond; static const uint32_t MinBitLength = (NominalBitLength * 10)/13; // allow 30% clock speed tolerance static const uint32_t MaxBitLength = (NominalBitLength * 13)/10; // allow 30% clock speed tolerance - static const uint32_t ErrorRecoveryDelayBits = 12; // after an error we wait for the line to be low for this long + static const uint32_t ErrorRecoveryDelayBits = 8; // before a start bit we want the line to be low for this long static const uint32_t ErrorRecoveryTime = NominalBitLength * ErrorRecoveryDelayBits; - const size_t numEdgesCaptured = numberOfEdgesCaptured; // capture volatile variable - const uint32_t now = Platform::GetInterruptClocks(); - switch (state) + bool again; + do { - case RxdState::waitingForStartBit: - if (numEdgesCaptured >= 2) + again = false; + const size_t writePointer = edgeCaptureWritePointer; // capture volatile variable + const uint32_t now = Platform::GetInterruptClocks(); + switch (state) { - // Check for a valid start bit - startBitLength = edgeCaptures[1] - edgeCaptures[0]; - if (startBitLength >= MinBitLength && startBitLength <= MaxBitLength) + case RxdState::waitingForStartBit: + if ((edgeCaptureReadPointer & 1u) == 0) // if we are out of sync (this is normal when the last stuffing bit was a 1) { - bitChangeIndex = 2; - valueBeingAssembled = 0; - nibblesAssembled = 0; - tentativeExtrusionCommanded = accumulatedExtrusionCommanded; - state = RxdState::waitingForNibble; + if (edgeCaptureReadPointer != edgeCaptureWritePointer) + { + edgeCaptureReadPointer = (edgeCaptureReadPointer + 1) % EdgeCaptureBufferSize; + again = true; + } } - else + else if (writePointer != edgeCaptureReadPointer) { - state = RxdState::errorRecovery; + if (edgeCaptures[edgeCaptureReadPointer] - edgeCaptures[(edgeCaptureReadPointer - 1) % EdgeCaptureBufferSize] < ErrorRecoveryTime) + { + // The input line has not been low for long enough before the start bit + edgeCaptureReadPointer = (edgeCaptureReadPointer + 1) % EdgeCaptureBufferSize; + state = RxdState::errorRecovery1; + again = true; + } + else + { + tentativeExtrusionCommanded = accumulatedExtrusionCommanded; // we have received what could be the beginning of a start bit + state = RxdState::waitingForEndOfStartBit; + again = true; + } } - } - break; + break; - case RxdState::waitingForNibble: - { - const uint32_t nibbleStartTime = edgeCaptures[bitChangeIndex - 1]; - if (now - nibbleStartTime > (13 * startBitLength)/2) + case RxdState::waitingForEndOfStartBit: + // This state must time out because while we are in it, comparison of filament extruded is suspended + if ((writePointer - edgeCaptureReadPointer) % EdgeCaptureBufferSize >= 2) { - // 6.5 bit times have passed since the start of the bit that preceded the current nibble, so we should have a complete nibble and the following stuffing bit - uint32_t samplePoint = (startBitLength * 3)/2; // sampling time after the end of the start bit for bit 7 (MSB) - uint8_t currentNibble = 0; - for (uint8_t numBits = 0; numBits < 5; ++numBits) + // Check for a valid start bit + lastBitChangeIndex = (edgeCaptureReadPointer + 1u) % EdgeCaptureBufferSize; + startBitLength = edgeCaptures[lastBitChangeIndex] - edgeCaptures[edgeCaptureReadPointer]; + if (startBitLength >= MinBitLength && startBitLength <= MaxBitLength) { - if (bitChangeIndex < numEdgesCaptured && edgeCaptures[bitChangeIndex] - nibbleStartTime < samplePoint) + valueBeingAssembled = 0; + nibblesAssembled = 0; + edgeCaptureReadPointer = lastBitChangeIndex; + state = RxdState::waitingForNibble; + again = true; + //debugPrintf("sb %u\n", startBitLength); + } + else + { + edgeCaptureReadPointer = (edgeCaptureReadPointer + 2) % EdgeCaptureBufferSize; + state = RxdState::errorRecovery2; + again = true; + } + } + else if (now - edgeCaptures[edgeCaptureReadPointer] > MaxBitLength) + { + state = RxdState::errorRecovery2; + again = true; + } + break; + + case RxdState::waitingForNibble: + // This state must time out because while we are in it, comparison of filament extruded is suspended + { + const uint32_t nibbleStartTime = edgeCaptures[lastBitChangeIndex]; + if (now - nibbleStartTime > (13 * startBitLength)/2) + { + // 6.5 bit times have passed since the start of the bit that preceded the current nibble, so we should have a complete nibble and the following stuffing bit + uint32_t samplePoint = (startBitLength * 3)/2; // sampling time after the end of the start bit for bit 7 (MSB) + uint8_t currentNibble = 0; + size_t nextBitChangeIndex = (lastBitChangeIndex + 1) % EdgeCaptureBufferSize; + for (uint8_t numBits = 0; numBits < 5; ++numBits) { - ++bitChangeIndex; - if (bitChangeIndex < numEdgesCaptured && edgeCaptures[bitChangeIndex] - nibbleStartTime < samplePoint) + if (nextBitChangeIndex != edgeCaptureWritePointer && edgeCaptures[nextBitChangeIndex] - nibbleStartTime < samplePoint) { - state = RxdState::errorRecovery; // there should be at most 1 transition per bit - return; + lastBitChangeIndex = nextBitChangeIndex; + nextBitChangeIndex = (lastBitChangeIndex + 1) % EdgeCaptureBufferSize; + if (nextBitChangeIndex != writePointer && edgeCaptures[nextBitChangeIndex] - nibbleStartTime < samplePoint) + { + edgeCaptureReadPointer = nextBitChangeIndex; + state = RxdState::errorRecovery3; + again = true; + break; + } } + currentNibble <<= 1; + currentNibble |= (uint8_t)(lastBitChangeIndex & 1u); + samplePoint += startBitLength; } - currentNibble <<= 1; - if ((bitChangeIndex & 1u) != 0) + + if (state != RxdState::waitingForNibble) { - currentNibble |= 1u; + break; } - samplePoint += startBitLength; - } - // The 5th bit we received should be the inverse of the 4th bit - if ((((currentNibble >> 1u) ^ currentNibble) & 0x01u) == 0) - { - state = RxdState::errorRecovery; - return; - } - - currentNibble >>= 1; - valueBeingAssembled = (valueBeingAssembled << 4) | currentNibble; - ++nibblesAssembled; - if (nibblesAssembled == 4) - { - numberOfEdgesCaptured = 0; // ready for a new byte - if (samplesReceived != 0) + // The 5th bit we received should be the inverse of the 4th bit + if ((((currentNibble >> 1u) ^ currentNibble) & 0x01u) == 0) { - const uint16_t angleChange = (valueBeingAssembled - sensorValue) & AngleMask; // angle change in range 0..1023 - const int32_t movement = (angleChange <= 512) ? (int32_t)angleChange : (int32_t)angleChange - 1024; - accumulatedExtrusionMeasured += (float)movement * mmPerRev * (1.0/1024.0); + edgeCaptureReadPointer = nextBitChangeIndex; + state = RxdState::errorRecovery4; + again = true; + break; } - lastMeasurementTime = millis(); - extrusionCommandedAtLastMeasurement = tentativeExtrusionCommanded; - sensorValue = valueBeingAssembled; - if (samplesReceived < 100) + currentNibble >>= 1; + valueBeingAssembled = (valueBeingAssembled << 4) | currentNibble; + ++nibblesAssembled; + if (nibblesAssembled == 4) { - ++samplesReceived; + edgeCaptureReadPointer = nextBitChangeIndex; // ready for a new word + if (samplesReceived == 0) + { + dataReceived = true; + accumulatedExtrusionCommanded -= tentativeExtrusionCommanded; + accumulatedRevsMeasured = 0.0; // use the first measurement sample as a baseline + } + else + { + const uint16_t angleChange = (valueBeingAssembled - sensorValue) & AngleMask; // angle change in range 0..1023 + const int32_t movement = (angleChange <= 512) ? (int32_t)angleChange : (int32_t)angleChange - 1024; + accumulatedRevsMeasured += (float)movement/1024; + } + + lastMeasurementTime = millis(); + extrusionCommandedAtLastMeasurement = tentativeExtrusionCommanded; + sensorValue = valueBeingAssembled; + if (samplesReceived < 100) + { + ++samplesReceived; + } + edgeCaptureReadPointer = nextBitChangeIndex; + state = RxdState::waitingForStartBit; } - state = RxdState::waitingForStartBit; + again = true; } } - } - break; + break; - case RxdState::errorRecovery: - if (Platform::ReadPin(GetPin()) || numEdgesCaptured != 0) // when we first enter this state, numEdgesCaptured is always nonzero - { - errorRecoveryStartTime = now; - numberOfEdgesCaptured = 0; - } - else if (now - errorRecoveryStartTime >= ErrorRecoveryTime) - { + default: // error recovery states + if (reprap.Debug(moduleFilamentSensors)) + { + debugPrintf("Fil err %u\n", (unsigned int)state); + } state = RxdState::waitingForStartBit; + again = true; + break; } - break; - } + } while (again); } // Return the current wheel angle @@ -186,29 +260,32 @@ float Duet3DFilamentSensor::GetCurrentAngle() const // Call the following at intervals to check the status. This is only called when extrusion is in progress or imminent. // 'filamentConsumed' is the net amount of extrusion since the last call to this function. -FilamentSensorStatus Duet3DFilamentSensor::Check(float filamentConsumed) +FilamentSensorStatus Duet3DFilamentSensor::Check(bool full, float filamentConsumed) { accumulatedExtrusionCommanded += filamentConsumed; Poll(); FilamentSensorStatus ret = FilamentSensorStatus::ok; - if ((sensorValue & ErrorBit) != 0) - { - ret = FilamentSensorStatus::sensorError; - } - else if (withSwitch && (sensorValue & SwitchOpenBit) != 0) + if (full) { - ret = FilamentSensorStatus::noFilament; - } - else if (samplesReceived >= 10) - { - if (extrusionCommandedAtLastMeasurement >= minimumExtrusionCheckLength) + if ((sensorValue & ErrorBit) != 0) { - ret = CheckFilament(extrusionCommandedAtLastMeasurement); + ret = FilamentSensorStatus::sensorError; } - else if (accumulatedExtrusionCommanded >= minimumExtrusionCheckLength && millis() - lastMeasurementTime > 110) + else if (withSwitch && (sensorValue & SwitchOpenBit) != 0) { - ret = CheckFilament(accumulatedExtrusionCommanded); + ret = FilamentSensorStatus::noFilament; + } + else if (samplesReceived >= 10 && state != RxdState::waitingForEndOfStartBit && state != RxdState::waitingForNibble) + { + if (extrusionCommandedAtLastMeasurement >= minimumExtrusionCheckLength) + { + ret = CheckFilament(extrusionCommandedAtLastMeasurement, false); + } + else if (accumulatedExtrusionCommanded >= minimumExtrusionCheckLength * 1.1 && millis() - lastMeasurementTime > 110) + { + ret = CheckFilament(accumulatedExtrusionCommanded, true); + } } } @@ -216,55 +293,91 @@ FilamentSensorStatus Duet3DFilamentSensor::Check(float filamentConsumed) } // Compare the amount commanded with the amount of extrusion measured, and set up for the next comparison -FilamentSensorStatus Duet3DFilamentSensor::CheckFilament(float amountCommanded) +FilamentSensorStatus Duet3DFilamentSensor::CheckFilament(float amountCommanded, bool overdue) { + const float extrusionMeasured = accumulatedRevsMeasured * mmPerRev; if (reprap.Debug(moduleFilamentSensors)) { - debugPrintf("Extr req %.3f meas %.3f\n", amountCommanded, accumulatedExtrusionMeasured); + debugPrintf("Extr req %.3f meas %.3f rem %.3f %s\n", amountCommanded, extrusionMeasured, accumulatedExtrusionCommanded - amountCommanded, (overdue) ? " overdue" : ""); } FilamentSensorStatus ret = FilamentSensorStatus::ok; - const float minExtrusionExpected = ( (amountCommanded >= 0.0) - ? amountCommanded * (1.0 - tolerance) - : amountCommanded * (1.0 + tolerance) - ) - - absTolerance; - if (accumulatedExtrusionMeasured < minExtrusionExpected) + if (!comparisonStarted) { - ret = FilamentSensorStatus::tooLittleMovement; + // The first measurement after we start extruding is often a long way out, so discard it + comparisonStarted = true; + calibrationStarted = false; + } + else if (tolerance >= 0.0) + { + const float minExtrusionExpected = (amountCommanded >= 0.0) + ? amountCommanded * (1.0 - tolerance) + : amountCommanded * (1.0 + tolerance); + if (extrusionMeasured < minExtrusionExpected) + { + ret = FilamentSensorStatus::tooLittleMovement; + } + else + { + const float maxExtrusionExpected = (amountCommanded >= 0.0) + ? amountCommanded * (1.0 + tolerance) + : amountCommanded * (1.0 - tolerance); + if (extrusionMeasured > maxExtrusionExpected) + { + ret = FilamentSensorStatus::tooMuchMovement; + } + } } else { - const float maxExtrusionExpected = ( (amountCommanded >= 0.0) - ? amountCommanded * (1.0 + tolerance) - : amountCommanded * (1.0 - tolerance) - ) - + absTolerance; - if (accumulatedExtrusionMeasured > maxExtrusionExpected) + // Tolerance < 0.0 means do calibration + const float ratio = accumulatedRevsMeasured/amountCommanded; + if (calibrationStarted) { - ret = FilamentSensorStatus::tooMuchMovement; + if (ratio < minMovementRatio) + { + minMovementRatio = ratio; + } + if (ratio > maxMovementRatio) + { + maxMovementRatio = ratio; + } + totalExtrusionCommanded += amountCommanded; + totalRevsMeasured += accumulatedRevsMeasured; + } + else + { + minMovementRatio = maxMovementRatio = ratio; + totalExtrusionCommanded = amountCommanded; + totalRevsMeasured = accumulatedRevsMeasured; + calibrationStarted = true; } } - accumulatedExtrusionCommanded -= amountCommanded; - extrusionCommandedAtLastMeasurement = accumulatedExtrusionMeasured = 0.0; + extrusionCommandedAtLastMeasurement = accumulatedRevsMeasured = 0.0; + return ret; } // Clear the measurement state - called when we are not printing a file. Return the present/not present status if available. -FilamentSensorStatus Duet3DFilamentSensor::Clear() +FilamentSensorStatus Duet3DFilamentSensor::Clear(bool full) { Poll(); // to keep the diagnostics up to date - accumulatedExtrusionCommanded = accumulatedExtrusionMeasured = extrusionCommandedAtLastMeasurement = tentativeExtrusionCommanded = 0.0; + accumulatedExtrusionCommanded = accumulatedRevsMeasured = extrusionCommandedAtLastMeasurement = tentativeExtrusionCommanded = 0.0; samplesReceived = 0; + comparisonStarted = false; + FilamentSensorStatus ret = FilamentSensorStatus::ok; - if ((sensorValue & ErrorBit) != 0) + if (full) { - ret = FilamentSensorStatus::sensorError; - } - else if (withSwitch && (sensorValue & SwitchOpenBit) != 0) - { - ret = FilamentSensorStatus::noFilament; + if ((sensorValue & ErrorBit) != 0) + { + ret = FilamentSensorStatus::sensorError; + } + else if (withSwitch && (sensorValue & SwitchOpenBit) != 0) + { + ret = FilamentSensorStatus::noFilament; + } } return ret; } @@ -273,11 +386,23 @@ FilamentSensorStatus Duet3DFilamentSensor::Clear() void Duet3DFilamentSensor::Diagnostics(MessageType mtype, unsigned int extruder) { Poll(); - const char* const statusText = (samplesReceived == 0) ? "no data received" + const char* const statusText = (!dataReceived) ? "no data received" : ((sensorValue & ErrorBit) != 0) ? "error" : (withSwitch && (sensorValue & SwitchOpenBit) != 0) ? "no filament" : "ok"; - reprap.GetPlatform().MessageF(mtype, "Extruder %u sensor: angle %.1f, %s\n", extruder, GetCurrentAngle(), statusText); + reprap.GetPlatform().MessageF(mtype, "Extruder %u sensor: angle %.1f, %s, ", extruder, GetCurrentAngle(), statusText); + if (calibrationStarted && fabs(totalRevsMeasured) > 1.0 && totalExtrusionCommanded > 20.0) + { + const float measuredMmPerRev = totalExtrusionCommanded/totalRevsMeasured; + const float normalRatio = 1.0/measuredMmPerRev; + const int measuredPosTolerance = lrintf(100.0 * (((normalRatio > 0.0) ? maxMovementRatio : minMovementRatio) - normalRatio)/normalRatio); + const int measuredNegTolerance = lrintf(100.0 * (normalRatio - ((normalRatio > 0.0) ? minMovementRatio : maxMovementRatio))/normalRatio); + reprap.GetPlatform().MessageF(mtype,"%.2fmm/rev, tolerance +%d%% -%d%%\n", measuredMmPerRev, measuredPosTolerance, measuredNegTolerance); + } + else + { + reprap.GetPlatform().Message(mtype, "no calibration data\n"); + } } // End diff --git a/src/FilamentSensors/Duet3DFilamentSensor.h b/src/FilamentSensors/Duet3DFilamentSensor.h index 679058cd..94e0204d 100644 --- a/src/FilamentSensors/Duet3DFilamentSensor.h +++ b/src/FilamentSensors/Duet3DFilamentSensor.h @@ -16,59 +16,68 @@ public: Duet3DFilamentSensor(int type); bool Configure(GCodeBuffer& gb, StringRef& reply, bool& seen) override; - FilamentSensorStatus Check(float filamentConsumed) override; - FilamentSensorStatus Clear() override; + FilamentSensorStatus Check(bool full, float filamentConsumed) override; + FilamentSensorStatus Clear(bool full) override; void Diagnostics(MessageType mtype, unsigned int extruder) override; void Interrupt() override; private: - static constexpr float DefaultMmPerRev = 15.0; + static constexpr float DefaultMmPerRev = 28.8; static constexpr float DefaultTolerance = 0.2; - static constexpr float DefaultAbsTolerance = 1.0; static constexpr float DefaultMinimumExtrusionCheckLength = 3.0; static constexpr uint16_t SwitchOpenBit = 0x4000u; static constexpr uint16_t ErrorBit = 0x8000u; - static constexpr uint16_t AngleMask = 0x03FF; // 10-bit sensor angle + static constexpr uint16_t AngleMask = 0x03FF; // 10-bit sensor angle - static constexpr size_t MaxEdgeCaptures = 30; + static constexpr size_t EdgeCaptureBufferSize = 64; // must be a power of 2 + void Init(); void Poll(); float GetCurrentAngle() const; - FilamentSensorStatus CheckFilament(float amountCommanded); + FilamentSensorStatus CheckFilament(float amountCommanded, bool overdue); // Configuration parameters float mmPerRev; float tolerance; - float absTolerance; float minimumExtrusionCheckLength; bool withSwitch; // Other data uint16_t sensorValue; float accumulatedExtrusionCommanded; - float accumulatedExtrusionMeasured; + float accumulatedRevsMeasured; float extrusionCommandedAtLastMeasurement; float tentativeExtrusionCommanded; - volatile size_t numberOfEdgesCaptured; uint32_t lastMeasurementTime; - uint32_t edgeCaptures[MaxEdgeCaptures]; + uint32_t edgeCaptures[EdgeCaptureBufferSize]; + size_t edgeCaptureReadPointer; + volatile size_t edgeCaptureWritePointer; + float minMovementRatio, maxMovementRatio; + float totalExtrusionCommanded, totalRevsMeasured; enum class RxdState : uint8_t { waitingForStartBit, + waitingForEndOfStartBit, waitingForNibble, - errorRecovery + errorRecovery1, + errorRecovery2, + errorRecovery3, + errorRecovery4 }; RxdState state; uint32_t startBitLength; uint32_t errorRecoveryStartTime; - size_t bitChangeIndex; + size_t lastBitChangeIndex; uint16_t valueBeingAssembled; uint8_t nibblesAssembled; uint8_t samplesReceived; + bool dataReceived; + bool comparisonStarted; + bool calibrationStarted; }; #endif /* SRC_FILAMENTSENSORS_DUET3DFILAMENTSENSOR_H_ */ diff --git a/src/FilamentSensors/FilamentSensor.cpp b/src/FilamentSensors/FilamentSensor.cpp index 77e9cf4d..02035f1d 100644 --- a/src/FilamentSensors/FilamentSensor.cpp +++ b/src/FilamentSensors/FilamentSensor.cpp @@ -11,7 +11,13 @@ #include "RepRap.h" #include "Platform.h" #include "GCodes/GCodeBuffer.h" +#include "Movement/Move.h" +#include "PrintMonitor.h" +// Static data +FilamentSensor *FilamentSensor::filamentSensors[MaxExtruders] = { 0 }; + +// Default destructor FilamentSensor::~FilamentSensor() { if (pin != NoPin) @@ -88,4 +94,79 @@ bool FilamentSensor::ConfigurePin(GCodeBuffer& gb, StringRef& reply, bool& seen) static_cast<FilamentSensor*>(param)->Interrupt(); } +/*static*/ void FilamentSensor::Spin(bool full) +{ + // Filament sensors + for (size_t extruder = 0; extruder < MaxExtruders; ++extruder) + { + if (filamentSensors[extruder] != nullptr) + { + GCodes& gCodes = reprap.GetGCodes(); + const float extrusionCommanded = (float)reprap.GetMove().GetAccumulatedExtrusion(extruder)/reprap.GetPlatform().DriveStepsPerUnit(extruder + gCodes.GetTotalAxes()); + // get and clear the Move extrusion commanded + if (reprap.GetPrintMonitor().IsPrinting() && !gCodes.IsPausing() && !gCodes.IsResuming() && !gCodes.IsPaused()) + { + const FilamentSensorStatus fstat = filamentSensors[extruder]->Check(full, extrusionCommanded); + if (full && fstat != FilamentSensorStatus::ok && extrusionCommanded > 0.0) + { + if (reprap.Debug(moduleFilamentSensors)) + { + debugPrintf("Filament error: extruder %u reports %s\n", extruder, FilamentSensor::GetErrorMessage(fstat)); + } + else + { + gCodes.FilamentError(extruder, fstat); + } + } + } + else + { + filamentSensors[extruder]->Clear(full); + } + } + } +} + +// Return the filament sensor associated with a particular extruder +/*static*/ FilamentSensor *FilamentSensor::GetFilamentSensor(int extruder) +{ + return (extruder >= 0 && extruder < (int)MaxExtruders) ? filamentSensors[extruder] : nullptr; +} + +// Set the filament sensor associated with a particular extruder +/*static*/ bool FilamentSensor::SetFilamentSensorType(int extruder, int newSensorType) +{ + if (extruder >= 0 && extruder < (int)MaxExtruders) + { + FilamentSensor*& 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 FilamentSensor::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 diff --git a/src/FilamentSensors/FilamentSensor.h b/src/FilamentSensors/FilamentSensor.h index 4461a8bf..1931a03a 100644 --- a/src/FilamentSensors/FilamentSensor.h +++ b/src/FilamentSensors/FilamentSensor.h @@ -28,10 +28,10 @@ public: // Call the following at intervals to check the status. This is only called when extrusion is in progress or imminent. // 'filamentConsumed' is the net amount of extrusion since the last call to this function. - virtual FilamentSensorStatus Check(float filamentConsumed) = 0; + virtual FilamentSensorStatus Check(bool full, float filamentConsumed) = 0; // Clear the measurement state - called when we are not printing a file. Return the present/not present status if available. - virtual FilamentSensorStatus Clear() = 0; + virtual FilamentSensorStatus Clear(bool full) = 0; // Print diagnostic info for this sensor virtual void Diagnostics(MessageType mtype, unsigned int extruder) = 0; @@ -45,12 +45,21 @@ public: // Return the type of this sensor int GetType() const { return type; } - // Create a filament sensor returning null if not a valid sensor type - static FilamentSensor *Create(int type); - // Return an error message corresponding to a status code static const char *GetErrorMessage(FilamentSensorStatus f); + // Poll the filament sensors + static void Spin(bool full); + + // Return the filament sensor associated with a particular extruder + static FilamentSensor *GetFilamentSensor(int extruder); + + // Set the filament sensor associated with a particular extruder + static bool SetFilamentSensorType(int extruder, int newSensorType); + + // Send diagnostics info + static void Diagnostics(MessageType mtype); + protected: FilamentSensor(int t) : type(t), pin(NoPin) { } @@ -61,8 +70,13 @@ protected: Pin GetPin() const { return pin; } private: + // Create a filament sensor returning null if not a valid sensor type + static FilamentSensor *Create(int type); + static void InterruptEntry(void *param); + static FilamentSensor *filamentSensors[MaxExtruders]; + int type; int endstopNumber; Pin pin; diff --git a/src/FilamentSensors/SimpleFilamentSensor.cpp b/src/FilamentSensors/SimpleFilamentSensor.cpp index a5c0549f..87ee7b33 100644 --- a/src/FilamentSensors/SimpleFilamentSensor.cpp +++ b/src/FilamentSensors/SimpleFilamentSensor.cpp @@ -23,7 +23,7 @@ bool SimpleFilamentSensor::Configure(GCodeBuffer& gb, StringRef& reply, bool& se if (seen) { - Check(0.0); + Check(true, 0.0); } else { @@ -49,14 +49,14 @@ void SimpleFilamentSensor::Poll() // Call the following at intervals to check the status. This is only called when extrusion is in progress or imminent. // 'filamentConsumed' is the net amount of extrusion since the last call to this function. -FilamentSensorStatus SimpleFilamentSensor::Check(float filamentConsumed) +FilamentSensorStatus SimpleFilamentSensor::Check(bool full, float filamentConsumed) { Poll(); return (filamentPresent) ? FilamentSensorStatus::ok : FilamentSensorStatus::noFilament; } // Clear the measurement state - called when we are not printing a file. Return the present/not present status if available. -FilamentSensorStatus SimpleFilamentSensor::Clear() +FilamentSensorStatus SimpleFilamentSensor::Clear(bool full) { Poll(); return (filamentPresent) ? FilamentSensorStatus::ok : FilamentSensorStatus::noFilament; diff --git a/src/FilamentSensors/SimpleFilamentSensor.h b/src/FilamentSensors/SimpleFilamentSensor.h index 73a5f96d..05122005 100644 --- a/src/FilamentSensors/SimpleFilamentSensor.h +++ b/src/FilamentSensors/SimpleFilamentSensor.h @@ -16,8 +16,8 @@ public: SimpleFilamentSensor(int type); bool Configure(GCodeBuffer& gb, StringRef& reply, bool& seen) override; - FilamentSensorStatus Check(float filamentConsumed) override; - FilamentSensorStatus Clear() override; + FilamentSensorStatus Check(bool full, float filamentConsumed) override; + FilamentSensorStatus Clear(bool full) override; void Diagnostics(MessageType mtype, unsigned int extruder) override; void Interrupt() override; diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 592eb19b..73b871db 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -3320,17 +3320,17 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply) gb.TryGetIValue('P', sensorType, seen); if (seen) { - platform.SetFilamentSensorType(extruder, sensorType); + FilamentSensor::SetFilamentSensorType(extruder, sensorType); } - FilamentSensor *sensor = platform.GetFilamentSensor(extruder); + FilamentSensor *sensor = FilamentSensor::GetFilamentSensor(extruder); if (sensor != nullptr) { // Configure the sensor error = sensor->Configure(gb, reply, seen); if (error) { - platform.SetFilamentSensorType(extruder, 0); // delete the sensor + FilamentSensor::SetFilamentSensorType(extruder, 0); // delete the sensor } } else if (!seen) diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp index 7387694d..394c348b 100644 --- a/src/Movement/DDA.cpp +++ b/src/Movement/DDA.cpp @@ -1530,7 +1530,7 @@ bool DDA::Step() if (state == completed) { // The following finish time is wrong if we aborted the move because of endstop or Z probe checks. - // However, following a move that checks endstops or the Z probe, we always wait fot the move to complete before we schedule another, so this doesn't matter. + // However, following a move that checks endstops or the Z probe, we always wait for the move to complete before we schedule another, so this doesn't matter. const uint32_t finishTime = moveStartTime + clocksNeeded; // calculate how long this move should take Move& move = reprap.GetMove(); move.CurrentMoveCompleted(); // tell Move that the current move is complete @@ -1629,40 +1629,7 @@ bool DDA::Free() int32_t DDA::GetStepsTaken(size_t drive) const { const DriveMovement * const dmp = pddm[drive]; - int32_t ret; - if (dmp == nullptr) - { - ret = 0; - } - else - { - const uint32_t ns = dmp->nextStep; - if (ns == 0) - { - ret = 0; // not taken any steps yet - } - else - { - const uint32_t rss = dmp->reverseStartStep; - if (ns <= rss) - { - ret = (int32_t)ns; // get number of steps already taken - if (!dmp->direction) // if backwards movement - { - ret = -ret; // invert sign - } - } - else - { - ret = (int)(2 * rss) - (int)ns; - if (dmp->direction) - { - ret = -ret; - } - } - } - } - return ret; + return (dmp != nullptr) ? dmp->GetNetStepsTaken() : 0; } // End diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp index db191b6d..831d575b 100644 --- a/src/Movement/DriveMovement.cpp +++ b/src/Movement/DriveMovement.cpp @@ -251,6 +251,7 @@ bool DriveMovement::CalcNextStepTimeCartesianFull(const DDA &dda, bool live) pre(nextStep < totalSteps; stepsTillRecalc == 0) { // Work out how many steps to calculate at a time. + // The last step before reverseStartStep must be single stepped to make sure that we don't reverse the direction too soon. uint32_t shiftFactor = 0; // assume single stepping if (stepInterval < DDA::MinCalcIntervalCartesian) { @@ -339,6 +340,7 @@ bool DriveMovement::CalcNextStepTimeDeltaFull(const DDA &dda, bool live) pre(nextStep < totalSteps; stepsTillRecalc == 0) { // Work out how many steps to calculate at a time. + // The last step before reverseStartStep must be single stepped to make sure that we don't reverse the direction too soon. // The simulator suggests that at 200steps/mm, the minimum step pulse interval for 400mm/sec movement is 4.5us uint32_t shiftFactor = 0; // assume single stepping if (stepInterval < DDA::MinCalcIntervalDelta) diff --git a/src/Movement/DriveMovement.h b/src/Movement/DriveMovement.h index 4c8e017c..36b44f95 100644 --- a/src/Movement/DriveMovement.h +++ b/src/Movement/DriveMovement.h @@ -43,6 +43,7 @@ public: void ReduceSpeed(const DDA& dda, float inverseSpeedFactor); void DebugPrint(char c, bool withDelta) const; int32_t GetNetStepsLeft() const; + int32_t GetNetStepsTaken() const; static void InitialAllocate(unsigned int num); static int NumFree() { return numFree; } @@ -121,14 +122,14 @@ public: }; // Calculate and store the time since the start of the move when the next step for the specified DriveMovement is due. -// Return true if there are more steps to do. +// Return true if there are more steps to do. When finished, leave nextStep == totalSteps + 1. // This is also used for extruders on delta machines. // We inline this part to speed things up when we are doing double/quad/octal stepping. inline bool DriveMovement::CalcNextStepTimeCartesian(const DDA &dda, bool live) { - if (nextStep < totalSteps) + ++nextStep; + if (nextStep <= totalSteps) { - ++nextStep; if (stepsTillRecalc != 0) { --stepsTillRecalc; // we are doing double/quad/octal stepping @@ -142,12 +143,12 @@ inline bool DriveMovement::CalcNextStepTimeCartesian(const DDA &dda, bool live) } // Calculate the time since the start of the move when the next step for the specified DriveMovement is due -// Return true if there are more steps to do +// Return true if there are more steps to do. When finished, leave nextStep == totalSteps + 1. inline bool DriveMovement::CalcNextStepTimeDelta(const DDA &dda, bool live) { - if (nextStep < totalSteps) + ++nextStep; + if (nextStep <= totalSteps) { - ++nextStep; if (stepsTillRecalc != 0) { --stepsTillRecalc; // we are doing double or quad stepping @@ -164,15 +165,40 @@ inline bool DriveMovement::CalcNextStepTimeDelta(const DDA &dda, bool live) } // Return the number of net steps left for the move in the forwards direction. +// We have already taken nextSteps - 1 steps, unless nextStep is zero. inline int32_t DriveMovement::GetNetStepsLeft() const { - const int32_t netStepsLeft = - ( (nextStep >= reverseStartStep || reverseStartStep >= totalSteps) - ? totalSteps // no reverse due, or we have already reversed - : 2 * reverseStartStep - totalSteps // we have yet to reverse - ) - - nextStep + 1; + int32_t netStepsLeft; + if (reverseStartStep > totalSteps) // if no reverse phase + { + netStepsLeft = (nextStep == 0) ? (int32_t)totalSteps : (int32_t)totalSteps - (int32_t)nextStep + 1; + } + else if (nextStep >= reverseStartStep) + { + netStepsLeft = (int32_t)totalSteps - (int32_t)nextStep + 1; + } + else + { + const int32_t totalNetSteps = (int32_t)(2 * reverseStartStep) - (int32_t)totalSteps - 2; + netStepsLeft = (nextStep == 0) ? totalNetSteps : totalNetSteps - (int32_t)nextStep + 1; + } return (direction) ? netStepsLeft : -netStepsLeft; } +// Return the number of net steps already taken for the move in the forwards direction. +// We have already taken nextSteps - 1 steps, unless nextStep is zero. +inline int32_t DriveMovement::GetNetStepsTaken() const +{ + int32_t netStepsTaken; + if (nextStep < reverseStartStep || reverseStartStep > totalSteps) // if no reverse phase, or not started it yet + { + netStepsTaken = (nextStep == 0) ? 0 : (int32_t)nextStep - 1; + } + else + { + netStepsTaken = (int32_t)nextStep - (int32_t)(2 * reverseStartStep) + 2; // allowing for direction having changed + } + return (direction) ? netStepsTaken : -netStepsTaken; +} + #endif /* DRIVEMOVEMENT_H_ */ diff --git a/src/Platform.cpp b/src/Platform.cpp index 5d037a84..d62169aa 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -478,7 +478,6 @@ void Platform::Init() { extruderDrivers[extr] = (uint8_t)(extr + MinAxes); // set up default extruder drive mapping SetPressureAdvance(extr, 0.0); // no pressure advance - filamentSensors[extr] = nullptr; // no filament sensor } #ifdef DUET_NG @@ -1531,36 +1530,6 @@ void Platform::Spin() } #endif - // Filament sensors - for (size_t extruder = 0; extruder < MaxExtruders; ++extruder) - { - if (filamentSensors[extruder] != nullptr) - { - GCodes& gCodes = reprap.GetGCodes(); - const float extrusionCommanded = (float)reprap.GetMove().GetAccumulatedExtrusion(extruder)/driveStepsPerUnit[extruder + gCodes.GetTotalAxes()]; - // get and clear the Move extrusion commanded - if (reprap.GetPrintMonitor().IsPrinting() && !gCodes.IsPausing() && !gCodes.IsResuming() && !gCodes.IsPaused()) - { - const FilamentSensorStatus fstat = filamentSensors[extruder]->Check(extrusionCommanded); - if (fstat != FilamentSensorStatus::ok && extrusionCommanded > 0.0) - { - if (reprap.Debug(moduleFilamentSensors)) - { - debugPrintf("Filament error: extruder %u reports %s\n", extruder, FilamentSensor::GetErrorMessage(fstat)); - } - else - { - gCodes.FilamentError(extruder, fstat); - } - } - } - else - { - filamentSensors[extruder]->Clear(); - } - } - } - ClassReport(longWait); } @@ -1799,6 +1768,12 @@ void Platform::InitialiseInterrupts() NVIC_SetPriority(PIOE_IRQn, NvicPriorityPins); #endif +#if SAM3XA + NVIC_SetPriority(UOTGHS_IRQn, NvicPriorityUSB); +#endif +#if SAM4E + NVIC_SetPriority(UDP_IRQn, NvicPriorityUSB); +#endif NVIC_SetPriority(TWI1_IRQn, NvicPriorityTwi); // Interrupt for 4-pin PWM fan sense line @@ -1814,7 +1789,7 @@ void Platform::InitialiseInterrupts() // Set up the timeout of the regulator watchdog, and set up the backup watchdog if there is one // The clock frequency for both watchdogs is 32768/128 = 256Hz const uint16_t timeout = 32768/128; // set watchdog timeout to 1 second (max allowed value is 4095 = 16 seconds) - wdt_init(WDT, WDT_MR_WDRSTEN, timeout,timeout); // reset the processor on a watchdog fault + wdt_init(WDT, WDT_MR_WDRSTEN, timeout, timeout); // reset the processor on a watchdog fault active = true; // this enables the tick interrupt, which keeps the watchdog happy } @@ -2060,15 +2035,6 @@ void Platform::Diagnostics(MessageType mtype) } #endif - // Filament sensors - for (size_t i = 0; i < MaxExtruders; ++i) - { - if (filamentSensors[i] != nullptr) - { - filamentSensors[i]->Diagnostics(mtype, i); - } - } - // Show current RTC time Message(mtype, "Date/time: "); struct tm timeInfo; @@ -3370,39 +3336,12 @@ bool Platform::SetExtrusionAncilliaryPwmPin(int logicalPin) return GetFirmwarePin(logicalPin, PinAccess::pwm, extrusionAncilliaryPwmFirmwarePin, extrusionAncilliaryPwmInvert); } -// Filament sensor support -// Get the filament sensor object for an extruder, or nullptr if there isn't one -FilamentSensor *Platform::GetFilamentSensor(int extruder) const -{ - return (extruder >= 0 && extruder < (int)MaxExtruders) ? filamentSensors[extruder] : nullptr; -} - -// Set the filament sensor type for an extruder, returning true if it has changed. -// Passing newSensorType as 0 sets no sensor. -bool Platform::SetFilamentSensorType(int extruder, int newSensorType) -{ - if (extruder >= 0 && extruder < (int)MaxExtruders) - { - FilamentSensor*& sensor = filamentSensors[extruder]; - const int oldSensorType = (sensor == nullptr) ? 0 : sensor->GetType(); - if (newSensorType != oldSensorType) - { - delete sensor; - sensor = FilamentSensor::Create(newSensorType); - return true; - } - } - - return false; -} - // Get the firmware pin number for an endstop, or NoPin if it is out of range Pin Platform::GetEndstopPin(int endstop) const { return (endstop >= 0 && endstop < (int)ARRAY_SIZE(endStopPins)) ? endStopPins[endstop] : NoPin; } - #if SUPPORT_INKJET // Fire the inkjet (if any) in the given pattern diff --git a/src/Platform.h b/src/Platform.h index 66f68954..b3d10a53 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -575,9 +575,7 @@ public: // User I/O and servo support bool GetFirmwarePin(int logicalPin, PinAccess access, Pin& firmwarePin, bool& invert); - // Filament sensor support - FilamentSensor *GetFilamentSensor(int extruder) const; - bool SetFilamentSensorType(int extruder, int newSensorType); + // For filament sensor support Pin GetEndstopPin(int endstop) const; // Get the firmware pin number for an endstop //------------------------------------------------------------------------------------------------------- @@ -689,7 +687,6 @@ private: float driveStepsPerUnit[DRIVES]; float instantDvs[DRIVES]; float pressureAdvance[MaxExtruders]; - FilamentSensor *filamentSensors[MaxExtruders]; float motorCurrents[DRIVES]; // the normal motor current for each stepper driver float motorCurrentFraction[DRIVES]; // the percentages of normal motor current that each driver is set to AxisDriversConfig axisDrivers[MaxAxes]; // the driver numbers assigned to each axis diff --git a/src/RepRap.cpp b/src/RepRap.cpp index d8de26a8..294a4555 100644 --- a/src/RepRap.cpp +++ b/src/RepRap.cpp @@ -45,6 +45,10 @@ extern "C" void hsmciIdle() } #endif + if (reprap.GetSpinningModule() != moduleFilamentSensors) + { + FilamentSensor::Spin(false); + } } // RepRap member functions. @@ -217,6 +221,10 @@ void RepRap::Spin() DuetExpansion::Spin(true); #endif + spinningModule = moduleFilamentSensors; + ticksInSpinState = 0; + FilamentSensor::Spin(true); + spinningModule = noModule; ticksInSpinState = 0; @@ -264,6 +272,7 @@ void RepRap::Diagnostics(MessageType mtype) heat->Diagnostics(mtype); gCodes->Diagnostics(mtype); network->Diagnostics(mtype); + FilamentSensor::Diagnostics(mtype); } // Turn off the heaters, disable the motors, and deactivate the Heat and Move classes. Leave everything else working. @@ -288,7 +297,7 @@ void RepRap::EmergencyStop() } // We do this twice, to avoid an interrupt switching a drive back on. move->Exit() should prevent interrupts doing this. - for(int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { move->Exit(); for (size_t drive = 0; drive < DRIVES; drive++) diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h index 327714ae..f4ba010f 100644 --- a/src/RepRapFirmware.h +++ b/src/RepRapFirmware.h @@ -211,15 +211,16 @@ const uint32_t NvicPriorityWatchdog = 0; // watchdog has highest priority (SAM4 const uint32_t NvicPriorityUart = 1; // UART is next to avoid character loss const uint32_t NvicPrioritySystick = 2; // systick kicks the watchdog and starts the ADC conversions, so must be quite high -const uint32_t NvicPriorityStep = 3; // step interrupt is next highest, it can preempt most other interrupts +const uint32_t NvicPriorityPins = 3; // priority for GPIO pin interrupts - filament sensors must be higher than step +const uint32_t NvicPriorityStep = 4; // step interrupt is next highest, it can preempt most other interrupts +const uint32_t NvicPriorityUSB = 5; // USB interrupt #if !defined(DUET_NG) && !defined(__RADDS__) -const uint32_t NvicPriorityNetworkTick = 4; // priority for network tick interrupt -const uint32_t NvicPriorityEthernet = 4; // priority for Ethernet interface +const uint32_t NvicPriorityNetworkTick = 5; // priority for network tick interrupt +const uint32_t NvicPriorityEthernet = 5; // priority for Ethernet interface #endif -const uint32_t NvicPrioritySpi = 5; // SPI used for network transfers on Duet WiFi/Duet vEthernet -const uint32_t NvicPriorityPins = 6; // priority for GPIO pin interrupts +const uint32_t NvicPrioritySpi = 6; // SPI used for network transfers on Duet WiFi/Duet vEthernet const uint32_t NvicPriorityTwi = 7; // TWI used to read endstop and other inputs on the DueXn #endif diff --git a/src/Version.h b/src/Version.h index e58614e1..dd647ab4 100644 --- a/src/Version.h +++ b/src/Version.h @@ -9,11 +9,11 @@ #define SRC_VERSION_H_ #ifndef VERSION -# define VERSION "1.19RC7" +# define VERSION "1.19" #endif #ifndef DATE -# define DATE "2017-08-11" +# define DATE "2017-08-14" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman" |