How can I use my LCD and Stepper motor?

Hello, I am playing around with my Stepper Motor and LCD display at the same time. My aim was to use buttons to turn the stepper and whilst it's turning have the LCD write "Direction = Anti-Clockwise" for example.

Individually I can make the stepper motor work, and the LCD work for what I want them to do. However, as soon as I put them BOTH into my loop, only one will work.

I have tried to highlight the code to make it easier, but it's still messy and I apologise.

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

#include <CustomStepper.h>


CustomStepper stepper(7, 8, 9, 10, (byte[]){8, B1000, B1100, B0100, B0110, B0010, B0011, B0001, B1001}, 4075.7728395, 12, CW);

boolean rotate1 = false;
boolean rotatedeg = false;
boolean crotate = false;
boolean cwStatus = false;

const int buttonPin = 11;
const int ledPin = 12;
const int buttonPin2 = 6;
const int buttonPin3 = 5;
const int ledPin2 = 4; 
const int buttonPin4 = 3;

int buttonState2 = 0;
int buttonState = 0;
int buttonState3 = 0;
int currentSpeedValue;
int currentSensorValue;
int buttonState4 = 0;

const int potPin = A0;
const int sensorPin = A1;

void setup()
{
  lcd.begin(16,2);
  lcd.setCursor(0,0); 
  lcd.print("Louis's Stepper");
  lcd.setCursor(0,1);
  lcd.print("Motor"); 
  
  
  stepper.setRPM(12);
  stepper.setSPR(4075.7728395);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(buttonPin4, INPUT);
  delay(3000);
  lcd.clear();
  
  
}

void loop() //############# SOMETHING IN HERE WON'T ALLOW LCD AND
//STEPPER MOTOR CONTROL##############################

{

//---------------------LCD CODE-----------------------------------
  //lcd.setCursor(0,0); // motor won't turn with these 4 lines?? 
  //lcd.print("Direction :");
  //lcd.setCursor(0,1);
  //lcd.print("Speed :");
//-----------------------------------------------------------------
  
  currentSpeedValue = map(analogRead(potPin), 0, 1024, 1, 17);
  stepper.setRPM(currentSpeedValue);

  
  

if (stepper.isDone() == true) {
      digitalWrite(ledPin, LOW);
      digitalWrite(ledPin2, LOW);
    }

if (cwStatus == true && stepper.isDone() == false) {

  digitalWrite(ledPin, HIGH);
}

if (cwStatus == false && stepper.isDone() == false) {

  digitalWrite(ledPin2, HIGH);
}
      


  buttonState = digitalRead(buttonPin);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);
  
  if (stepper.isDone() &&  rotate1 == false)
  {
    
    stepper.setDirection(CW);
    cwStatus = true;
    stepper.rotate(1);
    cwStatus = false;
    rotate1 = true;
    
  }
  

 if (buttonState3 == HIGH) {

  stepper.setDirection(STOP);
  
 }



    if (buttonState  == HIGH && stepper.isDone() == true) {
      
      stepper.setDirection(CW);
      cwStatus = true;
      stepper.rotate();
     
      
    }

    if (buttonState2 == HIGH && stepper.isDone() == true) {
      cwStatus = false;
      stepper.setDirection(CCW);
      stepper.rotate();
     
    }


    


  //this is very important and must be placed in your loop, it is this that makes the motor steps
  //when necessary
  stepper.run();

    
 

}

However, as soon as I put them BOTH into my loop, only one will work.

The code that you posted does something. "Only one works" doesn't tell us anything useful. What does the code actually do?

What does the CustomStepper class offer over the usual Stepper class? What does it offer over the AccelStepper class?

What is between the Arduino and the stepper motor?

What I mean by "only one works" is that I can't have them both working at the same time, it's either the LCD displaying "Direction" and "Speed" and the motor does not respond to pressing buttons. Or the motor will work fine but the LCD only runs the code in the setup then goes blank.

If I comment out the LCD code in my loop the stepper motor responds to the button presses, vice versa leaving it means the LCD display does what I think it should and the motor becomes un-responsive.

The CustomStepper works better for my stepper motor. I have the 28BYJ-28. And I haven't heard of AccelStepeper.

Between the arduino and stepper motor there is a driver board http://42bots.com/wp-content/uploads/2014/02/UNL2003-board.jpg. ZC-AO591

The CustomStepper works better for my stepper motor.

That was a hint that you needed to provide a link to the library.

A link to the LCD would be useful, too. Is it a shield, so that we can assume that the shield is using a known set of pins? If not, you'll need to provide a wiring diagram, showing how you have everything connected.

Here is the CustomStepper Library and info. Arduino Playground - CustomStepper

I am using a sainsmart2004 LCD 2 x 16 display. http://www.sainsmart.com/new-sainsmart-iic-i2c-twi-1602-serial-lcd-module-display-for-arduino-uno-mega-r3.html

I attempted to make a diagram here, I couldn't find the exact board so I used the note instead. It's unlcear but The first four Inputs from the stepper board go to 7, 8, 9 and 10 Digital Pins on Arduino.

Thank you for helping me with this and sorry for being a bit clueless.

You aren't really trying to power the stepper driver from the Arduino, are you?

should i use a seperate supply?

b8el018:
should i use a seperate supply?

Only if you want the motor(s) to work.

I tried to power the board with a battery but still have the same problem, I think it's more relating to the code.

What I found strange was that as soon as I comment the lcd part out of my loop the motor works but if I leave it uncommented the lcd works but the motor doesn't respond.

Everything works individually so I suspect they're all wired up correctly.

I don't know the CustomStepper library (and I don't plan to learn it) so please explain what the different commands are trying to do.

Perhaps the calls to the LCD are slowing loop() to the point where stepper.run() is not being called often enough? Try modifying your code so the LCD only updates once per second - and don't use delay(), see several things at a time.

...R
Stepper Motor Basics

stepper.isDone()

This returns true when the stepper is not moving

stepper.rotate(1);

This rotates the stepper 1 revolution in the set Direction

 if (buttonState  == HIGH && stepper.isDone() == true) {
      
      stepper.setDirection(CW);
      cwStatus = true;
      stepper.rotate();

This section is trying to turn the stepper Clockwise when the button is pressed.

 currentSpeedValue = map(analogRead(potPin), 0, 1024, 1, 17);
  stepper.setRPM(currentSpeedValue);

This uses a potentiometer to control the speed, I don't think this is causing the problem however.

If you go here and scroll down there is a list of the basic commands in CustomStepper library if you wanted more detail. Arduino Playground - CustomStepper

Referring to Reply #10

Thanks for the explanations. That is pretty much what I had been thinking.

You did not respond to my suggestion in Reply #9 that the LCD code is interfering with the speed at which loop() repeats?

...R

Is it possible to have two loops?

I just saw your post "several things at once" and understand that the delays pause the whole code, do you think this is causing the problem?

I'll try to use long variables to replace the delays and post the result.

b8el018:
I just saw your post "several things at once" ....

You have still not responded to the point in Reply #9 that I repeated in Reply #11.
That is separate from anything to do with delay() or millis()

I suspect you will find there is no need for multiple loops

...R

Right, okay. I was confused as the only delay was in the setup() which should work.

So, somehow I need to update the LCD only once per second.

So I could add in an if statement checking if it has been 1 second since last upadte, then if true it performs the LCD code?

So I could add in an if statement checking if it has been 1 second since last upadte, then if true it performs the LCD code?

Exactly.

You might also try using the Stepper library, temporarily, to see if the problem is caused by the CustomStepper library's use of interrupts vs that of the LCD class. Stepper doesn't use interrupts.

It very nearly does what I want, but for some reason the motor stops arfter roughly a second and the buttons become unresponsive again. I've probably made a mistake with the long variables somewhere and I have checked through and can't work it out.

This is outside of my setup()

unsigned long previousMillis = 0;
const long interval = 1000;
void loop()

{

  unsigned long currentMillis = millis();


if(currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;
  
  
  lcd.setCursor(0,0);  
  lcd.print("Direction :");
  lcd.setCursor(0,1);
  lcd.print("Speed :"); 
  
  }

It very nearly does what I want, but for some reason the motor stops arfter roughly a second and the buttons become unresponsive again.

Your snippets do not bear that out. Post ALL of your code. As an attachment, if necessary.

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <CustomStepper.h>

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

CustomStepper stepper(7, 8, 9, 10, (byte[]){8, B1000, B1100, B0100, B0110, B0010, B0011, B0001, B1001}, 4075.7728395, 12, CW);

boolean rotate1 = false;
boolean rotatedeg = false;
boolean crotate = false;
boolean cwStatus = false;

const int buttonPin = 11;
const int ledPin = 12;
const int buttonPin2 = 6;
const int buttonPin3 = 5;
const int ledPin2 = 4; 
const int buttonPin4 = 3;
const int potPin = A0;

int buttonState2 = 0;
int buttonState = 0;
int buttonState3 = 0;
int currentSpeedValue;

unsigned long previousMillis = 0;
const long interval = 1000;

void setup()
{
  lcd.begin(16,2);
  lcd.setCursor(0,0); 
  lcd.print("Louis's Stepper");
  lcd.setCursor(0,1);
  lcd.print("Motor"); 
  
  
  stepper.setRPM(12);
  stepper.setSPR(4075.7728395);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(buttonPin4, INPUT);
  delay(3000);
  lcd.clear();
  
  
}

void loop()

{

  unsigned long currentMillis = millis();


if(currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;
  
  
  lcd.setCursor(0,0);  
  lcd.print("Direction :");
  lcd.setCursor(0,1);
  lcd.print("Speed :"); 
  
  }

  
  


//-----------------------------------------------------------------
  
  currentSpeedValue = map(analogRead(potPin), 0, 1024, 1, 17);
  stepper.setRPM(currentSpeedValue);

  
  

if (stepper.isDone() == true) {
      digitalWrite(ledPin, LOW);
      digitalWrite(ledPin2, LOW);
    }

if (cwStatus == true && stepper.isDone() == false) {

  digitalWrite(ledPin, HIGH);
}

if (cwStatus == false && stepper.isDone() == false) {

  digitalWrite(ledPin2, HIGH);
}
      


  buttonState = digitalRead(buttonPin);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);

  
  if (stepper.isDone() &&  rotate1 == false)
  {
    
    stepper.setDirection(CW);
    cwStatus = true;
    stepper.rotate(1);
    cwStatus = false;
    rotate1 = true;
    
  }
  

 if (buttonState3 == HIGH) {

  stepper.setDirection(STOP);
  
 }



    if (buttonState  == HIGH && stepper.isDone() == true) {
      
      stepper.setDirection(CW);
      cwStatus = true;
      stepper.rotate();
     
      
    }

    if (buttonState2 == HIGH && stepper.isDone() == true) {
      cwStatus = false;
      stepper.setDirection(CCW);
      stepper.rotate();
     
    }


    


  //this is very important and must be placed in your loop, it is this that makes the motor steps
  //when necessary
  stepper.run();


  

}

Could be the CustomStepper Library?