7272#define PWM_MON_MAX_SEC 3600U
7373#define PWM_MEAS_WINDOW_MS 400U /* no edge within this window = signal lost */
7474#define PWM_TIM_HZ 1000000U /* timer timebase: 1 MHz -> 1 tick = 1 us */
75- /* "rotors step <n> ... verify [sec]" samples the coil-current feedback on PA0 to
76- * check the motor is actually turning while we drive STEP. It prints once per
77- * second by default (vs the standalone monitor's 5s) and clamps to the same
78- * PWM_MON_MIN/MAX_SEC bounds. */
79- #define PWM_VERIFY_DEFAULT_SEC 1U
75+ /* "rotors step <n> ... verify [ms]" samples the coil-current feedback on PA0 to
76+ * check the motor is actually turning while we drive STEP. The optional argument
77+ * is the check interval in MILLISECONDS (default 1000): each interval the coil
78+ * swing is evaluated and a fault stops the move, so a sub-second value catches a
79+ * fault faster. The floor spans several electrical cycles of the stepper so a
80+ * window always contains a full swing (at ~500 steps/s one cycle is ~8 ms). */
81+ #define STEP_VERIFY_DEFAULT_MS 1000U
82+ #define STEP_VERIFY_MIN_MS 50U
83+ #define STEP_VERIFY_MAX_MS 3600000U
84+ /* Healthy "motor ok" lines are throttled to at most one per this interval so a
85+ * sub-second check interval doesn't flood the console; a fault always prints. */
86+ #define STEP_VERIFY_PRINT_MIN_MS 1000U
8087
8188/* Motor-health check via the coil-current sense on PA0 (ADC1_IN0). PA0 carries the
8289 * shunt-resistor voltage through an INA sense amplifier, so a *running* motor makes
@@ -457,10 +464,11 @@ static void print_help(void)
457464 printf (" status\r\n" );
458465 printf (" rotors on\r\n" );
459466 printf (" rotors off\r\n" );
460- printf (" rotors step <n> [fwd|rev] [verify [seconds]] (PC10=STEP pulses, PC11=DIR; ~500 steps/s;\r\n" );
461- printf (" verify samples coil current on PA0 (ADC1_IN0) while stepping, printing\r\n" );
462- printf (" the peak-to-peak swing every `seconds` (default 1s) and stopping with\r\n" );
463- printf (" STEP FAULT if the current goes flat (motor stalled); any key aborts)\r\n" );
467+ printf (" rotors step <n> [fwd|rev] [verify [ms]] (PC10=STEP pulses, PC11=DIR; ~500 steps/s;\r\n" );
468+ printf (" verify samples coil current on PA0 (ADC1_IN0) while stepping, checking\r\n" );
469+ printf (" the peak-to-peak swing every `ms` (default 1000, min 50; status printed\r\n" );
470+ printf (" at most once/s) and stopping with STEP FAULT if the current goes flat\r\n" );
471+ printf (" (motor stalled); any key aborts)\r\n" );
464472 printf (" monitor i2c (reads BMP280 every 1s, press any key to stop)\r\n" );
465473 printf (" monitor pwm [seconds] (measure PWM on PA0/TIM2_CH1 each cycle; default 5s;\r\n" );
466474 printf (" prints 'failure detected' if the PWM is lost; any key stops)\r\n" );
@@ -579,6 +587,9 @@ static uint32_t rotor_step(uint32_t steps, int reverse, int verify, uint32_t ver
579587 /* First check one interval in, giving the motor time to spin up before we
580588 * expect any coil-current swing (an immediate check would see a flat reading). */
581589 uint32_t next_verify_ms = HAL_GetTick () + verify_ms ;
590+ /* Healthy status is printed at most once per STEP_VERIFY_PRINT_MIN_MS even when
591+ * the check interval is shorter, so a sub-second interval doesn't flood output. */
592+ uint32_t last_print_ms = HAL_GetTick ();
582593 uint32_t cycle = 0U ;
583594 uint32_t done = 0U ;
584595 uint16_t adc_min = 0xFFFFU ; /* min/max of the coil-current reading this interval */
@@ -614,19 +625,9 @@ static uint32_t rotor_step(uint32_t steps, int reverse, int verify, uint32_t ver
614625 uint32_t min_mv = adc_counts_to_mv (adc_min );
615626 uint32_t max_mv = adc_counts_to_mv (adc_max );
616627 uint32_t vpp_mv = motor_swing_vpp_mv (adc_min , adc_max );
617- if (!motor_swing_is_fault (adc_min , adc_max ))
618- {
619- printf (" verify cycle=%lu tick=%lu ms step=%lu/%lu motor ok: coil Vpp=%lu mV (min=%lu mV max=%lu mV)\r\n" ,
620- (unsigned long )cycle ,
621- (unsigned long )now ,
622- (unsigned long )done ,
623- (unsigned long )steps ,
624- (unsigned long )vpp_mv ,
625- (unsigned long )min_mv ,
626- (unsigned long )max_mv );
627- }
628- else
628+ if (motor_swing_is_fault (adc_min , adc_max ))
629629 {
630+ /* Faults always print (and stop the move), regardless of throttle. */
630631 printf (" verify cycle=%lu tick=%lu ms step=%lu/%lu failure detected: coil current flat on PA0, Vpp=%lu mV < %u mV (motor stalled / open coil)\r\n" ,
631632 (unsigned long )cycle ,
632633 (unsigned long )now ,
@@ -640,6 +641,19 @@ static uint32_t rotor_step(uint32_t steps, int reverse, int verify, uint32_t ver
640641 }
641642 break ; /* stop the move the moment the coil current goes flat */
642643 }
644+ /* Healthy: throttle to one line per STEP_VERIFY_PRINT_MIN_MS. */
645+ if ((int32_t )(now - last_print_ms ) >= (int32_t )STEP_VERIFY_PRINT_MIN_MS )
646+ {
647+ printf (" verify cycle=%lu tick=%lu ms step=%lu/%lu motor ok: coil Vpp=%lu mV (min=%lu mV max=%lu mV)\r\n" ,
648+ (unsigned long )cycle ,
649+ (unsigned long )now ,
650+ (unsigned long )done ,
651+ (unsigned long )steps ,
652+ (unsigned long )vpp_mv ,
653+ (unsigned long )min_mv ,
654+ (unsigned long )max_mv );
655+ last_print_ms = now ;
656+ }
643657 adc_min = 0xFFFFU ; /* reset the window for the next interval */
644658 adc_max = 0U ;
645659 next_verify_ms += verify_ms ;
@@ -649,9 +663,10 @@ static uint32_t rotor_step(uint32_t steps, int reverse, int verify, uint32_t ver
649663 return done ;
650664}
651665
652- /* "rotors step <n> [fwd|rev] [verify [seconds]]" — args points just past
653- * "rotors step". After the count the direction and the verify option may appear
654- * in any order; "verify" turns on the PWM feedback check (see rotor_step). */
666+ /* "rotors step <n> [fwd|rev] [verify [ms]]" — args points just past "rotors step".
667+ * After the count the direction and the verify option may appear in any order;
668+ * "verify" turns on the coil-current check (see rotor_step), with an optional check
669+ * interval in milliseconds. */
655670static void handle_rotor_step (const char * args )
656671{
657672 while (* args == ' ' )
@@ -660,7 +675,7 @@ static void handle_rotor_step(const char *args)
660675 }
661676 if (* args < '0' || * args > '9' )
662677 {
663- printf ("usage: rotors step <n> [fwd|rev] [verify [seconds ]]\r\n" );
678+ printf ("usage: rotors step <n> [fwd|rev] [verify [ms ]]\r\n" );
664679 return ;
665680 }
666681
@@ -678,9 +693,9 @@ static void handle_rotor_step(const char *args)
678693
679694 int reverse = 0 ;
680695 int verify = 0 ;
681- uint32_t verify_sec = PWM_VERIFY_DEFAULT_SEC ;
696+ uint32_t verify_ms = STEP_VERIFY_DEFAULT_MS ;
682697
683- /* Optional trailing tokens: fwd|rev and verify [seconds ], in any order. */
698+ /* Optional trailing tokens: fwd|rev and verify [ms ], in any order. */
684699 while (1 )
685700 {
686701 while (* p == ' ' )
@@ -703,7 +718,7 @@ static void handle_rotor_step(const char *args)
703718 else if (c == 'v' || c == 'V' )
704719 {
705720 verify = 1 ;
706- /* Skip the "verify" word, then read an optional seconds value . */
721+ /* Skip the "verify" word, then read an optional interval in ms . */
707722 while (* p != '\0' && * p != ' ' )
708723 {
709724 p ++ ;
@@ -714,25 +729,25 @@ static void handle_rotor_step(const char *args)
714729 }
715730 if (* p >= '0' && * p <= '9' )
716731 {
717- verify_sec = parse_u32_default (p , PWM_VERIFY_DEFAULT_SEC );
718- if (verify_sec < PWM_MON_MIN_SEC )
732+ verify_ms = parse_u32_default (p , STEP_VERIFY_DEFAULT_MS );
733+ if (verify_ms < STEP_VERIFY_MIN_MS )
719734 {
720- verify_sec = PWM_MON_MIN_SEC ;
735+ verify_ms = STEP_VERIFY_MIN_MS ;
721736 }
722- if (verify_sec > PWM_MON_MAX_SEC )
737+ if (verify_ms > STEP_VERIFY_MAX_MS )
723738 {
724- verify_sec = PWM_MON_MAX_SEC ;
739+ verify_ms = STEP_VERIFY_MAX_MS ;
725740 }
726741 while (* p >= '0' && * p <= '9' )
727742 {
728743 p ++ ;
729744 }
730745 }
731- continue ; /* p already advanced past any seconds value */
746+ continue ; /* p already advanced past any ms value */
732747 }
733748 else
734749 {
735- printf ("unknown option '%s' (use fwd|rev, verify [seconds ])\r\n" , p );
750+ printf ("unknown option '%s' (use fwd|rev, verify [ms ])\r\n" , p );
736751 return ;
737752 }
738753 while (* p != '\0' && * p != ' ' ) /* advance past fwd|rev token */
@@ -755,15 +770,16 @@ static void handle_rotor_step(const char *args)
755770
756771 if (verify )
757772 {
758- printf ("STEP verify: watching coil current on PA0 (ADC1_IN0) every %lu s; "
759- "failure = peak-to-peak swing < %u mV (motor flat; any key aborts)\r\n" ,
760- (unsigned long )verify_sec ,
773+ printf ("STEP verify: watching coil current on PA0 (ADC1_IN0) every %lu ms "
774+ "(status printed <=1/s); failure = peak-to-peak swing < %u mV "
775+ "(motor flat; any key aborts)\r\n" ,
776+ (unsigned long )verify_ms ,
761777 (unsigned int )MOTOR_SWING_MIN_MV );
762778 adc_input_init ();
763779 }
764780
765781 int motor_fault = 0 ;
766- uint32_t done = rotor_step (steps , reverse , verify , verify_sec * 1000U , & motor_fault );
782+ uint32_t done = rotor_step (steps , reverse , verify , verify_ms , & motor_fault );
767783
768784 if (verify )
769785 {
0 commit comments