Si, Max, il firmware lo ho scritto io.
Il problema che ho trovato nel riciclare codice e' che non c'e' nessuno in giro che ha un controllo "fino a che il pulsante e' premuto".
Sono tutti tipo "premi il pulsante e parte, premi il pulsante e si ferma" o peggio ancora "premi il pulsante e si muove di tot passi, poi si ferma".
Io, come ho detto, volevo un sistema tipo "fino a che tengo premuto ti muovi, appena lascio ti fermi".
In piu', avendo pochi input digitali a disposizione ho usato una rete resistiva per usare un solo pin analogico per 6 pulsanti.
Questo lo schema dei pulsanti ( e potenziometro per la velocita' su un altro ingresso digitale ):
Allegato:
Pulsanti.jpg
Il ciclo che faccio e' semplice: nel loop controllo il valore del potenziometro e lo infilo in una variabile, controllo il valore della rete resistiva, nel caso abbia una lettura "valida" setto la direzione, alzo il pin di step, aspetto il valore del pot, abbasso il pin di step, aspetto il valore del pot.
Codice:
#define PULSANTI A0
#define POTENZIOMETRO A1
#define D13 13
#define ENA_X 12
#define DIR_X 4
#define STP_X 5
#define ENA_Y 11
#define DIR_Y 6
#define STP_Y 7
#define ENA_Z 10
#define DIR_Z 8
#define STP_Z 9
int speedVal ;
int newspeedVal ;
int keyPressedVal;
int keyPressed;
void speedUp(int speedVal) {
newspeedVal = map(speedVal, 0, 1023, 150,2000); // Converts the read values of the potentiometer from 0 to 1023 into desireded delay values (150 to 2000)
}
void readValues(){
/*
* Val: 0 1
* Val: 683 2
* Val: 768 3
* Val: 512 4
* Val: 820 5
* Val: 854 6
*/
keyPressed=0;
speedVal = analogRead(POTENZIOMETRO);
speedUp(speedVal);
speedVal=newspeedVal;
keyPressedVal = analogRead(PULSANTI);
if (keyPressedVal <= 5) {
keyPressed=1;
} else if ( keyPressedVal > 5 && keyPressedVal <= 520 ) {
keyPressed=4;
} else if ( keyPressedVal > 520 && keyPressedVal <= 685 ) {
keyPressed=2;
} else if ( keyPressedVal > 685 && keyPressedVal <= 770 ) {
keyPressed=3;
} else if ( keyPressedVal > 770 && keyPressedVal <= 825 ) {
keyPressed=5;
} else if ( keyPressedVal > 825 && keyPressedVal <= 858 ) {
keyPressed=6;
}
}
void setup() {
pinMode(13, OUTPUT);
pinMode(PULSANTI, INPUT );
pinMode(POTENZIOMETRO, INPUT );
pinMode(ENA_X,OUTPUT );
pinMode(DIR_X,OUTPUT );
pinMode(STP_X,OUTPUT );
pinMode(ENA_Y,OUTPUT );
pinMode(DIR_Y,OUTPUT );
pinMode(STP_Y,OUTPUT );
pinMode(ENA_Z,OUTPUT );
pinMode(DIR_Z,OUTPUT );
pinMode(STP_Z,OUTPUT );
}
// the loop function runs over and over again forever
void loop() {
readValues(); // Leggiamo i valori analogici
digitalWrite(D13, LOW);
if ( keyPressed > 0 ) {
digitalWrite(D13, HIGH);
switch ( keyPressed ){
case 1: // Y Left
digitalWrite(DIR_Y, HIGH);
digitalWrite(STP_Y, HIGH);
delayMicroseconds(speedVal);
digitalWrite(STP_Y, LOW);
delayMicroseconds(speedVal);
break;
case 2: // X Forw
digitalWrite(DIR_X, HIGH);
digitalWrite(STP_X, HIGH);
delayMicroseconds(speedVal);
digitalWrite(STP_X, LOW);
delayMicroseconds(speedVal);
break;
case 3: // X BACK
digitalWrite(DIR_X, LOW);
digitalWrite(STP_X, HIGH);
delayMicroseconds(speedVal);
digitalWrite(STP_X, LOW);
delayMicroseconds(speedVal);
break;
case 4: // X BACK
digitalWrite(DIR_Y, LOW);
digitalWrite(STP_Y, HIGH);
delayMicroseconds(speedVal);
digitalWrite(STP_Y, LOW);
delayMicroseconds(speedVal);
break;
case 5: // Z UP
digitalWrite(DIR_Z, HIGH);
digitalWrite(STP_Z, HIGH);
delayMicroseconds(speedVal);
digitalWrite(STP_Z, LOW);
delayMicroseconds(speedVal);
break;
case 6: // Z UP
digitalWrite(DIR_Z, LOW);
digitalWrite(STP_Z, HIGH);
delayMicroseconds(speedVal);
digitalWrite(STP_Z, LOW);
delayMicroseconds(speedVal);
break;
default:
break;
}
}
}
Ovviamente e' gia' pronto per gestire i 3 assi, ma ne uso uno solo. Potrei anche ottimizzare il ciclo di step, ma per ora va funziona ( a parte i suddetti problemi.
Ho capito il tuo discorso sui cicli per l' accelerazione, ma come sempre mi scontro con il fatto del funzionamento a pulsante premuto.
Inoltre con la rete analogica non posso nemmeno usare proficuamente gli interrupt "on change" ( ma di questo non sono sicuro ) e quindi calcolare il ciclo dell' accelerazione deve essere empirico.
Quello che pero' ho capito bene e' di tenere fisso il tempo di ON, e forse e' per quello che il motore e' rumoroso alle basse velocita'.
Quindi cambiero':
Codice:
digitalWrite(STP_Y, HIGH);
delayMicroseconds(speedVal);
digitalWrite(STP_Y, LOW);
delayMicroseconds(speedVal);
in
Codice:
digitalWrite(STP_Y, HIGH);
delayMicroseconds(10);
digitalWrite(STP_Y, LOW);
delayMicroseconds(speedVal);
dove il 10 e' un valore assolutamente casuale ma dovrebbe andare bene, dato questo:
Allegato:
DRV8825_Timing.png
Il minimo time e' 1,9 micro, quindi a 10 dovrei andare bene.
Il codice fa abbastanza schifo, ma se vedi grosse cavolate sono tutto orecchi :)