Do programu se ale nejdřív musí zadat skutečné krajní hodnoty při vychýlení joysticku a hodnoty joysticku při nulové poloze.
Postup:
Po spuštění programu se spustí sériový terminál a zaznamenají se hodnoty, které to bude vypisovat v krajních polohách a při narovnaném joysticku
Tyto hodnoty se pak přepíšou na začátku programu do konstant:
Kód: Vybrat vše
#define min_X 0 // skutecne krajni polohy joysticku (teoreticky se joystick vychyluje v rozsahu 0 az 1023)
#define max_X 1023
#define min_Y 0
#define max_Y 1023
#define nula_X 512 // skutecna hodnota, kterou posila joystick v klidu
#define nula_Y 512
Kód: Vybrat vše
// -----------------------------------------------------------------------------------------------
// tenhle blok po otestovani krajnich a nulovych poloh zrusit
Serial.print("osa_X: "); // nejdriv vyzkouset jake hodnoty dava joystick pri maximalnich vychylkach
Serial.print(osa_X); // Zjistene hodnoty pak prepsat do konstant 'min_X', 'max_X', 'min_Y' a 'max_Y' na zacatku programu
Serial.print(" osa_Y: "); // Pak tento blok vypisu do seriove linky zakomentovat
Serial.println(osa_Y); // Do konstant 'nula_X' a 'nula_Y', zapsat hodnoty obou os pri narovnanem joysticku
// -----------------------------------------------------------------------------------------------
Kód: Vybrat vše
#define rychlost_max 5 // pocet milisekund mezi jednotlivymi kroky pri maximalnim vychyleni joysticku
#define rychlost_min 1000 // pocet milisekund mezi jednotlivymi kroky pri minimalnim vychyleni joysticku (tesne pres 'pasmo_klidu')
Menší číslo umožní nastavovat joystick citlivěji (ve větším úhlu), ale zase hrozí, že i při nevychýleném joysticku bude některý z motorů pomalu ujíždět.
Kód: Vybrat vše
#define pasmo_klidu 50
Program:
Kód: Vybrat vše
//-----------------------------------------------------------
// Ovladani krokoveho motoru pomoci joysticku pres DRV8255
// vlevo / vpravo .... prvni motor (osa X) - podle uhlu vychyleni zmena rychlosti krokovani
//
// nahoru / dolu .... druhy motor (osa y) - podle uhlu vychyleni zmena rychlosti krokovani
//
// stisk tlacitka na joysticku najede servem do jedne nastavene polohy (parametr 'servo_ON')
// uvolneni tlacitka na joysticku vrati servo do druhe nastavene polohy (parametr 'servo_OFF')
// rychlost pohybu serva je nastavitelna (parametr 'rychlost_serva')
//
//-----------------------------------------------------------
#include <Servo.h> // knihovna pro ovladani serva
Servo servo1;
//----------------------------------
// prirazeni pinu
#define pin_X A0 // joystick - osa X
#define pin_Y A1 // joystick - osa Y
#define motor_X_STEP 4 // impulzni vstup X_DRV8255
#define motor_X_DIR 5 // smerovy vstup X_DRV8255
#define motor_Y_STEP 6 // impulzni vstup Y_DRV8255
#define motor_Y_DIR 7 // smerovy vstup Y_DRV8255
#define joystick_tl 8 // tlacitko na joysticku (vnitrne se spina proti GND)
#define pin_servo 9 // ovladaci pin serva
//----------------------------------
// konstantni parametry
#define min_X 0 // skutecne krajni polohy joysticku (teoreticky se joystick vychyluje v rozsahu 0 az 1023)
#define max_X 1023
#define min_Y 0
#define max_Y 1023
#define nula_X 512 // skutecna hodnota, kterou posila joystick v klidu
#define nula_Y 512
#define pasmo_klidu 50 // Pokud je joystick v prime poloze +/- 'pasmo_klidu' motory se netoci.
// Teoreticky stred primeho joysticku je cislo 512, ale neda se na to presne spolehnout.
// Pri nastavene konstante 'pasmo_klidu' na hodnotu 50 jsou motory v klidu pri hodnotach 462 az 562.
// Zbytek rozsahu vychylky se linearne prevadi na rychlost mezi nasledujici konstanty
#define rychlost_max 5 // pocet milisekund mezi jednotlivymi kroky pri maximalnim vychyleni joysticku
#define rychlost_min 1000 // pocet milisekund mezi jednotlivymi kroky pri minimalnim vychyleni joysticku (tesne pres 'pasmo_klidu')
#define servo_ON 90 // krajni poloha serva pri stisknutem tlacitku (rozsah 0 az 180)
#define servo_OFF 180 // krajni poloha serva pri uvolnenem tlacitku (rozsah 0 az 180)
#define rychlost_serva 1 // jakou rychlosti ma servo prejizdet (mensi cislo je rychlejsi prejezd)
//----------------------------------
// globalni promenne
unsigned int osa_X; // analogova hodnota vychyleni joysticku pro osu X
unsigned int osa_Y; // analogova hodnota vychyleni joysticku pro osu Y
unsigned long casovac; // pro urcovani pauzy mezi kroky
unsigned int pauza_X; // aktualni pauza mezi kroky podle vychyleni joysticku v ose X
unsigned int pauza_Y; // aktualni pauza mezi kroky podle vychyleni joysticku v ose Y
int uhel; // aktualni uhel serva
int smer_serva; // pricitani nebo odecitani jednicky pri pohybu serva (v zavislosti na tom, jestli je klidova poloha mensi nebo vetsi nez aktivni)
int cil; // na jakou polohu se ma servo natocit (servo_ON nebo servo_OFF)
unsigned long posledni_zmena; // casova znacka pro cas posledniho pootoceni serva o 1 stupen
//----------------------------------
void setup(void)
{
Serial.begin(9600);
// nastaveni smeru pinu
pinMode(pin_X, INPUT);
pinMode(pin_Y, INPUT);
pinMode(motor_X_STEP, OUTPUT);
pinMode(motor_X_DIR, OUTPUT);
pinMode(motor_Y_STEP, OUTPUT);
pinMode(motor_Y_DIR, OUTPUT);
pinMode(joystick_tl, INPUT_PULLUP);
servo1.attach(pin_servo);
servo1.write(servo_OFF); // natoceni serva do klidove polohy
uhel = servo_OFF; // do stejne polohy se nastavi i promenna 'uhel'
}
//----------------------------------
// hlavni smycka
void loop(void)
{
osa_X = analogRead(pin_X); // v kazde smycce se zmeri napeti na obou osach
osa_Y = analogRead(pin_Y);
// -----------------------------------------------------------------------------------------------
// tenhle blok po otestovani krajnich a nulovych poloh zrusit
Serial.print("osa_X: "); // nejdriv vyzkouset jake hodnoty dava joystick pri maximalnich vychylkach
Serial.print(osa_X); // Zjistene hodnoty pak prepsat do konstant 'min_X', 'max_X', 'min_Y' a 'max_Y' na zacatku programu
Serial.print(" osa_Y: "); // Pak tento blok vypisu do seriove linky zakomentovat
Serial.println(osa_Y); // Do konstant 'nula_X' a 'nula_Y', zapsat hodnoty obou os pri narovnanem joysticku
// -----------------------------------------------------------------------------------------------
osa_X = constrain(osa_X, min_X , max_X); // pro jistotu, aby se nestalo, ze hodnota pri vychyleni prekroci zadane meze 'min_X' a 'max_X'
osa_Y = constrain(osa_Y, min_Y , max_Y); // pro jistotu, aby se nestalo, ze hodnota pri vychyleni prekroci zadane meze 'min_Y' a 'max_Y'
if (osa_X > (nula_X + pasmo_klidu)) // vychyleni smeru X do plusu
{
pauza_X = map(osa_X, nula_X + pasmo_klidu , max_X , rychlost_min , rychlost_max ); // vypocet pauzy v [ms] mezi kroky
if (millis() - casovac > pauza_X) // kdyz pauza mezi kroky vyprsela ...
{
casovac = millis();
krok_X_plus(); // ... provede se krok v ose X do plusu
}
}
if (osa_X < (nula_X - pasmo_klidu)) // vychyleni smeru X do minusu
{
pauza_X = map(osa_X, min_X , nula_X - pasmo_klidu , rychlost_max , rychlost_min ); // vypocet pauzy v [ms] mezi kroky
if (millis() - casovac > pauza_X) // kdyz pauza mezi kroky vyprsela ...
{
casovac = millis();
krok_X_minus(); // ... provede se krok v ose X do minusu
}
}
if (osa_Y > (nula_Y + pasmo_klidu)) // vychyleni smeru Y do plusu
{
pauza_Y = map(osa_Y, nula_Y + pasmo_klidu , max_Y , rychlost_min , rychlost_max ); // vypocet pauzy v [ms] mezi kroky
if (millis() - casovac > pauza_Y) // kdyz pauza mezi kroky vyprsela ...
{
casovac = millis();
krok_Y_plus(); // ... provede se krok v ose Y do plusu
}
}
if (osa_Y < (nula_Y - pasmo_klidu)) // vychyleni smeru Y do minusu
{
pauza_Y = map(osa_Y, min_Y , nula_Y - pasmo_klidu , rychlost_max , rychlost_min ); // vypocet pauzy v [ms] mezi kroky
if (millis() - casovac > pauza_Y) // kdyz pauza mezi kroky vyprsela ...
{
casovac = millis();
krok_Y_minus(); // ... provede se krok v ose Y do minusu
}
}
// --------------- SERVO ------------------
if (digitalRead(joystick_tl) == LOW) cil = servo_ON; // tlacitko na joysticku je stisknute (cilovy uhel se nastavi na polohu 'servo_OFF')
else cil = servo_OFF; // tlacitko na joysticku je uvolnene (cilovy uhel se nastavi na polohu 'servo_ON')
if ((uhel != cil) and ((millis() - posledni_zmena) > rychlost_serva))// se servem se otaci jen v pripade, ze se aktualni 'uhel' a 'cil' neshoduje. Jinak je servo v klidu
{ // Otaceni je mozne ale az po vyprseni nastaveneho intervalu
if (uhel > cil) uhel --; // vypocet noveho uhlu natoceni serva
else uhel ++;
servo1.write(uhel); // otoceni serva na nove vypocteny uhel
posledni_zmena = millis(); // nova znacka pro dalsi porovnani s pozadovanym casovym intervalem mezi krokovanim serva
}
// --------- KONEC SERVA ------------------
}
//-------------- konec hlavni smycky --------------------
//----------------------------------
// pootoceni motoru v ose X o jeden krok dopredu
void krok_X_plus(void)
{
digitalWrite(motor_X_DIR,HIGH);
digitalWrite(motor_X_STEP,HIGH);
delay(1);
digitalWrite(motor_X_STEP,LOW);
delay(1);
}
//----------------------------------
// pootoceni motoru v ose X o jeden krok dozadu
void krok_X_minus(void)
{
digitalWrite(motor_X_DIR,LOW);
digitalWrite(motor_X_STEP,HIGH);
delay(1);
digitalWrite(motor_X_STEP,LOW);
delay(1);
}
//----------------------------------
// pootoceni motoru v ose Y o jeden krok dopredu
void krok_Y_plus(void)
{
digitalWrite(motor_Y_DIR,HIGH);
digitalWrite(motor_Y_STEP,HIGH);
delay(1);
digitalWrite(motor_Y_STEP,LOW);
delay(1);
}
//----------------------------------
// pootoceni motoru v ose Y o jeden krok dozadu
void krok_Y_minus(void)
{
digitalWrite(motor_Y_DIR,LOW);
digitalWrite(motor_Y_STEP,HIGH);
delay(1);
digitalWrite(motor_Y_STEP,LOW);
delay(1);
}