| 102 | |
| 103 | // Handle M569.5 - Collect closed loop data |
| 104 | GCodeResult ClosedLoop::StartDataCollection(DriverId driverId, GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) |
| 105 | { |
| 106 | // Check what the user wants - record or report |
| 107 | // Record - A number of samples (Snn) is given to record |
| 108 | // Report - Samples (Snn) is not given |
| 109 | bool recording = false; |
| 110 | uint32_t parsedS; |
| 111 | gb.TryGetLimitedUIValue('S', parsedS, recording, MaxSamples + 1); |
| 112 | if (!recording) |
| 113 | { |
| 114 | // No S parameter was given so this is a request for the recording status |
| 115 | if (closedLoopFile.load() == nullptr) |
| 116 | { |
| 117 | reply.copy("Closed loop data is not being collected"); |
| 118 | return GCodeResult::warning; // looks like the closed loop plugin relies on this being a warning |
| 119 | } |
| 120 | else |
| 121 | { |
| 122 | reply.printf("Collecting sample: %u/%u", expectedRemoteSampleNumber, (unsigned int)numSamplesRequested); |
| 123 | return GCodeResult::ok; |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | // If we get here then the user is requesting a recording |
| 128 | if (closedLoopFile.load() != nullptr) // check if one is already happening |
| 129 | { |
| 130 | const uint32_t wlr = whenDataLastReceived; // load this volatile variable before calling millis() |
| 131 | if (millis() - wlr >= DataReceiveTimeout) |
| 132 | { |
| 133 | CloseDataCollectionFile(); // this case is to allow us to reset if data collection stalls |
| 134 | reply.copy("Closed loop data collection timed out, closing file"); |
| 135 | } |
| 136 | else |
| 137 | { |
| 138 | reply.copy("Closed loop data is already being collected"); |
| 139 | } |
| 140 | return GCodeResult::error; |
| 141 | } |
| 142 | |
| 143 | // Parse the additional parameters |
| 144 | bool seen = false; |
| 145 | uint32_t parsedA = 0, parsedD = 0, parsedR = 0, parsedV = 0; |
| 146 | |
| 147 | gb.TryGetLimitedUIValue('A', parsedA, seen, 2); // valid collection modes are 0 and 1 |
| 148 | gb.TryGetUIValue('D', parsedD, seen); |
| 149 | gb.TryGetLimitedUIValue('R', parsedR, seen, std::numeric_limits<uint16_t>::max() + 1); |
| 150 | gb.TryGetUIValue('V', parsedV, seen); |
| 151 | |
| 152 | // Validation passed - store the values |
| 153 | modeRequested = parsedA; |
| 154 | rateRequested = parsedR; |
| 155 | filterRequested = parsedD; |
| 156 | dataBytesPerSample = ClosedLoopSampleLength(filterRequested); |
| 157 | deviceRequested = driverId; |
| 158 | movementRequested = parsedV; |
| 159 | numSamplesRequested = parsedS; |
| 160 | |
| 161 | // Estimate how large the file will be |
no test coverage detected