Controlling Stepper Motor with IR Distance Sensor

Project: Hello, I'm creating a project in which a Nema 17 stepper motor with a screw that moves a connecting plate to predefined distances. I’m using a Sharp IR sensor to measure the distance of the plate from the base. The way the code is setup, it should step the motor until the distance measured by the sensor reaches the desired distance using a while() loop. Then going onto the next while() loop for the next distance. First time poster so apologies for any mistakes. Thanks!

Problem: The problem I’m having is that it seems like after reading the distance 1 time, the code gets stuck in the first while() loop. I’m still very new to using accelstepper.h so I’m not sure if im using the wrong commands as well.

Hardware:

  • Arduino Uno
  • Nema 17 Stepper
  • DRV8825 driver
  • SHARP gp2y0a51sk0f IR Sensor

Sharp Connections

• VCC -> 5v
• GND -> Gnd
• Signal -> A0

Code

#include <AccelStepper.h>

// Define stepper motor connections and parameters
#define DIR_PIN 2
#define STEP_PIN 3
// Create an instance of AccelStepper
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
float TargetDistance1 = 1; // 1 in away
float TargetDistance2 = 2; // 2 in away


// IR SENSOR
const int sensorPin= A0;
float distance, distanceIN;
const int AVERAGE_OF =5;
const float MCU_VOLTAGE = 5.0;
void readDistance(void);


void setup() 
{
  // Set maximum speed and acceleration
  Serial.begin(9600);
  stepper.setMaxSpeed(5000.0); // Adjust this value as needed
  stepper.setAcceleration(1000.0); // Adjust this value as needed
  
}

void loop() {
  readDistance();
  Serial.println(distanceIN);


  // go to target 1
  while (distanceIN != TargetDistance1)
  {
      readDistance();
      stepper.run();
  }
  delay(5000); // wait 5s

  // go to target 2
  while (distanceIN != TargetDistance1)
  {
      readDistance();
      stepper.run();
  }
  delay(5000); // wait 5s

}



void readDistance(void)
{
      float voltage_temp_average=0;
      
      for(int i=0; i < AVERAGE_OF; i++)
    {
      int sensorValue = analogRead(sensorPin );
      delay(1);      
      voltage_temp_average +=sensorValue * (MCU_VOLTAGE / 1023.0);

    }
     voltage_temp_average /= AVERAGE_OF;

  // eqution of the fitting curve
  // sensor outputs distance in centimeters
  ////33.9 + -69.5x + 62.3x^2 + -25.4x^3 + 3.83x^4
  distance = 33.9 + -69.5*(voltage_temp_average) + 62.3*pow(voltage_temp_average,2) + -25.4*pow(voltage_temp_average,3) + 3.83*pow(voltage_temp_average,4);
  distanceIN = distance / 2.54; // converting cm to IN
}

Comparing floats with "!=" is not a good idea because any small difference will ever fail.
Keep the compare inside a reasonable interval around the target.

There are several problems in your sketch:

distanceIN and TargetDistance1 are float values. Float values are nearly never exactly the same. You should only compare to '<' or '>'

Where should your motor go to? stepper.run() does nothing if no target is defined. And how do you determine in which direction the motor should move?

Thanks for the response! I've modified the two while loops to not use '!=' and have included a range instead. In regards to moving the stepper i've added stepper.moveTo() which should move it up/down by 1 step depending on where the distance is.

  // go to target 2 (2 inch)
  while (distanceIN < 1.9 || distanceIN > 2.1 )
  {
      readDistance();
      if (distanceIN < 1.9)
      {
          // lower than target
          stepper.moveTo(1); // rotate clockwise by 1 step (move up)
          stepper.run();
      }
      else if (distanceIN < 2.1)
      {
          // higher than target
          stepper.moveTo(-1); // rotate counterclockwise by 1 step (move down)
          stepper.run();
      }
  }
  delay(5000); // wait 5s

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