Stránka 1 z 1

Ovládání krokového motoru pomocí Arduina a hledání „nuly“

Napsal: 11 lis 2022, 22:29
od Jiris
Dobrý den všem,
k řízení směru jízdy u našeho stroje používáme krokový motor (KM), který otáčí celou pojezdovou jednotkou, a tak mění směr jízdy stroje. K buzení řídící jednotky KM používáme Arduino UNO naprogramované jako zdroj pulzů. Používáme dva výstupy Arduina. První je výstup určující jakým směrem se KM bude otáčet, a je připojený na vstup DIR řídící jednotky KM. Druhý výstup Arduina poskytuje pulzy pro otáčení (1 pulz = 1 krok KM) a je připojený na vstup PUL řídící jednotky. Stav vstupu DIR tedy udává, kterým směrem se bude motor otáčet a pulzy posílané z Arduina do vstupu PUL způsobují otáčení KM.

Pro změnu směru jízdy používáme dva režimy.

První režim funguje tak, že zmáčknutím tlačítka např. „korekce dráhy doleva“ Arduino nastaví stav vstupu DIR tak, aby se KM otáčel doleva a zároveň vyšle 200 impulzů do vstupu PUL. Toto způsobí, že se KM otočí o příslušný úhel daný počtem impulzů doleva. Po vymáčknutí tohoto tlačítka Arduino automaticky nastaví stav vstupu DIR tak, aby se KM otáčel doprava a vyšle opět 200 impulzů do vstupu PULZ. Toto způsobí, že se KM ocitne v původní „nulové“ poloze a pojezdová jednotka v přímém směru jízdy, což je to co potřebujeme.

Druhý režim změny směru jízdy funguje tak, že zmáčknutím tlačítka např. „jízda doleva“ Arduino vysílá impulzy do řídící jednotky KM po celou dobu po kterou je tlačítko zmáčknuté. Po vymáčknutí tlačítka zůstane KM v poloze, kterou dosáhl, takže pro dosažení „nulové“ polohy KM pro přímý směr jízdy pojezdové jednotky je třeba zmáčknout tlačítko „jízda doprava“ po přesně stejnou dobu po jakou bylo před tím zmáčknuté tlačítko „jízda doleva“. A to je samozřejmě problém.

Co bychom potřebovali je to, abychom v druhém režimu, bez ohledu na to v jaké poloze se KM ocitne, zmáčknutím přidaného speciálního tlačítka „přímý směr“ dostali KM do nulové polohy. Předpokládám, že to znamená, že potřebujeme, aby si Arduino tuto nulovu polohu nějak pamatovalo, nebo, aby bylo schopno počítat kolik pulzů jakým směrem se do řídící jednotky KM poslalo a odečítat pulzy otáčející KM na jednu stranu od pulzů na druhou stranu.
Jenže to je to co neumíme.
Máte nějaký návrh jak to vyřešit?

Zde je kód pro ovládání, který jsme prozatím vyplodili:

Kód: Vybrat vše

// C++ code
//
int konec = 0;

int konec1 = 0;

int unnamed = 0;

int i = 0;

int j = 0;

int k = 0;

int Konec2 = 0;

int m = 0;

int n = 0;

int konec3 = 0;

int counter;

int counter2;

int counter3;

int counter4;

void setup()
{ pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);

  konec1 = 1;
}

void loop()
{
  if (digitalRead(6) == HIGH) {
    while (!(digitalRead(6) == LOW)) {
      digitalWrite(3, HIGH);
      delayMicroseconds(1500); // Wait for 1.5 millisecond(s)
      digitalWrite(3, LOW);
      delayMicroseconds(1500); // Wait for 1.5 millisecond(s)
    }
  }

  if (digitalRead(7) == HIGH) {
    digitalWrite(2, HIGH);
    while (!(digitalRead(7) == LOW)) {
      digitalWrite(3, HIGH);
      delayMicroseconds(1500); // Wait for 1.5 millisecond(s)
      digitalWrite(3, LOW);
      delayMicroseconds(1500); // Wait for 1.5 millisecond(s)
    }
  }
  if (digitalRead(7) == LOW) {
    digitalWrite(2, LOW);
  }

  if (digitalRead(5) == HIGH) {
    konec = 0;
    konec1 = 0;
    while (!(digitalRead(5) == LOW)) {
      while (!(konec == 1)) {
        for (counter = 0; counter < 200; ++counter) {
          digitalWrite(3, HIGH);
          delayMicroseconds(700); // Wait for 0.7 millisecond(s)
          digitalWrite(3, LOW);
          delayMicroseconds(700); // Wait for 0.7 millisecond(s)
        }
        konec = 1;
      }
    }
  }
  if (digitalRead(5) == LOW) {
    while (!(konec1 == 1)) {
      digitalWrite(2, HIGH);
      for (counter2 = 0; counter2 < 200; ++counter2) {
        digitalWrite(3, HIGH);
        delayMicroseconds(700); // Wait for 0.7 millisecond(s)
        digitalWrite(3, LOW);
        delayMicroseconds(700); // Wait for 0.7 millisecond(s)
      }
      digitalWrite(2, LOW);
      konec1 = 1;
    }
  }

  if (digitalRead(4) == HIGH) {
    konec = 0;
    konec1 = 0;
    while (!(digitalRead(4) == LOW)) {
      while (!(konec == 1)) {
        digitalWrite(2, HIGH);
        for (counter3 = 0; counter3 < 200; ++counter3) {
          digitalWrite(3, HIGH);
          delayMicroseconds(700); // Wait for 0.7 millisecond(s)
          digitalWrite(3, LOW);
          delayMicroseconds(700); // Wait for 0.7 millisecond(s)
        }
        digitalWrite(2, LOW);
        konec = 1;
      }
    }
  }
  if (digitalRead(4) == LOW) {
    while (!(konec1 == 1)) {
      for (counter4 = 0; counter4 < 200; ++counter4) {
        digitalWrite(3, HIGH);
        delayMicroseconds (700); // Wait for 0.7 millisecond(s)
        digitalWrite(3, LOW);
        delayMicroseconds(700); // Wait for 0.7 millisecond(s)
      }
      konec1 = 1;
    }
  }
}
Edit: Používejte tag code - tlačítko s "nemravným obrázkem" </>

Re: Ovládání krokového motoru pomocí Arduina a hledání „nuly“

Napsal: 11 lis 2022, 23:29
od peterple
Ak som to pochopil správne tak ide o tlačítka pripojené na vstupy 6, 7
6 - posúva jedným smerom pokiaľ sa drži
7 - posúva druhým smerom
Neviem ktoré to má vrátiť do priameho smeru. tak povedzme že další vstup 8

Kód: Vybrat vše


long int poslanyPocet=0;

void step(){
 digitalWrite(3, HIGH);
 delayMicroseconds(1500); // Wait for 1.5 millisecond(s) 
 digitalWrite(3, LOW);
 delayMicroseconds(1500); // Wait for 1.5 millisecond(s)
}

void loop()
{
if (digitalRead(6) == HIGH) {
 while (!(digitalRead(6) == LOW)) {
  step();
  poslanyPocet++;
 }
}

if (digitalRead(7) == HIGH) {
 digitalWrite(2, HIGH);
 while (!(digitalRead(7) == LOW)) {
  step();
  poslanyPocet--;
 }
}
if (digitalRead(7) == LOW) {
 digitalWrite(2, LOW);
}

if (digitalRead(8) == HIGH) { // navrat do priameho smeru
  if (poslanyPocet>0){ //ak som isiel do plusu
     digitalWrite(2, HIGH); //tak idem do minusu
    while (poslanyPocet)) {
      step();
      poslanyPocet--;
    }
  
  } else if (poslanyPocet<0){ //ak som isiel do minusu
     digitalWrite(2, LOW); //tak idem do plusu
    while (poslanyPocet)) {
      step();
      poslanyPocet++;
    }
  }
}

...

}
Myšlienka toho programu je taká, že v premennej poslanyPocet sa počíta počet poslaných impulzov a to tak že jeden smer pripočítava a druhý smer odpočítava.
Návrat do priameho smeru je potom ľahká záležitosť. Len sa posiela zapamätaný počet impulzov opačným smerom.
Poradí si to aj s tým že to viackrát pošleš do jedného smeru opakovane, alebo to pošles moc a potom to trochu ubereš. Nulovacie tlačítko to vždy vráti do pôvodného smeru. Je to písané z hlavy môžu tam byť nejaké preklepy alebo zabudnuté zátvorky a pod.
(na urobenie kroku som si urobil spešl funkciu lebo a mi nechcelo stále kopírovať)

Re: Ovládání krokového motoru pomocí Arduina a hledání „nuly“

Napsal: 12 lis 2022, 02:18
od Jiris
Ano, pochopil jste to správně. Který vstup to vrátí do přímého směru je jedno, takže vstup 8 vyhovuje.
Moc děkuju, to vypadá dobře. Musím to vyzkoušet. Bude to ale chvíli trvat, protože to zařízení už je namontované ve stroji, a ten nemám doma.
Ale mohl bych to zítra vyzkoušet na Tinkercadu.
Ještě jednou moc díky.

Re: Ovládání krokového motoru pomocí Arduina a hledání „nuly“

Napsal: 12 lis 2022, 07:09
od gilhad
Asi by taky mohlo být šikovné přidat ještě další tlačítko pro "nulování/kalibrování", které po stisknutí vynuluje poslanyPocet.
Jednak pro případy, kdy se třeba vypne/restartuje Arduino při nějakém zatáčení a je pak znova potřeba nastavit, co znamená "rovně" a jednak pokud se během provozu stane, že je to "rovně" potřeba upřesnit, nastavit jinak.

Re: Ovládání krokového motoru pomocí Arduina a hledání „nuly“

Napsal: 12 lis 2022, 19:31
od Jiris
gilhad píše:
12 lis 2022, 07:09
Asi by taky mohlo být šikovné přidat ještě další tlačítko pro "nulování/kalibrování", které po stisknutí vynuluje poslanyPocet.
Jednak pro případy, kdy se třeba vypne/restartuje Arduino při nějakém zatáčení a je pak znova potřeba nastavit, co znamená "rovně" a jednak pokud se během provozu stane, že je to "rovně" potřeba upřesnit, nastavit jinak.
To je dobrý nápad. Díky moc.
Jiris