Kontinuální otáčení NEMA17

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
hafca
Příspěvky: 119
Registrován: 23 říj 2017, 23:05

Kontinuální otáčení NEMA17

Příspěvek od hafca » 06 dub 2025, 14:44

Potřebuji udělat po stisku tlačítka kontinuální otáčení NEMA17 a jeho zastavení po signálu HIGH z čidla. Pak by měly proběhnout povely které tam jsou po zastavení a celý cyklus by se měl opakovat.
Zkoušel jsem to vložit do kódu co už mi funguje na spuštění, ale motor nejde zastavit. Neumím ho dostat do režimu kontinuálního otáčení, ale jen na určitý počet otáček a tam to asi nikam vložit nepůjde.
Je na to nějaká finta?

Kód: Vybrat vše

#include <Arduino.h>
#include "A4988.h"

const int Step = 3; //GPIO3 in Arduino UNO --- Step of stepper motor driver
int Dire  = 2; //GPIO2 in Arduino UNO --- Direction of stepper motor driver
int Sleep = 4; //GPIO4 in Arduino UNO --- Control Sleep Mode on A4988
int MS1 = 7; //GPIO7 in Arduino UNO --- MS1 for A4988
int MS2 = 6; //GPIO6 in Arduino UNO --- MS2 for A4988
int MS3 = 5; //GPIO5 in Arduino UNO --- MS3 for A4988
int BLT_pin = 11;
int ENB_pin = 9;
int STEP_pin = 10;
const int SW_pin = 8;

//Motor Specs
const int spr =200; //Steps per revolution
int RPM = 64; //Motor Speed in revolutions per minute
int Microsteps = 16; //Stepsize (1 for full steps, 2 for half steps, 4 for quarter steps, etc)

//Providing parameters for motor control
A4988 stepper(spr, Dire, Step, MS1, MS2, MS3);

void setup() {
 Serial.begin(9600);

pinMode(MS1, INPUT_PULLUP); 
pinMode(MS2, INPUT_PULLUP); 
pinMode(MS3, INPUT_PULLUP); 

pinMode(SW_pin, INPUT);
 pinMode(STEP_pin, INPUT);
 pinMode(BLT_pin, OUTPUT);
 pinMode(ENB_pin, OUTPUT);
    pinMode(Step, OUTPUT); //Step pin as output
  pinMode(Dire,  OUTPUT); //Direcction pin as output
  pinMode(Sleep,  OUTPUT); //Set Sleep OUTPUT Control button as output
  digitalWrite(Step, LOW); // Currently no stepper motor movement
  digitalWrite(Dire, LOW);
  digitalWrite(Sleep, HIGH); //A logic high allows normal operation of the A4988 by removing from sleep
    digitalWrite(ENB_pin, HIGH);
  delay(1000);//Wait 1000 milliseconds (1 second) proceeding
   digitalWrite(BLT_pin, LOW);
   digitalWrite(ENB_pin, LOW);
  digitalWrite(SW_pin, LOW);
    digitalWrite(STEP_pin, HIGH);
  // Set target motor RPM to and microstepping setting
  stepper.begin(RPM, Microsteps);
  delay(5000);
 }
void loop() {
digitalRead(STEP_pin);

if(digitalRead(STEP_pin) == LOW){
     digitalWrite(Sleep, HIGH); //A logic high allows normal operation of the A4988 by removing from sleep
     stepper.move(3200);//Move  steps clockwise 
    delay(200);//Wait 1000 milliseconds 
   digitalWrite(BLT_pin, LOW);
    delay(500);//Wait 1000 milliseconds 
    digitalWrite(BLT_pin, HIGH);
    delay(1500);//Wait 1000 milliseconds
    digitalWrite(STEP_pin, LOW);
}
   }

AstroMiK
Příspěvky: 649
Registrován: 08 pro 2017, 19:05

Re: Kontinuální otáčení NEMA17

Příspěvek od AstroMiK » 06 dub 2025, 15:58

Tohle vypadá hodně divně.
Zdá se mi, že tam máš nějak proházené směry pinů.

Já bych na to asi nepoužíval žádnou knihovnu.

V setupu natvrdo nastavit "DIR", "SLEEP" a "ENABLE".
Pokud je to potřeba tak i ty mikrostepovací volby (MS1 až MS3).

A v loopu už bych jen postupně přepínal ten STEP pin mezi HIGH a LOW. V podstatě jako v základním příkladu pro blikání LEDkou.
Akorát teda ty pauzy mezi stavama by musely být o hodně kratší.

A k tomu už pak jen přidat to tlačítko a čidlo, které budou přepínat, jestli má STEP pin kmitat, nebo být v klidu.



Nějak takhle (NEOVĚŘENO!):

Kód: Vybrat vše


// prirazeni pinu
#define pin_STEP             10
#define pin_tlacitko          9
#define pin_cidlo             8
#define pin_DIR               7
#define pin_ENABLE            6
#define pin_SLEEP             5           
#define pin_MS1               4           
#define pin_MS2               3           
#define pin_MS3               2           



// globalni promenne
bool tocit_motorem = false;                        // false = po zapnuti napajeni motor stoji


void setup(void)
  {
    pinMode(pin_tlacitko, INPUT_PULLUP);           // tlacitko spina proti GND, rozepnute je v HIGH
    pinMode(pin_cidlo, INPUT);                     // cidlo dava LOW nebo HIGH (HIGH zastavuje motor)
    pinMode(pin_STEP , OUTPUT);                    // krokovani motoru

    pinMode(pin_DIR , OUTPUT);                     // smer otaceni
    digitalWrite(pin_DIR, HIGH);

    pinMode(pin_ENABLE , OUTPUT);                  // spusteni napajeni do motoru
    digitalWrite(pin_ENABLE, LOW);

    pinMode(pin_SLEEP , OUTPUT);                   // probudit motor
    digitalWrite(pin_SLEEP, HIGH);

    pinMode(pin_MS1 , OUTPUT);                     // mikrostepovaci piny ...
    pinMode(pin_MS2 , OUTPUT);
    pinMode(pin_MS3 , OUTPUT);
    digitalWrite(pin_MS1, LOW);                    // ... nastavit podle potreby
    digitalWrite(pin_MS2, LOW);
    digitalWrite(pin_MS3, LOW);
  }


void loop(void)
  {
    if (digitalRead(pin_tlacitko) == LOW)          // stisk spousteciho tlacitka ...
      {
        tocit_motorem = true;                      //  ... zapina motor
      }

    if (digitalRead(pin_cidlo) == HIGH)            // HIGH signal od cidla ...
      {
        tocit_motorem = false;                     // ... zastavuje motor       (ma vyssi prioritu nez tlacitko, takze dokud bude z cidla HIGH, ani tlacitkem se motor nerozoci)
        
        //  ************ 
        //  tady kdyztak doplnit jeste povely, ktere se maji vykonat pri zastaveni 
        //  ************ 
      }

    if (tocit_motorem == true)                     // kdyz se ma motor tocit, vykona se jeden (mikro)krok
      {
        digitalWrite(pin_STEP, HIGH);
        delayMicroseconds(5000);                   // pauzy upravit na pozadovanou rychlost otaceni (vetsi cislo = pomalejsi otaceni)
        digitalWrite(pin_STEP, LOW);
        delayMicroseconds(5000);
      }

  }

hafca
Příspěvky: 119
Registrován: 23 říj 2017, 23:05

Re: Kontinuální otáčení NEMA17

Příspěvek od hafca » 06 dub 2025, 17:22

Tak jsem to zkoušel a s malými úpravami to částečně chodí. Musel jsem přečíslovat piny, protože je to všechno už na DPS. Dál nastavit MS1-3 na input. Motor se ale otáčel jen při držení tlačítka. Po přidání řádku se už po stisku tlačítka točí stále, po signálu z čidla zastaví, ale zůstane stát jen dokud trvá signál z čidla. Správně by zůstat stát, měly proběhnout povely po zastavení a pak opakovat cyklus - (rozběh-zastavení na čidlo-povely-rozběh)....

Kód: Vybrat vše

// prirazeni pinu - jsem musel změnit, protože je už osazená DPS
#define pin_STEP              3
#define pin_tlacitko          10
#define pin_cidlo             8
#define pin_DIR               2
#define pin_ENABLE            9
#define pin_SLEEP             4           
#define pin_MS1               7           
#define pin_MS2               6           
#define pin_MS3               5          



// globalni promenne
bool tocit_motorem = false;                        // false = po zapnuti napajeni motor stoji


void setup(void)
  {
    pinMode(pin_tlacitko, INPUT_PULLUP);           // tlacitko spina proti GND, rozepnute je v HIGH
    pinMode(pin_cidlo, INPUT);                     // cidlo dava LOW nebo HIGH (HIGH zastavuje motor)
    pinMode(pin_STEP , OUTPUT);                    // krokovani motoru

    pinMode(pin_DIR , OUTPUT);                     // smer otaceni
    digitalWrite(pin_DIR, HIGH);

    pinMode(pin_ENABLE , OUTPUT);                  // spusteni napajeni do motoru
    digitalWrite(pin_ENABLE, LOW);

    pinMode(pin_SLEEP , OUTPUT);                   // probudit motor
    digitalWrite(pin_SLEEP, HIGH);

    pinMode(pin_MS1 , INPUT_PULLUP);                     // mikrostepovaci piny ...
    pinMode(pin_MS2 , INPUT_PULLUP);
    pinMode(pin_MS3 , INPUT_PULLUP);
    digitalWrite(pin_MS1, HIGH);                    // ... nastavit podle potreby
    digitalWrite(pin_MS2, HIGH);
    digitalWrite(pin_MS3, HIGH);
  
  }

void loop(void)
  {
    if (digitalRead(pin_tlacitko) == LOW)          // stisk spousteciho tlacitka ...
      {
       digitalWrite(pin_tlacitko, LOW);             // bez toho řádku se motor točí jen při stisknutém tlačítku
                                                    // s ním se točí stále, ale zastavuje jen dokud trvá signál čidla
        tocit_motorem = true;                      //  ... zapina motor
       
      }

    if (digitalRead(pin_cidlo) == HIGH)            // HIGH signal od cidla ...
      {
        
        tocit_motorem = false;                     // ... zastavuje motor       (ma vyssi prioritu nez tlacitko, takze dokud bude z cidla HIGH, ani tlacitkem se motor nerozoci)
        
        //  ************ 
        //  tady kdyztak doplnit jeste povely, ktere se maji vykonat pri zastaveni 
        //  ************ 
    
      }

    if (tocit_motorem == true)                     // kdyz se ma motor tocit, vykona se jeden (mikro)krok
      {
        digitalWrite(pin_STEP, HIGH);
        delayMicroseconds(50);                   // pauzy upravit na pozadovanou rychlost otaceni (vetsi cislo = pomalejsi otaceni)
        digitalWrite(pin_STEP, LOW);
        delayMicroseconds(50);
        
      }

  }

Uživatelský avatar
kiRRow
Příspěvky: 1313
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Kontinuální otáčení NEMA17

Příspěvek od kiRRow » 06 dub 2025, 17:39

Chybu bych nehledal konkrétně v programu, ale spíše v zapojení, popřípadě nedodržení různého časování (debounce na čidlu nebo tak). Tím, že do pinu, který máš nastavený jako input zapíšeš pomocí digitalWrite LOW, tak vypneš jeho interní pull up rezistor.

AstroMiK
Příspěvky: 649
Registrován: 08 pro 2017, 19:05

Re: Kontinuální otáčení NEMA17

Příspěvek od AstroMiK » 06 dub 2025, 19:07

To je nějaká blbost.

Piny MS1 až MS3 slouží k ovládání driveru a musí být z pohledu Arduina nastavené jako "OUTPUT".
V případě, že by byly úplně odpojené, má je driver vnitřně přitáhnuté k zemi, takže jsou ve stavu LOW.


Spouštěcí tlačítko v mém programu bylo plánované na připojení proti GND.
V tom případě platí, že uvolněné tlačítko je přes vnitřní Pull-Up Arduina ve stavu HIGH.
Po stisknutí je ve stavu LOW (přizemněné).

Program by neměl být náchylný na zákmity tlačítka. Když se tlačítkový vstup prvně ocitne ve stavu LOW,
proměnná 'tocit_motorem' se nastaví na TRUE a tim se motor roztočí. Pak už je jedno, jestli je tlačítko uvolněné, nebo znovu sepnuté.
Proměnná 'tocit_motorem' zůstává slále na TRUE až do okamžiku, kdy přijde signál HIGH z čidla, který ji přepne na FALSE a tím motor zastaví.
Opět nezáleží na zákmitech. První výskyt HIGH z čidla motor zastavuje.

Jediná věc, kterou tam nemám ošetřenou, ale upozorňuji na ni v komentáři, je v tom, že čidlo má prioritu před tlačítkem.
Dokud tedy bude čidlo vysílat signál HIGH, stisk tlačítka motor nespustí.

Pokud by bylo třeba priority změnit, jednoduše se prohodí mezi sebou podmínky tak, že testování čidla bude v programu umístěné před testováním tlačítka.

hafca
Příspěvky: 119
Registrován: 23 říj 2017, 23:05

Re: Kontinuální otáčení NEMA17

Příspěvek od hafca » 06 dub 2025, 19:33

Když byly piny MS1 až MS3 jak jsi je nastavil, motor se neroztočil. Spouštěcí tlačítko je nastavené na spojení s GND, motor spouští a ten po jeho stisku a po mé úpravě stále běží. Bez ní běžel jen dokud bylo tlačítko sepnuté.
Zákmity od digitálního výstupu čidla asi nehrozí. Jenže jeho signál motor zastaví jen na dobu, dokud je přítomen. Já potřebuji aby se motor zastavil a proběhly instrukce, motor se rozběhl a čekal na čidlo a celé se to opakovalo.
Abych vysvětlil k čemu to má sloužit. Po stisku tlačítka motor začne transportovat film. Až čidlo zaznamená perforaci zastaví motor, fotoaparát vyfotí políčko a začne zase transport filmu. To celé se opakuje dokud se nevypne napíjení.

Uživatelský avatar
kiRRow
Příspěvky: 1313
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Kontinuální otáčení NEMA17

Příspěvek od kiRRow » 06 dub 2025, 20:39

Ale tohle přesně v tom programu napsáno je ... po stisku tocit_motorem = true ... po detekci na čidle tocit_motorem = false + místo pro další příkazy ... další část programu říká pokud tocit_motorem == true , tak pošlu pulz na motor ...

hafca
Příspěvky: 119
Registrován: 23 říj 2017, 23:05

Re: Kontinuální otáčení NEMA17

Příspěvek od hafca » 06 dub 2025, 20:51

Tak proč to nechodí?

AstroMiK
Příspěvky: 649
Registrován: 08 pro 2017, 19:05

Re: Kontinuální otáčení NEMA17

Příspěvek od AstroMiK » 06 dub 2025, 22:55

Program jsem neověřoval.
Zítra si to zkusím postavit.

Podle detailnějšího popisu požadované funkce je jasné, že bude třeba změnit ty priority, jak jsem psal výše.
Protože tak jak je to napsané teď, tak když čidlo zaznamená díru (HIGH), motor se zastaví a tím to čidlo bude hlásit díru pořád (HIGH), takže nebude možné spustit motor tlačítkem.

Když se priority prohodí, tak po zastavení motoru na díře bude možné držením tlačítka motor spustit na tak dlouho, než díra z čidla odjede do LOW.

EDIT:
Jenom pro upřesnění - opravdu ti čidlo dává stav HIGH v okamžiku, kdy se má motor zastavit a stav LOW když je mimo perforaci?
Nemohlo se stát, že je ten signál opačně?

hafca
Příspěvky: 119
Registrován: 23 říj 2017, 23:05

Re: Kontinuální otáčení NEMA17

Příspěvek od hafca » 07 dub 2025, 08:21

Velká omluva. Máš pravdu s tím čidlem, je to obráceně.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 0 hostů