Need help, how to end loop of this function?

Hi,
I am doing project for my school and in one part of my code i have part with stepper motor. I need to rotate it just once, but the motor is rotating in loop. Is there any way to rotate it just once? when i call the function? (need to end loop of rotate function)

#include <AccelStepper.h>

#define motorPin1  8
#define motorPin2  9
#define motorPin3  10
#define motorPin4  11

#define MotorInterfaceType 8

AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);

int pos = 0; 

void setup() {
  stepper.setMaxSpeed(1000);
  stepper.moveTo(pos);

}

void loop() {

  rotate();
  
}

void rotate () {
    stepper.setCurrentPosition(0);
    
  while (stepper.currentPosition() != 1024) {
    stepper.setSpeed(500);
    stepper.runSpeed();
  }
  
  delay(2000);
  stepper.setCurrentPosition(0);
  
  while (stepper.currentPosition() != -1024) {
    stepper.setSpeed(-500);
    stepper.runSpeed();
  }
  
  delay(1000);
}
rotate();
while(true){};

One option, if you want something only done once, is to move it out of loop() and into setup().

Hi,
I am doing project for my school and i am doing metal detector with conveyor belt. In this project when metal is detected, LED diode start lighting and step motor (not from conveyor) will rotate. Problem is, when something metal is detected and motor will rotate, it doesn´t end the function and I can´t detect more than 1 object on the conveyor. Any idea how to end function to star loop part again? (main problem with ending the function is on line 93 - 97, where the LED is lighting, but after detection function "detekce" doesn´t end)

///// Program pro Maturitní Projekt 2021 Lukáš Voda 4.EA /////

// Pro tento program jsem použil knihovnu AccelStepper (knihovna pro krokové motory):
#include <AccelStepper.h>

// Zde jsem si nadefinoval piny pro motor *
#define motorPin1  8      // IN1 vstup na ULN2003 driveru
#define motorPin2  9      // IN2 vstup na ULN2003 driveru
#define motorPin3  10     // IN3 vstup na ULN2003 driveru
#define motorPin4  11     // IN4 vstup na ULN2003 driveru

// Zde definuji z knihovny AccelStepper rozhrání pro 4 krokový motor o 4 vodičích
#define MotorInterfaceType 8

// Zde přiřadím sekvenci pinů * IN1 - IN4 pro použití s mým motorem 28BYJ-48
AccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);

int pos = 0; 

const byte npulse = 12; // potřebný počet impulzů k nabití kondenzátoru, před každým měřením
 
const byte pin_pulse = A0; // do A0 se posílají tyto impulzy, k nabití kondenzátoru
const byte pin_cap  = A1; // A1 měří náboj kondenzátoru
const byte pin_LED = 12; // když detektor detekuje kov, rozsvítí se LEDka
 
void setup() {
  // zde nastavuji maximální počet kroků motoru za vteřinu a pozici kam se má motor otočit
  stepper.setMaxSpeed(1000);
  stepper.moveTo(pos);
  
  pinMode(pin_pulse, OUTPUT);
  digitalWrite(pin_pulse, LOW);
  pinMode(pin_cap, INPUT);
  pinMode(pin_LED, OUTPUT);
  digitalWrite(pin_LED, LOW);
}
 
const int nmeas = 256; // maximální hodnota impulzů
long int sumsum = 0; // průběžný součet impulzů
long int skip = 0; // počet přeskočených impulzů
long int diff = 0;      // rozdíl mezi součtem a průměrnou hodnotou
long int flash_period = 0; // perioda (v ms)
long unsigned int prev_flash = 0; // čas před předchozím detekováním
 
void loop() {
 
  int minval = 5000;
  int maxval = 0;
 
  // měření
  long unsigned int sum = 0;
  for (int imeas = 0; imeas < nmeas + 2; imeas++) {
    //reset the capacitor
    pinMode(pin_cap, OUTPUT);
    digitalWrite(pin_cap, LOW);
    delayMicroseconds(20);
    pinMode(pin_cap, INPUT);
    //provedení impulzů
    for (int ipulse = 0; ipulse < npulse; ipulse++) {
      digitalWrite(pin_pulse, HIGH); //trvá 3,5 ms
      delayMicroseconds(3);
      digitalWrite(pin_pulse, LOW); //trvá 3,5 ms
      delayMicroseconds(3);
    }
    //přečtení stavu na kondenzátoru
    int val = analogRead(pin_cap); //trvá 13x8=104 ms
    minval = min(val, minval);
    maxval = max(val, maxval);
    sum += val;
 
    //určení rozsvícení LED podle detekce 
    long unsigned int timestamp = millis();
    byte ledstat = 0;
    if (timestamp < prev_flash +12) {
      if (diff > 0)ledstat = 1;
      if (diff < 0)ledstat = 2;
    }
    if (timestamp > prev_flash + flash_period) {
      if (diff > 0)ledstat = 1;
      if (diff < 0)ledstat = 2;
      prev_flash = timestamp;
    }
    if (flash_period > 1000)ledstat = 0;
 
    //rozsvítí LEDku pro kontrolu zdali funguje detekce kovu

    if (ledstat == 0) {
      digitalWrite(pin_LED, LOW);
    }
    if (ledstat == 1) {
      digitalWrite(pin_LED, LOW);
    }
    if (ledstat == 2) {
      digitalWrite(pin_LED, HIGH);
      detekce();
      while(true){};
    }
    
  }
 
  //Zde odečtu minimální a maximální hodnoty, aby detektor kovu nepřeskakoval
  sum -= minval; sum -= maxval;
 
  //process
  if (sumsum == 0) sumsum = sum << 6; //Zde nastavuji součet na minimální hodnotu, kterou potřebuji pro detekci
  long int avgsum = (sumsum + 32) >> 6;
  diff = sum - avgsum;
  if (abs(diff)<avgsum >> 10) {   //Zde porovnávám hodnoty, pokud se nebudou moc lišit
    sumsum = sumsum + sum - avgsum;
    skip = 0;
  } else {
    skip++;
  }
  if (skip > 64) {  // Pokud detekce bude příliš dlouhá, tak se program přeskočí
    sumsum = sum << 6;
    skip = 0;
  }
 
  // Zde jsem 1 ms v periodě změnil na dvojnásobnou hodnotu kvůli větší efektivitě detekce
  if (diff == 0) flash_period = 1000000;
  else flash_period = avgsum / (2 * abs(diff));
}

//Funkce, kterou vyvolám, pokud detektor detekuje nějaký předmět jako kovový (vyhodí ho mimo pás)
void detekce() {
   // Nastavuji aktuální pozici motoru
  stepper.setCurrentPosition(0);

  // Ve funkci while nechám motor otočit páku o 500 kroků za vteřinu, dokud motor nedosáhne nastavené hodnoty na řádku níže
  while (stepper.currentPosition() != 1024) {
    stepper.setSpeed(1000);
    stepper.runSpeed();
  }
  delay(2000);

  //Motor nastaví aktuální pozici jako hlavní
  stepper.setCurrentPosition(0);

  // Zde opět pomocí funkce while motor otočí páku, tentokrát zpět na původní polohu
  while (stepper.currentPosition() != -1024) {
    stepper.setSpeed(-500);
    stepper.runSpeed();
  }
  stepper.setCurrentPosition(0);
  delay(1000);
}
     detekce();
      while(true){};

but after detection function "detekce" doesn´t end)

No surprise there with that while loop there. If you want the code not to stall at that point remove the while loop. Why is the while loop there in the first place ?

The while is there, because I need motor to rotate just once. If I remove it, the motor doesn´t stop. So I need to motor rotate just once and after that the loop function starts again.

But while(true){} will never be false so the code with loop there forever. Not what you want if you want loop() to run again.

You can also use stepper.runToNewPosition() to just move to a given location since you aren't doing anything else while the motor is running

void detekce() {
  // Nastavuji aktuální pozici motoru
  stepper.setCurrentPosition(0);

  // Ve funkci while nechám motor otočit páku o 500 kroků za vteřinu, dokud motor nedosáhne nastavené hodnoty na řádku níže
  stepper.setSpeed(1000);
  stepper.runToNewPosition(1024);
  delay(2000);

  // Zde opět pomocí funkce while motor otočí páku, tentokrát zpět na původní polohu
  stepper.setSpeed(-500);
  stepper.runToNewPosition(0);
  delay(1000);
}

@luigu

TOPIC MERGED.

Could you take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.

It will help you get the best out of the forum.

luigu:
The while is there, because I need motor to rotate just once. If I remove it, the motor doesn't stop. So I need to motor rotate just once and after that the loop function starts again.

So you program to do just that after you remove the spurious "while".

Beginners misunderstand what the loop() is for and how it is to be used. You do not need to and must not attempt to complete any action within the loop that requires waiting for anything. Properly written code is a sequence of mini-tasks one after the other in the loop, each of these testing whether it is at that very moment, appropriate to do something.

The point is that until it is appropriate to do that thing, they must "let it go" and drop to the next mini-task in the list. Once all those tasks have been tested, the loop begins to test them all again. :sunglasses:

And the test for such tasks may be whether sufficient time has past based on millis(), whether a certain number of steps of a stepper have been completed (each step requiring a certain time to execute) or whether a complete action such as your "single rotation" has been performed in which case you set a flag variable so that on each successive pass through the loop, testing the flag will indicate that no further stepper action is to take place.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.