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)
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);
}
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:
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.
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.