Rotácia v náhodnom smere, s náhodnou rýchlosťou a náhodným počtom krokov.
Doporučené preštudovať: Krokové Motory | Riadenie Unipolárneho Krokového motora #1
Ako podklad pre tento projekt použijem projekt Riadenie Unipolárneho Krokového motora #1, kde sme napísali program pre rotáciu motora v jednom smere a v konštantnej rýchlosti.
Typ motora + schémy použijem stávajúce z predošlého projektu.
Napíšem program, ktorý nám bude otáčať motor v náhodnom smere, náhodnou rýchlosťou a s náhodným počtom krokov.
stepper_diall.h |
struct _unipolar_stepper_motor_ {
struct __attribute__ ((packed)) { volatile unsigned int *Port; volatile unsigned int *Tris; }Direct; struct __attribute__ ((packed)) { int * Pins; int pin_size; }Config; struct __attribute__ ((packed)) { int from; int to; int routing; int left; int right; }Control; struct __attribute__ ((packed)) { int i; int a; int b; }Tmp; }Stepper; void Stepper_Init() { int stepper_pins[] = {1,2,3,7}; int err=1; if(*Stepper.Direct.Port == PORTA && PORTA != __No__Used__ && TRISA != __No__Used__) { Stepper.Direct.Tris = uintptr &TRISA; err=0; } if(*Stepper.Direct.Port == PORTB && PORTB != __No__Used__ && TRISB != __No__Used__) { Stepper.Direct.Tris = uintptr &TRISB; err=0; } if(*Stepper.Direct.Port == PORTC && PORTC != __No__Used__ && TRISC != __No__Used__) { Stepper.Direct.Tris = uintptr &TRISC; err=0; } if(*Stepper.Direct.Port == PORTD && PORTD != __No__Used__ && TRISD != __No__Used__) { Stepper.Direct.Tris = uintptr &TRISD; err=0; } if(err==0) { Stepper.Config.pin_size = sizeof(stepper_pins)/sizeof(int); Stepper.Config.Pins = malloc(Stepper.Config.pin_size); Stepper.Control.left = 0; Stepper.Control.right = 1; for(Stepper.Tmp.i = 0; Stepper.Tmp.i < Stepper.Config.pin_size; Stepper.Tmp.i++) { Stepper.Config.Pins[Stepper.Tmp.i] = stepper_pins[Stepper.Tmp.i]; } for(Stepper.Tmp.i = 0; Stepper.Tmp.i < Stepper.Config.pin_size; Stepper.Tmp.i++) { Init_Port(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.i],"digital"); Config_OUT(*Stepper.Direct.Tris,Stepper.Config.Pins[Stepper.Tmp.i]); Bit_Clr(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.i]); } } } void Stepper_Go(int way, int timer_ms, int rount) { if(way == Stepper.Control.left) { Stepper.Control.from = 0; Stepper.Control.to = Stepper.Config.pin_size; Stepper.Control.routing = BACKWARD; } else if(way == Stepper.Control.right) { Stepper.Control.from = Stepper.Config.pin_size-1; Stepper.Control.to = -1; Stepper.Control.routing = FORWARD; } for (Stepper.Tmp.b=0;Stepper.Tmp.b<rount;Stepper.Tmp.b++) { for(Stepper.Tmp.i = Stepper.Control.from; Stepper.Tmp.i!=Stepper.Control.to;) { for(Stepper.Tmp.a=Stepper.Control.from; Stepper.Tmp.a!=Stepper.Control.to;) { if(Stepper.Tmp.i==0) //1.takt - start { if(Stepper.Tmp.a==0 || Stepper.Tmp.a==1) { Bit_Set(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } else { Bit_Clr(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } } if(Stepper.Tmp.i==1) //2.takt - start { if(Stepper.Tmp.a==1 || Stepper.Tmp.a==2) { Bit_Set(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } else { Bit_Clr(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } } if(Stepper.Tmp.i==2) //3.takt - start { if(Stepper.Tmp.a==2 || Stepper.Tmp.a==3) { Bit_Set(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } else { Bit_Clr(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } } if(Stepper.Tmp.i==3) //4.takt - start { if(Stepper.Tmp.a==3 || Stepper.Tmp.a==0) { Bit_Set(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } else { Bit_Clr(*Stepper.Direct.Port,Stepper.Config.Pins[Stepper.Tmp.a]); } } if(Stepper.Control.routing == Stepper.Control.left) //prechadzanie pola pinov /urcenie smeru/ { Stepper.Tmp.a++; } else { Stepper.Tmp.a--; } } Delay_ms(timer_ms); if(Stepper.Control.routing == Stepper.Control.left) { //prechadzanie taktov /urcenie smeru/ Stepper.Tmp.i++; } else { Stepper.Tmp.i--; } } } Delay_ms(1500); } |
Úpravou pôvodného kódu sme pridali jeden parameter rount do funkcie Stepper_Init. Parameter je ako premenná použitý v ďalšom cykle "for".
Je potrebné si uvedomiť, že pri predošlom projekte sme veľa vecí neriešili, nakoľko funkcia beží v cykle while, v súbore main ako slučka. Jeden krok pozostáva zo štyroch taktov. Tento fakt je v slučke zacyklený, preto počekt taktov nie je nutné neakým spôsobom ďalej riešiť.
V tomto projekte však potrebujeme, aby sa nám motor otočil v náhodnom smere, náhodnou rýchlosťou a urobil náhodný počet krokov.
Jedna otočka okolo svojej osy - 48 krokov. Budeme požadovať, aby sa motor otočil minimálne o 4 kroky a maximálne o 48 - celá otočka.
Túto úlohu má pridaný cyklus "for", ktorý pracuje so spomenutým parametrom rount .
Isto prichádza otázka, k čomu je nám ďalšie spomalenie Delay_ms(1500); .
Predstavte si, že cheme vykonať jednu celú otočku pri jednej rýchlosti. V zápätí sa nám generuje polovičná otáčka pri tej istej rýchlosti. Aby sme sa vyhli tomu, že motor urobí jednu a pol otáčky bez zastavenia, každú jednu sekvenciu generovania odseba časovo oddelíme.
Zabránime tomu, aby sa nám motor točil bez zastávky a zaručíme, že motor sa nemusí točiť vôbec.
main.c |
#define __NoTypeDefh__
#include "config_diall.h" #include "stepper_diall.h" #include "config_words.h" char *PageSys(void) { return "0x21"; } int main(void) { Stepper.Direct.Port = uintptr &PORTB; Stepper_Init(); while(1) { Stepper_Go(way_tracking[Randoming(0,2)],Randoming(23,200),Randoming(4,48)); } } |
Obsah súbora main.c sa od predošlého projektu moc nelíši. Upravená je len funkcia Stepper_Go.
Pole way_tracking[] je globálne definované pole v konfiguračnóm súbore config_diall.h .
Obsahuje globálne premenné FORWARD,BACKWARD,UP,DOWN.
Funkciou Randoming(0,2) sa generujú náhodne čísla od 0-2, ktoré reprezentujú indexy poľa. Pri generovaní indexu "2" sa smer vo funkcií nerozozná a motor sa nepohybuje.
Ako hodnota druhého parametra je generovaná rýchlosť, Randoming(23,200).
V tretie v poradí sa generuje počet krokov - od 4 do 48, Randoming(4,48).
Jadrom náhodného výberu je funkcia Randoming(x,y) ktorú som zakomponoval do prostredia
config_diall pri návrhu tochto projektu. Ide o LFSR náhodný generátor.
Celý článok je k dispozícií >> Tu <<