stepper seriale

ciao a tutti

ho fatto un circuitino per pilotare uno stepper tramite seriale.
Il booster dello stepper è quello classico a 2 fili corretto con le resistenze di pull-up.
Praticamente mi sto divertendo a tirare su e giù una pallina tramite comandi seriali, ma il codice è il più brutto che io abbia mai scritto ;D

#include <Stepper.h>

Stepper myStepper(100,5,6);
long int steps =0;
int incomingByte = 0;      // for incoming serial data
char commandbuffer[2];

void setup() {
      Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps
        myStepper.setSpeed(600);
}

void loop() {
 
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // say what you got:
    Serial.print("Step = ");
    if(incomingByte == 'z'){ 
              myStepper.step(10000);
              steps = steps +10000;
              Serial.println(steps);              
            }
    if(incomingByte == 'x'){ 
              myStepper.step(-10000);
              steps = steps -10000;
              Serial.println(steps);              
            }
    if(incomingByte == 'a'){ 
              myStepper.step(100);
              steps = steps +100;
              Serial.println(steps);              
            }
            if(incomingByte == 'q'){          
              myStepper.step(1000);
              steps = steps +1000;
              Serial.println(steps);              
            }
            if(incomingByte == 'w'){
              myStepper.step(-1000);
              steps = steps -1000;
              Serial.println(steps);              
            }
            if(incomingByte == 's'){
              myStepper.step(-100);
              steps=steps-100; 
              Serial.println(steps);
            }
            if(incomingByte == 'r'){
            steps =0;
            Serial.println(steps);
            }
            
          if(incomingByte != 'r' && incomingByte != 'w' && incomingByte != 's' && incomingByte != 'z' && incomingByte != 'x' && incomingByte != 'a' && incomingByte != 'q'){
            Serial.println("wrong key");
          }
          }
     
}

Vorrei mettere due comandi unici, solo che non ho capito molto del buffer per infilarci i comandi.
Volevo crearmi un array di comando in cui mi vengono messi tutti i dati che spedisco su seriale es
u = 123000
e lo stepper fa 123000 passi in una direzione (in questo caso in alto), oppure d =123000 e lo stepper va nella direzione inversa di 123000 passi.

qualche hint? magari vi servirà pure per la cnc... appena avrò più driver provo a fare una cosa a 3 stepper ;D ...
Per gli stepper vi consiglio di andare nelle assistenze delle stampanti e chiedere le stampanti rotte :smiley:

ciao Calamaro
Non ho capito che problema hai. Puoi spegarti meglio?
Ciao Uwe

vorrei mandare dei comandi seriali tipo up e down , magari uno stop e un reset della posizione.
ma mi basterebbe capire come interpretare dal lato arduino un comando seriale tipo up 150000. Poi dopo mi farò il down, il cambio di velocità e il resto.
se mi son spiegato male cerco di fare un video domani sera e di postare altro codice :smiley:

non c'è reset di posizione, ma puoi mandare comandi per fare girare da una parte o dall'altra il motore
dovrebbe essere abbastanza semplice anche settare la velocità di rotazione...

in questo esempio ho lavorato su un motore recuperato da una stampante con il suo driver, avevo dovuto modificare la lib stepper, ma solo per una questione di driver non dovrebbe cambiare nel codice.

c'è anche il codice per una GUI in py (richiede wx) per mandare i comandi...

http://blog.lampugnani.org/arduino/motori-passo-passo-ed-elettronica/

spero ti sia di aiuto...

ciao Calamaro
Allora il tuo problema é che vorresti leggere dalla seriale non lettere singole ma una stringa?
Ciao Uwe

grazie t30,
@uwe voglio leggere una stringa di lunghezza indefinita o anche di lunghezza definita se è più semplice :smiley:

dopo studierò quel codice :smiley:

edit però boh non lo capisco vediamo se riesco a tirarne fuori qualcosa allora

byte nextByte() {
  while(1) {
    if(Serial.available() > 0) {
      byte b = Serial.read();
      return b;
    }
  }
}

Questa funzione praticamente, mi legge i cararatteri che arrivano sulla seriale e li mette nella variabile b sottoforma di byte. quindi un insieme di 8 uni e zeri.

if (nextByte() == 126) { // header byte ('~' character) step command
    char args[] = {:-*//<---
0,0,0,0    }; //<---
    char charIn = 0;
    byte i = 0;
    while (charIn != 35) { // wait for header byte again
      charIn = nextByte();
      args[i] = charIn;
      i +=1;
    }
    int steps = (args[1]-48)*100+(args[2]-48)*10+(args[3]-48);//<---
    if (args[0] == 45 ) steps = steps * (-1);//<---
    Serial.print("rotazione di ");
    Serial.print(args[0]);
    Serial.print(args[1]);
    Serial.print(args[2]);
    Serial.print(args[3]);
    Serial.println(" step");
    turn(steps);
  }

se gli arriva quel carattere tilde lui cosa fa? non capisco le funzioni che ho commentato con //<--- ma in linea di massima quando gli arriva tilde e qualcosa lui fa i passi. mentre se gli arriva il carattere 64 cambia la velocità. serial.flush è uno sciacquone per i dati?

Il programma fa quello che mi serve :smiley:

inizializza un matrice dove salverà i dati che recupera dalla seriale ( sono un po' mongoloide con i puntatori... :smiley: )

char args[] = {
0,0,0,0    };

Converte cio' che legge dalla seriale in un int da passare successivamente

int steps = (args[1]-48)*100+(args[2]-48)*10+(args[3]-48);//<---

Se vede il meno davanti al numero di step .... moltiplica per -1

    if (args[0] == 45 ) steps = steps * (-1);//<---

Con il carattere tilde prende il comando "step", ed esegue il numero di step inviato in un senso o nell'altro in funzione del segno.

Se invece che la tilde usi il 64 (@) il comando che passi viene interpretato come una velocità da settare, quindi al successivo comando con ~, la velocità di rotazione sarà quella appena settata

tranquillo, io ho dato fondamenti di informatica e non sapevo neanche cosa fossero i puntatori... li sto scoprendo ora per la prima volta ;D
quindi il comando che si aspetta è una roba tipo
~1304123@300

edit scusa ho letto solo ora i comandi sul tuo blog, sono un fagiano :stuck_out_tongue:

tranquillo, io ho dato fondamenti di informatica e non sapevo neanche cosa fossero i puntatori... li sto scoprendo ora per la prima volta

io ho dato ben piu' di fondamenti di informatica... avrei anche una laurea in ingegneria (biomedica ma semplre ingegneria...) i puntatori li avevo studiati ma non ho mai capito bene come usarli... cma passiamo oltre.. :smiley:

edit scusa ho letto solo ora i comandi sul tuo blog, sono un fagiano

LOL

Se hai bisogno qualche altra dritta... io resto sintonizzato sul thread :smiley:

boh sembra che non legga i comandi...
io ho un'altro ide rispetto al tuo, sono su linux con arduino 0018
ora come ora non ho attaccato arduino alla breadboard perchè dovrei montare tutto l'ambaradam con cavi passanti su mensole ecc ecc... però ho messo LED al posto di MOTOR (quindi se mi entra in modalità "steps" lo vedo con il led) e al posto del tilde ho messo l'ascii hex 21 che sarebbe ! (per me è molto più facile da trovare ;D).
mando il comando -> rx si accende e fine. boh

edit mentre postavo hai postato tu e ti ringrazio per l'aiuto :smiley:

ora non ricordo a che IDE eravamo quando ho fatto quello sketch...
in ogni caso io ora sono su
IDE Arduino 018
slackware 12.2 / 13 (dipende se sto in casa o in lab :smiley: )

conta che con motori stepper dovresti mettere 4 led e li vedresti lampeggiare... non è un motore in CC che metti il led e si accende o spegne o al massimo va piu' forte o piu' piano...

si si lo so ma io uso quello schema che con 2 pin muovi lo stepper... lo schema funziona bene come puoi vedere anche da qui stepper with gears + arduino diecimila! - YouTube
ho visto che lo usi anche tu solo che io uso arduino diecimila (limited edition ahahah che pro eh? ;D) quindi cambio la funzione Stepper in questo modo Stepper stepper(STEPS, 5, 6); ma alla fine non credo che cambi nulla a livello di seriale. é proprio la seriale che non mi risponde. cioè ho visto dal tuo video che tu mandi un comando e la scheda ti risponde, a me non risponde.
Anche se la scheda non è collegata alla breadboard con tutto il circuito per pilotare lo stepper, comunque dovrebbe rispondermi perchè alla fine la board riceve input seriali e li trasforma in output.
uhm devo provare a mettere dei Serial.print per vedere cosa riceve.

cmq la tilde in linux si fa con AltGr+ì (il tasto a sx del backspace)
tastiera it e layout it ovviamente...

rieccomi :smiley:

allora ho modificato un po' di codice e ora però sclera un pochetto...

    if (nextByte() == 33) { // header byte ('!' character) step command
   // Serial.println(nextByte());
    char args[] = {0,0,0,0};
    char charIn = 0;
    byte i = 0;
    while (charIn != 43) { // wait for header byte again
      charIn = nextByte();
      args[i] = charIn;
      i +=1;
    }
    int steps = (args[1]-48)*100+(args[2]-48)*10+(args[3]-48);
    if (args[0] == 45 ) steps = steps * (-1);
    Serial.print("rotazione di ");
    Serial.print(steps);
   // Serial.print(args[0]);
  //  Serial.print(args[1]);
   // Serial.print(args[2]);
    //Serial.print(args[3]);
    Serial.println(" step");
    turn(steps);
  }

do ad esempio !+230! e mi risponde
Ready!
rotazione di -5328 step

poi smette di rispondere :S

#include <Stepper.h>
//define light led during motor turn
#define LED 13
// change this to the number of steps on your motor
#define STEPS 200
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper(STEPS, 5, 6);
// the previous reading from the analog input
int pos =0;
int previous = 0;
int turn(int steps){
digitalWrite(LED, HIGH);
  stepper.step(steps);
digitalWrite(LED, LOW);
}
byte nextByte() {
  while(1) {
    if(Serial.available() > 0) {
      byte b = Serial.read();
      return b;
    }
  }
}
void setup()
{
  // set the speed of the motor to 30 RPMs
  stepper.setSpeed(10);
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
  Serial.println("Ready!");
}
void loop()
{
    
    if (nextByte() == 33) { // header byte ('!' character) step command
   // Serial.println(nextByte());
    char args[] = {0,0,0,0};
    char charIn = 0;
    int i = 0;
    while (i<4) { // wait for header byte again
      charIn = nextByte();
      args[i] = charIn;
      i +=1;
    }
    int steps = (args[1]-48)*100 + (args[2]-48)*10 + (args[3]-48);
    if (args[0] == 45 ) steps = steps * (-1);
    pos = pos + steps;
    Serial.print("rotazione di ");
    Serial.print(steps);
    Serial.println(" step");
    Serial.print("posizione attuale =");
    Serial.println(pos);
    Serial.println("Aspetta");
    turn(steps);
  }
    else if (nextByte() == 64) {
    char args[] = {0,0,0};
    char asd;
    int i = 0;
    while (i<3) { // wait for header byte again
      args[i] = nextByte();
      i +=1;
    }
    int rpm = ((args[0]-48)*100+(args[1]-48)*10+(args[2]-48));
    Serial.print("Settaggio a ");
    Serial.print(rpm);
    Serial.println(" rmp");
    stepper.setSpeed(rpm);
    }
    else if (nextByte() == 114) {
    pos = 0;
    Serial.println("posizione azzerata");
    }
    Serial.println("Comunicazione Abilitata");
    Serial.flush();
}

ora mi funziona

il comando per gli step è !+999! e per la velocità è @@999 ora proverò a mettere gli step a 5 cifre e la velocità senza un @.

Beh si puo' dire che hai creato un protocollo.
Complimenti! :smiley:

vabbè ho solo modificato il codice di t30 niente di che :smiley: ora devo provarlo perchè non è detto che funzioni con ste modifiche.