// *** Disclaimer: This is an untested hobby development.
// -------------- Include the following Librarys -------------- //
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
#include <Stepper.h>
#include <TimerOne.h>
// -------------- Connect to LCD via I2C -------------- //
//Define the LCD Being used and its settings
hd44780_I2Cexp lcd1(0x27);
// -------------- Defines pins numbers -------------- //
const int stepPin = 3;
const int dirPin = 4;
const int switchPinA = A1;
const int switchPinB = A2;
int customDelay, customDelayMapped; // Defines variables
const int ms1 = 8;
const int ms2 = 9;
const int ms3 = 10;
int switchPinAVal = 0;
int switchPinBVal = 0;
enum class MotorControl { CLOCKWISE, ANTICLOCKWISE, STOP } ; //MD1
volatile MotorControl motorControl = MotorControl::STOP ; //initial state //MD1
//--------------------------MIN & MAX Potentiometer Settings-------------------------------//
// Define our maximum and minimum speed in steps per second (scale pot to these) //
void setup() {
Serial.begin( 115200 ) ; //MD1
Serial.println(F("Motor Controller")) ; //MD1
// -------------- Initiate the LCD -------------- //
lcd1.init(); // initialize the lcd
lcd1.init(); // initialize the lcd
lcd1.backlight(); // turn on backlight
lcd1.begin(16, 2);
// -------------- On power up display on the LCD intro -------------- //
lcd1.print("Speed:");
lcd1.setCursor(12, 0);
lcd1.print("RPM");
lcd1.setCursor(0, 1);
lcd1.print("Direction:");
pinMode(switchPinA, INPUT_PULLUP);
pinMode(switchPinB, INPUT_PULLUP);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(ms1, OUTPUT);
pinMode(ms2, OUTPUT);
pinMode(ms3, OUTPUT);
digitalWrite(ms1, LOW);
digitalWrite(ms2, HIGH);
digitalWrite(ms3, HIGH);
motorDirection() ;
Timer1.initialize( 1000 ); //start 1mS but may be better read the required sped here
Timer1.attachInterrupt( motorController ) ; //MD1
}
// -------------- Begin Loop , Begin Operating Machine -------------- //
void loop()
{
motorDirection() ;
static int speedControlUsLast = -1 ;
int speedControlUs = speedControl() ;
if ( speedControlUs < 50 ) speedControlUs = 50 ; // can't be too low
if ( speedControlUs != speedControlUsLast ) {
Timer1.setPeriod( speedControl() ) ; // microseconds
speedControlUsLast = speedControlUs ;
}
}
void motorDirection() {
// handles motor direction switches
switchPinAVal = digitalRead(switchPinA);
switchPinBVal = digitalRead(switchPinB);
if (switchPinAVal == HIGH && switchPinBVal == LOW)
{
// motorRunClockwise(); //MD1
motorControl = MotorControl::CLOCKWISE ; //MD1
// -------------- Update LCD to ">>>>>>" -------------- //
lcd1.setCursor(10, 1);
lcd1.print(">>>>>>");
}
if (switchPinAVal == LOW && switchPinBVal == HIGH)
{
// motorRunAntiClockwise();
motorControl = MotorControl::ANTICLOCKWISE ; //MD1
// -------------- Update LCD to "<<<<<<" -------------- //
lcd1.setCursor(10, 1);
lcd1.print("<<<<<<");
}
//else
if ( (switchPinAVal == HIGH && switchPinBVal == HIGH) || (switchPinAVal == LOW && switchPinBVal == LOW) )
{
motorControl = MotorControl::STOP ; //MD1
digitalWrite(stepPin, LOW); // stop the motor
// -------------- Update LCD to "STOP" -------------- //
lcd1.setCursor(10, 1);
lcd1.print(" STOP ");
}
}
void motorController() {
static bool toggle = false ; // we make two entries here per cycle
if ( motorControl == MotorControl::STOP ) {
// handle stop here
}
else {
if ( toggle == false ) {
digitalWrite(stepPin, HIGH);
}
else {
if ( motorControl == MotorControl::CLOCKWISE ) {
// clockwise
digitalWrite(dirPin, LOW);
}
else if ( motorControl == MotorControl::ANTICLOCKWISE ) {
digitalWrite(dirPin, HIGH);
}
else {
// should not happen
}
// digitalWrite(ms1, LOW); // now in setup()
// digitalWrite(ms2, HIGH); // now in setup()
// digitalWrite(ms3, HIGH); // now in setup()
digitalWrite(stepPin, LOW);
}
toggle = ! toggle ;
}
}
// -------------- Function for reading the Potentiometer -------------- //
int speedControl() {
int customDelay = analogRead(A0); // Reads the potentiometer
int newCustom = map(customDelay, 0, 1023, 0, 4000); // Converts the read values of the potentiometer from 0 to 1023 into desireded delay values (0 to 4000)
// -------------- Update LCD to "Potentiometer value" -------------- //
//lcd1.setCursor(7, 0);;
lcd1.print(" "); //three blank spaces
lcd1.setCursor(7, 0);;
lcd1.print( (4000 - newCustom) / 40 ) ;
return newCustom;
}
/////////////////////////////////////////////////////////////////////////
void motorRunClockwise() {
//NOT USED
customDelayMapped = speedControl();
digitalWrite(stepPin, LOW);
delayMicroseconds(customDelayMapped);
digitalWrite(stepPin, HIGH);
delayMicroseconds(customDelayMapped);
digitalWrite(dirPin, LOW);
digitalWrite(ms1, HIGH);
digitalWrite(ms2, HIGH);
digitalWrite(ms3, HIGH);
}
////////////////////////////////////////////////////////////////////////
void motorRunAntiClockwise() {
//NOT USED
customDelayMapped = speedControl();
digitalWrite(stepPin, LOW);
delayMicroseconds(customDelayMapped);
digitalWrite(stepPin, HIGH);
delayMicroseconds(customDelayMapped);
digitalWrite(dirPin, HIGH);
digitalWrite(ms1, HIGH);
digitalWrite(ms2, HIGH);
digitalWrite(ms3, HIGH);
}