Which Arduino?
/*
* Sicherheit variante 1:
this program runs the motor in forward and reverse direction depedning on choice of button.
Once the motor starts running, it stops with release of a push button.
On reaching Limit Switch in direction of movement, motor will stop.
this program lets the Interrupt triggered, however in ISR Pulse signal is only then generated, when program is in moveForward or moveBackward mode.
otherwise, Interrupts are still there, but nothing is executed in ISR
maxSteps counts the maximum Steps which motor is allowed to take in case any of limit switch should get broken
*/
//********************************* Pins and Variables Declaration *********************************
// Input Pin Definitions for User Interface
const int fwdButtonPin = 2;
const int revButtonPin = 3;
const int fwdLimitSwitchPin= 4;
const int revLimitSwitchPin= 5;
// Containers for storing the states of Input Pins
int fwdButton = LOW;
int revButton = LOW;
int fwdLimitSwitch = HIGH;
int revLimitSwitch = HIGH;
//***variables needed for debouncing**********************
int revButtonState;
int revLastButtonState = LOW;
unsigned long revLastDebounceTime = 0;
unsigned long revDebounceDelay = 100; // debounce delay is 100ms
//**variables needed for debouncing***********************
int fwdButtonState;
int fwdLastButtonState = LOW;
unsigned long fwdLastDebounceTime = 0;
unsigned long fwdDebounceDelay = 100; // debounce delay is 100ms
//****************************************
// Motor Interface Output Pins
int motorStep = 8;
int motorDir = 9;
int motorEN = 10;
// Variable to count steps of a motor
int maxSteps = 0; // this variable adjust maximum rotation of +/-100° or +/-851 Steps (1 Step = 0,1176°)
// Different States of Stepper
enum state_t { standby, moveForward, moveBackward };
state_t motorState_t = standby;
// maximum timer count
#define TIMER_COUNT 5228
//************************ Routines Declaration *****************************************************
void setup()
{
// setup input pins
pinMode(fwdButtonPin, INPUT);
pinMode(revButtonPin, INPUT);
pinMode(fwdLimitSwitchPin, INPUT);
pinMode(revLimitSwitchPin, INPUT);
// setup output pins
pinMode(motorStep, OUTPUT);
pinMode(motorDir, OUTPUT);
pinMode(motorEN, OUTPUT);
digitalWrite(motorStep, LOW); // to be sure that step is not yet high
// motorEN is active LOW !!!!
digitalWrite(motorEN, HIGH); // to be sure that motor is not enable
digitalWrite(motorDir, LOW); // CW
// setup timer1 to Interrupt at a frequency of 382,65Hz
cli(); // stops system interrupts => google.it
TCCR1A = 0; // Set entire register TCCR1A to 0
TCCR1B = 0; // Set entire register TCCR1B to 0
TCNT1 = 0; // initialize counter value with 0
// set counter for Interrupts at 328,5Hz
OCR1A = TIMER_COUNT; // uC clock frequency / [ (Pre- Scaler * Frequency_needed) - 1 ]
// we had to use Timer1 because Timer 0 and 2 can't count more than 255
TCCR1B |= ( 1<<WGM12 ); // turn on Counter Compare Mode (CTC)
//**** set bits for timer Pre- scaler 8 ****
// TCCR1B |= ( 0<<CS10 ); // sets cs11 to 1 => Not needed, because we already have set this register bits to 0
TCCR1B |= ( 1<<CS11 ); // sets CS11 bit of this register to 1 => Check timer1 clock select register table
// TCCR1B |= ( 0<<CS12 ); // sets cs11 to 1 => Not needed, because we already have set this register bits to 0
TIMSK1 = 0;
TIMSK1 |= ( 1<<OCIE1A ); // enables timer compare interrupt = interrupt at compared point
sei();
// open up serial port to monitor steps counted by motor
Serial.begin(9600);
}
// **** Interrupt Handler Function: Interrupt Service Routine **********
ISR (TIMER1_COMPA_vect)
{
// perfom one step of a motor
if(motorState_t == moveForward) // generate Pulses only when motor is active
{
digitalWrite(motorStep, HIGH);
delayMicroseconds(10); // needs at least 2,2us High Time and 2,2us Low Time
digitalWrite(motorStep, LOW);
maxSteps++; // increament Total Steps
}
// perfom one step of a motor
if(motorState_t == moveBackward) // generate Pulses only when motor is active
{
digitalWrite(motorStep, HIGH);
delayMicroseconds(10); // needs at least 2,2us High Time and 2,2us Low Time
digitalWrite(motorStep, LOW);
maxSteps--; // decreament Steps
}
}
//***************new Rev Debouncing Function**************************************
int readRevPin()
{
int reading = digitalRead(revButtonPin);
if(reading != revLastButtonState && millis() - revLastDebounceTime > revDebounceDelay)
{
revLastButtonState = reading;
revLastDebounceTime = millis ();
}
return revLastButtonState;
/* if( (millis() - revLastDebounceTime) > revDebounceDelay ) // 1
{
if(reading != revButtonState) //2
{
revButtonState = reading;
if(revButtonState == HIGH) // 3
{
return HIGH;
} // 3
} // 2
} // 1
revLastButtonState = reading;
return LOW;
*/
}
//***************new Rev Debouncing Function**************************************
int readFwdPin()
{
int reading = digitalRead(fwdButtonPin);
if(reading != fwdLastButtonState && millis() - fwdLastDebounceTime > fwdDebounceDelay)
{
fwdLastButtonState = reading;
fwdLastDebounceTime = millis ();
}
return fwdLastButtonState;
/* if( (millis() - fwdLastDebounceTime) > fwdDebounceDelay ) // 1
{
if(reading != fwdButtonState) //2
{
fwdButtonState = reading;
if(fwdButtonState == HIGH) // 3
{
return HIGH;
} // 3
} // 2
} // 1
fwdLastButtonState = reading;
return LOW;
*/
}
//*************************************************************************************
// ********** Function tracks User Inputs and decides a suitable motor state based on input values *************
void loop()
{
// read all user inputs
fwdButton = readFwdPin();
revButton = readRevPin();
fwdLimitSwitch = digitalRead(fwdLimitSwitchPin);
revLimitSwitch = digitalRead(revLimitSwitchPin);
// State Machine Implementation
if( maxSteps<-1000 || maxSteps>1000 ) // if limit Switches are broken, stop !
{
digitalWrite(motorEN, HIGH); // stop the motor
motorState_t = standby;
digitalWrite(motorStep, LOW);
digitalWrite(motorDir, LOW);
Serial.println(maxSteps);
}
else if(fwdButton == HIGH && revButton == HIGH)
{
digitalWrite(motorEN, HIGH); // stop the motor
motorState_t = standby;
digitalWrite(motorStep, LOW);
digitalWrite(motorDir, LOW);
Serial.println(maxSteps);
}
else if(fwdButton == HIGH && fwdLimitSwitch != HIGH)
{
digitalWrite(motorDir, HIGH); // run the motor forward (CCW)
motorState_t = moveForward;
digitalWrite(motorEN, LOW);
}
else if(revButton == HIGH && revLimitSwitch != HIGH)
{
digitalWrite(motorDir, LOW); // run the motor reverse (CW)
motorState_t = moveBackward;
digitalWrite(motorEN, LOW);
}
else
{
digitalWrite(motorEN, HIGH); // stop the motor in anyother case => e.g. Limit Switch is reached
motorState_t = standby;
digitalWrite(motorStep, LOW);
digitalWrite(motorDir, LOW);
}
}