Trying to use stepper motor position/angle to control word output to an LCD

Good morning,
I’m relatively new to Arduino (we used it in a previous class) but I’m enjoying learning more and building in my free time. Right now, I have a joystick that controls a stepper motor to either rotate clockwise or counterclockwise with 36 steps. My code works so far. However, I also want to add an LCD to the circuit that displays one of 9 words depending on which 40 degree angle segment/position the stepper motor is in, and I’m not sure where to start when putting this into my code. For example, when the stepper motor is in pos 0->40, the LCD would display “This” and then for 41-80 it would display “is” and so forth, for a total of nine words. Here is my code so far (which only controls the joystick and stepper motor). I plan on using pins 2-7 for the LCD. If anyone would be able to offer a general (or specific) direction for adding this into my code it would be unbelievably appreciated. Thank you to all of you on this forum and for all of the help you provide!

#include <Stepper.h>
#define STEPS 36
#define IN1 11
#define IN2 10
#define IN3 9
#define IN4 8
Stepper stepper(STEPS, IN4, IN2, IN3, IN1);
#define joystick A0
void setup()
{
}
void loop()
{
int val = analogRead(joystick);
if( (val > 500) && (val < 523) )
{
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
else
{
while (val >= 523)
{
int speed_ = map(val, 523, 1023, 5, 250);
stepper.setSpeed(speed_);
stepper.step(1);
val = analogRead(joystick);
}
while (val <= 500)
{
int speed_ = map(val, 500, 0, 5, 500);
stepper.setSpeed(speed_);
stepper.step(-1);
val = analogRead(joystick);
}
}
}

If You use code tags, upper left symbol in this window, when You post cide You will impress helpers.
I use I2C connected LCDs and a goid library is hh44..... Can't open. ino from here.

pos 0->40, the LCD would display "This" and then for 41-80 it would display "is" and so forth

An integer divide of "pos" by 40 produces the integers 0-9 (assuming that pos varies from 0 to 360 inclusive). The actual intervals will be 0-39 (inclusive), 40-79, etc.

Please edit your post to add code tags, so your posted code looks like this:

if (pos/40 == 0) print("This");

For example, when the stepper motor is in pos 0->40, the LCD would display “This” and then for 41-80 it would display “is” and so forth,

Here is one way using if, else if, else. Before you run theses examples, set line endings in serial monitor to None.

void setup()
{
   Serial.begin(115200);
   Serial.println("\n enter a number");
}

void loop()
{
   if (Serial.available())
   {
      int stepperPos = Serial.parseInt();
      //Serial.print("\nstepper position = ");
      //Serial.println(stepperPos);
      if (stepperPos >= 0 && stepperPos < 41)
      {
         Serial.print("This");
      }
      else if (stepperPos >= 41 && stepperPos < 81)
      {
         Serial.print(" is");
      }
      else if (stepperPos >= 81 && stepperPos < 121)
      {
         Serial.print(" what");
      }
      else if (stepperPos >= 121 && stepperPos < 161)
      {
         Serial.print(" you");
      }
      else
      {
         Serial.println("invalid input");
      }
   }
}

Here is another way using the switch case and ellipses.

void setup()
{
   Serial.begin(115200);
   Serial.println("\n enter a number");
}

void loop()
{
   if (Serial.available())
   {
      int stepperPos = Serial.parseInt();
      //Serial.print("\nstepper position = ");
      //Serial.println(stepperPos);
      switch (stepperPos)
      {
         case 0 ... 40:  // important spaces, 0 space ... space 40
            Serial.print("This");
            break;
         case 41 ... 80:
            Serial.print(" is");
            break;
         case 81 ... 120:
            Serial.print(" what");
            break;
         case 121 ... 160:
            Serial.print(" you");
            break;
         default:
            Serial.println("invalid entry");
      }
   }
}

The first step is going to be to keep track of where the motor is. To do that, count steps:

    while (val >= 523)
    { 
      int speed_ = map(val, 523, 1023, 5, 250);
      stepper.setSpeed(speed_);
      stepper.step(1);
      position++;
      if (position >= STEPS)
          position = 0;
      val = analogRead(joystick);
    }

Now that you have a position from 0 to 35 (36 steps per revolution) you can calculate which of the 9 segments the motor is in:

  int segment = position / 6; // segment 0-8 of 36.

Then you can pick the word to display from a list of 9 words:

 const char const * words[9] = {"This","is", ... };
   Serial.print(words[segment]);

Thank you so much! I made the suggested edits to my code and I am running into an error message however (it’s probably on my end)

Arduino: 1.8.13 (Windows 10), Board: “Arduino Uno”
C:\Users\cp5be\Documents\Arduino\Final_Project__2_\Final_Project__2_.ino: In function ‘void loop()’:
Final_Project__2_:39:7: error: ‘position’ was not declared in this scope
position++;
^~~~~~~~
exit status 1
‘position’ was not declared in this scope

I’ve tried doing some research online but all that I can find about this particular error message is that it often occurs when a variable was not defined, however it is my understanding that position is an inherent variable of the stepper motor and isn’t something that needs to be declared. I’ve also seen that the error message pops up when using different libraries, however I believe i’m using the standard stepper library from arduino. Do you have any insights on this? Thank you so much again! Attached below is my code (hopefully in the right format this time)

#include <Stepper.h>
#define STEPS 36
 
#define IN1  11
#define IN2  10
#define IN3   9
#define IN4   8
 
Stepper stepper(STEPS, IN4, IN2, IN3, IN1);

#define joystick  A0

#include <LiquidCrystal.h>
LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7);

char const *words[] = {"This","is", "my", "final", "design", "project", "for", "ECE", "303"};

void setup()
{
  lcd.begin(16, 2);
}
void loop()
{ 
  int val = analogRead(joystick); 
  if(  (val > 500) && (val < 523) )
  {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
  }
  else
  {  
    while (val >= 523)
    { 
      int speed_ = map(val, 523, 1023, 5, 250);
      stepper.setSpeed(speed_);
      stepper.step(1);
      position++;
      if (position>= STEPS);
      position = 0;
      val = analogRead(joystick);
      int segment = position/4
      lcd.print(words[segment])
    }
    while (val <= 500)
    { 
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    }
  }

}

Before you can use a variable it must be declared.

Oh my gosh silly mistake. The code finally compiles (thanks everyone). Unfortunately, i’m not getting exactly the results that I’m looking for. When I move my joystick in the positive direction, the word output on the screen stays as “This” no matter what the position of the stepper is, as opposed to writing a new word every segment. I know that I could use a for loop and make the LCD output what I want it to, but then it wouldn’t be dependent on my variable “position,” which is a condition I need to satisfy (maybe there is a way to incorporate a for loop that I’m not thinking of, I don’t know). I’ve been playing with my code but I can’t seem to get the results I need. I also tried including an lcd.clear statement at the beginning of the code to see if that helps, but to no avail. Attached is my updated code. Thank you again to everyone who has been responding with help!

#include <Stepper.h>
#define STEPS 36
 
#define IN1  11
#define IN2  10
#define IN3   9
#define IN4   8
 
Stepper stepper(STEPS, IN4, IN2, IN3, IN1);

#define joystick  A0

#include <LiquidCrystal.h>
LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7);

const char *words[] = {"This","is", "my", "final", "design", "project", "for", "ECE", "303"};

void setup()
{
  lcd.begin(16, 2);
}
void loop()
{ 
  int val = analogRead(joystick); 
  if(  (val > 500) && (val < 523) )
  {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
  }
  else
  {  
    while (val >= 523)
    { 
  
      lcd.clear();
      int speed_ = map(val, 523, 1023, 5, 250);
      stepper.setSpeed(speed_);
      stepper.step(1);
      int position;
      position=position+1;
      if (position>= STEPS);
      position = 0;
      val = analogRead(joystick);
      int segment = position/4;
      lcd.setCursor(0,0);
      lcd.print(words[segment]);
    }
    while (val <= 500)
    { 
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    }
  }

}
if (position>= STEPS);
      position = 0;

The semi colon at the end of the if statement will cause the position = 0 to execute unconditionally. Lose the semicolon.

 if (position>= STEPS) // removed semicolon
      position = 0;
    while (val <= 500)
    {
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, LOW);
    }

This will freeze your sketch in an infinite loop if ‘val’ is <= 500. Remove the whole statement.

I think what you want is more like this:

#include <Stepper.h>
const byte STEPS = 36;


const byte IN1 = 11;
const byte IN2 = 10;
const byte IN3 = 9;
const byte IN4 = 8;


Stepper stepper(STEPS, IN4, IN2, IN3, IN1);
int Position = 0;
int LastSegment = 0;


const byte JoystickPin = A0;


#include <LiquidCrystal.h>
LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7);


const char *words[9] = {"This", "is", "my", "final", "design", "project", "for", "ECE", "303"};


void setup()
{
  lcd.begin(16, 2);
}


void loop()
{
  int val = analogRead(JoystickPin);


  if (val >= 523) // Forward
  {
    int speed_ = map(val, 523, 1023, 5, 250);
    stepper.setSpeed(speed_);
    stepper.step(1);


    Position = Position + 1;
    if (Position >= STEPS)
      Position = 0;
  }


  if (val <= 500) // Backward
  {
    int speed_ = map(val, 0, 500, 250, 5);
    stepper.setSpeed(speed_);
    stepper.step(-1);


    Position = Position - 1;
    if (Position < 0)
      Position = STEPS - 1;
  }


  int segment = Position / 4;


  // If the segment has changed, display the new word
  if (segment != LastSegment)
  {
    LastSegment = segment;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(words[segment]);
  }
}