Here's an attempt at it, compiled, but not tested - no stepper motor drivers free. I noticed four or five defects (and fixed them) after I thought it was done, so there are almost certainly more. It'll take some debugging therefore. Speeds and delays in particular will likely need tweaking.
#include <Stepper.h>
const long StepsPerRevolution = 17750L*4L;
const int StepsForMove = 10; // How many steps to move at a time - allows us to read the switch frequently
// Make sure this divides into StepsPerRevolution
const int MoveStepDelay = 5; // ms to allow stepper to move StepsForMove - may need adjusting
//pins
const int HomePin = 12; // Pin that indicates turntable is at the home position
const int NorthPin = 2;
const int EastPin = 3;
const int SouthPin = 4;
const int WestPin = 5;
const int ClockwisePin = 6;
const int WiddershinsPin =7;
//States
#define GO_NORTH 1
#define GO_EAST 2
#define GO_SOUTH 3
#define GO_WEST 4
#define TURN_CLOCKWISE 5
#define TURN_WIDDERSHINS 6
#define STOP 7
//Steps clockwise from home position, assumed to be NORTH
const long NORTH = 0L;
const long EAST = 17750L;
const long SOUTH = 17750L*2L;
const long WEST = 17750L*3L;
Stepper TurntableStepper((int)(StepsPerRevolution/4L), 8,9,10,11); // Full steps won't fit in an int - affects speed setting
long CurrentPosition; // What is the turntable's current orientation
long TargetPosition; // What would we like it to be?
void SetPins()
{
pinMode(HomePin,INPUT);
digitalWrite(HomePin, HIGH);
pinMode(NorthPin,INPUT);
digitalWrite(NorthPin, HIGH);
pinMode(EastPin,INPUT);
digitalWrite(EastPin, HIGH);
pinMode(SouthPin,INPUT);
digitalWrite(SouthPin, HIGH);
pinMode(WestPin,INPUT);
digitalWrite(WestPin, HIGH);
pinMode(ClockwisePin,INPUT);
digitalWrite(ClockwisePin, HIGH);
pinMode(WiddershinsPin,INPUT);
digitalWrite(WiddershinsPin, HIGH);
}
void setup()
{
Serial.begin(9600);
Serial.println("Turntable controller V0.1");
SetPins();
MoveTurntableToHome();
TurntableStepper.setSpeed(10); // set the speed at 10/4 rpm
}
void loop()
{
static int state=STOP;
state=ReadSwitches(state); // Change state if switches are pressed
switch(state)
{
case STOP:
TargetPosition=CurrentPosition; //Don't move
break;
case GO_NORTH:
TargetPosition = NORTH;
break;
case GO_SOUTH:
TargetPosition = SOUTH;
break;
case GO_EAST:
TargetPosition = EAST;
break;
case GO_WEST:
TargetPosition = WEST;
break;
case TURN_CLOCKWISE:
DoMove(StepsForMove,MoveStepDelay); // Called DoMove directly so
TargetPosition=CurrentPosition; // make sure move function doesn't do anything
break;
case TURN_WIDDERSHINS:
DoMove(-StepsForMove,MoveStepDelay); // Ditto
TargetPosition=CurrentPosition;
break;
default:
Serial.print("Invalid state: ");
Serial.println(state);
state = STOP;
break;
}
Move();
}
void MoveTurntableToHome()
{
// Home switch to be wired between HomePin (12) and ground. Internal pullups enabled
// run the motor until we see a low value. Adjust speed to whatever is fastest but doesn't miss the switch
// Step StepsForMove at a time, reduce if needed
TurntableStepper.setSpeed(10); // set the speed at 10/4 rpm
while(digitalRead(HomePin)==HIGH)
{
TurntableStepper.step(StepsForMove);
delay(MoveStepDelay); // adjust as necessary
}
CurrentPosition=NORTH; //Assumes the home switch is at north
}
int ReadSwitches(int state)
{
// Read all switches to determine new state - if you're pressing more than one, last one in the function wins.
if(digitalRead(NorthPin)==LOW)
state = GO_NORTH;
if(digitalRead(SouthPin)==LOW)
state = GO_SOUTH;
if(digitalRead(EastPin)==LOW)
state = GO_EAST;
if(digitalRead(WestPin)==LOW)
state = GO_WEST;
if(digitalRead(ClockwisePin)==LOW)
if(state==TURN_CLOCKWISE)
state = STOP;
else
state=TURN_CLOCKWISE;
if(digitalRead(WiddershinsPin)==LOW)
if(state==TURN_WIDDERSHINS)
state = STOP;
else
state=TURN_WIDDERSHINS;
delay(15); //debounce
return state;
}
void Move()
{
// Move some way towards target. Dumb: may take the long way round.
if(TargetPosition == CurrentPosition)
return; // We're at our destination, nothing to do
if(TargetPosition > CurrentPosition)
DoMove(StepsForMove,MoveStepDelay);
else
DoMove(-StepsForMove,MoveStepDelay);
}
void DoMove(int Steps,int msDelay)
{
TurntableStepper.step(Steps);
CurrentPosition+=Steps;
CurrentPosition %= StepsPerRevolution;
delay(msDelay); // adjust as necessary
}