#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// //RPM N = 9375/Delay. RPM range: 1rpm - 1875rpm
// //delayMicroSeconds limit ~ 16383
#define stepPin 2
#define dirPin 4
#define btnPinYellow 6
#define btnPinGreen 7
#define btnPinBlue 8
#define btnPinRed 9
#define btnPinBlack 10
const int timeDelay = 500;
inline void lcdPrint(String msg, String nxt = "", bool clear = false, int delayTime = 100) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(msg);
if(nxt != "")
{
lcd.setCursor(0, 1);
lcd.print(nxt);
}
delay(delayTime);
if(clear)
lcd.clear();
}
void setup() {
lcd.init();
lcd.backlight();
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(btnPinYellow, INPUT_PULLUP);
pinMode(btnPinGreen, INPUT_PULLUP);
pinMode(btnPinBlue, INPUT_PULLUP);
pinMode(btnPinRed, INPUT_PULLUP);
pinMode(btnPinBlack, INPUT_PULLUP);
Serial.begin(9600);
}
void amt(float &amt) {
lcdPrint("green for 100deg", "red for 10deg", false, 2*timeDelay);
lcdPrint("blue for 1deg", "black for 0.1deg", false, 2*timeDelay);
lcdPrint("yellow to set", "", false, 2*timeDelay);
while(digitalRead(btnPinYellow))
{
if(!digitalRead(btnPinGreen))
{
amt += 100.0;
delay(timeDelay);
}
if(!digitalRead(btnPinRed))
{
amt += 10.0;
delay(timeDelay);
}
if(!digitalRead(btnPinBlue))
{
amt += 1.0;
delay(timeDelay);
}
if(!digitalRead(btnPinBlack))
{
amt += 0.1;
delay(timeDelay);
}
lcdPrint("Degrees = " + String(amt), "", false, 200);
}
}
void setDir()
{
lcdPrint("Green -> clock", "Red -> Anticlock");
int state1 = 0, state2 = 0;
while(!(state1 ^ state2))// This makes the program wait for an input using buttons.
{
state1 = !digitalRead(btnPinGreen), state2 = !digitalRead(btnPinRed);
}
if(state1)
{
digitalWrite(dirPin, HIGH);
lcdPrint("Clockwise set", "", true);
}
else
{
digitalWrite(dirPin, LOW);
lcdPrint("Anticlock set", "", true);
}
}
void rotByAmt(float amt)
{
setDir();//setting direction
int newDelay = calibrate(), start, stop;
for(int i = 0; i < int (amt/0.1125); i++)
{
if(!i)
start = millis();
digitalWrite(stepPin, HIGH);
delayMicroseconds(newDelay);
digitalWrite(stepPin, LOW);
delayMicroseconds(newDelay);
}
stop = millis();
Serial.println(stop - start);
lcdPrint("Step Rot Done!");
}
int calibrate()
{
int newDelay;
lcdPrint("Use pot, set RPM", "yellow to set");
while(digitalRead(btnPinYellow))
{
int pot_reading = analogRead(A0);
unsigned long currRPM = map(pot_reading, 0, 1023, 5, 2000);
newDelay = 9375/currRPM;
lcdPrint("Current RPM: ", String(currRPM), true, 50);
}
lcdPrint("Calibration done", "Starting Rot-");
return newDelay;
}
void rotContinuous()
{
setDir(); //setting direction
int newDelay = calibrate();
lcdPrint("Yellow to quit");
while(digitalRead(btnPinYellow))
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(newDelay);
digitalWrite(stepPin, LOW);
delayMicroseconds(newDelay);
}
lcdPrint("Cont rot done!", "", true);
}
void loop() {
lcdPrint("Green -> step", "Red -> cont");
int state1 = 0, state2 = 0;
while(!(state1 ^ state2))// This makes the program wait for an input using buttons.
{
state1 = !digitalRead(btnPinGreen), state2 = !digitalRead(btnPinRed);
}
if(state1)
{
float degree = 0.0;
amt(degree); //stores the rotation amount in degree;
rotByAmt(degree);
}
if(state2)
{
rotContinuous();
}
delay(2*timeDelay);
}