Pagina 1 di 2

Affilare le eliche delle frese con Arduino

Inviato: sab gen 24, 2026 09:18
da ofranco
Buongiorno, ho intenzione di affilare le eliche delle frese con un sistema motorizzato a due assi. Uno che fa l'avanzamento longitudinale lungo la fresa e l'altro rotativo. In particolare inserendo i valori di avanzamento (passo) sui due assi l'utensile (mola) dovrebbe scorrere lungo la scanalatura dell'elica per affilarla.
Sono in cerca di uno sketch Arduino per pilotare due motori stepper.
Qui, sul forum non mi sembra che sia stato realizzato qualcosa di simile.
Grazie per l'aiuto che vorrete darmi. Franco

Re: Affilare le eliche delle frese con Arduino

Inviato: sab gen 24, 2026 09:50
da Piccio
Progetto ambizioso ti seguo

Re: Affilare le eliche delle frese con Arduino

Inviato: mar gen 27, 2026 16:46
da raunarde

Re: Affilare le eliche delle frese con Arduino

Inviato: mar gen 27, 2026 20:08
da lelef
molto bello la difficolta per me e^misurare il passo giusto, con la penna che forza la mola a seguire non ci si deve pensare, piu^grerzzo ma, lo ritengo un sistema molto piu^rapido

Re: Affilare le eliche delle frese con Arduino

Inviato: mar gen 27, 2026 21:15
da McMax
Non é complicatissimo. L'unica cosa é che gli stepper vanno pilotati coi timer e per farlo devi agire direttamente sui registri. Altra cosa da verificare é quanti timer ci sono disponibili (te ne servono minimo 2) considerando che uno, se non sbaglio, viene utilizzato dalle API di arduino non ricordo per fare cosa...

Re: Affilare le eliche delle frese con Arduino

Inviato: mer gen 28, 2026 13:10
da ofranco
raunarde ha scritto: mar gen 27, 2026 16:46 https://www.youtube.com/watch?v=VNDwdyo1ioI

tipo questo giusto?
Giusto proprio così. Io ritengo che la parte più problematica sia il software. Calcolare l’angolo di rampa o il passo della fresa non credo sia così difficile. Quello che deve fare tutto è lo sketch di Arduino. Io lo immagino così: Nelle impostazioni dovrebbero esserci i parametri della vite madre (scorrimento longitudinale) e della demoltiplica dove è fissata la fresa. Poi l’inserimento del passo della fresa.

Re: Affilare le eliche delle frese con Arduino

Inviato: mer gen 28, 2026 13:42
da lelef
a mio parere sarebbe comodissimo inserire un sistema che misuri da solo il passo dell elica poi basta inserire il numero di principi ,inizio e fine e fa tutto da solo

Re: Affilare le eliche delle frese con Arduino

Inviato: mer gen 28, 2026 18:43
da McMax
far misurare il passo dell'elica al sistema lo complica notevolmente: bisognerebbe montare un encoder sull'albero della fresa e misurarne la rotazione movendo la fresa avanti e indietro, ovviamente impegnando la scanalatura con una pennetta e muovento solo il motore stepper longitudinale. Comunque arduino non è il massimo per fare sta roba, occorrerebbe un micro un po' più potente, magari una STM32 bluepill...

Re: Affilare le eliche delle frese con Arduino

Inviato: mer gen 28, 2026 20:12
da ofranco
Io mi accontenterei se Arduino mi facesse un elica per volta, lasciando a me l’impostazione di partenza di ognuna di loro.
In questo modo si semplifica il codice e viene più facile modificarlo in seguito.
Qualcuno mi può aiutare a scriverlo?

Re: Affilare le eliche delle frese con Arduino

Inviato: mer gen 28, 2026 21:11
da lelef
metti quanto hai scritto sinora e vedo se posso aiutarti

Re: Affilare le eliche delle frese con Arduino

Inviato: gio gen 29, 2026 00:19
da McMax
Prima di scrivere il codice bisogna impostare il sistema, definire come pilotare gli stepper, ovvero con quale passo e soprattutto quali impostazioni poter configurare. Altra cosa fondamentale é l'interfaccia utente, quanti tasti, che LCD e poi progettare tutta la parte hardware (alimentatore per i driver stepper e per arduino). Diciamo che il codice é l'ultima cosa :risatina:

Re: Affilare le eliche delle frese con Arduino

Inviato: gio gen 29, 2026 09:49
da ofranco
lelef ha scritto: mer gen 28, 2026 21:11 metti quanto hai scritto sinora e vedo se posso aiutarti
Grazie, quando vuoi ti posso postare quali stepper ho in dotazione, il tipo di display LCD da usare, il tipo di tastierino numerico da usare come interfaccia per l’inserimento dei dati.

Re: Affilare le eliche delle frese con Arduino

Inviato: gio feb 05, 2026 18:52
da ofranco
In casa ho questo hardware per lo sviluppo dell'automatismo.
Arduino
Arduino.jpeg
Alimentatore per Arduino:
AlimentatoreArduino.jpeg
Tastierino:
Tastierino.jpeg
Display 4 righe:
Display_1.jpeg
Display2.jpeg
Driver:
Driver.jpeg
Per quanto riguarda l'alimentazione del driver userò un alimentatore di un vecchio computer portatile.

Re: Affilare le eliche delle frese con Arduino

Inviato: gio feb 05, 2026 18:55
da ofranco
Per quanto riguarda il motore passo passo è un Nema 23, eccolo qui:
tab01.jpeg
Tab02.jpeg
Tab03.jpeg

Spero che qualcuno di buona volontà mi aiuti concretamente. :muro:

Re: Affilare le eliche delle frese con Arduino

Inviato: lun feb 16, 2026 10:45
da ofranco
McMax ha scritto: gio gen 29, 2026 00:19 Prima di scrivere il codice bisogna impostare il sistema, definire come pilotare gli stepper, ovvero con quale passo e soprattutto quali impostazioni poter configurare. Altra cosa fondamentale é l'interfaccia utente, quanti tasti, che LCD e poi progettare tutta la parte hardware (alimentatore per i driver stepper e per arduino). Diciamo che il codice é l'ultima cosa :risatina:
dai un'occhiata qui:

Codice: Seleziona tutto

/*
 * SISTEMA AUTOMATICO AFFILATURA FRESE - CONTROLLO CNC ARDUINO (VERSIONE SEQUENZIALE)
 * 
 * Questo programma automatizza l'affilatura di frese a candela eseguendo una passata 
 * per ogni tagliente della fresa. Dopo ogni passata, il mandrino ruota automaticamente 
 * per posizionare il tagliente successivo.
 * 
 * ===================================================================================
 * GUIDA ALL'USO DEL TASTIERINO (4x4)
 * ===================================================================================
 * [A] - SU: Sposta il cursore verso l'alto nel menu.
 * [B] - GIU: Sposta il cursore verso il basso nel menu.
 * [C] - INVIO/CONFERMA: 
 *       - Nel Menu: Entra in modalità modifica o avvia l'azione selezionata.
 *       - Durante l'inserimento: Salva il valore digitato.
 *       - A fine lavoro: Riavvia il ciclo completo di affilatura.
 * [D] - STOP/ANNULLA:
 *       - Durante la lavorazione: Ferma immediatamente i motori e torna al menu.
 *       - Durante l'inserimento: Annulla l'operazione e torna al menu.
 * [*] - RESET: Cancella il numero che stai scrivendo se hai fatto un errore.
 * [0-9] - NUMERI: Usati per inserire i valori dei parametri.
 * 
 * ===================================================================================
 * PARAMETRI DI LAVORO
 * ===================================================================================
 * 1. PASSO ELICA (mm/giro): La distanza lineare che la fresa percorrerebbe in un giro.
 * 2. LUNGHEZZA (mm): Quanto è lungo il tratto del tagliente da affilare.
 * 3. NUM. TAGLIENTI: Quanti taglienti ha la fresa (es. 2, 3, 4).
 * 4. GRADI DIVIS.: L'angolo esatto tra un tagliente e l'altro (es. 90° per 4 taglienti).
 * 
 * HARDWARE: Arduino, LCD I2C, Keypad 4x4, 2x Driver Stepper.
 */

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <AccelStepper.h>

// ===================================================================================
// CONFIGURAZIONE HARDWARE
// ===================================================================================

const float PASSI_PER_MM_LINEARE = 320.0; 
const float PASSI_PER_GIRO_MANDRINO = 1600.0;

const float VELOCITA_MAX = 1000.0;
const float ACCELERAZIONE = 500.0;

const int PIN_STEP_LINEARE = 2; 
const int PIN_DIR_LINEARE  = 3;
const int PIN_STEP_MANDRINO = 4; 
const int PIN_DIR_MANDRINO  = 5;
const int PIN_ENABLE_MOTORI = 8; 

const byte RIGHE = 4; 
const byte COLONNE = 4; 
char keys[RIGHE][COLONNE] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte pinRighe[RIGHE] = {22, 24, 26, 28}; 
byte pinColonne[COLONNE] = {30, 32, 34, 36}; 

LiquidCrystal_I2C lcd(0x27, 20, 4); 
Keypad tastierino = Keypad(makeKeymap(keys), pinRighe, pinColonne, RIGHE, COLONNE);
AccelStepper motoreLineare(AccelStepper::DRIVER, PIN_STEP_LINEARE, PIN_DIR_LINEARE);
AccelStepper motoreMandrino(AccelStepper::DRIVER, PIN_STEP_MANDRINO, PIN_DIR_MANDRINO);

// ===================================================================================
// STATI E VARIABILI
// ===================================================================================

enum StatoSistema {
  MENU_PRINCIPALE,
  EDIT_VALORE,
  LAVORO_ANDATA,
  LAVORO_RITORNO,
  LAVORO_ROTAZIONE,
  LAVORO_COMPLETATO
};

StatoSistema stato = MENU_PRINCIPALE;
int voceSelezionata = 0;

// Parametri Utente
float passoElica = 50.0;
float lunghezzaAffilatura = 150.0;
int numTaglienti = 4;
float gradiDivisione = 90.0;

// Variabili di controllo ciclo
int taglienteCorrente = 0;
String inputBuffer = "";

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("AFFILATRICE FRESE");
  lcd.setCursor(0,1);
  lcd.print("Ver. Sequenziale");
  delay(2000);

  pinMode(PIN_ENABLE_MOTORI, OUTPUT);
  digitalWrite(PIN_ENABLE_MOTORI, LOW);

  motoreLineare.setMaxSpeed(VELOCITA_MAX);
  motoreLineare.setAcceleration(ACCELERAZIONE);
  motoreMandrino.setMaxSpeed(VELOCITA_MAX);
  motoreMandrino.setAcceleration(ACCELERAZIONE);

  mostraMenu();
}

void loop() {
  motoreLineare.run();
  motoreMandrino.run();

  char tasto = tastierino.getKey();

  switch (stato) {
    case MENU_PRINCIPALE:
      gestisciNavigazione(tasto);
      break;

    case EDIT_VALORE:
      gestisciInserimento(tasto);
      break;

    case LAVORO_ANDATA:
      if (tasto == 'D') fermaTutto();
      if (motoreLineare.distanceToGo() == 0 && motoreMandrino.distanceToGo() == 0) {
        delay(500);
        lcd.setCursor(0, 3);
        lcd.print("Stato: RITORNO   ");
        motoreLineare.moveTo(0);
        motoreMandrino.moveTo(0);
        stato = LAVORO_RITORNO;
      }
      break;

    case LAVORO_RITORNO:
      if (tasto == 'D') fermaTutto();
      if (motoreLineare.distanceToGo() == 0 && motoreMandrino.distanceToGo() == 0) {
        taglienteCorrente++;
        if (taglienteCorrente < numTaglienti) {
          delay(500);
          lcd.setCursor(0, 3);
          lcd.print("Stato: PROSSIMO  ");
          
          // Ruota il mandrino per il prossimo tagliente
          long passiRotazione = (gradiDivisione / 360.0) * PASSI_PER_GIRO_MANDRINO;
          motoreMandrino.move(passiRotazione);
          stato = LAVORO_ROTAZIONE;
        } else {
          stato = LAVORO_COMPLETATO;
          mostraFineLavoro();
        }
      }
      break;

    case LAVORO_ROTAZIONE:
      if (tasto == 'D') fermaTutto();
      if (motoreMandrino.distanceToGo() == 0) {
        delay(500);
        // Reset coordinate relative per la nuova passata
        motoreLineare.setCurrentPosition(0);
        motoreMandrino.setCurrentPosition(0);
        avviaPassataSincronizzata();
        aggiornaDisplayLavoro();
        stato = LAVORO_ANDATA;
      }
      break;

    case LAVORO_COMPLETATO:
      if (tasto == 'C') { // Ripeti ciclo
        avviaCicloCompleto();
      } else if (tasto == 'D') {
        stato = MENU_PRINCIPALE;
        mostraMenu();
      }
      break;
  }
}

// ===================================================================================
// INTERFACCIA E MENU
// ===================================================================================

void mostraMenu() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("--- IMPOSTAZIONI ---");
  
  lcd.setCursor(0,1);
  lcd.print(voceSelezionata == 0 ? ">Elica: " : " Elica: ");
  lcd.print(passoElica, 1);
  
  lcd.setCursor(0,2);
  lcd.print(voceSelezionata == 1 ? ">Lung.: " : " Lung.: ");
  lcd.print(lunghezzaAffilatura, 1);

  lcd.setCursor(0,3);
  if (voceSelezionata == 2) lcd.print(">Taglienti: " + String(numTaglienti));
  else if (voceSelezionata == 3) lcd.print(">Gradi: " + String(gradiDivisione, 1));
  else if (voceSelezionata == 4) lcd.print("> [AVVIA AFFILATURA]");
}

void gestisciNavigazione(char tasto) {
  if (!tasto) return;
  if (tasto == 'A') { voceSelezionata = (voceSelezionata > 0) ? voceSelezionata - 1 : 4; mostraMenu(); }
  else if (tasto == 'B') { voceSelezionata = (voceSelezionata < 4) ? voceSelezionata + 1 : 0; mostraMenu(); }
  else if (tasto == 'C') {
    if (voceSelezionata == 4) avviaCicloCompleto();
    else { stato = EDIT_VALORE; inputBuffer = ""; lcd.setCursor(0,3); lcd.print("Valore:         "); lcd.setCursor(8,3); }
  }
}

void gestisciInserimento(char tasto) {
  if (!tasto) return;
  if (tasto >= '0' && tasto <= '9') { inputBuffer += tasto; lcd.print(tasto); }
  else if (tasto == '*') { inputBuffer = ""; lcd.setCursor(8,3); lcd.print("        "); lcd.setCursor(8,3); }
  else if (tasto == 'C') {
    if (inputBuffer.length() > 0) {
      float val = inputBuffer.toFloat();
      if (voceSelezionata == 0) passoElica = val;
      if (voceSelezionata == 1) lunghezzaAffilatura = val;
      if (voceSelezionata == 2) numTaglienti = (int)val;
      if (voceSelezionata == 3) gradiDivisione = val;
    }
    stato = MENU_PRINCIPALE; mostraMenu();
  } else if (tasto == 'D') { stato = MENU_PRINCIPALE; mostraMenu(); }
}

// ===================================================================================
// LOGICA DI LAVORAZIONE
// ===================================================================================

void avviaCicloCompleto() {
  taglienteCorrente = 0;
  lcd.clear();
  lcd.print("AVVIO AFFILATURA...");
  delay(1000);
  
  motoreLineare.setCurrentPosition(0);
  motoreMandrino.setCurrentPosition(0);
  
  avviaPassataSincronizzata();
  aggiornaDisplayLavoro();
  stato = LAVORO_ANDATA;
}

void avviaPassataSincronizzata() {
  long targetLineare = lunghezzaAffilatura * PASSI_PER_MM_LINEARE;
  float gradiRotazione = (lunghezzaAffilatura / passoElica) * 360.0;
  long targetMandrino = (gradiRotazione / 360.0) * PASSI_PER_GIRO_MANDRINO;

  motoreLineare.moveTo(targetLineare);
  motoreMandrino.moveTo(targetMandrino);

  // Calcolo velocità sincronizzata
  float velBase = 400.0; 
  float tempo = abs(targetLineare) / velBase;
  float velMandrino = abs(targetMandrino) / tempo;

  motoreLineare.setMaxSpeed(velBase);
  motoreMandrino.setMaxSpeed(velMandrino);
}

void aggiornaDisplayLavoro() {
  lcd.clear();
  lcd.print("AFFILATURA IN CORSO");
  lcd.setCursor(0,1);
  lcd.print("Tagliente: ");
  lcd.print(taglienteCorrente + 1);
  lcd.print("/");
  lcd.print(numTaglienti);
  lcd.setCursor(0,2);
  lcd.print("D: STOP");
  lcd.setCursor(0,3);
  lcd.print("Stato: ANDATA    ");
}

void mostraFineLavoro() {
  lcd.clear();
  lcd.print("LAVORO FINITO!");
  lcd.setCursor(0,1);
  lcd.print("Taglienti fatti: ");
  lcd.print(numTaglienti);
  lcd.setCursor(0,2);
  lcd.print("C: RIPETI CICLO");
  lcd.setCursor(0,3);
  lcd.print("D: ESCI AL MENU");
}

void fermaTutto() {
  motoreLineare.stop();
  motoreMandrino.stop();
  stato = MENU_PRINCIPALE;
  mostraMenu();
}
Suggerimenti?