Problema con motore stepper

Salve, ho bisogno di aiuto con motore stepper. Ho realizzato un progetto tratto da questo tutorial. Lo stesso si occupa di movimentare una slitta tramite inserimento della misura da keypad. Descrivo la configurazione usata: Arduino Mega, Motore passo-passo 24V, Driver TB6600 tb67s109, Keypad 12 tasti, LCD Nokia 5110.
Il problema principale è che la misura massima digitabile è di mm. 999 mentre a me occorre una corsa di mm.3000 quindi ho modificato lo sketch in questo modo:

#include <AccelStepper.h> // AccelStepper Library
#include <Keypad.h>  // Keypad Library
#include "U8glib.h"  // U8glib for Nokia LCD

// Variables to hold entered number on Keypad
volatile int firstnumber=99;  // used to tell how many numbers were entered on keypad
volatile int secondnumber=99;
volatile int thirdnumber=99;
volatile int fourthnumber=99;

// Variables to hold Distance and CurrentPosition
int keyfullnumber=0;  // used to store the final calculated distance value
String currentposition = "";  // Used for display on Nokia LCD


// Keypad Setup
const byte ROWS = 4; // Four Rows
const byte COLS = 4; // Four Columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {22, 24, 26, 28}; // Arduino pins connected to the row pins of the keypad
byte colPins[COLS] = {31, 33, 35, 37}; // Arduino pins connected to the column pins of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );  // Keypad Library definition


// U8glib Setup for Nokia LCD
#define backlight_pin 11
U8GLIB_PCD8544 u8g(3, 4, 6, 5, 7);  // Arduino pins connected to Nokia pins:
                                    // CLK=3, DIN=4, CE=6, DC=5, RST=7
                                    
                                    
// AccelStepper Setup
AccelStepper stepper(1, A0, A1);  // 1 = Easy Driver interface
                                  // Arduino A0 connected to STEP pin of Easy Driver
                                  // Arduino A1 connected to DIR pin of Easy Driver
                                  


void setup(void) {
  
  //  Light up the LCD backlight LEDS
  analogWrite(backlight_pin, 0);  // Set the Backlight intensity (0=Bright, 255=Dim)
    
  //  AccelStepper speed and acceleration setup
  stepper.setMaxSpeed(1500);  // Not to fast or you will have missed steps
  stepper.setAcceleration(400);  //  Same here
  
  // Draw starting screen on Nokia LCD
  u8g.firstPage();
  do {
  u8g.drawHLine(0, 15, 84);
  u8g.drawVLine(50, 16, 38);
  u8g.drawHLine(0, 35, 84); 
  u8g.setFont(u8g_font_profont11);
  u8g.drawStr(0, 10, "DIGITA MISURA");
  u8g.drawStr(62, 29, "MM");
  u8g.drawStr(4, 46, "MISURA");
  }
  while( u8g.nextPage() );
  
}


void loop(){
  
  char keypressed = keypad.getKey();  // Get value of keypad button if pressed
  if (keypressed != NO_KEY){  // If keypad button pressed check which key it was
    switch (keypressed) {
      
      case '1':
        checknumber(1);
      break;
        
      case '2':
        checknumber(2);
      break;

      case '3':
        checknumber(3);
      break;

      case '4':
        checknumber(4);
      break;

      case '5':
        checknumber(5);
      break;

      case '6':
        checknumber(6);
      break;

      case '7':
        checknumber(7);
      break;

      case '8':
        checknumber(8);
      break;

      case '9':
        checknumber(9);
      break;

      case '0':
        checknumber(0);
      break;

      case '*':
        deletenumber();
      break;

      case '#':
        calculatedistance();
      break;
    }
  }

}

void checknumber(int x){
  if (firstnumber == 99) { // Check if this is the first number entered
    firstnumber=x;
    String displayvalue = String(firstnumber);  //  Transform int to a string for display
    drawnokiascreen(displayvalue); // Redraw Nokia lcd
    
  } else {
    if (secondnumber == 99) {  // Check if it's the second number entered
      secondnumber=x;
      String displayvalue = (String(firstnumber) + String(secondnumber));
      drawnokiascreen(displayvalue);
  } else {
    if (thirdnumber == 99) {  // Check if it's the 3rd number entered
      thirdnumber=x;
      String displayvalue = (String(firstnumber) + String(secondnumber) + String(thirdnumber));
      drawnokiascreen(displayvalue);

    } else {  // It must be the 3rd number entered
      fourthnumber=x;
      String displayvalue = (String(firstnumber) + String(secondnumber) + String(thirdnumber) + String(fourthnumber));
      drawnokiascreen(displayvalue);

      }
    }
  }
}

 
void deletenumber() {  // Used to backspace entered numbers
    if (fourthnumber !=99) {
      String displayvalue = (String(firstnumber) + String(secondnumber) + String(fourthnumber));
      drawnokiascreen(displayvalue);

    fourthnumber=99;
  } 
  else {  
   if (thirdnumber !=99) {
      String displayvalue = (String(firstnumber) + String(secondnumber));
      drawnokiascreen(displayvalue);

    thirdnumber=99;
  } 
  else {
    if (secondnumber !=99) {
      String displayvalue = String(firstnumber);
      drawnokiascreen(displayvalue);

      secondnumber=99;
   } 
   else {
     if (firstnumber !=99) {
       String displayvalue = "";
       drawnokiascreen(displayvalue);

       firstnumber=99;
        }
      }
    }
  }
}
  
void calculatedistance() {  // Used to create a full number from entered numbers

    if (fourthnumber == 99 && thirdnumber == 99 && secondnumber == 99 && firstnumber != 99) {
      keyfullnumber=firstnumber;
      movestepper(keyfullnumber);
    }
    
    if (secondnumber != 99 && thirdnumber == 99 && fourthnumber == 99) {
      keyfullnumber=(firstnumber*10)+secondnumber;
      movestepper(keyfullnumber);
    }
    
    if (thirdnumber != 99 && fourthnumber == 99) {
      keyfullnumber=(firstnumber*100)+(secondnumber*10)+thirdnumber;
      movestepper(keyfullnumber);
    }
        
    if (fourthnumber != 99) {
      keyfullnumber=(firstnumber*1000)+(secondnumber*100)+(thirdnumber*10)+fourthnumber;
      movestepper(keyfullnumber);
    }
    
    resetnumbers(); // Reset numbers to get ready for new entry
  } 


void movestepper(int z) {  //  Move the stepper

  int calculatedmove=((z*1600)/80);  //  Calculate number of steps needed in mm
  stepper.runToNewPosition(calculatedmove);
  currentposition = String(z);
  u8g.firstPage();
  do {
    u8g.drawHLine(0, 15, 84);
    u8g.drawVLine(50, 16, 38);
    u8g.drawHLine(0, 35, 84); 
    u8g.setFont(u8g_font_profont11);
    u8g.drawStr(0, 10, "DIGITA MISURA");
    u8g.drawStr(62, 29, "MM");
    u8g.drawStr(4, 46, "MISURA");
    u8g.setPrintPos(57,47);
    u8g.print(currentposition);       
  }
  while( u8g.nextPage() ); 
}
                
void resetnumbers() {  // Reset numbers for next entry
  firstnumber=99;
  secondnumber=99;
  thirdnumber=99;
  fourthnumber=99;
} 
  

void drawnokiascreen(String y) {

    u8g.firstPage();
    do {
      u8g.drawHLine(0, 15, 84);
      u8g.drawVLine(50, 16, 38);
      u8g.drawHLine(0, 35, 84); 
      u8g.setFont(u8g_font_profont11);
      u8g.drawStr(0, 10, "DIGITA MISURA");
      u8g.setPrintPos(0,29);
      u8g.print(y);  // Put entered number on Nokia lcd    
      u8g.drawStr(62, 29, "MM");
      u8g.drawStr(4, 46, "MISURA");
      u8g.setPrintPos(57,47); 
      u8g.print(currentposition);  //  Display current position of stepper
    }
      while( u8g.nextPage() );

}

Il problema è che se digito misure da 0 a mm. 1640 il motore mi calcola le varie misure correttamente sia in addizione che in sottrazione, superata quella soglia, il motore inizia a girare in senso antiorario, praticamente torna indietro invece di sommare. Non riesco a capire il perchè di questo comportamento. Vi allego un documento di testo con i due codici, l'originale e quello da me modificato. Vi prego di dargli un'occhiata e, se possibile, darmi qualche dritta!
Vi ringrazio anticipatamente
Saluti
Cappuccio Domenico

Sketch_motore_stepper.txt (13.6 KB)

Non ho esaminato il codice, ma letto solo ciò che dici, e mi viene in mente che potrebbe esserci un "overflow" su qualche operazione che fai ... se un "int" positivo, va in "overflow" ... da un numero negativo e non so se questa potrebbe essere la causa.

Attenzione specie nelle moltiplicazioni ... nel dubbio, usare sempre i suffissi dei numeri per indicare il tipo (... o usare l'operatore di cast) ... e verifica che in una formula, nessuna parte possa superare, per gli int, i valori +32767 .. -32768.

Guglielmo

Comunque secondo me il TB6600 non puó pilotare bene un motore da 24V.
Secondo me il problema sta nel
int calculatedmove=((z1600)/80);
Dove z
1600 diventa piú grande di 32767

per primo perché fai 1600 e poi /80?
perché non moltiplichi per 20?
Poi anche una distanza da 3000 moltiplicata per 20 supera il range acettabile dei int.
Devi usare delle variabili long e fare anche il cast
long calculatedmove=(z
20L);

Ciao Uwe

Prima di tutto grazie per le risposte, il fatto è che non conosco le specifiche del motore, sull'etichetta è riportato solo l'alimentazione ed il n° matr. per poterlo identificare l'ho dovuto smontare ed ho visto che ha 8 bobine collegate tra loro in serie da due con 8 fili(Unipolare che ho collegato in serie in configurazione bipolare a 4 fili), mentre sul rotore sono poste 4 corone dentate. Non sò quanti step o microstep totali per giro. Quindi mi sono attenuto all'esempio del tutorial dove viene calcolato un motore avente totale di 200 step per giro moltiplicato per 1/8 step del easydriver (200x8=1600) mentre considerando che la puleggia del motore è fatta da 40 denti con interasse 2 mm. quindi 80mm. per giro. per quanto concerne il driver TB6600 posso, tramite switch, selezionare sia la corrente che attraversa il motore che il numero di microstep e pulse/rev. Considerando che, come avete avuto modo di capire, non essendo io un asso in programmazione, mi risulta abbastanza difficile risolvere la problematica. Spero che le informazioni su descritte vi siano di aiuto e vi ringrazio.
PS. Nel video del tutorial viene spiegato il discorso "calculatedmove" ma sfortunatamente io non capisco una mazza di inglese!
Cappuccio Domenico.

Ok, risolto con il consiglio di Uwefed, ho usato la variabile "long calculatedmove=(z*40L);" e va che è una meraviglia. Adesso vorrei sottoporre un'altra questione:
Arduino non ha memoria, quindi, nella ipotesi che il carrello sia in una posizione centrale e ci sia una interruzione di corrente, alla riaccensione del sistema mi ritroverei un display che mi segna posizione 0 mm. con un carrello a 1500 mm. Da qui l'esigenza di creare un reset carrello. Avevo pensato ad un pulsante ed un sensore di prossimità. Chiaramente il sistema non dovrà funzionare fin quando non avviene il reset. Chiedo aiuto e consigli in riguardo. Come già anticipato nel post precedente non sono un esperto di programmazione.
Non so come ringraziarvi!
Saluti
Cappuccio Domenico