interpolare i passi di due stepper

Ciao a tutti, facendo qualche esperimento con un paio di stepper unipolari, considerando che sono strumenti molto versatili.
La cosa che mi interessa molto degli stepper è che in genere sono alla base delle macchine cnc.
So che ci sono molte schede dedicate da connettere direttamente al computer, però mi interesserebbe di più riuscirci con arduino, magari per un piccolo plotter tanto per iniziare.
Di seguito un piccolo script che ho messo giù per provare a indagare la cosa, in sostanza si digitano sulla seriale due coordinate e arduino calcola i passi necessari per raggiungerle, muovendo un motore alla volta.
Dovrei a questo punto interpolare i passi, qualcuno sa aiutarmi o eventualmente suggerire una strada diversa e magari più semplice di quella seguita fino ad qui?
Grazie

#include <Stepper.h>

#define STEPS 48 //passi dello stepper


Stepper stepper(STEPS, 2, 4, 3, 5);
Stepper stepper2(STEPS, 6, 8, 7, 9);

int x = 0;          //input x da seriale
int y = 0;          //input y da seriale
int xpos = 0;       //posizione di x
int ypos = 0;       //posizione di y
int xdis = 0;       //passi complessivi necessari a x per raggiungere xpos
int ydis = 0;       //passi complessivi necessari a y per raggiungere ypos
int xlon = 0;       //valore assoluto di xdis (sempre >0)
int ylon = 0;       //valore assoluto di ydis (sempre >0)


void setup()
{
  Serial.begin(9600);
 
 
  stepper.setSpeed(100);
  stepper2.setSpeed(100);

}

void loop(){
   while (Serial.available() > 0) {
    
        x = Serial.parseInt();  //il numero prima della virgola è x
        y = Serial.parseInt();  //il numerodopo la virgola è y
        
        
         
    if (Serial.read() == '\n') //se premo invio i valori vengono letti
{
      
if(x == xpos && y == ypos)
{Serial.println("In posizione!");}  // se x e y sono giù in posizione si limita a dirlo

if(y != ypos && x != xpos || y != ypos && x == xpos || y == ypos && x != xpos)
{
 
if(x == xpos)
  {xdis=0;}

else if(x != xpos)
{
  if(x > xpos)
  { xdis = x-xpos;
  xpos=xpos+xdis;
 }
     if(x < xpos)
  { xdis = xpos-x;
   xpos=xpos-xdis;
   xdis=-xdis;
}
}

if(y == ypos)
  {ydis=0;}
  
  else if(y != ypos)
{
  if(y > ypos)
  { ydis = y-ypos;
  ypos=ypos+ydis;
 }
     if(y < ypos)
  { ydis = ypos-y;
   ypos=ypos-ydis;
   ydis=-ydis;
stepper2.step(ydis);

}  
}


xlon=abs(xdis);
ylon=abs(ydis);
 
  Serial.print("x= ");
  Serial.print(x);
  Serial.print("\t");
  Serial.print("xdis= ");
  Serial.print(xdis);
  Serial.print("\t");
  Serial.print("xpos= ");
  Serial.print(xpos);
  Serial.print("\t");
  Serial.print("xlon= ");
  Serial.println(xlon);
  
 
 Serial.print("x= ");
 Serial.print(y);
 Serial.print("\t");
 Serial.print("ydis= ");
 Serial.print(ydis);
 Serial.print("\t");
 Serial.print("ypos= ");
 Serial.print(ypos);
 Serial.print("\t");
 Serial.print("ylon= ");
 Serial.println(ylon);

 Serial.println("movimento x");
 stepper.step(xdis);
 Serial.println("x in posizione");
 Serial.println("--------------------------");
 
 Serial.println("movimento y");
 stepper2.step(ydis); 
 Serial.println("Y in posizione");
 Serial.println("--------------------------");
 
 Serial.println("////////////// DIGITARE NUOVE COORDINATE //////////////");




}



}}
}

L' unica cosa é fare passi piccoli e pilotare un motore dpo l'altro.
oppure usare dei driver per motore passo-passo tipo il EASYDRIVER o quello della Pololu che vengono pilotati con la direzione e un segnale rettangolare per i passi. In quel caso é piú semplice a fare i passi combinati per tutti le due direzioni.

Prova a vedere i Sketch per le varie stampanti 3D che usano Arduino.
Ciao Uwe

Ma forse per interpolare intende calcolare le coordinate da assumere data una funzione? Interpolazione - Wikipedia
O forse non sopporto questa materia scolastica fino al punto di ritrovarmela ovunque :smiley:

Sì forse mi esprimo male. Comuqnue ho presente i driver ma mi piacerebbe fare la cosa più semplice possibile, anche se la risoluzione non dovesse essere nulla di che.
Intendo dire questo: sono al punto x0,y0 voglio andare a x10,y5.
Ci sono 10 passi in una direzione e 5 nell'altra, e le posizioni intermedie.
Io vorrei che queste posizioni fossero:
x1, y1
x2, y1
x3, y2
x4, y2
x5, y3
x6, y3
x7, y4
x8, y4
x9, y5
x10, y5
Generandole in questo modo, il mio script saprebbe portare di volta in volta i motori nella posizione richiesta.

devi fare piccoli passi e non da 0,0 a 10,5 ma come scrivi pasi da 1,1 2,1 3,2 ecc

Ciao Uwe

Sò già che magari quello che ti sto per proporre non ti sarà molto simpatico, ma ti assicuro che è il metodo più preciso per ottenere esattamente ciò che cerchi, l'effetto è quello di una "naturalezza" nel movimento.
Magari troverai qualche metodo più "artigianale", io, però, da informatico/matematico mi sento di proporti la "strada" più idonea.
Deciderai se seguirla o meno :slight_smile:
Il fatto è che in questi casi la matematica aiuta.
Il sistema che ti propongo (e che ho usato con successo in circostanze simili) è quello delle coordinate polari, e, contrariamente al solito, è più facile a farsi che a dirsi.
Immagina il tragitto dal punto A(x0,y0) verso B(x1, y1) come l'ipotenusa del triangolo formato dai lati:
a=x1-x0
b=y1-y0
e l'ipotenusa c che varrà c= sqrt(a^2 + b^2).
Ora ti serve conoscere gli angoli che forma l'ipotenusa con i lati a e b, secondo la nota relazione del teorema di pitagora:
cos alpha = c/a
sen alpha = c/b
Ora che conosci il modulo c e gli angoli è facile trovare le coordinate x e y ricorrendo, appunto al metodo delle coordinate polari.
Puoi trattare, infatti, il tragitto tra A e B come uno scalare (un valore semplice) realizzando un banale ciclo che va da 0 a c (lunghezza del tragitto) e calcolando i punti x e y corrispondenti come:
x = c * cos alpha
y = c * sen alpha
in questo modo puoi anche stabilire facilmente a che velocità vuoi che si muovano gli stepper semplicemente incrementando la variabile da 0 a c con un passo a tuo piacimento.
Se vuoi qualche info supplementare sulle coordinate polari le trovi qui Sistema di coordinate polari - Wikipedia.

uwefed:
devi fare piccoli passi e non da 0,0 a 10,5 ma come scrivi pasi da 1,1 2,1 3,2 ecc

Ciao Uwe

Sì, certo ma lo script che avevo fatto le interpreta così, cioé quando da 5 deve andare a 6, consdera che la distanza è 1 e fa un passo.
Certo, ora se da zero gli dico 10 fa dieci passi, ma è questa la ragione per cui vorrei dirgli 1, 2, 3, 4, 5... lui farà 1 ogni volta o magari zero se ne ha di fila due uguali.
Gli sketch delle stampanti 3d che dicevi non li ho mai visti, anche se uno una ultimaker, però li carico come firmware senza l'ide...

A dabular... sì mi sta tutto molto antipatico! :slight_smile:
Il sistema polare l'avevo usato nel corso di rilievo, ad architettura.
Non sono ferratissimo di matematica ma adesso mi studio un po' la tua ipotesi perché comunque è molto utile anche per i cnc a pendolo, quelli tra due cavi sospesi, che mi hanno sempre intrigato.

Allora...ho più di un quarto di secolo di insegnamento alle spalle (azz...sono vecchio!! :astonished:) e se c'è una cosa che ho sempre cercato di fare per "mestiere" e missione è quella di far sembrare simpatiche anche le cose che non lo sono.
Ti ho detto che era più facile a farsi che a dirsi...e questa è la dimostrazione.
Questo breve codice scritto in pochi minuti mostra come venga eseguita l'interpolazione con il metodo suddetto.

int x0, y0;
float c, cosAlpha, sinAlpha;

void setup() {
  Serial.begin(9600);
  setPosition(0, 0, 10, 5);   // demo 1: va da (0,0) a (10,5)
  moveVector();                
  setPosition(20, 10, 10, 5); // demo 2: va da (20,10) a (10,5)
  moveVector();
  setPosition(50, 30, 25, 35); // demo 3: va da (50,30) a (25,35)
  moveVector();

}


void setPosition(int px0, int py0, int px1, int py1) {
  x0 = px0; y0 = py0;
  int x1 = px1; int y1 = py1;
  int a = x1-x0;
  int b = y1-y0;
  c = sqrt(pow(a,2) + pow(b,2));
  cosAlpha = a/c;
  sinAlpha = b/c;  
}

void moveVector() {
  for (float v=0; v<=c; v++) {
    float x = x0 + (v * cosAlpha);
    float y = y0 + (v * sinAlpha);
    Serial.print("x=");
    Serial.print(x);
    Serial.print("  y=");
    Serial.println(y);
  }  
  Serial.println("============================");
}

void loop() {

}

Questo metodo ha anche un altro fantastico vantaggio: sa DA SOLO in che direzione andare (magia dei quadranti trigonometrici).
Infatti come puoi vedere dai tre setPosition di demo, non ci sono if o altre diavolerie, per fargli sapere se il segmento deve andare a crescere o decrescere, perchè è il (seno e coseno del) l'angolo che risulterà essere positivo o negativo.

dalubar:
a=x1-x0
b=y1-y0
e l'ipotenusa c che varrà c= sqrt(a^2 + b^2).
Ora ti serve conoscere gli angoli che forma l'ipotenusa con i lati a e b, secondo la nota relazione del teorema di pitagora:
cos alpha = c/a
sen alpha = c/b
Ora che conosci il modulo c e gli angoli è facile trovare le coordinate x e y ricorrendo, appunto al metodo delle coordinate polari.
Puoi trattare, infatti, il tragitto tra A e B come uno scalare (un valore semplice) realizzando un banale ciclo che va da 0 a c (lunghezza del tragitto) e calcolando i punti x e y corrispondenti come:
x = c * cos alpha
y = c * sen alpha

  1. (la faccina degli applausi non l'ho trovata)

Da qui a passare ad un interpolazione a 3 assi è molto complicato?

Gli applausi glieli faccio io!
Personalmente non ci sarei arrivato, e alleggerisce molto il mio sketch.
Ho solo dovuto trasformare i float in integrali dopo averli calcolati perché gli stepper credo non accettino comandi diversi, comunque adesso ho le posizioni assolute e non mi resta che riapplicare il principio del vecchio sketch per far copiere un passo avanti, uno indietro o nessun passo a seconda dei casi, cosa che sto provando a fare.
Eh, non per dar la colpa a loro a temo che i miei insegnanti fossero diversi!

quello che vuoi fare è già stato fatto Txapuzas electrónicas: Txapu-CNC: Hardware

Gli applausi glieli faccio io!
Personalmente non ci sarei arrivato, e alleggerisce molto il mio sketch.

Grazie ma non c'è bisogno di applausi, quello che importa è che si sia capito il meccanismo.
Ho incontrato spesso degli "informatici" con la (errata) convinzione che la matematica non serva a costruire i loro programmi... :open_mouth:

quello che vuoi fare è già stato fatto Txapuzas electrónicas: Txapu-CNC: Hardware

Credo che ormai sia stato realizzato quasi tutto. Personalmente sono il primo che, quando può, non ri-inventa l'acqua calda (filosofia OOP, tra l'altro...) ma sono del parere che bisogna avere anche l'idea che sta alla base del principio di funzionamento di ciò che si usa.

Madwriter:
quello che vuoi fare è già stato fatto Txapuzas electrónicas: Txapu-CNC: Hardware

Quello che voglio fare è capire come funzionano le macchine cnc per essere più bravo a usarle, e non l'ho ancora fatto.
Per adesso proverò a convertire le coordinare ottenute con questo sistema in passi e poi a leggere una sequenza da un .csv, poi proverò con un gcode vero e proprio.
A proposito, vorrei ringraziare questa comunità perché mediamente non sarei riuscito a far lampeggiare nemmeno un led senza di essa, anche se i lampadari, a ben vedere, c'erano già :wink:

Se è per questo non è che sai come funziona una mcu(atmel 328) è sempre bene prendere spunto da ciò che è stato già fatto per poi capire,imparare e migliorare ciò che già c'è (: