Vai al contenuto
PLC Forum


Arduino E G-Code


walterword

Messaggi consigliati

si , grbl lo stavo gia guardando , c'e' la version eper uno e per due (arduino) .Ci sono vari motion controller in giro

Ma il mio scopo non e' quello di prendere , caricare e lavorare con le cnc ma capire e magari creare qualcosa di utile ed interessante oltreche' capire le varie tecnologie che vi ruotano attorno

Link al commento
Condividi su altri siti

  • 2 weeks later...

  • Risposte 52
  • Created
  • Ultima risposta

Top Posters In This Topic

  • walterword

    36

  • Livio Orsini

    12

  • bigalex

    2

  • AlexB

    1

sto tentando di creare una routine per rampare un motore stepper con un potenziometro

Per avere un po di stabilità nella lettura del potenziometro eseguo una lettura ogni ciclo ed ogni 300 cicli calcolo la media .Ho provato anche a creare un piccolo filtro RC con frequenza di taglio di circa 1 Hz ma otlre alla caduta di tensione non desiderata sul resistore non ho avuto grandi progressi . Per cui ho adottato il metodo di fare la media nel micro .Mi serve un valore stabile perche il settaggio del tempo di interrupt lo devo fare solo quando cambia il valore letto dal potenziometro , altrimenti la funzione di settaggio timer continua ad essere chiamata con conseguente fermo del timer , per cui niente impulsi allo stepper .

Come si potrebbe fare per avere una lettura del potenziometro stabile ...sto provando con 500 letture e poi la media .... <_<

Link al commento
Condividi su altri siti

Prima cosa con quale sorgente di tensione alimenti il potenziometro?

Se la tensione non è stabile è inutile cercare di stabilizzare la lettura.

Poi fai il solito timer a 10 ms, leggi il potenziometro ogni 10 ms e fai una media scorrevole su 10 letture; ottieni aggiornamenti abbastanza veloci con un buon filtraggio.

Però ti posso garantire che se alimenti arduino con una sorgente esterna stabile e prelevi l'alimentazione del potenziometro dai 5 V della scheda, la lettura è inchiodata su un valore fisso.

Link al commento
Condividi su altri siti

la prima prova l'ho fatta con sorgente esterna , un alimentatore stabilizzato

La seconda con i 3.3V di arduino , alimentandolo con l'usb solita .

Non uso l'interrupt del timer , leggo 300 volte il valore e lo sommo , poi ogni 300 cicli faccio la media ....si anche cosi e' stabile .

Diciamo che da 0-4095 se per esempio sono a 2000 mi oscilla tra 2000, 2001 , 2000, 2002 , 2000 ....e' quasi perfetto

Ho messo anche un controllo , cioe' vario il preset del timer interrup per la generazione degli impulsi dello stepper , solo se la variazione (rispetto ad una variabile memoria ) e' di 0.1 o 0.5 o 1.0 .

Sto preparando un programmino per testare i motori stepper che mi arriveranno piu avanti , per cui ipotizzavo usando il potenziometro .

Tra l'altro , quando c'e' una variazione di riferimento velocità (chiamiamola cosi la funzione del potenziometro ) , cambio il preset del timer solo quando ho l'onda bassa del pwm .Questo perche se sono in ON e devo cambiare la frequenza e quindi il tempo di interrupt mi succede che per ottenere questo devo ristartare il timer ....

Adesso sto pensando anche di valutare se al cambio di frequenza , questa e' minore o maggiore della precedente ...a frequenze alte accade tutto piu veloce , con l'oscilloscopio vedo abbastanza bene nonostante il refresh , a frequenze basse insomam non e' proprio il massimo

E' anche vero che comunque lo stepper ha una frequenza minima per potersi muovere per cui ....

Il ragionamenteo che sto facendo e' questo :ho due assi interpolati linearmente X ed Y . Considerando che i comandi arrivano come g-code , in una riga si trova il punto da raggiungere espresso come coordinate x ed y a la feed che e' la velocità di crociera.

Sulla carta , disegno gli assi cartesiani e ragiono con i vettori , per cui partendo da 0,0 e volendo raggiungere il punto P(10,10) alla velocità di 200 ( mm/min) posso considerare la velocità come vettore e quindi anche l'accelerazione .

Scomponendo il vettore velocità tramite

- arcotangente y/x per trovare l'angolo

- coseno di questo angolo per trovare la componente x

- seno di questo angolo per trovare la componente y

a questo punto posso distrubuire ai due stepper la velocità di ogni asse m costruita in due distinti interrupt a tempo di due timer distinti , uno per l'asse x e l'altro per l'asse y

In ogni relativo interrupt conto quanti impulsi devo fare , sempre in base al fatto che essendo lo spostamento un vettore lo posso dividere nelle due componenti di spostamento x e spostamento y

In base alla posizione attuale e a quella da raggiungere , se ogni componente (x e y ) è minore o maggiore decido la direzione da dare al driver .

il feedback e' quindi la radice quadrata del quadrato dei due spostamenti ossia SQRT(X^2 + Y^2)

Se usassi degli encoder , gli impulsi che conto non saranno piu quelli che conto nel interrupt che genera il pwm di ogni asse ma gli impulsi veri e propri degli encoders

Per ora tutto teoria e test su componenti parziali , sarebe gia bello arrivare e posizionare due assi interpolati linearmente senza problemi

Modificato: da walterword
Link al commento
Condividi su altri siti

const int cicli = 500;
int ind = 0;                  
boolean rq=false;
double lettura=0.0;
double finale=0.0;

void loop()
{
	                                                                                 
	 //   mytimers.runTimers(millis());        
		                           
		float cycleTime=mytimers.getDeltaTime();                                   
		 analogReadResolution(12);		
		 lettura+=(double) analogRead(A0);
		 ind ++;

		 if (ind > cicli)
		 { 
			  finale=lettura/cicli;
			  lettura=0.0;
			  ind = 0;
			 	
		 }
			 
		 freq_x =map(finale,0, 4095,30,500);
		
	      if(abs(freq_x - mem_freq_x) > 1.0)
		  {
			 rq=true;
		  }
			mem_freq_x= freq_x;
	  
	     if( rq==true && ledOn1==false)
		 {
			  Timer4.start(freq_x*1000.0);   // 500.000 sono 0.5 secondi 
			  rq=false;
		 }
	
	//	 speedRamp.runRamp (true,100000.0,2000000.0,100000.0,cycleTime );    // 126 uS
		
	//	CheckForSerialData();                                                // 130 uS
	
	//	SerialMessages();                                                     // 2 mS
	
}

non e' proprio male , pero' devo vedere col motore .....appena mi arriva ...

Modificato: da walterword
Link al commento
Condividi su altri siti

devo mettere giu una funzione parametrizzabile per generare rampe , accelerazione e decellerazione in base al target, la posizione attuale (o impulsi) , % di intervento ect .Per il tempo ciclo lo posso tirare fuori con millis() o micros() e calcolare il delta tra due scansioni con i relativi controlli , lavoro che faccio gia nella mia libreria timer

Cosa ne dici Livio? Una bella rampetta veloce che mi faccia acc. e dec. la troviamo in giro ? oppure devo farmi anche questa?

Link al commento
Condividi su altri siti

quella che sto scrivendo che vedi commentata nel codice prende come ingressi

void WRamp::runRamp(bool emergencyPB,float setPoint,float rampUp,float rampDown,unsigned long cycletime)

Il pulsante di emergenza , il setpoint di velocità , la rampa di salita in mS , quella di discesa e il tempo ciclo

Potrebbe andar bene , i cambi di velocità in base al punto raggiunto piuttosto che la prossimità alla massima corsa li faccio fuori e li passo alla funzione , cosa mi consigli?

Link al commento
Condividi su altri siti

potrei anche fare cosi ....prendo il potenziometro dopo 400-500 letture come faccio sopra , e passo il valore ottenuto al generatore di rampe e a passi di 40-50 Hz cambio il preset del timer che mi genera gli impulsi

non c'e' bisogno di cambiare il preset del timer per ogni variazione di decimi di hz per i motivi che primo non abdrebbe mai il timer perche sarebbe sempre reimpostato , secondo non serve fare rampe cosi infinitesime ....o no?

Link al commento
Condividi su altri siti

con queste modifiche riesco a vedere qualcosa di buono , in pratica il potenziometro lo mando in rampa da 3 sec accel e decel. poi ogni 30 Hz cambio il preset del timer ....

void loop()
{
	                                                                                 
	         mytimers.runTimers(millis());        
		 float cycleTime=mytimers.getDeltaTime();    
		 analogReadResolution(12);		
		 lettura+=(double) analogRead(A0);
		 ind ++;

		 if (ind > cicli)
		 { 
			  finale=lettura/cicli;
			  lettura=0.0;
			  ind = 0;
			 	
		 }
			 
		 app =map(finale,0, 4095,30,500);
		
		 speedRamp.runRamp (true, app,3000.0,3000.0,cycleTime );   
	         freq_x=speedRamp.getSpeed();
		 
		  if(abs(freq_x - mem_freq_x) > 30)
		  {
			  Timer4.start(freq_x*1000.0);
			  mem_freq_x= freq_x;
			 
		  }
	
	
}

pero' c'e' ancora qualcosa da sistemare ....

Dunque uno stepper che gira a 1800 RPM sono 30 giri al secondo , avendo lo stepper 200 impulsi giro sono la bellezza di 6 KHz come massima velocità , mettiamo che considero solo meta giri per non ridurre troppo la coppia , quindi 900 RMP corrispondono a 3 KHz

Con questa scalatura posso regolare da 5 Hz a 3KHz

 app =map(finale,0, 4095,3,1000);
 speedRamp.runRamp (true, app,3000.0,3000.0,cycleTime );   
 freq_x=speedRamp.getSpeed();
		 
  if(abs(freq_x - mem_freq_x) > 30)
   {
	Timer4.start(freq_x*100.0);
	 mem_freq_x= freq_x;
		 
   }
			

l'unica cosa che mi preoccupa e' quando devo cambiare il preset del timer che genera gli impulsi da mandare al driver dello stepper .....il led ad alte velocità sembra funzionare bene e la rampa funziona bene in entrambe le direzioni , pero' e' un led ....

Modificato: da walterword
Link al commento
Condividi su altri siti

La seconda con i 3.3V di arduino , alimentandolo con l'usb solita .

E' questa alimentazione che non è pulita e ti da l'impressione che il convertitore A/D "balli"

Link al commento
Condividi su altri siti

comunque sto usando quella adesso .COn l'oscilloscopio vedo il segnale stringersi ed allargars in base alla frequenza ....piccola modifica

	 
		 app =map(finale,0, 4095,4,6000);
		
		 speedRamp.runRamp (true, app,3000.0,3000.0,cycleTime );   
	         freq_x=(long)speedRamp.getSpeed();
		 
		  if(abs(freq_x - mem_freq_x) > 30)
		  {
			Timer4.setFrequency(freq_x).start();
			mem_freq_x= freq_x;
		  }
Link al commento
Condividi su altri siti

comunque io ti chiedevo su come fare una rampa per stepper , il problema del potenziometro l'ho risolto con 500 letture e con la rampa ad inseguimento

Link al commento
Condividi su altri siti

La rampa per stepper la si fa come qualsiasi altra rampa di frequenza.

Io preferirei usare un VCO, perchè semplifica tutto.

per uno stepper devi prima generarti il timer per il periodo voluto e da questo ricavi i 2 o 4 impulsi in sequenza.

Link al commento
Condividi su altri siti

il timer per gli impulsi l'ho gia fatto , e quando cambi ala frequenza cambia il suo preset

Il convertitore tensione frequenza va bene se hai l'encoder che conta gli impulsi , altrimenti come li conti ?

Link al commento
Condividi su altri siti

Conti gli impulsi che escono dal convertitore, com se contassi l'encoder.

Sto facendo qualche cosa del genere, tra un attacco di lazzaronite ed un po' di lavori di girdino, appena ho pronto qualche cosa te lo mostro.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

quindi gli impulsi che escono dal covnertitore li conti con interrupt esterni ?

Mah ......poi bisogna trovare il componente che lavora con un range massimo difrequenza sui 10 KHz ...

Modificato: da walterword
Link al commento
Condividi su altri siti

No usi uno dei contatori del micro per contare gli impulsi, sai che alcuni contatori possono avere un clock esterno.

Link al commento
Condividi su altri siti

e pero' non saprei sulla piattaforma arduino come farlo .Il datasheet del DUE come microcontrollore l'ho guardato un po e ne ha di cose ....ufffff

Poi il componente VFO ? Analog Device ? Quanti KHz ? Con la 3.3V ?

Un casino no ?

La fai troppo facile Livio , dopo settimane che sto facendo prove mi vieni fuori a dire queste cose :D .....ribaltare tutto ...adesso il timer interrupt non va piu bene per generare gli impulsi ....arduino due se non lo si conosce bene come micro arm sam cortex e non si conoscono le librerie per usare il core library non se ne viene fuori piu ......qua bisogna studiare tutti i registri come se fosse un micro "nudo" ...senza il vestito di arduino

Modificato: da walterword
Link al commento
Condividi su altri siti

Walter Arduino2 non lo conosco, anche se ci sto pensendo. Però basta che tu tilegga il dasheet o ti leggi uno dei anti forum specifici di arduino e trovi qauli terminali corrispondono all'ingresso dei contatori. Per il momento ho provato ad usare uno e mega come frequenzimentri e contatori e funzionano molto bene.

Io come VF a basso costo ho usato un XR, c'è anche qui sul forum uno schema per un simulatore di encoder. Però non devi buttare tutto per aria Se hai inizato con la geenrazione del clok da un timer, non ti dovrebbe essere difficile farti una funzioncina che cambia il preset per variare il periodo.

Link al commento
Condividi su altri siti

walter...i fori per gli spinotti colorati li hai fatti con il trapano a mano..? ci voleva la cnc... :P:lol: comunque complimenti per il resto che c è dentro :smile:

Modificato: da roberto8303
Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora

×
×
  • Crea nuovo/a...