Ciao a tutti. Vi espongo il mio problema nella speranza di ricevere qualche idea.
Ho un attuatore AT1 che usa un motore M1 per funzionare. Per coprire tutta la corsa utile del attuatore AT1 il motore M1 compie 19 giri. Sul albero del motore M1 è montato un sensore S1 as5600. Il motore M1 è comandato tramite un h-bridge bts7960. Mentre si avvicina alla fine della corsa il motore deve rallentare. Durante il normale funzionamento invece deve rispondere velocemente al comando mandato tramite il potenziometro P1. All'avviamento il motore fa Hominig. La finecorsa è rilevata all'avviamento con la seguente logica:
Pwm dal 30% a 50% in rampa per 200ms poi valuta se il motore gira tramite sensore AS5600. Se l'angolo rilevato è inferiore a X nell'unita di tempo Y considera homing avvenuto. Voglio comandare la corsa del motore tramite un potenziometro P1. Potenziometro tutto a destra motore tutto a destra, potenziometro tutto a sinistra motore tutto a sinistra. Dopo homing il motore si posiziona in funzione del potenziometro. Ovviamente non tiene conto del potenziometro durante homing.
Ho fatto tanti test con l'aiuto dell'AI ma non ho ottenuto i risultati sperati.
Devo anche dire che nel mio caso il sensore di corrente integrato nel modulo bts7960 non è lineare e su un canale presenta un valore incoerente anche a zero ampere. Quindi ho abbandonato l'idea di ricavare il finecorsa usando il valore del consumo di corrente.
Questo codice per homing per esempio funziona
#include <Wire.h>
#include <AS5600.h>
// === PIN CONFIG ===
#define RPWM_PIN 5
#define LPWM_PIN 6
// === PWM CONFIG ===
#define PWM_START 92
#define PWM_MAX 110
#define PWM_STEP 1
#define PWM_DELAY 20
// === HOMING PARAMETRI ===
#define NO_MOVEMENT_TIMEOUT 200 // ms
#define MIN_ANGLE_CHANGE_DEG 1 // °
#define IGNORE_MOVEMENT_TIME 20 // ms di attesa prima di controllare angolo
AS5600 as5600;
// === VARIABILI ===
int pwmValue = PWM_START;
int lastAngleForPosition = 0;
int lastAngleForHoming = 0;
long absolutePosition = 0;
unsigned long lastMovementTime = 0;
// ✅ Calcolo differenza angolare con rollover gestito
int calculateAngleDifference(int a, int b) {
int diff = a - b;
if (diff > 180) diff -= 360;
if (diff < -180) diff += 360;
return abs(diff);
}
void updateAbsolutePosition(int currentAngle) {
int delta = currentAngle - lastAngleForPosition;
if (delta > 180) delta -= 360;
if (delta < -180) delta += 360;
// Inverti il segno perché il sensore "gira al contrario" rispetto al codice
absolutePosition -= delta;
lastAngleForPosition = currentAngle;
}
void driveMotor(int pwm) {
analogWrite(RPWM_PIN, 0);
analogWrite(LPWM_PIN, pwm);
}
void stopMotor() {
analogWrite(RPWM_PIN, 0);
analogWrite(LPWM_PIN, 0);
}
void setup() {
Serial.begin(9600);
Wire.begin();
as5600.begin();
pinMode(RPWM_PIN, OUTPUT);
pinMode(LPWM_PIN, OUTPUT);
delay(300); // Stabilizzazione
int initialRaw = as5600.readAngle();
int initialAngle = map(initialRaw, 0, 4095, 0, 360);
lastAngleForHoming = initialAngle;
lastAngleForPosition = initialAngle;
lastMovementTime = millis();
Serial.println("⚙️ Inizio homing: PWM da 30 a 150...");
}
void loop() {
int rawAngle = as5600.readAngle();
int angleDeg = map(rawAngle, 0, 4095, 0, 360);
updateAbsolutePosition(angleDeg);
int angleChange = calculateAngleDifference(angleDeg, lastAngleForHoming);
Serial.print("PWM: ");
Serial.print(pwmValue);
Serial.print(" | Angolo AS5600: ");
Serial.print(angleDeg);
Serial.print("° | ΔAngolo: ");
Serial.print(angleChange);
Serial.print("° | Posizione: ");
Serial.println(absolutePosition);
if (angleChange >= MIN_ANGLE_CHANGE_DEG) {
lastMovementTime = millis();
lastAngleForHoming = angleDeg;
}
if (millis() - lastMovementTime >= NO_MOVEMENT_TIMEOUT) {
Serial.println("✅ Homing completato: angolo stabile.");
stopMotor();
while (true); // Fine programma
}
driveMotor(pwmValue);
}
Se possibile qualche idea su come gestire il problema e magari qualche esempio del genere in rete da dove poter prendere spunto.
Per quanto riguarda l'hardware non ci sono problemi poiche funziona tutto.
Il sensore AS5600 trasmette la lettura perche lo vedo in seriale.
Arduino genera Pwm perche lo vedo con oscilloscopio.
bts7960 funziona perche lo posso comandare con generatore di segnali.