Figure 8: Arduino Program to handle one (1) Stepper Motor:
//
//--------------------------------------------------------------------------------------------
// LED display using LedControl.h Library.
//
// This program as well as the C# program were developed in its entirety by:
// Arnoldo B. Canales
// July 8, 2018.
//
// To power the motor(s), I am using the AccelStepper Library property of Mike McCauley.
//
//--------------------------------------------------------------------------------------------
//include libraries
#include <stdio.h>
#include <time.h>
#include <AccelStepper.h>
//#include <MultiStepper.h>
#include "pitches.h"
//
//Memory variables
//
String mCntrlrName; //Assigning Name to Controller Board.
//
int mDelayTime = 10; //This Delay Time.
int mDialLocation = 399; //Assuming Dial is position in the middle.
const int mStepsXcm = 50; //Number of steps to advance one (1) cm.
int mCurrentStep = 0; //Current step to reach mStepsXcm.
bool mMoveRight, mMoveLeft; //Motor is rotating Left/Right.
bool mMoveRight1Step, mMoveLeft1Step; //Motor is rotating Left/Right.
bool mIntLeftLEDOnOff = false; //Preserves status of the Left Interrupt LED.
bool mIntRightLEDOnOff = false; //Preserves status of the Right Interrupt LED.
String mCurrLocation; //Dial Current Location. To be sent via USB to C# Routine.
bool mHomeLeft = false; //Signals that Home Left has been reached.
bool mHomeRight = false; //Signals that Home Right has been reached.
int mMoveLeftAma = 3000;
int mMoveRightAma = mMoveLeftAma * -1;
//
//Variables to talk to the Master Computer via USB port.
byte cmdByte0; byte cmdByte1; byte cmdByte2; byte cmdByte3;
byte cmdByteX[80] = { 0x5E };
//
bool mReadingPort = false; unsigned int mPulseFrequency = 0;
//
//Definition of Frequencies to play Tones and signal events.
int mStartUpFreq = NOTE_C5;
int mGenericFreq = NOTE_E4;
//
// Pin-related Memory variables
//
//RIGHT SIDE
const byte interruptPin3 = 3; //Interrupt Pin 2 to detect when Far Left is reached.
const int pButtonPin29 = 29; //Right Button Power Motor
const int LedPin30 = 30; //Right Moving LED
const int LedPin31 = 31; //Right Button FAR RIGHT LIMIT reached
const int LedPin32 = 32; //Right Interrupt LED.
//
//LEFT SIDE
const byte interruptPin2 = 2; //Interrupt Pin 2 to detect when Far Left is reached.
const int pButtonPin37 = 37; //Left Button Power Motor
const int LedPin38 = 38; //Left Moving LED
const int LedPin39 = 39; //Left Button FAR RIGHT LIMIT reached
const int LedPin40 = 40; //Left Interrupt LED.
//
//BUZZER PIN
const int LedPin50 = 50; //Main Loop w Reading Port Cycle LED.
const int pBuzzerPin51 = 51; //Buzzer -plugged at Controller's pin 39.
//
//
// Define the stepper motors and the pins that will be using
AccelStepper stepper1(1, 7, 6); // (Type:driver, STEP, DIR)
//
//--------------------------------------------------------------------------------------------
//
//Main Setup
//
//--------------------------------------------------------------------------------------------
void setup()
{
//LEFT SIDE
pinMode(pButtonPin37, INPUT_PULLUP); //Left Button Power Motor
pinMode(LedPin38, OUTPUT); //Left Moving LED
pinMode(LedPin39, OUTPUT); //Left Button FAR RIGHT LIMIT reached
pinMode(LedPin40, OUTPUT); //Left Interrupt LED.
digitalWrite(LedPin38, LOW);
digitalWrite(LedPin39, LOW);
digitalWrite(LedPin40, LOW);
//
//RIGHT SIDE
pinMode(pButtonPin29, INPUT_PULLUP); //Right Button Power Motor
pinMode(LedPin30, OUTPUT); //Right Moving LED
pinMode(LedPin31, OUTPUT); //Right Button FAR RIGHT LIMIT reached
pinMode(LedPin32, OUTPUT); //Right Interrupt LED.
digitalWrite(LedPin30, LOW);
digitalWrite(LedPin31, LOW);
digitalWrite(LedPin32, LOW);
//
pinMode(LedPin50, OUTPUT); //Main Loop w Reading Port Cycle LED LED.
digitalWrite(LedPin50, LOW); //initialize Main Loop w Reading Port Cycle LED.
pinMode(pBuzzerPin51, OUTPUT); //initialize the buzzer pin as an output
//
pinMode(interruptPin2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin2), FarLeft_Reached, FALLING);
//
pinMode(interruptPin3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin3), FarRight_Reached, FALLING);
//
//Set initial seed values for the steppers
stepper1.setMaxSpeed(3000); stepper1.setSpeed(200);
//
mMoveRight = false; mMoveLeft = false;
//
Serial.begin(9600); //start serial communication
//
PlayTone(2, mStartUpFreq);
}
//
//--------------------------------------------------------------------------------------------
//
//Main Loop Starts
//Main Loop Starts
//Main Loop Starts
//
//--------------------------------------------------------------------------------------------
void loop()
{
if (Serial.available() > 0) //Read data to bytes
{
for (int i = 0; i <= 63; i++) cmdByteX[i] = 0x5E; //this was 0x20
//
Serial.readBytesUntil('|', cmdByteX, 80); // (^) Carat char indicates end of text being trasmitted
Serial.flush();
//
cmdByte0 = cmdByteX[0] - 48; //These four bytes are the command.
cmdByte1 = cmdByteX[1] - 48;
cmdByte2 = cmdByteX[2] - 48;
cmdByte3 = cmdByteX[3] - 48;
}
//
//----------------------------------------
// START: This code is to process commands
//----------------------------------------
if (cmdByte0 == 1) // FIRST byte is equal to "1", then someone maybe talking to Arduino,
{
if (cmdByte1 == 1) // SECOND byte is equal to "1".
{
if (cmdByte2 == 1) // THIRD byte is equal to "1".
{
buzzerX(10);
//Command 1,1,1,1 - Command query the controller.
// FORTH byte is equal to "1", tell me your ID!
if (cmdByte3 == 1) { mCntrlrName = "A1"; Serial.print(mCntrlrName); }
//
//Command 1,1,1,2 -
if (cmdByte3 == 2) {}
//
//Command 1,1,1,3 - Command to Increase/Decrease the Delay Time.
if (cmdByte3 == 3) { mDelayTime += 50; if (mDelayTime == 500) mDelayTime = 50; }
//
//Command 1,1,1,4 - Command to Test Code.
if (cmdByte3 == 4) {}
//
//Command 1,1,1,5 - Command to
if (cmdByte3 == 5) { buzzerX(10); }
}
}
//
//Command 1,2,x,x are the ... Commands
if (cmdByte1 == 2) {}
//
//Command 1,3,x,x are the ... Commands
if (cmdByte1 == 3) {}
//
//Command 1,4,x,x are the ... Commands
if (cmdByte1 == 4) // SECOND byte is equal to "4".
{
buzzerX(10);
//Command 1,4,1,0 - Move Right.
if (cmdByte2 == 1) // THIRD byte is equal to "1".
{
mMoveRight = true;
//
mMoveLeft = false; mMoveLeft1Step = false; mMoveRight1Step = false;
}
//
//Command 1,4,2,0 - Move Left.
if (cmdByte2 == 2) // THIRD byte is equal to "2".
{
mMoveLeft = true;
//
mMoveRight = false; mMoveLeft1Step = false; mMoveRight1Step = false;
}
//
//Command 1,4,3,0 - Command to Stop Motor.
if (cmdByte2 == 3) // THIRD byte is equal to "3".
{
mMoveRight = false; mMoveLeft = false; mMoveLeft1Step = false; mMoveRight1Step = false;
}
//
//Command 1,4,4,0 - Command to Find Home.
if (cmdByte2 == 4) // THIRD byte is equal to "4".
{ FindHome(); }
//
//Command 1,4,5,0 - Command to Move One Step to the Left.
if (cmdByte2 == 5) // THIRD byte is equal to "5".
{ mMoveRight1Step = false; mMoveLeft1Step = true; }
//
//Command 1,4,6,0 - Command to Move One Step to the Right.
if (cmdByte2 == 6) // THIRD byte is equal to "6".
{ mMoveLeft1Step = false; mMoveRight1Step = true; }
//
//Command 1,4,7,0 - Command to .
if (cmdByte2 == 7) // THIRD byte is equal to "7".
{}
//
//Command 1,4,8,0 - Command to .
if (cmdByte2 == 8) // THIRD byte is equal to "8".
{}
//
//Command 1,4,9,0 - Command to Test.
if (cmdByte2 == 9) // THIRD byte is equal to "9".
{ Testing_Routine(); }
}
}
//----------------------------------------
// END: This code is to process commands
//----------------------------------------
//
//
//
//Button pressed - Right BUTTON
if (digitalRead(pButtonPin29) == LOW)
{
buzzerX(10);
do { MoveRight(); }
while (digitalRead(pButtonPin29) == LOW); //de-bounce pressed button
}
//
//Button pressed - Left BUTTON
if (digitalRead(pButtonPin37) == LOW)
{
buzzerX(10);
do { MoveLeft(); }
while (digitalRead(pButtonPin37) == LOW); //de-bounce pressed button
}
//
//
//
if (mMoveRight == true) MoveRight();
if (mMoveLeft == true) MoveLeft();
if (mMoveLeft1Step == true) MoveOneStep(mMoveLeftAma);
if (mMoveRight1Step == true) MoveOneStep(mMoveRightAma);
//
//
//
cmdByte0 = 0; cmdByte1 = 0; cmdByte2 = 0; cmdByte3 = 0;
if (++mPulseFrequency == 65500) { mReadingPort = !mReadingPort; digitalWrite(LedPin50, mReadingPort); mPulseFrequency = 0; }
//
//xLedPin35 = !xLedPin35; digitalWrite(LedPin35, xLedPin35);
}
//
//--------------------------------------------------------------------------------------------
//
//Main Loop Ends
//Main Loop Ends
//Main Loop Ends
//
//--------------------------------------------------------------------------------------------
//
//
//--------------------------------------------------------------------------------------------
//Routine to Centralize the Delays in one point
//
//--------------------------------------------------------------------------------------------
void xDelay(int x)
{
delay(x);
}
//
//--------------------------------------------------------------------------------------------
//Testing Routine
//This routine is called when command 1,4,4,0 is issued.
//--------------------------------------------------------------------------------------------
void Testing_Routine()
{
//delay(500);
}
//-------------------------------------------------------------------------------
//buzzerX Routine - Sound the Buzzer.
//
//-------------------------------------------------------------------------------
void buzzerX(int xDuration)
{
for (int i = 0; i<xDuration; i++)
{
digitalWrite(pBuzzerPin51, HIGH);
xDelay(10); //wait for 5ms
digitalWrite(pBuzzerPin51, LOW);
}
}
//-------------------------------------------------------------------------------
//PlayTone Routine - Sound the Buzzer using Tone() function.
//
//-------------------------------------------------------------------------------
void PlayTone(int pTone,int pFreq)
{
int mFrequency = pFreq; // NOTE_C5 = 523Hz
switch (pTone)
{
case 1:
tone(pBuzzerPin51, mFrequency, 250);
delay(300);
tone(pBuzzerPin51, mFrequency + 1, 250);
delay(300); break;
case 2: //Start-Up
for (int freq = mFrequency; freq <= (mFrequency* 2); ++freq)
{tone(pBuzzerPin51, freq, 5); delay(1);} break;
case 3: break;
case 4: break;
default: break;
}
}
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//
// START - Routines to power up/down the Motor.
//
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------
//Stepper Motor
//MoveRight Function.
//-------------------------------------------------------------------------------
void MoveRight()
{
if (mHomeRight == false)
{
digitalWrite(LedPin30, HIGH);
//
mDialLocation++;
if (mDialLocation < 800)
{
MoveOneStep(mMoveRightAma);
mHomeLeft = false;
Report_Current_Location();
}
else
{
mMoveRight = false; mHomeRight = true; mHomeLeft = false;
mDialLocation = 800;
Report_Current_Location();
}
if (mDialLocation == 800) { digitalWrite(LedPin31, HIGH); }
if (mDialLocation != 000) { digitalWrite(LedPin39, LOW); }
//
digitalWrite(LedPin30, LOW);
}
}
//-------------------------------------------------------------------------------
//Stepper Motor
//MoveLeft Function.
//-------------------------------------------------------------------------------
void MoveLeft()
{
if (mHomeLeft == false)
{
digitalWrite(LedPin38, HIGH);
//
mDialLocation--;
if (mDialLocation > 0)
{
MoveOneStep(mMoveLeftAma);
mHomeRight = false;
Report_Current_Location();
}
else
{
mMoveLeft = false; mHomeLeft = true; mHomeRight = false;
mDialLocation = 0;
Report_Current_Location();
}
if (mDialLocation == 000) { digitalWrite(LedPin39, HIGH); }
if (mDialLocation != 800) { digitalWrite(LedPin31, LOW); }
//
digitalWrite(LedPin38, LOW);
}
}
//-------------------------------------------------------------------------------
//Stepper Motor
//MoveOneStep Function.
//-------------------------------------------------------------------------------
void MoveOneStep(int pLR)
{
for (mCurrentStep = 0; mCurrentStep < mStepsXcm; ++mCurrentStep)
{ stepper1.setSpeed(pLR); stepper1.run(); }
}
//-------------------------------------------------------------------------------
//Stepper Motor
//Report_Current_Location.
//-------------------------------------------------------------------------------
void Report_Current_Location()
{
char mLocIndicator = 'z';
switch (mDialLocation)
{
case 0: mLocIndicator = 'a'; break;
case 50: mLocIndicator = 'b'; break;
case 100: mLocIndicator = 'c'; break;
case 150: mLocIndicator = 'd'; break;
case 200: mLocIndicator = 'e'; break;
case 250: mLocIndicator = 'f'; break;
case 300: mLocIndicator = 'g'; break;
case 350: mLocIndicator = 'h'; break;
case 400: mLocIndicator = 'i'; break;
case 450: mLocIndicator = 'j'; break;
case 500: mLocIndicator = 'k'; break;
case 550: mLocIndicator = 'l'; break;
case 600: mLocIndicator = 'm'; break;
case 650: mLocIndicator = 'n'; break;
case 700: mLocIndicator = 'o'; break;
case 750: mLocIndicator = 'p'; break;
case 800: mLocIndicator = 'q'; break;
}
if (mLocIndicator != 'z') Serial.print(mLocIndicator);
}
//-------------------------------------------------------------------------------
//Stepper Motor
//FarLR_Reached Function.
//Routine called when Interrupt on Pin 2 (INT 0) is triggered.
//-------------------------------------------------------------------------------
void FarLeft_Reached()
{
noInterrupts();
//
mIntLeftLEDOnOff = !mIntLeftLEDOnOff;
digitalWrite(LedPin40, mIntLeftLEDOnOff);
//
mCurrentStep = mStepsXcm;
mDialLocation = 0;
mHomeRight = false;
mHomeLeft = true; mMoveLeft = false;
buzzerX(10);
//
interrupts();
}
//-------------------------------------------------------------------------------
//Stepper Motor
//FarRight_Reached Function.
//Routine called when Interrupt on Pin 3 (INT 1) is triggered.
//-------------------------------------------------------------------------------
void FarRight_Reached()
{
noInterrupts();
//
mIntRightLEDOnOff = !mIntRightLEDOnOff;
digitalWrite(LedPin32, mIntRightLEDOnOff);
//
mCurrentStep = mStepsXcm;
mDialLocation = 800;
mHomeLeft = false;
mHomeRight = true; mMoveRight = false;
buzzerX(10);
//
interrupts();
}
//-------------------------------------------------------------------------------
//Stepper Motor
//FindHome Function
//-------------------------------------------------------------------------------
void FindHome()
{
mHomeRight = false;
mMoveRight = false;
digitalWrite(LedPin30, LOW);
digitalWrite(LedPin31, LOW);
digitalWrite(LedPin32, LOW);
mIntRightLEDOnOff = false;
//
mHomeLeft = false;
digitalWrite(LedPin38, LOW);
digitalWrite(LedPin39, LOW);
digitalWrite(LedPin40, LOW);
mIntLeftLEDOnOff = false;
//
mMoveLeft = true; //Moving LEFT
digitalWrite(LedPin38, HIGH); //Moving LEFT
//
do { MoveOneStep(mMoveLeftAma); } while (mHomeLeft == false);
//
mDialLocation = 0; //Set Dial location to zero.
digitalWrite(LedPin38, LOW); //Moving LEFT no longer
digitalWrite(LedPin39, HIGH); //FAR LEFT reached
}
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//
// END - Routines to power up/down the Motor.
//
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// END OF PROGRAM - 542 LoC