Skip to content

Commit 91c2e4c

Browse files
committed
faster fault checking
1 parent 67fc03f commit 91c2e4c

1 file changed

Lines changed: 55 additions & 39 deletions

File tree

‎scenario-sensors-stm32/main.c‎

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,18 @@
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. */
655670
static 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

Comments
 (0)