#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
//const int stepsperrevolution = 200; // NO. OF STEPS PER REVOLUTION
int msf = 16; // MICROSTEPPING FACTOR
// LCD SCREEN SPECS
#define LCD_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_ROWS 4
// LABELLING OF DIGITAL PINS
const int power = 2; // POWER SUPPLY TO MOTOR (A4998 DRIVER) - ON/OFF
const int type_rot = 3; // TYPE OF ROTATION (INDIVIDUAL DEGREES / RPM MODE)
const int rot = 4; // TO OBTAIN DIRECTION OF ROTATION
const int buttoninc = 5; // TO INCREASE DIGITAL INPUT
const int buttondec = 6; // TO DECREASE DIGITAL INPUT
const int dirpin = 8; // DIRECTION PIN TO DRIVER (A4998)
const int steppin = 9; // STEP PIN TO DRIVER (A4998)
const int enter = 10; // BUTTON FOR PROCEEDING STEPS FURTHER
const int res = 13; // TO SET RESOLUTION OF DIGITAL INPUT
// ACCELSTEPPER MOTOR LIBRARY STEPPER DECLERATION
AccelStepper stepper(AccelStepper::DRIVER,steppin,dirpin);
// LCD CRYSTAL DISPLAY LIBRARY
LiquidCrystal_I2C lcd (LCD_ADDR, LCD_COLUMNS, LCD_ROWS);
unsigned long previousMillis = 0;
const long interval = 100; // Update interval (lag of inc and dec buttons) in milliseconds
float required_value;
void update_lcd_m(int value1,int value2){
lcd.setCursor(16,0);
// lcd.print("MO: ");
lcd.print(" ");
if(value1 == HIGH){
lcd.setCursor(17,0);
lcd.print("RPM");
}
if(value1 == LOW){
lcd.setCursor(17,0);
lcd.print("DEG");
}
lcd.setCursor(13,1);
// lcd.print("MO: ");
lcd.print(" ");
if(value2 == HIGH){
lcd.setCursor(13,0);
lcd.print("CW ");
}
if(value2 == LOW){
lcd.setCursor(13,0);
lcd.print("ACW");
}
}
void update_lcd_a(){
int value;
lcd.setCursor(0,0);
lcd.print("A.I: ");
lcd.print(" ");
lcd.setCursor(5,0);
value=calibrate();
lcd.print(value);
}
void update_lcd_d(float value){
lcd.setCursor(0,1);
lcd.print("D.I:");
lcd.print(" ");
lcd.setCursor(5,1);
lcd.print(value);
}
void update_lcd_r(float value){
// lcd.setCursor(12,1);
// lcd.print("N:");
lcd.setCursor(13,1);
lcd.print(" ");
lcd.setCursor(13,1);
lcd.print(value);
}
void update_lcd_deg(float required_value){
lcd.setCursor(0,2);
lcd.print("DEG : ");
lcd.print(" ");
lcd.setCursor(5,2);
lcd.print(required_value);
}
void update_lcd_rpm(float required_value){
lcd.setCursor(0,3);
lcd.print("RPM : ");
lcd.print(" ");
lcd.setCursor(5,3);
lcd.print(required_value);
}
float update_res(float a){
if((digitalRead(res)==HIGH)&&(a>=100)){
a=0.01;
delay(500);
}
else if((digitalRead(res)==HIGH)&&(a<100 )){
a=a*10;
delay(500);
}
else if((digitalRead(res)==HIGH)){
a=1;
delay(500);
}
lcd.setCursor(13,2);
lcd.print(" ");
lcd.setCursor(13,2);
lcd.print(a);
// Serial.print(a);
return a;
}
int calibrate(){
int input;
int customDelay = analogRead(A0);
input = map(customDelay, 0, 1023, 30, 7500);
return input;
}
void setup() {
stepper.setMaxSpeed(10000);
// ASSIGNMENT OF INPUT AND OUTPUT TO DIGITAL PINS
pinMode(power, INPUT);
pinMode(type_rot, INPUT);
pinMode(rot, INPUT);
pinMode(buttoninc, INPUT);
pinMode(buttondec, INPUT);
pinMode(enter, INPUT);
pinMode(dirpin, OUTPUT);
pinMode(steppin, OUTPUT);
pinMode(res, INPUT);
// ASSIGNMENT OF ANALOG INPUT
pinMode(A0, INPUT);
// LCD CUSTOMIZATION
lcd.begin(20,4);
lcd.init();
lcd.backlight();
//Serial.begin(9600);
Serial.begin(115200);
//LCD INITIAL OPUTPUT
lcd.setCursor(4,0);
lcd.print("STEPPER MOTOR");
lcd.setCursor(6,1);
lcd.print("CONTROL");
lcd.setCursor(3,2);
lcd.print("GROUP SPARTANS");
delay(5000);
lcd.clear();
// for microstepping (PENDING)
digitalWrite(7, HIGH);
}
int ana_value;
float dig_value = 170; // INITIAL DIGITAL VALUE
int b=0;
static float as=1;
void loop() {
// UPDATING TYPE OF ROTATION ON LCD and DIRECTION
update_lcd_m(digitalRead(type_rot),digitalRead(rot));
// UPDATING ANALOG VALUE AND STATIC DIGITAL VALUE TO SYSTEM
ana_value = calibrate();
as = update_res(as);
// Serial.print("in");
// Serial.print(a);
// UPDATING ANALOG VALUE ON LCD
if (millis() - previousMillis >= interval){
update_lcd_a();
update_lcd_d(dig_value); // FOR INITIALIZATION OF DIGITAL VALUE
if(digitalRead(buttoninc)==HIGH){ // UPDATING DIGITAL INCREASING VALUE ON SYSTEM AND LCD
dig_value = dig_value + as;
update_lcd_d(dig_value);
}
if(digitalRead(buttondec)==HIGH){ // UPDATING DIGITAL DECREASING VALUE ON SYSTEM AND LCD
dig_value = dig_value - as;
update_lcd_d(dig_value);
}
required_value = ana_value+ dig_value ;
update_lcd_r(required_value);
previousMillis = millis();
}
// DEG MODE
float step;
float deg;
int rpm;
float sps;
if((digitalRead(type_rot) == LOW)){
if(digitalRead(power) == HIGH){
if(digitalRead(rot)==HIGH)
digitalWrite(dirpin, HIGH);
else
digitalWrite(dirpin, LOW);
Serial.print(b);
if(b==0){
update_lcd_deg(required_value);
if((digitalRead(enter)==HIGH)){
deg=required_value;
update_lcd_deg(deg);
delay(500);
b=1;
}
}
if(b==1){
update_lcd_rpm(required_value);
if((digitalRead(enter)==HIGH)){
rpm=required_value;
update_lcd_rpm(rpm);
delay(500);
b=2;
}
}
if(b==2){
step = deg * (200.0 / 360.0) * msf; // Convert degrees to steps (assuming 200 steps per revolution for your motor)
sps = (rpm) * (200.0 / 60.0) * msf; // Convert RPM to steps per second
for(;stepper.currentPosition()<step;){
stepper.run();
stepper.setSpeed(sps);// steps per second
}
stepper.stop();
b=3;
}
if(b==3){
lcd.setCursor(1,3);
lcd.print("TASK COMPLETED");
delay(500);
stepper.moveTo(0);
b=0;
lcd.clear();
}
}
}
// RPM MODE
// RPM MODE
if (digitalRead(type_rot) == HIGH) {
if (digitalRead(power) == HIGH) {
if (digitalRead(rot) == HIGH)
digitalWrite(dirpin, HIGH);
else
digitalWrite(dirpin, LOW);
int rpm = 0; // Initialize rpm variable
// Check if the user has entered the RPM value
if (b == 0) {
update_lcd_rpm(required_value); // Display the required RPM on LCD
if (digitalRead(enter) == HIGH) {
rpm = required_value; // Set the RPM value from the user input
update_lcd_rpm(rpm); // Display the chosen RPM on LCD
delay(500);
b = 1;
}
}
if (b == 1) {
sps = (rpm) * (200.0 / 60.0) * msf; // Convert RPM to steps per second
for(;1==1;){
// Set the speed of the stepper motor
stepper.setSpeed(sps);
// Run the stepper motor
stepper.run();
}
//lcd.clear();
// You might add additional logic here for any other functionality you need in RPM mode
}
Serial.print(b);
}
}
}