From c0c8cb91c7484c3752a66289c32036fa4e69cb95 Mon Sep 17 00:00:00 2001 From: Jonathan Roth Date: Tue, 10 Mar 2026 16:46:46 +0100 Subject: [PATCH] dev --- includes/arm.h | 30 ++++++++++++++-------- src/arm.c | 68 +++++++++++++++++++++----------------------------- src/spool.c | 48 ++++++++++++++++++++++++----------- 3 files changed, 82 insertions(+), 64 deletions(-) diff --git a/includes/arm.h b/includes/arm.h index 465f710..cce07dd 100644 --- a/includes/arm.h +++ b/includes/arm.h @@ -14,14 +14,25 @@ #define ARM_REG_LEFT 0x0804 // position limite gauche (1/10 mm) #define ARM_REG_RIGHT 0x0805 // position limite droite (1/10 mm) +// ───────────────────────────────────────────── +// Valeurs par défaut LEFT/RIGHT +// ───────────────────────────────────────────── + +#define ARM_LEFT_DEFAULT 500U // 50.0 mm en dixièmes +#define ARM_RIGHT_DEFAULT 4500U // 450.0 mm en dixièmes + // ───────────────────────────────────────────── // Mécanique // 1 tour ARM = 40mm = 1600 micropas // 1 micropas ARM = 25µm // ───────────────────────────────────────────── -#define ARM_UM_PER_USTEP 25U // µm par micropas -#define ARM_USTEP_PER_REV 1600U // micropas par tour +// 8 microsteps +// #define ARM_UM_PER_USTEP 25U // µm par micropas +// #define ARM_USTEP_PER_REV 1600U // micropas par tour +// 4 microsteps +#define ARM_UM_PER_USTEP 50U // µm par micropas +#define ARM_USTEP_PER_REV 800U // micropas par tour #define ARM_UM_PER_REV ((uint32_t)ARM_UM_PER_USTEP * ARM_USTEP_PER_REV) // 40000µm // ───────────────────────────────────────────── @@ -31,19 +42,12 @@ #define ARM_GEAR_MIN 0 // µm (arrêt vgear) #define ARM_GEAR_MAX 65535 // µm = 65.535mm par tour SPOOL -// ───────────────────────────────────────────── -// Valeurs par défaut positions (1/10 mm) -// ───────────────────────────────────────────── - -#define ARM_LEFT_DEFAULT 500 // 50.0mm -#define ARM_RIGHT_DEFAULT 4500 // 450.0mm - // ───────────────────────────────────────────── // API publique // ───────────────────────────────────────────── void ARM_Init(void); -void ARM_Step(void); // appelé depuis l'ISR SPOOL à chaque step +void ARM_UpdateTarget(void); // appelé depuis l'ISR SPOOL — met à jour arm_target_position void ARM_Enable(uint8_t state); // ENABLE moteur ARM void ARM_SetDir(uint8_t dir); // sens de rotation ARM void ARM_SetFree(uint8_t state); // free ARM + désactive vgear (REG_CTRL bit1) @@ -53,6 +57,12 @@ void ARM_SetOffset(uint16_t um); // écriture registre 0x0803 + sauvegard uint16_t ARM_GetOffset(void); // lecture offset courant void ARM_SetLeft(uint16_t dmm); // écriture registre 0x0804 (1/10 mm) void ARM_SetRight(uint16_t dmm); // écriture registre 0x0805 (1/10 mm) +void ARM_SetLeft(uint16_t pos); // écriture registre 0x0804 (1/10 mm) +void ARM_SetRight(uint16_t pos); // écriture registre 0x0805 (1/10 mm) +uint16_t ARM_GetLeft(void); // lecture position gauche courante +uint16_t ARM_GetRight(void); // lecture position droite courante +void ARM_SetLeft(uint16_t dmm); // écriture registre 0x0804 (1/10 mm) +void ARM_SetRight(uint16_t dmm); // écriture registre 0x0805 (1/10 mm) uint16_t ARM_GetLeft(void); uint16_t ARM_GetRight(void); diff --git a/src/arm.c b/src/arm.c index 150b702..1028294 100644 --- a/src/arm.c +++ b/src/arm.c @@ -1,5 +1,6 @@ #include #include +#include // ───────────────────────────────────────────── // Machine d'état traverse @@ -18,7 +19,7 @@ typedef enum { // Constantes // ───────────────────────────────────────────── -#define ARM_WAIT_STEPS 1200U // 3/4 tour SPOOL (200pas × 8µstep × 3/4) +#define ARM_WAIT_STEPS 600U // 3/4 tour SPOOL (200pas × 4µstep × 3/4) #define ARM_DIR_RIGHT 1 #define ARM_DIR_LEFT 0 @@ -26,20 +27,18 @@ typedef enum { // État interne // ───────────────────────────────────────────── -static volatile uint16_t gear_um; // déplacement µm par tour SPOOL -static volatile uint32_t accumulator; // accumulateur µm -static uint16_t arm_offset; // distance capteur home → origine (µm) -static volatile uint8_t free_arm; // 1 = vgear désactivé, moteur libre -static uint16_t pos_left; // limite gauche (1/10 mm) -static uint16_t pos_right; // limite droite (1/10 mm) -static volatile arm_state_t state; // état courant de la machine -static volatile uint16_t arm_pos; // position courante en micropas depuis LEFT -static volatile uint16_t wait_ctr; // compteur steps SPOOL pour les pauses -static uint16_t travel_steps; // micropas pour aller de LEFT à RIGHT +static volatile uint16_t gear_um; // déplacement µm par tour SPOOL +static volatile uint32_t accumulator; // accumulateur µm +static uint16_t arm_offset; // distance capteur home → origine (µm) +static volatile uint8_t free_arm; // 1 = vgear désactivé, moteur libre +static uint16_t pos_left; // limite gauche (1/10 mm) +static uint16_t pos_right; // limite droite (1/10 mm) +static volatile arm_state_t state; // état courant +static volatile uint16_t wait_ctr; // compteur steps SPOOL pour les pauses +static uint16_t travel_steps; // micropas pour aller de LEFT à RIGHT // ───────────────────────────────────────────── // Calcul du trajet LEFT→RIGHT en micropas -// (pos_right - pos_left) en 1/10mm → µm → micropas // ───────────────────────────────────────────── static uint16_t ARM_CalcTravelSteps(void) @@ -60,7 +59,6 @@ void ARM_Init(void) pos_left = ARM_LEFT_DEFAULT; pos_right = ARM_RIGHT_DEFAULT; state = ARM_IDLE; - arm_pos = 0; wait_ctr = 0; travel_steps = ARM_CalcTravelSteps(); @@ -71,7 +69,7 @@ void ARM_Init(void) } // ───────────────────────────────────────────── -// Enable / Dir — appelés depuis homing ou PLC +// Enable / Dir // ───────────────────────────────────────────── void ARM_Enable(uint8_t state_en) @@ -85,10 +83,12 @@ void ARM_SetDir(uint8_t dir) } // ───────────────────────────────────────────── -// Step — appelé depuis l'ISR SPOOL +// UpdateTarget — appelée depuis l'ISR SPOOL +// Machine d'état légère : accumule µm et met +// à jour arm_target_position (pas de steps ici) // ───────────────────────────────────────────── -void ARM_Step(void) +void ARM_UpdateTarget(void) { if (free_arm || gear_um == 0) return; @@ -99,19 +99,15 @@ void ARM_Step(void) break; case ARM_GO_TO_ZERO: - // Déplacement vers LEFT — on décrémente arm_pos accumulator += gear_um; while (accumulator >= ARM_UM_PER_REV) { accumulator -= ARM_UM_PER_REV; - if (arm_pos > 0) { - ARM_HSTEP(); - arm_pos--; - } else { - // Arrivée à LEFT + if (arm_target_position > 0) + arm_target_position--; + else { accumulator = 0; wait_ctr = 0; state = ARM_WAIT_LEFT; - ARM_REV(ARM_DIR_RIGHT); } } break; @@ -120,24 +116,22 @@ void ARM_Step(void) wait_ctr++; if (wait_ctr >= ARM_WAIT_STEPS) { wait_ctr = 0; - state = ARM_TRAVERSE; + ARM_REV(ARM_DIR_RIGHT); + state = ARM_TRAVERSE; } break; case ARM_TRAVERSE: - // Déplacement vers RIGHT accumulator += gear_um; while (accumulator >= ARM_UM_PER_REV) { accumulator -= ARM_UM_PER_REV; - if (arm_pos < travel_steps) { - ARM_HSTEP(); - arm_pos++; - } else { - // Arrivée à RIGHT + if (arm_target_position < travel_steps) + arm_target_position++; + else { accumulator = 0; wait_ctr = 0; - state = ARM_WAIT_RIGHT; ARM_REV(ARM_DIR_LEFT); + state = ARM_WAIT_RIGHT; } } break; @@ -151,19 +145,16 @@ void ARM_Step(void) break; case ARM_RETURN: - // Déplacement vers LEFT accumulator += gear_um; while (accumulator >= ARM_UM_PER_REV) { accumulator -= ARM_UM_PER_REV; - if (arm_pos > 0) { - ARM_HSTEP(); - arm_pos--; - } else { - // Arrivée à LEFT + if (arm_target_position > 0) + arm_target_position--; + else { accumulator = 0; wait_ctr = 0; - state = ARM_WAIT_LEFT; ARM_REV(ARM_DIR_RIGHT); + state = ARM_WAIT_LEFT; } } break; @@ -172,7 +163,6 @@ void ARM_Step(void) // ───────────────────────────────────────────── // GO_TO_ZERO — retour à LEFT, nouvelle bobine -// appelé depuis REG_CTRL bit12 // ───────────────────────────────────────────── void ARM_GoToZero(void) diff --git a/src/spool.c b/src/spool.c index c78733c..4ef1942 100644 --- a/src/spool.c +++ b/src/spool.c @@ -1,5 +1,6 @@ #include #include +#include // ───────────────────────────────────────────── // État interne @@ -7,6 +8,10 @@ static volatile uint16_t reload; static volatile uint8_t running; +static uint16_t ratio; +static uint16_t current_freq; + +volatile uint16_t arm_target_position; // position cible ARM en micropas, mise à jour par ISR // ───────────────────────────────────────────── // Calcul du reload Timer5 @@ -16,7 +21,7 @@ static volatile uint8_t running; static uint16_t SPOOL_CalcReload(uint16_t hz) { - return (uint16_t)(65536UL - (8000000UL / ((uint32_t)hz * 2))); + return (uint16_t)(65536UL - (8000000UL / ((uint32_t)hz * 2UL))); } // ───────────────────────────────────────────── @@ -25,23 +30,26 @@ static uint16_t SPOOL_CalcReload(uint16_t hz) void SPOOL_Init(void) { - reload = 0; - running = 0; + reload = 0; + running = 0; + arm_target_position = 0; + ratio = EE_ReadWord(EE_SPOOL_RATIO_H, EE_SPOOL_RATIO_L); + if (ratio == 0) ratio = 1000; MOTOR_EN(0); MOTOR_REV(0); - // Timer5 off, prescaler 1:1, 16bit, Fosc/4 T5CON = 0b00000000; TMR5H = 0; TMR5L = 0; PIR3bits.TMR5IF = 0; - IPR3bits.TMR5IP = 0; // basse priorité + IPR3bits.TMR5IP = 1; // haute priorité PIE3bits.TMR5IE = 1; } // ───────────────────────────────────────────── -// ISR Timer5 — basse priorité +// ISR Timer5 — haute priorité +// Génère le step SPOOL, délègue ARM au main // ───────────────────────────────────────────── void SPOOL_TimerISR(void) @@ -51,12 +59,11 @@ void SPOOL_TimerISR(void) TMR5L = reload & 0xFF; MOTOR_HSTEP(); - ARM_Step(); + ARM_UpdateTarget(); // machine d'état ARM — met à jour arm_target_position } // ───────────────────────────────────────────── // Écriture registre CTRL (0x0800) -// bit15 = ENABLE, bit14 = DIR // ───────────────────────────────────────────── void SPOOL_SetCtrl(uint16_t ctrl) @@ -64,8 +71,6 @@ void SPOOL_SetCtrl(uint16_t ctrl) MOTOR_EN((ctrl & CTRL_SPOOL_ENABLE) ? 1 : 0); MOTOR_REV((ctrl & CTRL_SPOOL_DIR) ? 1 : 0); ARM_SetFree((ctrl & CTRL_ARM_FREE) ? 1 : 0); - - // CTRL_ARM_HOMING : one-shot, traité dans RTU_Task } // ───────────────────────────────────────────── @@ -74,27 +79,40 @@ void SPOOL_SetCtrl(uint16_t ctrl) void SPOOL_SetFreq(uint16_t hz) { + if (hz == current_freq) + return; + + current_freq = hz; + if (hz == 0) { - // Arrêt — timer off, position maintenue par ENABLE T5CONbits.TMR5ON = 0; running = 0; return; } - // Clamping if (hz < SPOOL_FREQ_MIN) hz = SPOOL_FREQ_MIN; if (hz > SPOOL_FREQ_MAX) hz = SPOOL_FREQ_MAX; reload = SPOOL_CalcReload(hz); if (!running) { - // Premier démarrage — charger le timer et démarrer TMR5H = reload >> 8; TMR5L = reload & 0xFF; PIR3bits.TMR5IF = 0; T5CONbits.TMR5ON = 1; running = 1; } - // Si déjà running, le nouveau reload sera pris en compte - // au prochain débordement dans l'ISR +} + +// ───────────────────────────────────────────── +// Écriture registre RATIO (0x0806) + EEPROM +// ───────────────────────────────────────────── + +void SPOOL_SetRatio(uint16_t milli) +{ + if (milli == 0) milli = 1; + ratio = milli; + EE_WriteWord(EE_SPOOL_RATIO_H, EE_SPOOL_RATIO_L, milli); + if (running && current_freq > 0) + reload = SPOOL_CalcReload(current_freq); } \ No newline at end of file