Stepper Motor runs extremly slow when used with Display and Sensor (2)

Hello everyone,

I have a problem when running a stepper motor (Nema 17-04) with a lcd display and a light sensor. When running the Motor alone, it runs smoothly without any troubles. But as soon as i add other parts that i need for the project, it starts to rotate slower.

I have made a wiring diagramm and will include the code i used.

  #include <Wire.h>
  #include "Adafruit_VL6180X.h"
  #include <LiquidCrystal_I2C.h>
  #include <AccelStepper.h>
  #include <TimerOne.h>

  const int SetPotPin = A2;

  // Define pin connections
  const int dirPin = 8;
  const int stepPin = 9;

  // Define motor interface type
  #define motorInterfaceType 1

  // Creates an instance
  AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);

  Adafruit_VL6180X vl = Adafruit_VL6180X();

  LiquidCrystal_I2C lcd(0x27, 16, 2);

  const unsigned long UpdateInterval = 50;
  
  unsigned long LastUpdate = 0;
  const unsigned long UpdateInterval_2 = 1000;

  volatile bool timerFlag = false;

  const int numReadings = 10;
  int readings[numReadings];      // the readings from the sensor
  int readIndex = 0;              // the index of the current reading
  int total = 0;                  // the running total
  int average = 0;                // the average

  void setup() {
    lcd.begin();

    if (!vl.begin()) {
      lcd.println("Failed to find sensor");
      while (1);
    }
    lcd.println("Sensor found!");
    delay (1000);

    lcd.setCursor(0, 0);
    lcd.print("Set:   ");

    lcd.setCursor(0, 1);
    lcd.print("Sens:    ");
    

    // set the maximum speed
    myStepper.setMaxSpeed(1000);

    // configure timer interval
    Timer1.initialize(UpdateInterval * 1000);
    Timer1.attachInterrupt(timerISR);

  }

  void loop() {
    int posDiff;
    
    if (timerFlag) {  //Sensor Interrupt------------------------------------------------------
      // take multiple readings and average them
      total = total - readings[readIndex];
      readings[readIndex] = vl.readRange();
      total = total + readings[readIndex];
      readIndex = readIndex + 1;

      if (readIndex >= numReadings) {
        readIndex = 0;
      }

      average = total / numReadings;
      if (average > 10) {
          average = average + 9;
      }

          timerFlag = false;
    }
 if (millis() - LastUpdate >= UpdateInterval_2) {//Pot und Display----------------------------------------------
      //Read the value from the potentiometer
      int SetPinValue =  analogRead(SetPotPin);
      // Convert the value to a distance value from 0mm to 100mm
      int set = map(SetPinValue, 0, 1023, 0, 100);

      lcd.setCursor(5, 0);
      lcd.print(set, DEC);
      lcd.print("mm      ");

      uint8_t status = vl.readRangeStatus();
      if (status == VL6180X_ERROR_NONE) {
        lcd.setCursor(5, 1);
        lcd.print(average, DEC);
        lcd.print("mm        ");
      }
      else if ((status >= VL6180X_ERROR_SYSERR_1) && (status <= VL6180X_ERROR_SYSERR_5)) {
        lcd.println("System error");
      }
      LastUpdate = millis(); 
      posDiff = set - average;
    }

      if (posDiff > 3){
        myStepper.setAcceleration(100);
        myStepper.setSpeed(1000);
        myStepper.run();
      }

      else if (posDiff < -3) {
        myStepper.setAcceleration(100);
        myStepper.setSpeed(-1000);
        myStepper.run();
      }

      else if (posDiff >= -3 && posDiff <= 3) {
        myStepper.setSpeed(0);
        myStepper.run();
      }
      
  }
  void timerISR() {
    timerFlag = true;
  }

do you have any suggestions or improvments for the code?

Regards

Ali

Four bit I2C LCD updates are really slow

To speed up your program, only display NEW data, not always the same data. Save the values and only display then new when they change.

Im using millis() function to update it once every second.

There is also the sensor and i need to read his values fast. Im using Timer Interrupt to update once every 50 milisecond.

How long does that take?

last time i check, it was 3184 us for one reading.

You need to be calling myStepper.run() every time through loop(), not just when the position difference it large. .run() may or may not actually take a step, depending on how much time has elapsed since the last time you called it.

I also see no call to .MoveTo() so not sure your stepper will ever move. You need to set the target position you are attempting to move to with .run()

it does move. I indeed tried using moveTo() and it didn't get rid of the issue.

No, it won't solve your issue. As others point out, the display update is taking a lot of time. You still need to use the AccelStepper library properly.

Curious, is the motor really getting its power from a breadboard?

Did you jumper the power rail on the breadboard?

Post an image.

the motor is getting it's power from the motor driver, and the motor driver is getting it power from an external power source (12v). It also gets 5V from the arduino

Can you point out the places where i need to use the library better? How can i improve on the code?

you need to set your target position with a .moveTo() call
you need to call .run() every time through loop(), not just inside an if() statement

if i use moveTo() i don't need to call run().

The idea with using run() in if statements is to control which way the motor turns, depending on the value of posDiff.

That is not correct. .moveTo() sets the target stopping position. Every time you call .run() it will take another step, if the timing is correct and then move 1 step closer to the target. If the time is too short, it does nothing

.runToPosition() is a blocking call that moves to a given position before returning.

Look at the examples that came with the library.

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