Need programming help, could include some cash

Tired of pulling my hair out so I might as well ask for someone who knows what the heck they are doing

Arduino Uno
Running a stepper motor driver
4 buttons to run the motor to 4 cardinal positions
1 button to start and stop it running clockwise
1 button to start and stop it running counterclockwise

And a couple other items to be discussed.

Anyone ?

Thanks

4 buttons to run the motor to 4 cardinal positions

How are the cardinal positions defined? Are the motors moving a carriage that trips a limit switch?

Set number of steps... 17750 is one quarter turn. So need to track current position and number of steps to next position defined by which button pushed.

The other half is while it is running clockwise or counter clockwise continuously ( as defined by button 5 and 6 ( Which if hit again would stop the motor )) it needs to track the number of steps ( position ) so if one of the four cardinal points are pushed it will go to that location.

The whole idea of the project is they are presenting a building on a turntable.... the model will be slowly rotating, as the presenter says " on the west side " they will hit the button and the unit will rotate to the west side and stop... the presenter will then say " on the North side" hit a button and it will rotate to the north side etc etc... until at such point the presentation ends and the presenter will hit the CW(6) or CCW(5) buttons and the model will just continuously rotate.

I'm finishing up the hardware and I have limited control of the motor with the arduino but not all the functions I want.

Thanks all

So need to track current position and number of steps to next position defined by which button pushed.

No, you need to track the current position and calculate the number of steps to the next position (which is defined by which switch is pressed).

It doesn't seem all that complicated, what you want to do.

One switch causes a transition to rotate clockwise mode.
One switch causes a transition to rotate counterclockwise mode.
Four switches cause transitions to N, E, W, or S mode.

Those 4 transitions entail something happening (step rapidly until the number of steps matches a defined value (different for each mode)).

Then, nothing happens when you are in those modes.

In the other two modes, you step periodically (the direction depends on the mode) and update when the last step occurred (as in the blink without delay example).

Not complicated for someone who knows what they are doing.... me not so much. That is why I am looking for someone who is willing to write it up and earn some beer money.
I've just gotten too frustrated, and the beer wasn't helping :slight_smile:

Sounds simple enough, but to ask PaulS' question a different way, how do you know what position the model is in when you power up? Do you just assume that it's set up pointing North? Otherwise, how do you know where the cardinal points are? Post the code you have that does the rudimentary motor control.

Sorry, missed Paul's question.

The evil plan was on power up to rotate the model till it hit a switch that would decide it's home.

Not at the computer that has the code on it right now. Basically I was just sending a high low to pin 13 x number of times on button push. Seems simple but I ran in to two problems doing it this way, one I messed up and only could get 1 of 4 buttons to work .... and the second was while the motor is running how to check the switch to see if it has been pushed again.

I also didn't want to post my code out of embarrassment :frowning: Somebody with a fresh start might be quicker then trying to understand my lack of logic.

But an earlier comment got me thinking more about a different approache. I think I was doing a lot of unnecessary coding using ifelse... if button is pushed, send 17000 pulses to motor controller, check next button instead of if button is pushed, add to variable... if variable is above 0 send pulses to motor... clear as mud
The second problem was making the calls to the switch while the motor was running.... and then my head exploded and figured there was someone out there who would say " oh that's easy"
dooh

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
}

Thanks to Wildbill for all his help !!!