Controllo di Motori Stepper con Microcontrollore

NE555   I Motori Passo Passo o Stepper Hanno Bisogno di un Apposito Segnale di Controllo, lo Schema Seguente può Controllare la Modalità, la Velocità e la Direzione di Rotazione di Questi Motori…


 
 
 
 




 

I SEGNALI DI CONTROLLO

Le modalità di controllo più usate per i motori passo passo bipolari sono due, uno detto full step che garantisce una coppia maggiore però con frequenze a coppia nulla e la modalità half step che garantisce un controllo migliore ma con meno coppia. Le forme d’onda, come visto nell’articolo precedente, sono:

NE555

Quindi connettendo il motore passo passo ad un microcontrollore si possono generare le forme d’onda. Nel caso del full step il path logico è il seguente: “1001”, “1010”, “0110” e “0101”. Questo connettendo A al MSB, poi A’, poi B e infine al LSB si connette B’.

Per la modalità half step invece, considerando sempre la stessa connessione, si avrà il seguente path logico: “1001”, “1000”, “1010”, “0010”, “0110”, “0100, “0101” e “0001”.

Variando la frequenza, ovvero il tempo tra un path logico e l’altro, si varia la velocità. Supponendo che la frequenza massima sia 50Hz, allora il tempo minimo tra un path logico e l’altro allora è 20mS. Il tempo massimo invece può essere molto maggiore, ma supponiamo 4Hz, in modo tale che in un secondo si possono avere 4 passi del motore.

Per quanto riguarda la direzione, questa si può variare invertendo o i MSB o i LSB dei path logici, dove gli LSB sono gli ultimi due bit del path logico, mentre i MSB sono i primi due bit. (LSB = low significative bit, MSB=most significative bit).

 




 

CODICE

Con le considerazioni fatte in precedenza sul segnale di controllo, il codice è il seguente:

#define direction portc.f4         //Ingresso set direzione
#define fullhalf portc.f5          //Ingresso set modalità
#define start portc.f6             //Ingresso stop-avvia motore

unsigned conversione;              //Valore che contiene la conversione
unsigned period;                   //Valore che contiene il periodo

full_step_dir1(unsigned period){   //Full Step senso Orario
  portc = 0b00001001;              //Path logico 1001
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001010;              //Path logico 1010
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000110;              //Path logico 0110
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000101;              //Path logico 0101
  Vdelay_ms(period);               //Delay di valore periodo
}

full_step_dir2(unsigned period){   //Full Step senso Antiorario
  portc = 0b00000101;              //Path logico 0101
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000110;              //Path logico 0110
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001010;              //Path logico 1010
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001001;              //Path logico 1001
  Vdelay_ms(period);               //Delay di valore periodo
}

half_step_dir1 (unsigned period){  //Half Step senso orario
  portc = 0b00001001;              //Path logico 1001
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001000;              //Path logico 1000
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001010;              //Path logico 1010
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000010;              //Path logico 0010
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000110;              //Path logico 0110
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000100;              //Path logico 0100
  Vdelay_ms(period);               //Delay di valore periodo
  
  portc = 0b00000101;              //Path logico 0101
  Vdelay_ms(period);               //Delay di valore periodo
  
  portc = 0b00000001;              //Path logico 0001
  Vdelay_ms(period);               //Delay di valore periodo
}

half_step_dir2 (unsigned period){  //Half Step senso Antiorario
  portc = 0b00000101;              //Path logico 0101
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000100;              //Path logico 0100
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00000110;              //Path logico 0110
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001110;              //Path logico 1110
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001010;              //Path logico 1010
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001000;              //Path logico 1000
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001001;              //Path logico 1001
  Vdelay_ms(period);               //Delay di valore periodo

  portc = 0b00001101;              //Path logico 1101
  Vdelay_ms(period);               //Delay di valore periodo
}

void main() {                       //Programma principale

 trisc = 0b01110000;                //PC0, PC1, PC2 e PC3 out PC4, PC5, PC6 in
 trisa = 0b00000001;                //AN0 ingresso

 ADC_Init();                        //Inizializza ADC

 //while(start){                    //Da usare se si vuole start-stop
 while(1){                          //Da usare se si vuole start continuo

   conversione = ADC_Read(0);       //Leggi da AN0
   period = conversione >> 2;       //Shift di 2 posizioni a DX
   period = period + 20;            //Somma valore minimo per ottenere il periodo

   if(fullhalf){                    //Se PC5=1
     if(direction){                 //Se PC4=1
       full_step_dir1(period);      //esegui full_step_dir1
     }

     else full_step_dir2(period);   //Se PC4=0 esegui full_step_dir2
   }                                //fine if

   if(!fullhalf){                   //Se PC5=0
     if(direction){                 //Se PC4=1
       half_step_dir1(period);      //esegui half_step_dir1
     }

       else half_step_dir2(period); //Se PC4=0 esegui half_step_dir2
   }                                //fine if
 }                                  //fine while
}                                   //fine

Il codice è molto semplice, prima di tutto si definiscono due ingressi, “direction” per selezionare la direzione mentre “fullhalf” per selezionare la modalità di funzionamento, se full wave o half wave. Questi due ingressi sono i pin PC4 e PC5 del PORTC.

Successivamente si inizializzano 4 sottoprogrammi che eseguono in uscita su PORTC i path logici, in particolare vi sarà A connesso a PC0, A’ a PC1, B connesso a PC2 e infine, B’ a PC3. Nei 4 sottoprogrammi sono contenuti in ordine il path logico per full wave in senso orario, full wave senso antiorario, half wave in senso orario e infine half wave in senso antiorario. Ovviamente il senso di rotazione dipende dalla corretta connessione del motore, in ogni caso cambiando l’ingresso del pin PC4 cambierà la direzione di rotazione.

Nel programma principale vengono segnalati ingressi e uscite e viene inizializzato l’ADC, infatti si utilizza l’ADC per convertire un segnale di controllo della velocità. In particolare si converte l’ingresso di AN0 e si ottiene un dato a 10bit di cui vengono eliminati 2 LSB, ottenendo un risultato a 8 bit, quindi al massimo si ottiene 255 come valore. A questo valore viene sommato 20 e diventa una variabile detta period, che rappresenta il tempo di ogni step logico, quindi la frequenza del segnale di controllo. Questo valore di periodo va da un minimo di 20 fino ad un massimo di 275, quindi visto che si usa la routine “Vdelay_ms(period)” vi sarà una pausa di 20ms minima, fino ad un massimo di 275ms , fra gli step, quindi una frequenza da 50Hz, fino ad un minimo di 4Hz circa. Variando il valore iniziale o lo shift della conversione si possono variare le frequenze minime e massime.

Dopo di che si utilizza “if” ed “else” per selezionare le modalità e direzioni. Se PC5=1 e PC4=1 allora si avrà il sottoprogramma “full_step_dir1”, se PC5=1 e PC4=0 allora si avrà il sottoprogramma “full_step_dir2”, PC5=0 e PC4=1 allora si avrà il sottoprogramma “half_tep_dir1” e infine se PC5=0 e PC4=0 allora si avrà il sottoprogramma “half_tep_dir2”. In questo caso il ciclo viene ripetuto all’infinito, ma se si utilizza la stringa “while(start){“ allora il ciclo, e quindi gli step possono essere avviati e stoppati controllando il livello logico sul pin PC6, ovvero il pin nominato start. Se sul pin PC6 vi è un livello alto allora il ciclo è avviato e si eseguono step, se è a livello logico basso il ciclo non si avvia, quindi si stoppa e si avvia il motore tramite PC6.

 




 

SCHEMA

Lo schema è il seguente:

NE555   Si utilizza un quarzo da 8MHz con due condensatori da 22pF, un alimentazione che può andare da 3.3V e 5V e un condensatore sistemato vicino i pin di alimentazione del microcontrollore per avere meno rumore di conversione.  Per il controllo della velocità si usa una resistenza variabile collegata tra VCC e GND con il contatto strisciante connesso al pin AN0. Si può inserire anche un condensatore tra il pin AN0 e massa del valore da 10nF per avere meno rumore sull’ingresso dell’ADC. Il controllo della direzione, della modalità di controllo e della partenza e stop può essere fatta da segnali digitali esterni, oppure tramite interruttori e  resistenze di pull-up come si vede in figura. Il microcontrollore può fornire poca corrente in uscita, il motore ne richiede invece molta, di conseguenza è necessario un buffer. In questo caso è stato usato un ADP3654 un integrato in grado di garantire 4A e di avere tensioni in ingresso più piccole di quelle di alimentazione. Può anche essere usato un integrato come ULN2003 o si può usare un ponte ad H con 4 gambe costruito a mosfet o transistor con componenti discreti. Tutte queste soluzioni verranno affrontate in un successivo articolo. Lo schema montato su breadboard è il seguente:

NE555

 

DOWNLOAD

Il file .HEX, il codice, il file MikroC e la simulazione dello schema possono essere scaricati a questo LINK!!!



 

4832 Visite totali 57 Visite di oggi

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *