I want stepper motor and ultrasonic sensors to work at the same time

I want stepper motor and ultrasonic sensors to work at the same time, but I couldn't find a solution. I tried to shorten the time of the stepper motor, but it always stays the same and this time is too long. here are the codes

int trigPin1 = 2;
int echoPin1 = 3;
int trigPin2 = 4;
int echoPin2 = 5;
int trigPin3 = 6;
int echoPin3 = 7;

#define buzzer 8  
#define potentiometer A0

int valueOfPot;
int frequenceOfBuzzer;

#include <X113647Stepper.h>
const int stepsPerRevolution = 32 * 32;
X113647Stepper myStepper(stepsPerRevolution, 10, 11, 12, 13);

void setup() {
  Serial.begin (9600);
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(trigPin3, OUTPUT);
  pinMode(echoPin3, INPUT);

  pinMode(buzzer, OUTPUT);
  pinMode(potentiometer, INPUT);

  myStepper.setSpeed(200);
}

void firstsensor(){ 
  int duration1, distance1;
  digitalWrite (trigPin1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigPin1, LOW);
  duration1 = pulseIn (echoPin1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1); 
      Serial.print("cm    ");

 if (distance1 > 30 and distance1 < 62) { 
    tone(buzzer, frequenceOfBuzzer, frequenceOfBuzzer);  
 }
 else if (distance1 > 0 and distance1 < 31) {
    tone(buzzer, frequenceOfBuzzer);
 }
  else {
    noTone(buzzer);
  } 
}
void secondsensor(){
    int duration2, distance2;
    digitalWrite (trigPin2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin2, LOW);
    duration2 = pulseIn (echoPin2, HIGH);
    distance2 = (duration2/2) / 29.1;
 
      Serial.print("2nd Sensor: ");
      Serial.print(distance2); 
      Serial.print("cm    ");
  
 if (distance2 > 30 and distance2 < 62) { 
    tone(buzzer, frequenceOfBuzzer, frequenceOfBuzzer);  
 }
 else if (distance2 > 0 and distance2 < 31) {
    tone(buzzer, frequenceOfBuzzer);
 }
  else {
    noTone(buzzer);
  }
}
void thirdsensor(){
    int duration3, distance3;
    digitalWrite (trigPin3, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin3, LOW);
    duration3 = pulseIn (echoPin3, HIGH);
    distance3 = (duration3/2) / 29.1;

      Serial.print("3rd Sensor: ");  
      Serial.print(distance3); 
      Serial.print("cm");
  
 if (distance3 > 30 and distance3 < 62) { 
    tone(buzzer, frequenceOfBuzzer, frequenceOfBuzzer);
 }
 else if (distance3 > 0 and distance3 < 31) {
    tone(buzzer, frequenceOfBuzzer); 
 }
  else {
    noTone(buzzer);
  }

}

void stepper(){
  if (valueOfPot == 0) {
    myStepper.setSpeed(0);
  } else {
    myStepper.step(stepsPerRevolution);
    delay(50);
    myStepper.step(-stepsPerRevolution);
    delay(50);
  }
}

void loop() {
  
/*Buzzer Control*/
valueOfPot = analogRead(potentiometer); 
frequenceOfBuzzer = map(valueOfPot,0,1023,0,900); 
  
Serial.println("\n");
firstsensor();
delay(200);
secondsensor();
delay(200);
thirdsensor();
delay(200);
stepper();
delay(200);
}

Have you noticed that your firstSensor, secondSensor and thirdSensor functions are almost identical?

Can you explain what you mean by that, please?

Maybe with a footnote about how you want your code to behave, and how it fails to meet those expectations?

I want the stepper motor to run in the background while the sensors are working, but they all work in sequence. how can i change the code.

The stepper lib you are using blocks while the stepper is moving.
You could try my MobaTools library to drive the stepper. This lib creates the stepping in timer interrupts independent from loop - so the stepper runs in the background independent from your sensors. In loop it is only necessary to set speed and target position ( which can be changed at any time ).

I couldn't find what I wanted in the documents. Do you have a chance to convert these codes to your library's codes?

#include <X113647Stepper.h>

#define potentiometer A0
int valueOfPot;
const int stepsPerRevolution = 32 * 32;
X113647Stepper myStepper(stepsPerRevolution, 10, 11, 12, 13);

void setup()
{
  myStepper.setSpeed(1000);
  pinMode(potentiometer, INPUT);
}
void loop() {
  valueOfPot = analogRead(potentiometer);
  
  if (valueOfPot == 0) {
    myStepper.setSpeed(0);
  } else {
    myStepper.step(stepsPerRevolution);
    delay(50);
    myStepper.step(-stepsPerRevolution);
    delay(50);
  }
}

Can you explain what this sketch should do?
Why use an analog input, when you don't use that value? Only 0 or not 0 can also be be done by a digital input. And when do you set the speed to a reasonable value again after it has been set to 0?

I just want it to go 180 degrees + and - direction. When the value of the potentiometer is 0, the stepper motor needs to stop. If you just write the code that rotates 180 degrees in + and - directions, I can do the rest. like this

#include <X113647Stepper.h>

const int stepsPerRevolution = 32 * 32; //180 degree
X113647Stepper myStepper(stepsPerRevolution, 10, 11, 12, 13); //stepper pins

void setup()
{
  myStepper.setSpeed(1000); //stepper timer
}
void loop() {
    myStepper.step(stepsPerRevolution); //stepper + direction
    delay(50);
    myStepper.step(-stepsPerRevolution); //stepper - direction
    delay(50);
}
#include <MobaTools.h>

MoToStepper myStepper(2048, FULLSTEP);
void setup() {
    // put your setup code here, to run once:
    myStepper.attach( 10,11,12,13 );
    myStepper.setSpeedSteps( 1000 );
    myStepper.setRampLen( 100 );
}

void loop() {
    // put your main code here, to run repeatedly:
    if ( !myStepper.moving() ) {
      if ( myStepper.read() == 0 ) {
            myStepper.write(180);
        } else {
            myStepper.write(0);
        }
    }

}

Maybe you must interchange pin 11/12. depends how your X113647Stepper library creates the steps.

Edit: minor changes to the sketch ( without direction variable )

1 Like

Have you verified the the potentiometer value actually gets to zero?
Paul

void stepper(){
  valueOfPot = analogRead(potentiometer);
  if (valueOfPot == 0) {
    myStepper.write(0);
    myStepper.setSpeedSteps( 0 );
  } else if(valueOfPot > 0) {
    if ( !myStepper.moving() ) {
      if ( myStepper.read() == 0 ) {
            myStepper.write(180);
        } else {
            myStepper.write(0);
        }
    }
  }
}

void loop() {
stepper();
valueOfPot = analogRead(potentiometer);
}

The library works fine in the background, but I couldn't do a single thing. It works when the value of the potentiometer is not 0 and stops when it is 0, but when I turn the potentiometer back on, it does not start to rotate. what is the solution to this? (These are part of the codes.)

I understood why. I added the following codes in the if and the problem was solved.

 else if(valueOfPot > 0) {
    //this codes
    myStepper.setSpeedSteps( 1500 );
    myStepper.setRampLen( 100 );
    //----------
    if ( !myStepper.moving() ) {
      if ( myStepper.read() == 0 ) {
            myStepper.write(180);
        } else {
            myStepper.write(0);
        }

thank you all for your helping.

You must not use myStepper.setSpeedSteps( 0 ); to stop the stepper ( speed=0 is invalid and will be set to the minimum value internally ). MoToStepper is a positioning system. The motor runs up to the target position and stops there automatically. But you can change the target position at any time - no matter if the motor has reached the previous target position or not. To stop the motor while it is running, you must set the target position to the actual position of the motor. There are several methods to accomplish this.

  • myStepper.rotate(0) - this sets a new target postion one ramplen beyond of the actual position. The motor decelerates immediatly and stops at the end of the ramp.

  • myStepper.doSteps(0) - this sets the target position to the actual position. The motor decelerates until stop, and than moves back to the position where it was at the moment of issuing the command.

  • myStepper.stop() - this is an emergency stop. The motor stops immediatly without decelerating. This may lead to step errors, if the motor mechanically cannot stop that fast.

If no accelerating/decelerating is defined ( rampLen = 0 ), all three methods behave the same.

Speed and ramplen are remembered and need not to be set again, when setting a new Target position to start the motor again.
A new target can be set absolutely with mystepper.write(angle); or mystepper.writeSteps(steps); measured from the reference point (zeropoint). Or it can be set in steps relative to the actual position with myStepper.doSteps(relativeSteps);

so change

    myStepper.write(0);
    myStepper.setSpeedSteps( 0 );

to

myStepper.rotate(0);

that should be sufficent.

Continuing the discussion from I want stepper motor and ultrasonic sensors to work at the same time:
Hello Hasan.
I'm working on a radar project using an ultrasonic and a stepper motor. Once the ultrasonic detects an object, it will start beeping using a buzzer. The stepper motor is to move the ultrasonic sensor. I have very little experience in coding and I would greatly appreciate it if you can help me with my code. Thats what I have so far, I don't know if thats correct, I've been trying to teach myself via youtube:
#include <Stepper.h>
#define STEPS 255 // the number of steps in one revolution of your motor (28BYJ-48)
const int stepsPerRevolution = 2038;
const int trigPin = 7;
const int echoPin = 6;
const int buzzer = 12;
const int ledPin = 13;

long duration;
int distance;
int roundAngle;
int Angle;
Stepper stepper(STEPS, 8, 10, 9, 11);

void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(buzzer, OUTPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600); // Starts the serial communication
stepper.setSpeed(60);
stepper.step(1300);
stepper.step(-1300);
}

void loop() {

}

Thank you!!

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