Stránka 1 z 3

Spouštění a zastavení motoru 28BYJ-48 Arduinem

Napsal: 04 pro 2024, 16:54
od hafca
Potřebuji spouštět a zastavovat motor 28BYJ-48+ULN2003 koncovými spínači. Motor by měl po zapnutí začít zvedat páku, která nahoře najede na koncák a motor vypne. Páka jede pomalu samočinně dolů, dole najede na koncák, který motor zapne a páka jede zase nahoru. A tak pořád dokola.
Nedokážu nastavit podmínky tak, aby se motor po nájezdu na dolní koncák zapnul.
Mohl by mi někdo poradit jak to dát dohromady?

Kód: Vybrat vše

#include <Stepper.h>

#define OUTPUT1   11                
#define OUTPUT2   10               
#define OUTPUT3   9                
#define OUTPUT4   8                
// Define the number of steps per rotation
const int stepsPerRotation = 2048;  
int switch_H  = 4; // up button
int switch_D = 5; // down button


Stepper myStepper(stepsPerRotation, OUTPUT2, OUTPUT4, OUTPUT1, OUTPUT3);  


void setup() {
 pinMode(4,INPUT_PULLUP);// push button pin as input
 pinMode(5,INPUT_PULLUP);// push button pin as input 
 pinMode(2, OUTPUT);
  myStepper.setSpeed(15);  // 15 RPM

 }
void loop() {
  
  myStepper.step(stepsPerRotation);  
  
if (digitalRead(4)==LOW)

    {
              myStepper.setSpeed(0);
              delay (20);
              digitalWrite(4, HIGH);
    }
    
    
else (digitalRead(5)==LOW);

   {
            myStepper.setSpeed(15);
              digitalWrite(4, HIGH);
              delay (20);
       
     }
  }  


Napsal: 04 pro 2024, 17:49
od Valdano
Úprava zdrojáku viz níže.

Kód: Vybrat vše

#include <Stepper.h>

#define OUTPUT1   11
#define OUTPUT2   10
#define OUTPUT3   9
#define OUTPUT4   8
#define SW_H      4
#define SW_D      5

const int stepsPerRotation = 2048; 

Stepper myStepper(stepsPerRotation, OUTPUT2, OUTPUT4, OUTPUT1, OUTPUT3); 

void setup()
{
  pinMode(SW_H,INPUT_PULLUP);
  pinMode(SW_D,INPUT_PULLUP);
  pinMode(2, OUTPUT);
  myStepper.setSpeed(15);
}

void loop()
{
  myStepper.step(stepsPerRotation); 
  if (digitalRead(SW_H)==LOW) {
    // sepnul horní koncák tj. vypnout motor
    myStepper.setSpeed(0);
    delay(20);
  } else {
    if (digitalRead(SW_D)==LOW) {
      // sepnul dolní koncák tj. zapnout motor
      myStepper.setSpeed(15);
      delay(20);
    }
  }
}

Napsal: 04 pro 2024, 18:01
od samec
Valdano, o čo sa snažíš? Prepísal si nefunkčnú blbosť na funkčnú blbosť. Myslíš, že už to pôjde?

hafca, nemôžeš do vstupu zapisovať digitalWrite(4, HIGH);.
Potrebuješ ešte jednu premennu definujúcu aktuálny stav a podľa nej kontrolovať horný alebo dolný spínač. Po zadetekovaní zopnutia spínača, zmeniť stav a zapnúť alebo vypnúť motor.

Napsal: 04 pro 2024, 18:14
od Valdano
Oprava. Teď by to mělo být funkční.

Úprava zdrojáku viz níže.

Krokový motor 28BYJ-48 má 32 kroků na otáčku motoru a s převodovkou 64:1 je to 2048 kroků na otáčku výstupního hřídele.

Kód: Vybrat vše

#include <Stepper.h>

#define OUTPUT1   11
#define OUTPUT2   10
#define OUTPUT3   9
#define OUTPUT4   8
#define SW_H      4
#define SW_D      5

// řízení chodu
int chod = 0;

// počet kroků na jednu otáčku motoru
const int stepsPerRotation = 32;

Stepper myStepper(stepsPerRotation, OUTPUT2, OUTPUT4, OUTPUT1, OUTPUT3);

void setup()
{
  pinMode(SW_H,INPUT_PULLUP);
  pinMode(SW_D,INPUT_PULLUP);
  pinMode(2, OUTPUT);
  // tímto se nastavuje rychlost otáčení na 1024 RPM tj. 1024 otáček motoru za minutu
  // na převodovce 64:1 to bude 16 RPM tj. 16 otáček výstupního hřídele za minutu
  myStepper.setSpeed(1024);
  chod = 1;
}

void loop()
{
  if (chod) {
    // pokud má běžet motor volá se step(256) 
    // 256 kroků (tj. 8 otáček motoru) během jednoho cyklu loop()
    // na převodovce 64:1 to bude 0,125 otáčky výstupního hřídele
    // funkce je blokující tj. čeká až motor dokončí pohyb 256 kroků
    // při rychlosti 1024RPM a při počtu 32 kroků na jednu otáčku motoru
    // bude její provedení trvat cca 256 * (60 / (1024 * 32)) tj. cca 470ms
    myStepper.step(256);
  };
  if (digitalRead(SW_H)==LOW) {
    // sepnul horní koncák tj. vypnout motor
    // páka pojede samočinně dolů bez motoru
    chod = 0;
    delay(20);
  } else {
    if (digitalRead(SW_D)==LOW) {
      // sepnul dolní koncák tj. zapnout motor
      // motor začne zvedat páku nahoru
      chod = 1;
      delay(20);
    }
  }
}

Napsal: 04 pro 2024, 20:20
od hafca
Dík za snahu, ale nefunguje to. Navíc se motor po zapnutí nerozběhne, jen "vrní".
V původním programu jsem měl pohyb motoru v pořádku. To není potřeba řešit.
Problém byl a je jen v jeho (ne)reagování na koncáky. Dokáži ho po zapnutí napájení rozběhnout a horním koncákem zastavit. Ale dolní koncák ho nespustí.

Napsal: 04 pro 2024, 20:31
od asdf
Mě tam udivuje tahle konstrukce:

Kód: Vybrat vše

else (digitalRead(5)==LOW);
To asi má být:

Kód: Vybrat vše

else if (digitalRead(5)==LOW)

Napsal: 04 pro 2024, 21:04
od Valdano
A co tohle?

Kód: Vybrat vše

#include <Stepper.h>

#define OUTPUT1   11
#define OUTPUT2   10
#define OUTPUT3   9
#define OUTPUT4   8
#define SW_H      4
#define SW_D      5

int chod = 0;
const int stepsPerRotation = 2048;

Stepper myStepper(stepsPerRotation, OUTPUT2, OUTPUT4, OUTPUT1, OUTPUT3);

void setup()
{
  pinMode(SW_H,INPUT_PULLUP);
  pinMode(SW_D,INPUT_PULLUP);
  pinMode(2, OUTPUT);
  myStepper.setSpeed(15);
  chod = 1;
}

void loop()
{
  if (chod) {
    myStepper.step(stepsPerRotation);
  };
  if (digitalRead(SW_H)==LOW) {
    // sepnul horní koncák tj. vypnout motor
    // páka pojede samočinně dolů bez motoru
    chod = 0;
    delay(20);
  } else {
    if (digitalRead(SW_D)==LOW) {
      // samozřejmě bez toho v úvodu chybně uvedeného středníku
      // sepnul dolní koncák tj. zapnout motor
      // motor začne zvedat páku nahoru
      chod = 1;
      delay(20);
    };
  };
}

Napsal: 04 pro 2024, 21:06
od samec
asdf píše:Mě tam udivuje tahle konstrukce:

Kód: Vybrat vše

else (digitalRead(5)==LOW);
To asi má být:

Kód: Vybrat vše

else if (digitalRead(5)==LOW)
Ale veď o tom je hneď prvý komentár, Mlho. :lol:

Napsal: 04 pro 2024, 21:14
od samec
Valdano, nechceš radšej použiť to, čo funguje? To jest myStepper.setSpeed(0); a myStepper.setSpeed(15); ? :D

Napsal: 04 pro 2024, 21:20
od asdf
To setSpeed(0) v původním kódu taky není dobrý nápad. Kdo ví, co to udělá, protože se tam pak dělí nulou. Je to totiž naprogramováno takhle:

Kód: Vybrat vše

void Stepper::setSpeed(long whatSpeed)
{
  this->step_delay = 60L * 1000L * 1000L / this->number_of_steps / whatSpeed;
}
Ten Valdanův kód by to mohl řešit.

Napsal: 04 pro 2024, 21:22
od asdf
samec píše:Ale veď o tom je hneď prvý komentár, Mlho. :lol:
Aha, ten jsem nějak vynechal. :oops:

Napsal: 04 pro 2024, 21:23
od Valdano
samec píše:Valdano, nechceš radšej použiť to, čo funguje? To jest myStepper.setSpeed(0); a myStepper.setSpeed(15); ? :D
Nechci, protože podle mého názoru je to nesprávné použití funkce setSpeed() viz citace.

Zdroj: Stepper - setSpeed()
Tato funkce nastavuje otáčky motoru v otáčkách za minutu (RPM). Tato funkce nespouští motor, pouze nastavuje rychlost, kterou se bude otáčet, když zavoláte step().
Při běhu motoru se má volat step() a při zastavení motoru se step() prostě nevolá. Navíc setSpeed(0) je chyba i vzhledem k tomu dělení nulou, které zde již zmínil asdf.

Proto mám v příkladu volání step() s podmínkou dle stavu proměnné chod, setSpeed(0) vůbec nevolám a setSpeed(15) stačí pro daný účel nastavit jen jednou v setup().

S tou poslední změnou tj. vrácením stepsPerRotation zpět na 2048 by to už mělo fungovat.

Napsal: 05 pro 2024, 08:00
od dj_Paul
není popsán důvod použití arduina ale nestačila by jedna L297 + 555 ?

Napsal: 05 pro 2024, 08:06
od hafca
Valdano píše:A co tohle?
...
Ano, tohle už funguje. Velké díky za pomoc všem.
Jen je zajímavé, že zastavování funguje až na několikátý pokus, ale rozběh hned. Ale možná je to tím, že to zatím mám na "prkénku". Uvažuji o spínání buď magnetem a jazýčkovým zátavem nebo magnet a Hallovo čidlo. Tam by asi nebylo potřeba řešit debounce.

Napsal: 05 pro 2024, 09:09
od hafca
dj_Paul píše:není popsán důvod použití arduina ale nestačila by jedna L297 + 555 ?
Máš pravdu, je to asi s kanonem na vrabce, ale nic jiného mi nenapadlo. I vzhledem k jednoduššímu nastavení parametrů otáčení. Asi by to šlo i s ATTINY, to ale neumím vůbec.