| 250 | } |
| 251 | |
| 252 | int32_t I2CPositionEncoder::get_axis_error_steps(const bool report) { |
| 253 | if (!active) { |
| 254 | if (report) { |
| 255 | SERIAL_CHAR(AXIS_CHAR(encoderAxis)); |
| 256 | SERIAL_ECHOLNPGM(" axis encoder not active!"); |
| 257 | } |
| 258 | return 0; |
| 259 | } |
| 260 | |
| 261 | float stepperTicksPerUnit; |
| 262 | int32_t encoderTicks = position, encoderCountInStepperTicksScaled; |
| 263 | //int32_t stepperTicks = stepper.position(encoderAxis); |
| 264 | |
| 265 | // With a rotary encoder we're concerned with ticks/rev; whereas with a linear we're concerned with ticks/mm |
| 266 | stepperTicksPerUnit = (type == I2CPE_ENC_TYPE_ROTARY) ? stepperTicks : planner.settings.axis_steps_per_mm[encoderAxis]; |
| 267 | |
| 268 | //convert both 'ticks' into same units / base |
| 269 | encoderCountInStepperTicksScaled = LROUND((stepperTicksPerUnit * encoderTicks) / encoderTicksPerUnit); |
| 270 | |
| 271 | const int32_t target = stepper.position(encoderAxis); |
| 272 | int32_t error = encoderCountInStepperTicksScaled - target; |
| 273 | |
| 274 | //suppress discontinuities (might be caused by bad I2C readings...?) |
| 275 | const bool suppressOutput = (ABS(error - errorPrev) > 100); |
| 276 | |
| 277 | errorPrev = error; |
| 278 | |
| 279 | if (report) |
| 280 | SERIAL_ECHOLN(C(AXIS_CHAR(encoderAxis)), F(" axis target="), target, F("; actual="), encoderCountInStepperTicksScaled, F("; err="), error); |
| 281 | |
| 282 | if (suppressOutput) { |
| 283 | if (report) SERIAL_ECHOLNPGM("!Discontinuity. Suppressing error."); |
| 284 | error = 0; |
| 285 | } |
| 286 | |
| 287 | return error; |
| 288 | } |
| 289 | |
| 290 | int32_t I2CPositionEncoder::get_raw_count() { |
| 291 | uint8_t index = 0; |
no test coverage detected