Posizione attuatore in funzione del potenziometro

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.

Perché ripeti lo homing ad ogni loop?

Grazie mille per l'osservazione. In effetti va fatto solamente all'avvio per favore puoi darmi un codice di esempio su come fare eseguire una sola volta a l'azione?

No, grazie

se non sei in grado di capire quali righe spostare da una funzione all'altra su dell'hardware e del software scelti da te, figurati se posso farlo alla cieca io

puoi fare due cose:
o studi e capisci cosa stai facendo con quel codice e poi lo correggi oppure se hai fretta ti rivolgi ad un professionista
che comunque non sarò io: non mi interessa infilarmi nei tuoi problemi

i miei migliori auguri

Scusa, quale è la funzione che, in un .ino, viene eseguita una sola volta all'avvio?

Sposta quello che devi fare una sola volta all'avvio li dentro ... :roll_eyes:

Guglielmo

Se la loop la chiami homing e poi la chiami al termine del setup, dovresti stare a posto...subito dopo il

Serial.println("⚙️ Inizio homing: PWM da 30 a 150...");
homing();
1 Like

@kymya74 benvenuto nella sezione Italiana del forum,

... cortesemente, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15) e poi, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie
Alex

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Gentilmente chiedo al moderatore di rimuovere i contenuti non inerenti al tema.

@Jimmy: precisamente QUALI numeri di post?

Guglielmo

I post N° 6, 7, 8 oltre a non essere inerenti al tema sono anche offensivi nei miei confronti.

Bah ... sul fatto che siano "offensivi" NON sono d'accordo, che siano fuori tema ok ... li ho rimossi.

Guglielmo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.