Hello friends :
I’m currently learning programming and need your help. Hope you guys can help me
I’m writing a program on Visula Studio Code
I am writing a program for myself to control stepper motor operation
I am using Arduino UNO board, 20x4 I2C LCD, Encoder, TB6600 stepper motor driver, push button, LED, Optical Endstop
Currently, I have written and declared a program like this, I can rotate the stepper motor and stop the stepper motor when it reaches Endstop.
and has displayed menus on LCD
But I don’t know how to write a program so that it can handle the events in case 1,2,3 for me.
My request is as follows:
In case 1:
I want it to display the 1 mm numeric value right on the 2nd menu’s screen display.
First, the program will check whether ENDSTOP_Z_PIN is enabled or not. If it is enabled, the program will allow the stepper motor to run.
move, otherwise do not allow the stepper motor to move
Then I press the Encoder down in the second menu, the cursor will flash at position 1 and if I rotate the Encoder in the right or reverse direction, the value 1 will increase.
or decrease by 1mm, which means the stepper motor will rotate 1mm forward or reverse at a speed of 2000mm/s
The encoder can be rotated to a maximum value of 30mm
Then I press Encoder down again and it will update the new value to the LCD and exit this menu.
In case 2:
I want it to display the numeric value 5 right on the screen of the 3rd menu
Then I press the Encoder down in the second menu, the cursor will flash at position 5 and if I rotate the Encoder in the right or reverse direction, the value of number 5 will increase.
or decrease by 5mm, Maximum encoder can be rotated to a value of 50mm
Then I press Encoder down again and it will update the new value to the LCD and exit this menu.
In case 3:
I want it to show the value as ON right on the screen of the 4th menu
Then I press the Encoder down in the second menu, the cursor will flash in the ON position and I rotate the Encoder forward or reverse, the ON value will change to
OFF
Then I press Encoder down again and it will update the new value to the LCD and exit this menu.
Please help me write a complete program. In my program, if I have written any part incorrectly, please help me correct it.
So I can use it completely and learn more about coding from you guys
Sincerely thank you very much.
Here is my program code
#include <AccelStepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "pin.h"
LiquidCrystal_I2C lcd(0x27, 20, 4);
AccelStepper stepper(AccelStepper::DRIVER, STEP_Z, DIR_Z);
#define STEPS_PER_REVOLUTION (200 * 16)
#define SCREW_PITCH 8
#define STEPS_PER_MM (STEPS_PER_REVOLUTION / SCREW_PITCH)
static int pinA = 5;
static int pinB = 6;
static int enSW = 7;
volatile byte aFlag = 0;
volatile byte bFlag = 0;
long encoderPos = 0;
long oldEncPos = 0;
volatile byte reading = 0;
int menuCnt = 0;
int menuLength = 4;
String menu[] = {"1-HOME_Z", "2-MOVE :", "3-Distance :", "4-Status :"};
int menuValue[] = {1, 2, 3, 4};
void handlePinA() {
cli();
reading = PIND & 0xC;
if (reading == B00001100 && aFlag) {
encoderPos--;
bFlag = 0;
aFlag = 0;
} else if (reading == B00000100) bFlag = 1;
sei();
}
void handlePinB() {
cli();
reading = PIND & 0xC;
if (reading == B00001100 && bFlag) {
encoderPos++;
bFlag = 0;
aFlag = 0;
} else if (reading == B00001000) aFlag = 1;
sei();
}
void updateMenu(int menuSelect) {
lcd.clear();
for (int i = 0; i < menuLength; i++) {
lcd.setCursor(1, i);
lcd.print(menu[i]);
}
int select = 1;
if (menuSelect % 2 == 0) {
select = 2;
if (menuSelect >= menuLength - 1) {
select = 0;
}
}
lcd.setCursor(0, menuSelect);
if (select == 1) {
lcd.print(">");
} else if (select == 2) {
lcd.print("<");
}
}
int numDigit(int n) {
int count = 0;
if (n <= 0) {
count = 1;
}
while (n != 0) {
count++;
n = n / 10;
}
return count;
}
void updateSettingValue(int menuSelect) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(">Back");
lcd.setCursor(1, 1);
lcd.print(menu[menuSelect]);
lcd.setCursor(16 - numDigit(menuValue[menuSelect]), 1);
lcd.print(menuValue[menuSelect]);
}
void settingValue(int menuSelect) {
updateSettingValue(menuSelect);
while (true) {
if (oldEncPos != encoderPos) {
if (oldEncPos < encoderPos) {
menuValue[menuSelect]++;
} else {
menuValue[menuSelect]--;
}
oldEncPos = encoderPos;
updateSettingValue(menuSelect);
}
if (digitalRead(enSW) == 0) {
while (digitalRead(enSW) == 0);
updateMenu(menuCnt);
break;
}
}
}
void setup() {
Serial.begin(9600);
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
pinMode(enSW, INPUT_PULLUP);
attachInterrupt(0, handlePinA, RISING);
attachInterrupt(1, handlePinB, RISING);
pinMode(ENDSTOP_Z_PIN, INPUT_PULLUP);
pinMode(ENA_Z, OUTPUT);
pinMode(DIR_Z, OUTPUT);
pinMode(STEP_Z, OUTPUT);
pinMode(LED_LASER_PIN, OUTPUT);
pinMode(PROBLE_Z_PIN, INPUT);
pinMode(ENDSTOP_Z_PIN, INPUT_PULLUP);
stepper.setMaxSpeed(3000);
stepper.setAcceleration(3000);
digitalWrite(ENA_Z, LOW);
pinMode(BT_RESET, OUTPUT);
pinMode(LED_RESET, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(3, 0);
lcd.print("AT");
lcd.setCursor(7, 1);
lcd.print("Q");
lcd.setCursor(2, 2);
lcd.print("VN");
lcd.setCursor(0, 3);
lcd.print("--------2023--------");
delay(2000);
lcd.clear();
updateMenu(menuCnt);
}
void loop() {
reading = digitalRead(pinA);
if ((aFlag == 0) && (reading == 1)) {
if (digitalRead(pinB) == 0) {
menuCnt = constrain(menuCnt - 1, 0, menuLength - 1);
} else {
menuCnt = constrain(menuCnt + 1, 0, menuLength - 1);
}
updateMenu(menuCnt);
}
aFlag = reading;
if (digitalRead(enSW) == 0) {
switch (menuCnt) {
case 0:
// Ve_Goc_Truc_Z
stepper.setSpeed(3000);
while (digitalRead(ENDSTOP_Z_PIN) == LOW) {
stepper.runSpeed();
}
stepper.stop();
updateMenu(menuCnt);
break;
case 1:
// Di_Chuyen
break;
case 2:
// Khoang_Cach
break;
case 3:
// Trang_Thai
break;
}
}
}