LCD Keypad Shield for backward motion

Hello everyone,

I´ve some trouble with my project. The aim is that a stepper motor would change its direction by pressing the buttons of my Keypad Shield, but it wouldn´t do it. When I use it without the LCD Keypad Shield, everything is fine, but with it, the motor only moves in one direction.
I use a TB6600 as a driver and a NEMA stepper motor. The code without the LCD is this one

#include <AccelStepper.h>

// Definiere die Anzahl der Mikroschritte pro Vollschritt
const int microsteps = 16;
const int dirPlusPin = 7; // Verwende Pin 7 für die Richtungssteuerung (Dir+)
const int dirMinusPin = 8; // Verwende Pin 8 für die Richtungssteuerung (Dir-)
const int fullStepsPerRevolution = 200;
const int stepsPerRevolution = microsteps * fullStepsPerRevolution;

// Definiere den Schrittmotor-Pin
const int motorPin = 3;

// Initialisiere den Schrittmotor mit den Pins und der Art des Treibers
AccelStepper stepper(AccelStepper::DRIVER, motorPin);

void setup() {
  // Setze die Pins für die Richtungssteuerung als Ausgänge
  pinMode(dirPlusPin, OUTPUT);
  pinMode(dirMinusPin, OUTPUT);

  // Setze die maximale Geschwindigkeit und Beschleunigung des Schrittmotors
  stepper.setMaxSpeed(2000.0);
  stepper.setAcceleration(1000.0);
}

void loop() {
  // Setze die Richtung auf vorwärts (Dir+ mit HIGH, Dir- mit LOW verbinden)
  digitalWrite(dirPlusPin, HIGH);
  digitalWrite(dirMinusPin, LOW);

  // Bewege den Schrittmotor im Uhrzeigersinn um 1000 Schritte
  stepper.moveTo(500); // Setze die Zielposition
  stepper.runToPosition(); // Bewege den Schrittmotor zur Zielposition

  delay(3000);

  // Setze die Richtung auf rückwärts (Dir+ mit LOW, Dir- mit HIGH verbinden)
  digitalWrite(dirPlusPin, LOW);
  digitalWrite(dirMinusPin, HIGH);

  // Bewege den Schrittmotor gegen den Uhrzeigersinn um 1000 Schritte
  stepper.moveTo(-500); // Setze die Zielposition
  stepper.runToPosition(); // Bewege den Schrittmotor zur Zielposition
}

And the other code is here:

#include <LiquidCrystal.h>
#include <AccelStepper.h>


/******************************************************
Implementation of Button-Logic, Microsteps of movement 
and Menuitems
*******************************************************/
const int microsteps = 16;
const int fullStepsPerRevolution = 200;
const int stepsPerRevolution = microsteps * fullStepsPerRevolution;
const int motorPin = 3;
const int dirPlusPin = 2;
const int dirMinusPin = 1;

AccelStepper stepper(AccelStepper::DRIVER, motorPin);

enum Button {
  NONE = 0,
  RIGHT = 1,
  UP = 2,
  DOWN = 3,
  LEFT = 4,
  SELECT = 5
};

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

struct MenuItem {
  String name;
  int nextMenu;
  void (*displayFunction)();
};



/******************************************************
Overview of the used functions, variables and menustructure
*******************************************************/

// Vorankündigungen der Funktionen
void displayMainMenu();
void displaySubMenuA();
void displaySubMenuB();
void displaySubMenuC();
void displaySubMenuD();
void handleSelectButton();
void displaySubMenuA1();
void displaySubMenuB1();
void displaySubMenuC1();

void displayCurrentMenu();
void setVolume();
void setLengthDiameter();
int readButtons();
void adjustFlowRate(int direction);
float calculateSpeedFromFlowRate(float flowRate);
void setFlowRate();
int selectedSyringeIndex = 0; // Standardmäßig die erste Spritze auswählen


MenuItem menuItems[] = {
  {"Main Menu", 0, displayMainMenu},
  {"Infuse", 1, displaySubMenuA},
  {"Refill", 2, displaySubMenuB},
  {"Cycle Mode", 3, displaySubMenuC},
  {"Start Infuse", 5, displaySubMenuA1},  
  {"Start Refill", 6, displaySubMenuB1},  
  {"Start Cycle Mode", 7, displaySubMenuC1}
};

float currentVolume = 0.0; // Deklariert das aktuelle Volumen und setzt es auf 0.0
float volumePerStep = 1.0;
float length = 0.0; // Neue Variable für Länge
float diameter = 0.0; // Neue Variable für Durchmesser
int currentMenu = 0;
float flowRate = 0.0;
float averageCorrectionFactor(float measuredVolumes[], float setVolumes[], int numSamples);
float volumeParts[8] = {100000.0, 10000.0, 1000.0, 100.0, 10.0, 1.0, 0.1, 0.01};
float calibrationFactor = 5.78;




/******************************************************
Setup and Loop
*******************************************************/

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  stepper.setMaxSpeed(2000.0);
  stepper.setAcceleration(1000.0);
  displayCurrentMenu();

  pinMode(dirPlusPin, OUTPUT);
  pinMode(dirMinusPin, OUTPUT);

  stepper.setMaxSpeed(2000.0);
  stepper.setAcceleration(1000.0);
  
}

void loop() {

  digitalWrite(dirPlusPin, HIGH);
  digitalWrite(dirMinusPin, LOW);

  int button = readButtons();

  switch (button) {
    case UP:
      handleUpButton();
      break;

    case DOWN:
      handleDownButton();
      break;

    case SELECT:
      handleSelectButton();
      break;

    case RIGHT:
      handleRightButton();
      break;

    case LEFT:
      handleLeftButton();
      break;
  }

      stepper.run();
}

/******************************************************
Handling of the Button cases and Submenus
*******************************************************/

void handleUpButton() {
  if (currentMenu != 0 && currentMenu < 5) { // Prüfe via Variable, ob Menu nicht Main oder SubMenu ist
    int nextMenu = currentMenu - 1; // Springt ins nächste Menu, indem die Variable um 1 reduziert wird
    currentMenu = nextMenu;         // setzt das Menu auf das aktuelle Menu
    displayCurrentMenu();           // Aktualisiert Bildschirm
  } else if(currentMenu == 0){      
    currentMenu = 4;                // Stellt den Weg von Main zu D dar evtl später durch A ersetzen
    displayCurrentMenu();
  }else if(currentMenu >= 5 && currentMenu <= 8){
    
  }else if (currentMenu == 9){
      int nextMenu = currentMenu -1;
      currentMenu = nextMenu;
      displayCurrentMenu();
     // delay(500);
  }
  else {
      currentMenu = 0;              // Zurücksetzen ins Main bei Grenzwertüberschreitung
      displayCurrentMenu();
    }
}

void handleDownButton() {
  if (currentMenu != 0 && currentMenu < 5) { // Prüfe via Variable, ob Menu nicht Main oder SubMenu ist
      int nextMenu = currentMenu + 1; // Springt ins nächste Menu, indem die Variable um 1 erhöht wird
      currentMenu = nextMenu;         // setzt das Menu auf das aktuelle Menu
      displayCurrentMenu();           // Aktualisiert Bildschirm
  } else if(currentMenu == 4){      
      currentMenu = 0;                // Stellt den Weg von D zu Main dar evtl. später durch A ersetzen
      displayCurrentMenu();
  } else if (currentMenu >= 5 && currentMenu <= 7){
      
  } else if (currentMenu == 8){
      int nextMenu = currentMenu +1;
      currentMenu = nextMenu;
      displayCurrentMenu();
     // delay(500);
    }
  
  else {
    currentMenu = 0;              // Zurücksetzen ins Main bei Grenzwertüberschreitung
    displayCurrentMenu();
  }
}

void handleRightButton() {
  if (currentMenu >= 1 && currentMenu <= 4) {
    currentMenu += 4;
    displayCurrentMenu();
  } else if(currentMenu == 5){
    delay(5000);
    startForwardMotion();
  } else if(currentMenu == 6){
    startBackwardMotion();
    lcd.setCursor(0,1);
    lcd.print("Backward motion");
  } else if(currentMenu == 8){
    setVolume();
  } else if(currentMenu == 9){
    currentMenu = 12;
    displayCurrentMenu();
    setFlowRate();
  } 
}

void handleLeftButton() {
  if(currentMenu >= 5 && currentMenu <= 8){
    currentMenu = currentMenu - 4;
    displayCurrentMenu();
  }
}

void handleSelectButton() {
  switch (currentMenu) {
    case 7: // Start Cycle Mode
      cycleMode();
      break;
    // Hier können weitere Cases für andere Funktionen hinzugefügt werden
  }
}

void displayCurrentMenu() {
  lcd.clear();
  if (currentMenu >= 0 && currentMenu < sizeof(menuItems) / sizeof(menuItems[0])) {
    lcd.print(menuItems[currentMenu].name);
  }
  delay(500);
}

void displayMainMenu() {
  lcd.clear();
  lcd.print("Main Menu");
}

void displaySubMenuA() {
  lcd.clear();
  lcd.print("Infuse");
 
}

void displaySubMenuB() {
  lcd.clear();
  lcd.print("Refill");
 
}

void displaySubMenuC() {
  lcd.clear();
  lcd.print("CycleMode");
 
}

void displaySubMenuA1() {
  lcd.clear();
  lcd.print("Start Infuse");

}

void displaySubMenuB1() {
  lcd.clear();
  lcd.print("Start Refill");
}



/******************************************************
Implementation of Movement-Logic
*******************************************************/

void startForwardMotion() {
  
  digitalWrite(dirPlusPin, HIGH);
  digitalWrite(dirMinusPin, LOW);
  
  stepper.setSpeed(2000.0); // Example for Velocity
  stepper.moveTo(stepper.currentPosition() + stepsPerRevolution * volumePerStep);

  // Führe die Bewegung aus und warte, bis sie abgeschlossen ist
  while (stepper.distanceToGo() != 0) {
    stepper.run();
  }
}

void startBackwardMotion() {

  digitalWrite(dirPlusPin, LOW);
  digitalWrite(dirMinusPin, HIGH);
  
  stepper.setSpeed(2000.0); // Example for Velocity
  stepper.runToNewPosition( stepper.currentPosition()- stepsPerRevolution * volumePerStep);

  // Führe die Bewegung aus und warte, bis sie abgeschlossen ist
  while (stepper.distanceToGo() != 0) {
    stepper.run();
  }
}

void cycleMode() {
  startForwardMotion(); // Starte die Vorwärtsbewegung

  // Warte 5 Sekunden
  delay(5000);

  startBackwardMotion(); // Starte die Rückwärtsbewegung
}





int readButtons() {
  delay(50);
  int adc_key_in = analogRead(0);

  if (adc_key_in > 1000) return NONE;
  else if (adc_key_in < 52) return RIGHT;
  else if (adc_key_in < 184) return UP;
  else if (adc_key_in < 336) return DOWN;
  else if (adc_key_in < 524) return LEFT;
  else if (adc_key_in < 828) return SELECT;

  return NONE;
}

When you combine the two codes, this will give a conflict; can that be the reason?

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
                  ^

and

const int dirMinusPin = 8;
                        ^

Yes, I know. However, I changed the pins to avoid this error. I've chosen the Pins 1,2 and 3 instead.

Please show your combined sketch that gives the problem. Be aware that pin 1 is used by Serial. Also be aware that the pins on the shield are fixed.

The sketch is shown in my original post. I've changed the pins for that. The motion logic can be seen there

I could fix it by myself. The error was that one of the cables didn't connect correctly. There was a loose contact. But thank you for your effort

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