Buonasera a tutti scrivo solamente per sapere da voi esperti se il seguente codice è corretto.
Il mio progetto è quello di automatizzare tramite un motore stepper l'avanzamento di una macchina utensile in modo da non dover cambiare ogni volta le ruote dentate per modificarne gli avanzamenti. In stato di riposo lo stepper deve essere libero in modo tale da poter ruotale la manovella del macchinario mentre premendo un pulsante lo stepper farà ruotare la stessa manovella in avanti, per l'inversione di marcia porterò semplicemente i 5 volt al driver tramite un semplice interruttore. La velocità la regolo con un potenziometro,non mi sembra molto affidabile ma mi potrebbe anche andare bene cosi. Non ho capacità a fare qualcosa di piu evoluto. Attualmente uso Arduino Uno che sostituirò con Arduino nano per ragioni di ingombri,potenziometro rotativo 10k, stepper nema 17, driver basato su chip toshiba tb6600 alimentato a 12 volt.
Ecco il codice:
int enable = 8; //coppia motore
int pull = 7; //impulso per lo step
int marcia = 5; //pulsante di marcia
int valpulsante = 0;
int potenziometro = 0;
void setup() {
pinMode(enable,OUTPUT);
pinMode(pull,OUTPUT);
pinMode(marcia,INPUT);
pinMode(potenziometro,INPUT);
}
void loop() {
int leggipotenziometro = analogRead(potenziometro);
int velocita = map(leggipotenziometro,0,1023,200,800);
valpulsante = digitalRead(marcia);
digitalWrite(enable,HIGH);
if (valpulsante == HIGH){
digitalWrite(enable,LOW);
digitalWrite(pull,HIGH);
delayMicroseconds(velocita);
digitalWrite(pull,LOW);
delayMicroseconds(velocita);
}
else{
digitalWrite(enable,HIGH);
digitalWrite(pull,LOW);
}
}
Ciao,
se ho capito bene cosa vuoi fare credo che digitalWrite(enable,HIGH); vada dentro l'if, devi abilitare il driver se chiudi l'interruttore, secondo me dato che sei stato in grado di scrivere questo codice sarai sicuramente in grado di svilupparlo ulteriormente.
Se ritieni possa essere utile ti posso indicare come procedere per fare un lavoretto semplice ma allo stesso tempo fatto bene e funzionale.
Che ne dici di utilizzare un semplicissimo joystick (cerca joystick arduino su google se non sai di cosa si tratta) per poter controllare be due assi, contemporaneamente o indipendentemente se preferisci, sia in un verso che nell'altro? Lasciando il joy al centro dopo un certo tempo potresti disabilitare il driver così da lasciare libero l'asse (anche se comunque avresti un certo "carico" parassita dato dallo stepper)
se ho capito bene cosa vuoi fare credo che
Code: [Select]
digitalWrite(enable,HIGH);
vada dentro l'if
se io lo inserisco dentro l'if il motore rimarrebbe in coppia non potendo lavorare in manuale,per questo motivo l'ho inserito fuori dall'if di modo che come premo il pulsante gli do uno stato logico basso e mi attiva il motore in modo da non tenerlo in coppia quindi bloccato mentre non lo aziono e così scalda anche meno.Mi sembra dalle prove che ho fatto che se non lo mettevo con logica bassa non girava(magari mi confondo dalle mille prove che ho fatto).
riguardo il joystic lo avevo gia preso in considerazione ma mi risultava troppo complicato per me far girare il motore proporzionalmente alla posizione della leva e farlo fermare quando la leva è al centro (quindi resistenza a zero), esteticamente è un lavoro migliore ma avendo un po di tempo tra una cosa e l'altra in questo periodo ho utilizzato ciò che avevo aquistato tempo fà, magari piu in là posso provare;dovrei fare un map del potenziometro e fare vari 'settori' in modo che quando il potenziometro si trova nella posizione iniziale da me dichiarata rimane a riposo mentre come la supera varia la velocita in base alla posizione giusto? mentre per l'inversione di marcia devo cambiare stato logico sul pin direzione del driver usando un uscita in piu di Arduino, è corretto?
Se vorrai darmi qualche info prendo nota e quando mi sarà possibile farò questo upgrade ;D
Secondo me la cosa migliore è utilizzare la libreria AccelStepper per pilotare il motore, fai il controllo in velocità (non in posizione) (Stepper - Arduino Reference) dato che a te non interessa far fare uno spostamento fisso ma solamente variare la velocità e la direzione in base alla posizione del joystick.
Leggi la posizione del joy e decidi cosa fare, dividerei la corsa totale (se non mappi avrai 0-1023 in uscita dalla lettura analogica) in 6, 8, 10 parti (fai qualche prova e vedi come ti trovi meglio (puoi farlo anche con la funzione map )), le due centrali le considererei "motore fermo" quindi dopo tipo 3 secondi metterei a off il driver, poi man mano che ci si allontana aumenterei la velocità e setterei il senso di rotazione in base alla posizione del joy (positiva o negativa), è più difficile da spiegare che da fare
Grazie mille.
Appena avrò l'occasione di mettere in pratica i tuoi consigli lo farò. Prima devo procurarmi il joy
Comunque posso effettuare la prova anche provare con un potenziometro classico.
Eventualmente scrivo qui per avere ulteriori consigli in merito, sperando tu sia sempre a disposizione
Beh sì puoi usare anche un potenziometro classico, ovviamente dovrai portare "a mano" al centro per fermare la rotazione, ma è esattamente lo stesso, oppure ci metti due molle che riportano il cursore al centro, se hai manualità basta che avvolgi qualche giro di filo in acciaio armonico ed è fatto.
Manualità ne ho da vendere,quello che manca sono le basi della programmazione.Ho provato a fare come dicevi te, al posto del joystic ho usato un potenziometro giusto per imbastire il tutto(tanto il principio è quello a parte i valore che in posizione centrale avrò un valore pari a 512k ma basta settare i vari valori), solo che non mi piace molto come risultato perchè ho troppi gradini tra una velocita e l altra(in piu il potenziometro rotativo che ho io è troppo sensibile basta sfiorarlo un poco di piu e cambia velocità a causa della sua costruzione) ma non appena ordino il joy sicuramente sarà più stabile e proverò sicuramente anche con quello. Per tagliare ta testa al toro mi sembra piu un lavoro ben fatto unendo il mio progetto e il tuo: invece che fare le varie velocita uso il joy come potenziometro per regolare la velocita usando map credo, e nella posizione centrale magari tra 450k e 574k lasciare il motore fermo,che dici?
Comunque qui c'è il codice come credo dicevi te,sarebbe giusto secondo te?
Praticamente stai pilotando il driver del motore direttamente nel loop e posizionando il potenziometro al massimo (tra 1000 e 1023) fermi il motore e disabiliti il driver, se ho capito bene.
Se preferisci avere una variazione continua della velocità in base alla posizione del potenziometro potresti, invece che utilizzare tutti quei delayMicroseconds() per variare la frequenza in uscita, utilizzare la funzione tone() /www.arduino.cc/reference/en/language/functions/advanced-io/tone/ settando la frequenza in base alla posizione del cursore, se vuoi la possibilità di variare anche il senso di rotazione potresti far calcolare la frequenza tra -freqMax e + freqMax, se il risultato è negativo setti il pin direzione in uno stato se è positivo nell'altro.
Farei qualcosa tipo:
#define PIN_POT A0 // pin in anal potenziometro
#define PIN_ENABLE 8 // pin out enable driver
#define PIN_STEP 7 // pin out step driver
#define PIN_DIR 9 // pin out dir driver
#define BAUD 115200 // bps
#define MAX_FREQ 5000 // frequenza massima generata
void setup() {
pinMode(PIN_ENABLE, OUTPUT);
pinMode(PIN_STEP, OUTPUT);
pinMode(PIN_DIR, OUTPUT);
pinMode(PIN_POT, INPUT);
digitalWrite(PIN_ENABLE, HIGH); // disabilito il driver
Serial.begin(BAUD); // per debug
}
void loop() {
int analogValue = analogRead(PIN_POT);
/*
* la massima frequenza che si vuol generare leggendo la
* posizione del cursore è MAX_FREQ, considerando che
* vogliamo che la posizione del cursore indichi anche
* il senso di rotazione dovremo considerare due frequenze
* massime quindi 2 * MAX_FREQ più un po' di gioco al centro
* dove considereremo la zona di "fermo" diciamo un decimo
* della corsa totale quindi tutta la scala 0-1023 verrà
* divisa in
* MAX_FREQ + MAX_FREQ + (MAX_FREQ * 0.1) = 2.1 * MAX_FREQ
* Faremo due map() per mappare la frequenza correttamente
*/
int val = map(analogValue, 0, 1023, -31500, 31500); // le variabili di tipo int hanno range da -32,768 a 32,767, per comodità taglio a 30000 più mezzo decimo per parte
/*
* ora in val abbiamo sia l'informazione del senso di rotazione (dato dal segno) che la posizione del cursode (dato dal valore numerico)
*/
if (val >= 0) {
// rotazione oraria
digitalWrite(PIN_DIR, HIGH); // setto la rotazione oraria
if (val >= 1500) {
// sono fuori dalla zona considerata neutra (un decimo al centro della corsa)
int freq = map(val, 1500, 31500, 0, MAX_FREQ); // mappo il range fuori dalla zona neutra per ottenere la frequenza
digitalWrite(PIN_ENABLE, HIGH); // abilito il driver
tone(PIN_STEP, freq); // genero la frequenza in uscita
Serial.print("Rotazione oraria, frequenza ");
Serial.println(freq);
} else {
// sono nella zona considerata neutra
noTone(PIN_STEP); // fermo la generazione dell'onda quadra
digitalWrite(PIN_ENABLE, HIGH); // disabilito il driver
Serial.println("Motore fermo");
}
} else {
// rotazione antioraria
digitalWrite(PIN_DIR, LOW); // setto la rotazione antioraria
if (val <= -1500) {
// sono fuori dalla zona considerata neutra (un decimo al centro della corsa)
int freq = map(val, -1500, -31500, 0, MAX_FREQ); // mappo il range fuori dalla zona neutra per ottenere la frequenza
digitalWrite(PIN_ENABLE, HIGH); // abilito il driver
tone(PIN_STEP, freq); // genero la frequenza in uscita
Serial.print("Rotazione antioraria, frequenza ");
Serial.println(freq);
} else {
// sono nella zona considerata neutra
noTone(PIN_STEP); // fermo la generazione dell'onda quadra
digitalWrite(PIN_ENABLE, HIGH); // disabilito il driver
Serial.println("Motore fermo");
}
}
delay(333); // attesa utile solo per non stampare troppi dati sulla seriale
}
Ti ringrazio per gli aiuti molto utili, per il momento provo ad adattare il tutto ad un classico potenziometro per mancanza di materiale, non appena sarò in possesso del materiale necessario farò tutto sul joy.