Stránka 2 z 2

Re: Prosím o pomoc, zapojeni+kód (nema23)

Napsal: 30 dub 2023, 22:58
od AstroMiK
Níže přikládám upravený program. Funkce serva zůstala stejná jako v poslední verzi.

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
Pak se smaže nebo zakomentuje blok Serial.printů:

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
// -----------------------------------------------------------------------------------------------  
Rozsah rychlostí otáčení pro obě osy se nastavuje tady (menší číslo je rychlejší pohyb):

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')
Je tam ještě konstanta, která udává, jak velká tolerance hodnoty joysticku je považovaná za narovnaný joystick (to bylo vidět v předchozím obrázku jako zelené pásmo).
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);        
  }

Re: Prosím o pomoc, zapojeni+kód (nema23)

Napsal: 06 kvě 2023, 23:21
od bernkop
Děkuji moc za pomoc!! vše šlape jak má. Teď jen dořešit to vzdálené ovládání ....