Does de LCD affects the Stepper Motor/driver?

Hi, guys!

Recently, I was assigned to learn Arduino to control some machines in my work. I am pretty new in this field and even though I have read a lot I'm still struggling with something. To make a long story short: We have a tape feeding mechanism that I control with a rotary encoder from 0 to let's say 40mm/s and this information should be displayed on the screen. It's a very simple project but I can't succeed in making the stepper motor being controlled accurately.

Below 20mm/s the feeding mechanism works perfectly fine, but above that the stepper motor starts to ignore 10mm. I've been struggling with that and I read that the LCD might interfere with stepper motor work. That's why I changed to the 'liquidCrystal" to "hd44780" library. This device takes a while to respond, and therefore, can also affect other devices, is that correct? If so, what should I do?

In addition to that, I read that quick changes using the rotary encoder can also lead to the misbehavior of the stepper motor because sometimes the rotary encoder sends extra signals that can trigger the stepper motor. So, in this case, I used a "debounce" code that I found here. Apart from that, I also read somewhere that the stepper motor is meant to rotate at a fixed speed, and since I am using the rotary encoder to change the speed, this could be a potential cause. As I said before, I am pretty new to arduino, but since I am stuck in this problem I can't move on, haha. The code is below:

#include <Wire.h>                           // LIBRARY FOR COMUNICATION
#include <hd44780.h>                        // MAIN HD44780 HEADER, ALTERNATIVE LIBRARY FOR LCD
#include <math.h>                           // LIBRARY TO SET THE PI NUMBER
#include <AccelStepper.h>                   // LIBRARY TO CONTROL STEPPER MOTOR
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c EXPANDER i/o CLASS HEADER
hd44780_I2Cexp lcd;                         // DECLARE LCD OBJECT:  AUTO LOCATE & AUTO CONFIG EXPANDER CHIP


#define motorInterfaceType 1  // FOR STEPPER MOTOR INSTANCE

#define VCC_encoder 11  // DIGITAL PIN 11 IS CONNECTED TO THE VCC PIN OF THE ENCODER
#define GND_encoder 12  // DIGITAL PIN 12 IS CONNECTED TO THE GND PIN OF THE ENCODER

#define VCC_screen 18  // DIGITAL PIN 18 IS CONNECTED TO THE VCC PIN OF THE SCREEN
#define GND_screen 22  // DIGITAL PIN 22 IS CONNECTED TO THE GND PIN OF THE SCREEN

const int LCD_COLS = 16;  // INFORMATION RELATED TO THE COLUMNS OF THE SCREEN
const int LCD_ROWS = 2;   // INFORMATION RELATED TO THE ROWS OF THE SCREEN

int stepPin = 5;  // DIGITAL PIN 5 IS CONNECTED TO THE STEPPER PIN OF THE STEPPER DRIVER
int dirPin = 2;   // DIGITAL PIN 5 IS CONNECTED TO THE STEPPER PIN OF THE STEPPER DRIVER
int enPin = 7;    // DIGITAL PIN 5 IS CONNECTED TO THE STEPPER PIN OF THE STEPPER DRIVER

int DT = 9;   // DIGITAL PIN 6 IS CONNECTED TO THE DT PIN OF THE ENCODER MODULE
int CLK = 8;  // DIGITAL PIN 5 IS CONNECTED TO THE CLK PIN OF THE ENCODER MODULE
int SW = 10;  // THIS PIN IS USED FOR THE PUSHBUTTON ON THE ENCODER MODULE AND WILL NOT BE USED

int y = 0;                // INPUT VALUE
int Letzte_q = LOW;       // VARIABLE FOR STORING THE VALUE OF q
int letzte_y;             // VARIABLE FOR STORING THE VALUE OF y
int q = LOW;              // VARIABLE FOR STORING THE VALUE OF CLK
int Taster = LOW;         // VARIABLE FOR STORING THE VALUE OF SW. THIS WILL NOT BE USED
int Letzte_Taster = LOW;  // -||-


int tapeSpeed;  // STARTING THE VARIABLE TO STORE THE VALUES WHILE TURNING THE ROTARY ENCODER

AccelStepper myStepper = AccelStepper(motorInterfaceType, stepPin, dirPin);  // OBJECT TO CONTROL STEPPER MOTOR

void setup() {

  int status;

  status = lcd.begin(LCD_COLS, LCD_ROWS);  // CREATING AND STARING THE OBJECT OF LCD SCREEN

  if (status)  // NON ZERO STATUS MEANS IT WAS UNSUCCESFUL
  {
    hd44780::fatalError(status);
  }
  // SETUP OF THE PINS THAT ARE CONNECTED TO THE ENCODER MODULE

  pinMode(CLK, INPUT_PULLUP);       // PIN ACTS AS CLK INPUT
  pinMode(DT, INPUT_PULLUP);        // PIN ACTS AS DT INPUT
  pinMode(SW, INPUT_PULLUP);        // PIN ACTS AS SW INPUT
  pinMode(VCC_encoder, OUTPUT);     // PIN ACTS AS VCC OUTPUT OF THE ENCODER
  digitalWrite(VCC_encoder, HIGH);  // DIGITAL PIN SETS THE OUTPUT AS HIGH
  pinMode(GND_encoder, OUTPUT);     // PIN ACTS AS GND OUTPUT OF THE ENCODER
  digitalWrite(GND_encoder, LOW);   // DIGITAL PIN SETS THE OUTPUT AS LOW

  // SETUP OF THE PINS THAT ARE CONNECTED TO THE SCREEN MODULE

  pinMode(VCC_screen, OUTPUT);     // PIN ACTS AS VCC OUTPUT OF THE SCREEN
  digitalWrite(VCC_screen, HIGH);  // DIGITAL PIN SETS THE OUTPUT AS HIGH
  pinMode(GND_screen, OUTPUT);     // PIN ACTS AS GND OUTPUT OF THE SCREEN
  digitalWrite(GND_screen, LOW);   // DIGITAL PIN SETS THE OUTPUT AS LOW

  // SETUP OF THE PINS THAT ARE CONNECTED TO THE STEPPER DRIVER (MICROSTEPPER)

  pinMode(stepPin, OUTPUT);  // PIN ACTS AS STEP OUTPUT
  pinMode(dirPin, OUTPUT);   // PIN ACTS AS DIRECTION OUTPUT
  pinMode(enPin, OUTPUT);    // PIN ACTS AS ENABLE OUTPUT
  digitalWrite(enPin, LOW);  // DIGITAL PIN SETS THE ENABLE OUTPUT AS LOW

  // SETTINGS TO CONTROL THE STEPPER DRIVER, AND THEREFORE THE STEPPER MOTOR

  myStepper.setMaxSpeed(4000);      // SET THE MAX SPEED TO A LIMIT OF 4000 STEPS/S
  myStepper.setAcceleration(500);   // MUST BE > 0.0, IT WAS SET HIGH BECAUSE IT WAS DESIRABLE A QUICK RESPONSE
  myStepper.setSpeed(0);            // INITIALLY IT IS NECESSARY TO SET THE SPEED AS ZERO
  myStepper.setCurrentPosition(0);  // STARTS THE POSITION FROM 0

  // SETTINGS TO CONTROL THE LCD SCREEN
  // PRINTING THE TEXT ONTO THE DISPLAY FOR THE FIRST TIME

  lcd.clear();
  lcd.setCursor(3, 0);
  //lcd.backlight();
  lcd.print("Tape Speed ");
  lcd.setCursor(7, 1);
  lcd.print("mm/s");
  lcd.setCursor(4, 1);
  lcd.print(y);
}


void loop() {
  // THIS NEXT PART IS USED TO INCREASE AND DECREASE THE VALUE OF y.

  q = digitalRead(CLK);
  Taster = !digitalRead(SW);


  if ((Letzte_q == LOW) && (q == HIGH)) {
    if (digitalRead(DT) == LOW) {
      y++;
      if (y > 40) {
        y = 40;
      }
    } else {
      y--;
      if (y < 0) {
        y = 0;
      }
    }
  }
  Letzte_q = q;
  //If the value of y has changed, update the display
  if (letzte_y != y) {
    letzte_y = y;
  }


  lcd.setCursor(4, 1);
  lcd.print(" ");


  tapeSpeed = (y * 200.0 * 4.0) / (15.00 * PI);

  myStepper.setSpeed(tapeSpeed);
  myStepper.runSpeed();
}

Some extra comments... I am using:

1 - LCD Display 16*2 characters with white text and blue backlight - With I2C Backpack(GND, VCC, SDA and SCL) - already on the board
2 - Arduino Mega 2560;
3 - Rotaty Encoder KY-040
4 - Nema 23
5 - SL2690A Stepper driver / 6.5A / 1/128 microsteps / 20-90V

I would appreciate very much if you can help me on this!

Unlike the comment, you update the LCD with every loop cycle. You must move the LCD commands into the if-block. And I don't even see that you print something useful.

Nevertheless updating a I2C LCD always needs some time. It would be better to use a stepper library that creates the steps in the background like my MobaTools library. Then steps are even created while the LCD is updated.

Sorry @MicroBahner ! I deleted this part accidentally before put the code here:

//If the value of y has changed, update the display
  if (letzte_y != y) {
    letzte_y = y;
  }


  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.print(y);

This is what I intended... but, do you think the LCD slows the time response of the stepper motor? If so, how can I avoid that?

  myStepper.runSpeed();

creates at most one step.
So you cannot create steps faster than your loop cycle time. Because updating your LCD is fairly slow, it limits the possible speed.
At first I would move the lcd commands into the if block. As it is now, the commands slow down every loop cycle - and so generally slow down your stepper speed.

@MicroBahner I moved the code line to if block and now it works!

Thank you very much!

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