changed feeder expected time behaviour and altered the feeder state machine behaviour if feeding is faster than peeling

This commit is contained in:
janik
2026-04-10 17:05:52 +07:00
parent 542a5ffd2c
commit e3054e3e73
15 changed files with 10015 additions and 9856 deletions
+37 -24
View File
@@ -59,7 +59,7 @@
#define BACKWARDS_FEED_FILM_SLACK_REMOVAL_TIME 350 // ms to take up slack after backward
#define BACKLASH_COMP_TENTH_MM 10 // 1mm backlash compensation
#define FEED_SETTLE_TIME 50 // ms to wait for position to settle
#define FEED_POSITION_TOLERANCE 10 // encoder counts tolerance (~0.044mm)
#define FEED_POSITION_TOLERANCE 15 // encoder counts tolerance (~0.066mm)
// OneWire timing (microseconds)
@@ -86,6 +86,7 @@
#define FLOOR_ADDRESS_NOT_PROGRAMMED 0x00
#define FLOOR_ADDRESS_NOT_DETECTED 0xFF
// Position overflow prevention
#define POSITION_OVERFLOW_THRESHOLD (INT32_MAX / 2)
#define POSITION_RESET_AMOUNT (INT32_MAX / 4)
@@ -168,6 +169,8 @@ uint32_t feed_timeout_time = 0; // absolute timeout for driving phase
int16_t feed_distance_tenths = 0; // requested feed distance in 0.1mm
uint8_t feed_direction = 1; // 1 = forward, 0 = backward
int32_t feed_target_position = 0; // target encoder position for current phase
uint8_t peel_done = 1; // peel phase complete flag
uint8_t drive_done = 1; // motor reached position flag
uint8_t feed_retry_count = 0; // retry counter
#define FEED_RETRY_LIMIT 3
@@ -1171,7 +1174,7 @@ void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef * htim)
int32_t brake_distance = velocity * brake_time_tenths / 10;
if (error > FEED_POSITION_TOLERANCE && (is_stopped || error > brake_distance))
if (error >= FEED_POSITION_TOLERANCE && (is_stopped || error > brake_distance))
{
set_Feeder_PWM(PWM_MAX, 1); // Full forward
debug_pid_output = PWM_MAX;
@@ -1282,9 +1285,12 @@ void rs485_transmit(uint8_t *data, uint16_t len)
{
// Turnaround delay — let controller switch to RX mode
HAL_Delay(1);
// Disable receiver, transmit, re-enable receiver, re-arm DMA
// Stop DMA receive before transmitting
HAL_UART_AbortReceive(&huart2);
// Disable receiver, transmit
HAL_GPIO_WritePin(USART2_NRE_GPIO_Port, USART2_NRE_Pin, GPIO_PIN_SET); // NRE high = receiver off
HAL_UART_Transmit(&huart2, data, len, 100);
// Re-enable receiver and re-arm DMA
HAL_GPIO_WritePin(USART2_NRE_GPIO_Port, USART2_NRE_Pin, GPIO_PIN_RESET); // NRE low = receiver on
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, DMA_buffer, 64);
__HAL_DMA_DISABLE_IT(huart2.hdmarx, DMA_IT_HT);
@@ -1787,9 +1793,10 @@ uint16_t calculate_expected_feed_time(uint8_t distance, uint8_t forward)
if (forward)
{
// Forward: peel time + peel backoff + drive time + extra for first feed
// Report realistic expected time, not the timeout value
uint16_t time = (distance * PEEL_TIME_PER_TENTH_MM) +
PEEL_BACKOFF_TIME +
(distance * TIMEOUT_TIME_PER_TENTH_MM) + 200;
(distance * 10) + 200; // ~10ms per 0.1mm actual drive time
return time;
}
else
@@ -1819,12 +1826,15 @@ void start_feed(int16_t distance_tenths, uint8_t forward)
if (forward)
{
// Forward feed: drive both motors simultaneously
feed_state = FEED_STATE_PEEL_FORWARD;
// Forward feed: drive both motors simultaneously, tracked independently
feed_state = FEED_STATE_DRIVING;
feed_state_start_time = HAL_GetTick();
// Peel: runs for timed duration
peel_done = 0;
feed_state_duration = distance_tenths * PEEL_TIME_PER_TENTH_MM;
peel_motor(1); // Peel forward
// Start feed motor at the same time
peel_motor(1);
// Drive: ISR drives toward target, state machine monitors
drive_done = 0;
feed_timeout_time = HAL_GetTick() + (distance_tenths * TIMEOUT_TIME_PER_TENTH_MM) + 500;
feed_target_position = total_count + tenths_to_counts(distance_tenths);
target_count = feed_target_position;
@@ -1853,14 +1863,7 @@ void feed_state_machine_update(void)
switch (feed_state)
{
case FEED_STATE_PEEL_FORWARD:
// Peeling film while feed motor drives simultaneously
if (elapsed >= feed_state_duration)
{
peel_brake(); // Peel done, feed motor continues via PID
feed_state = FEED_STATE_DRIVING;
feed_state_start_time = now;
// feed_target_position and feed_timeout_time already set in start_feed
}
// Legacy: not used for forward feeds anymore
break;
case FEED_STATE_UNPEEL:
@@ -1879,8 +1882,15 @@ void feed_state_machine_update(void)
break;
case FEED_STATE_DRIVING:
// Check for position reached, overshoot, and timeout
// Track peel independently: stop peel when timer expires
{
if (!peel_done && elapsed >= feed_state_duration)
{
peel_brake();
peel_done = 1;
}
// Track drive independently: check position
int32_t error = feed_target_position - total_count;
int32_t abs_error = error < 0 ? -error : error;
@@ -1888,27 +1898,30 @@ void feed_state_machine_update(void)
// <5: none, >=5: ±5, >=10: ±10, >=20: ±20
int32_t brake_adj = abs_error >= 20 ? 20 : abs_error >= 10 ? 10 : abs_error >= 5 ? 5 : 0;
if (abs_error < FEED_POSITION_TOLERANCE)
if (!drive_done && abs_error < FEED_POSITION_TOLERANCE)
{
// Position reached - fine-tune brake time based on where we stopped
if (error < 0) // overshot
// Position reached - fine-tune brake time
if (error < 0)
brake_time_tenths += brake_adj;
else if (error > 0 && brake_time_tenths > brake_adj) // undershot
else if (error > 0 && brake_time_tenths > brake_adj)
brake_time_tenths -= brake_adj;
else if (error > 0)
brake_time_tenths = 1;
drive_done = 1;
}
// Both done? Feed complete
if (peel_done && drive_done)
{
if (!feed_direction)
{
// Backward feed: take up slack then do final approach
feed_state = FEED_STATE_SLACK_REMOVAL;
feed_state_start_time = now;
feed_state_duration = BACKWARDS_FEED_FILM_SLACK_REMOVAL_TIME;
peel_motor(1); // Peel forward to take up slack
peel_motor(1);
}
else
{
// Forward feed complete
feed_state = FEED_STATE_SETTLING;
feed_state_start_time = now;
feed_state_duration = FEED_SETTLE_TIME;