HI!
I have a problem with the LCD menu code. I should get the motor cycle adjusted via the LCD menu, the motor will start and the speed can be adjusted. But I don't get the cycle to work. I have a motor control Cytron MD10C R3 and for a cycle break I thought I could use an SSR relay. I found that LCD menu program on the curiousscientist.tech page meaning this is a cut and paste project.
![]()
I have a problem with the LCD menu code. I should get the motor cycle adjusted via the LCD menu, the motor will start and the speed can be adjusted. But I don't get the cycle to work. I have a motor control Cytron MD10C R3 and for a cycle break I thought I could use an SSR relay. I found that LCD menu program on the curiousscientist.tech page meaning this is a cut and paste project. :
I like to listen to other ways to program similar functions.
The problem is menu2 at line 161 forward to line 181 because it is taken from the examples of Arduino. Otherwise the code works but that menu2 needs a wiser study of how to make it work. Menu2 item works on the LCD the values change and work ok but the relay does not work. The connections have been checked several times.
Thanks to all the helpers.
Here is the code:
//20x4 LCD
#include <LiquidCrystal_I2C.h> //SDA = B7[A4], SCL = B6[A5] STM32/[Arduino]
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include "CytronMotorDriver.h"
CytronMD motor(PWM_DIR, 11, 12); // PWM = Pin 3, DIR = Pin 4.
int menuCounter = 0; //counts the clicks of the rotary encoder between menu items (0-3 in this case)
int menu1_Value = 0; //value within menu 1
int menu2_Value = 0; //value within menu 2
int menu3_Value = 0; //value within menu 3
int menu4_Value = 0; //value within menu 4
bool menu1_selected = false; //enable/disable to change the value of menu item
bool menu2_selected = false;
bool menu3_selected = false;
bool menu4_selected = false;
//Note: if a menu is selected ">" becomes "X".
//Defining pins
//Arduino interrupt pins: 2, 3.
const int RotaryCLK = 2; //CLK pin on the rotary encoder
const int RotaryDT = 6; //DT pin on the rotary encoder
const int PushButton = 3; //Button to enter/exit menu
const int PAUSERELAY = 8;// the number of the LED pin
//Statuses for the rotary encoder
int CLKNow;
int CLKPrevious;
int DTNow;
int DTPrevious;
bool refreshLCD = true; //refreshes values
bool refreshSelection = false; //refreshes selection (> / X)
int relayState = LOW; // relayState used to set the relay
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time relay was updated
// constants won't change:
//const long interval = 1000 ; // interval at which to blink (milliseconds)
void setup()
{
pinMode(2, INPUT_PULLUP); //RotaryCLK
pinMode(6, INPUT_PULLUP); //RotaryDT
pinMode(3, INPUT_PULLUP); //Button
pinMode(9, OUTPUT); // Pauserelay
//------------------------------------------------------
lcd.begin(); // initialize the lcd
lcd.backlight();
//------------------------------------------------------
lcd.setCursor(0,0); //Defining positon to write from first row, first column .
lcd.print("Menu demo");
lcd.setCursor(0,1); //Second row, first column
lcd.print("Rotary encoder");
lcd.setCursor(0,2); //Second row, first column
lcd.print("Improved version");
delay(2000); //wait 2 sec
lcd.clear(); //clear the whole LCD
printLCD(); //print the stationary parts on the screen
//------------------------------------------------------
//Store states of the rotary encoder
CLKPrevious = digitalRead(RotaryCLK);
DTPrevious = digitalRead(RotaryDT);
attachInterrupt(digitalPinToInterrupt(RotaryCLK), rotate, CHANGE); //CLK pin is an interrupt pin
attachInterrupt(digitalPinToInterrupt(PushButton), pushButton, FALLING); //PushButton pin is an interrupt pin
}
void loop()
{
if(refreshLCD == true) //If we are allowed to update the LCD ...
{
updateLCD(); // ... we update the LCD ...
//... also, if one of the menus are already selected...
if(menu1_selected == true || menu2_selected == true || menu3_selected == true || menu4_selected == true)
{
// do nothing
}
else
{
updateCursorPosition(); //update the position
}
refreshLCD = false; //reset the variable - wait for a new trigger
}
if(refreshSelection == true) //if the selection is changed
{
updateSelection(); //update the selection on the LCD
refreshSelection = false; // reset the variable - wait for a new trigger
}
}
void rotate()
{
//-----MENU1--------------------------------------------------------------
if(menu1_selected == true)
{
CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
// If last and current state of CLK are different, then a pulse occurred
if (CLKNow != CLKPrevious && CLKNow == 1)
{
// If the DT state is different than the CLK state then
// the encoder is rotating in A direction, so we increase
if (digitalRead(RotaryDT) != CLKNow)
{
if(menu1_Value < 100) //we do not go above 100
{
menu1_Value++;
map(menu1_Value, 0, 100, 0, 255);
motor.setSpeed(menu1_Value); // Run forward at 50% speed.
delay(500);
}
else
{
menu1_Value = 100;
motor.setSpeed(0); // Run forward at 50% speed.
delay(500);
}
}
else
{
if(menu1_Value < 1) //we do not go below 0
{
menu1_Value = 0;
}
else
{
// Encoder is rotating B direction so decrease
menu1_Value--;
motor.setSpeed(menu1_Value); // Run forward at 50% speed.
}
}
}
CLKPrevious = CLKNow; // Store last CLK state
}
//---MENU2---------------------------------------------------------------
else if(menu2_selected == true)
{
CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
// If last and current state of CLK are different, then a pulse occurred
if (CLKNow != CLKPrevious && CLKNow == 1)
{
// If the DT state is different than the CLK state then
// the encoder is rotating in A direction, so we increase
if (digitalRead(RotaryDT) != CLKNow)
{
if(menu2_Value < 100) //we do not go above 100
{
menu2_Value++;
map(menu2_Value, 0, 100, 0, 1000);
const long interval = menu2_Value ; // interval at which to blink (milliseconds)
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
}
// if the LED is off turn it on and vice-versa:
if (relayState == LOW) {
relayState = HIGH;
}
else {
relayState = LOW;
}
// set the relay with the relayState of the variable:
digitalWrite(PAUSERELAY, relayState);
}
else
{
menu2_Value = 100;
}
}
else
{
if(menu2_Value < 1) //we do not go below 0
{
menu2_Value = 0;
}
else
{
// Encoder is rotating in B direction, so decrease
menu2_Value--;
}
}
}
CLKPrevious = CLKNow; // Store last CLK state
}
//---MENU3---------------------------------------------------------------
else if(menu3_selected == true)
{
CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
// If last and current state of CLK are different, then a pulse occurred
if (CLKNow != CLKPrevious && CLKNow == 1)
{
// If the DT state is different than the CLK state then
// the encoder is rotating in A direction, so we increase
if (digitalRead(RotaryDT) != CLKNow)
{
if(menu3_Value < 100) //we do not go above 100
{
menu3_Value++;
}
else
{
menu3_Value = 0;
}
}
else
{
if(menu3_Value < 1) //we do not go below 0
{
menu3_Value = 100;
}
else
{
// Encoder is rotating B direction so decrease
menu3_Value--;
}
}
}
CLKPrevious = CLKNow; // Store last CLK state
}
//---MENU4----------------------------------------------------------------
else if(menu4_selected == true)
{
CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
// If last and current state of CLK are different, then a pulse occurred
if (CLKNow != CLKPrevious && CLKNow == 1)
{
// If the DT state is different than the CLK state then
// the encoder is rotating in A direction, so we increase
if (digitalRead(RotaryDT) != CLKNow)
{
if(menu4_Value < 100) //we do not go above 100
{
menu4_Value++;
}
else
{
menu4_Value = 0;
}
}
else
{
if(menu4_Value < 1) //we do not go below 0
{
menu4_Value = 100;
}
else
{
// Encoder is rotating in B direction, so decrease
menu4_Value--;
}
}
}
CLKPrevious = CLKNow; // Store last CLK state
}
else //MENU COUNTER----------------------------------------------------------------------------
{
CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
// If last and current state of CLK are different, then a pulse occurred
if (CLKNow != CLKPrevious && CLKNow == 1)
{
// If the DT state is different than the CLK state then
// the encoder is rotating in A direction, so we increase
if (digitalRead(RotaryDT) != CLKNow)
{
if(menuCounter < 3) //we do not go above 3
{
menuCounter++;
}
else
{
menuCounter = 0;
}
}
else
{
if(menuCounter < 1) //we do not go below 0
{
menuCounter = 3;
}
else
{
// Encoder is rotating CW so decrease
menuCounter--;
}
}
}
CLKPrevious = CLKNow; // Store last CLK state
}
//Refresh LCD after changing the counter's value
refreshLCD = true;
}
void pushButton()
{
switch(menuCounter)
{
case 0:
menu1_selected = !menu1_selected; //we change the status of the variable to the opposite
break;
case 1:
menu2_selected = !menu2_selected;
break;
case 2:
menu3_selected = !menu3_selected;
break;
case 3:
menu4_selected = !menu4_selected;
break;
}
refreshLCD = true; //Refresh LCD after changing the value of the menu
refreshSelection = true; //refresh the selection ("X")
}
void printLCD()
{
//These are the values which are not changing the operation
lcd.setCursor(1,0); //1st line, 2nd block
lcd.print("Menu 1"); //text
//----------------------
lcd.setCursor(1,1); //2nd line, 2nd block
lcd.print("Menu 2"); //text
//----------------------
lcd.setCursor(1,2); //3rd line, 2nd block
lcd.print("Menu 3"); //text
//----------------------
lcd.setCursor(1,3); //4th line, 2nd block
lcd.print("Menu 4"); //text
//----------------------
lcd.setCursor(13,0); //1st line, 14th block
lcd.print("cnt: "); //counts - text
}
void updateLCD()
{
lcd.setCursor(17,0); //1st line, 18th block
lcd.print(menuCounter); //counter (0 to 3)
lcd.setCursor(9,0); //1st line, 10th block
lcd.print(" "); //erase the content by printing space over it
lcd.setCursor(9,0); //1st line, 10th block
lcd.print(menu1_Value); //print the value of menu1_Value variable
lcd.setCursor(9,1);
lcd.print(" ");
lcd.setCursor(9,1);
lcd.print(menu2_Value); //
lcd.setCursor(9,2);
lcd.print(" ");
lcd.setCursor(9,2);
lcd.print(menu3_Value); //
lcd.setCursor(9,3);
lcd.print(" ");
lcd.setCursor(9,3);
lcd.print(menu4_Value); //
}
void updateCursorPosition()
{
//Clear display's ">" parts
lcd.setCursor(0,0); //1st line, 1st block
lcd.print(" "); //erase by printing a space
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(" ");
//Place cursor to the new position
switch(menuCounter) //this checks the value of the counter (0, 1, 2 or 3)
{
case 0:
lcd.setCursor(0,0); //1st line, 1st block
lcd.print(">");
break;
//-------------------------------
case 1:
lcd.setCursor(0,1); //2nd line, 1st block
lcd.print(">");
break;
//-------------------------------
case 2:
lcd.setCursor(0,2); //3rd line, 1st block
lcd.print(">");
break;
//-------------------------------
case 3:
lcd.setCursor(0,3); //4th line, 1st block
lcd.print(">");
break;
}
}
void updateSelection()
{
//When a menu is selected ">" becomes "X"
if(menu1_selected == true)
{
lcd.setCursor(0,0); //1st line, 1st block
lcd.print("X");
}
//-------------------
if(menu2_selected == true)
{
lcd.setCursor(0,1); //2nd line, 1st block
lcd.print("X");
}
//-------------------
if(menu3_selected == true)
{
lcd.setCursor(0,2); //3rd line, 1st block
lcd.print("X");
}
//-------------------
if(menu4_selected == true)
{
lcd.setCursor(0,3); //4th line, 1st block
lcd.print("X");
}
}