PLEASE HELP! Trying to program an automatic watch winder

I will start by saying that I have no idea what I am doing. I decided to learn this via a project I found on thingiverse and its not going well. I built the whole thing but i feel like the code (see bellow) that I copied from github is missing some lines. I cant get it to complete a full rotation eventhough i have (i think) set the proper number (64) of steps for my motor.

--Copied directly from GITHUB:


/*
 Stepper Motor Control - speed control

 This program drives a unipolar or bipolar stepper motor.
 The motor is attached to digital pins 4 - 7 of the Arduino.

 The motor will rotate in a clockwise, turn elements off, and pause for 60 seconds;
 then rotate counter clockwise, turn elements off, and pause for 60 seconds.
 The result is 650 rotations per day.

 Created 30 Nov. 2009
 Modified 28 Oct 2010
 by Tom Igoe

 Modified 6 Dec 2020
 by Greg Powell

 */

#include <Stepper.h>

const int stepsPerRevolution = 100;  // change this to fit the number of steps per revolution
// for your motor

#define motor_pin_1 4
#define motor_pin_2 5
#define motor_pin_3 6
#define motor_pin_4 7

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, motor_pin_1, motor_pin_3, motor_pin_2, motor_pin_4);

int stepCount = 0;  // number of steps the motor has taken
int motorSpeed = 100;
int num_steps = 1500;

void setup() 
{
  myStepper.setSpeed(motorSpeed);
}

void loop() 
{
  // Clockwise
  for(int i = 0; i < num_steps; i++)
  {
    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution / 100);
  }
  
  // setup the pins on the microcontroller:
  pinMode(motor_pin_1, INPUT);
  pinMode(motor_pin_2, INPUT);
  pinMode(motor_pin_3, INPUT);
  pinMode(motor_pin_4, INPUT);
  delay(60000);
  pinMode(motor_pin_1, OUTPUT);
  pinMode(motor_pin_2, OUTPUT);
  pinMode(motor_pin_3, OUTPUT);
  pinMode(motor_pin_4, OUTPUT);
    
  // Counter Clockwise
  for(int i = 0; i < num_steps; i++)
  {
    // step 1/100 of a revolution:
    myStepper.step(-stepsPerRevolution / 100);
  }

   // setup the pins on the microcontroller:
  pinMode(motor_pin_1, INPUT);
  pinMode(motor_pin_2, INPUT);
  pinMode(motor_pin_3, INPUT);
  pinMode(motor_pin_4, INPUT);
  delay(60000);
  pinMode(motor_pin_1, OUTPUT);
  pinMode(motor_pin_2, OUTPUT);
  pinMode(motor_pin_3, OUTPUT);
  pinMode(motor_pin_4, OUTPUT);
}

I appreciate any help!

edit your post. put the code between code-tags.

start from basics.

I think I did it.

link

link

picture

1 Like



Does it do the wrong number of steps or no steps at all?

Also, I don't see a 64 in that code.

your sketch compiles successfully. what is the problem?

Always

Always show us a good schematic of your proposed circuit.

try this

const int motorPin1 = 7; // Blue   28BYJ48 pin 1
const int motorPin2 = 6; // Pink   28BYJ48 pin 2
const int motorPin3 = 5; // Yellow  28BYJ48 pin 3
const int motorPin4 = 4; // Orange  28BYJ48 pin 4

const int motorSpeed = 10;
byte count = 0;
const byte lookup[8] = {  B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

void setup() {
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  // Serial.begin(9600);
}

void loop() {
  if (motorSpeed < 0)count--;
  else count++;
  byte temp = PIND & B00001111;
  PIND = temp | (lookup[count % 8]<<4);
  delay(1000 / abs(motorSpeed));
}

or maybe for Atmega32u4 better this:

// Sketch to turn around an unipolar Stepper motor

const byte Pin0 = A2;
const byte Pin1 = A3;
const byte Pin2 = A4;
const byte Pin3 = A5;
const boolean dir = true;
byte Step = 1;

void setup() {
  pinMode(Pin0, OUTPUT);
  pinMode(Pin1, OUTPUT);
  pinMode(Pin2, OUTPUT);
  pinMode(Pin3, OUTPUT);
}

void loop() {
  switch (Step) {
    case 0:
      digitalWrite(Pin0, HIGH);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, HIGH);
      break;
    case 1:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, HIGH);
      break;
    case 2:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, HIGH);
      digitalWrite(Pin3, HIGH);
      break;
    case 3:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, HIGH);
      digitalWrite(Pin3, LOW);
      break;
    case 4:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, HIGH);
      digitalWrite(Pin2, HIGH);
      digitalWrite(Pin3, LOW);
      break;
    case 5:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, HIGH);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, LOW);
      break;
    case 6:
      digitalWrite(Pin0, HIGH);
      digitalWrite(Pin1, HIGH);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, LOW);
      break;
    case 7:
      digitalWrite(Pin0, HIGH);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, LOW);
      break;
  }
  if (dir) Step++;
  else Step--;
  Step %= 8;
  delay(100);
}

i pasted it as it was written so i left the 100 SPR count, but even when i make it the 64 that the motor specs says it only makes it part way through a revolution (3/4) then it stops and holds until it changes direction. then it is just rinse and repeat.

You cannot, must not power motors from the Nano’s 5V power pin !

Use 4 AA batteries or an external 5V power supply for the stepper, connect the GND of this supply to the Arduino GND.

yea I'm running it on its own power.

Show us an updated schematic with all components.

Connect the GND of the external 5V supply to the Arduino GND.

1 Like

yea, it uploads successfully as well. Problem is that I only get 3/4 of a rotation in each direction and a short pause in between.

This is what it should do: ''The motor will rotate in a clockwise, turn elements off, and pause for 60 seconds; then rotate counter clockwise, turn elements off, and pause for 60 seconds. The result is 650 rotations per day."

Here is a youtube video of what it should do: https://www.youtube.com/watch?v=Ih0F2J6PN-E&t=75s

Please post the code that you’re actually using.

This might be at higher level than you are at now, however, try to see if you can follow what is happening.

  • Ask Questions.
//********************************************^************************************************
//  URL
//
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ====================================================================
//  1.00       23/10/07    Running code
//
//
//

#define ENABLED            true
#define DISABLED           false

#define YES                true
#define NO                 false

enum : byte {STILLtiming = 0, EXPIRED, TIMERdisabled};


//********************************************^************************************************
//GPIOs
const byte motorPin1         = 4;      // Blue   - 28BYJ48 pin 1
const byte motorPin2         = 5;      // Pink   - 28BYJ48 pin 2
const byte motorPin3         = 6;      // Yellow - 28BYJ48 pin 3
const byte motorPin4         = 7;      // Orange - 28BYJ48 pin 4
//                                     // Red    - 28BYJ48 pin 5 (VCC)

const byte heartbeatLED      = 13;

//********************************************^************************************************
// This Arduino example demonstrates bidirectional operation of a
// 28BYJ-48, using a ULN2003 interface board to drive the stepper.
// The 28BYJ-48 motor is a 4-phase, 8-beat motor, geared down by
// a factor of 68. One bipolar winding is on motor pins 1 & 3 and
// the other on motor pins 2 & 4. The step angle is 5.625/64 and the
// operating Frequency is 100pps. Current draw is 92mA.
//
const byte clockWise         = 1;
const byte counterClockWise  = 0;

int counter                  = 0;
byte directionFlag           = 1;

int motorSpeed               = 1200;  //variable to set stepper speed

int lookup[8]                = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};


//********************************************^************************************************
//                     millis() / micros()   B a s e d   T I M E R S
//
//TIMER objects are non-blocking
struct makeTIMER
{
#define MILLIS             1
#define MICROS             1000  //we can use this value to divide into a variable to get milliseconds

  //#define ENABLED        true
  //#define DISABLED       false
  //
  //#define YES            true
  //#define NO             false
  //
  //#define STILLtiming    0
  //#define EXPIRED        1
  //#define TIMERdisabled  2
  //
  //enum : byte{STILLtiming = 0, EXPIRED, TIMERdisabled};

  //these are the bare minimum "members" needed when defining a TIMER
  int           TimerType;      //what kind of TIMER is this? MILLIS/MICROS
  unsigned long Time;           //when the TIMER started
  unsigned long Interval;       //delay time which we are looking for
  bool          TimerFlag;      //is the TIMER enabled ? ENABLED/DISABLED
  bool          Restart;        //restart this TIMER   ? YES/NO

  //****************************************
  //condition returned: STILLtiming (0), EXPIRED (1) or TIMERdisabled (2)
  //function to check the state of our TIMER  ex: if(myTimer.checkTIMER() == EXPIRED);
  byte checkTIMER()
  {
    //*********************
    //is this TIMER enabled ?
    if (TimerFlag == ENABLED)
    {
      //*********************
      //has this TIMER expired ?
      if (getTime() - Time >= Interval)
      {
        //*********************
        //should this TIMER restart again?
        if (Restart == YES)
        {
          //restart this TIMER
          Time = getTime();
        }

        //this TIMER has expired
        return EXPIRED;
      }

      //*********************
      else
      {
        //this TIMER has not expired
        return STILLtiming;
      }

    } //END of   if (TimerFlag == ENABLED)

    //*********************
    else
    {
      //this TIMER is disabled
      return TIMERdisabled;
    }

  } //END of   checkTime()

  //****************************************
  //function to enable and restart this TIMER  ex: myTimer.enableRestartTIMER();
  void enableRestartTIMER()
  {
    TimerFlag = ENABLED;

    //restart this TIMER
    Time = getTime();

  } //END of   enableRestartTIMER()

  //****************************************
  //function to disable this TIMER  ex: myTimer.disableTIMER();
  void disableTIMER()
  {
    TimerFlag = DISABLED;

  } //END of    disableTIMER()

  //****************************************
  //function to restart this TIMER  ex: myTimer.restartTIMER();
  void restartTIMER()
  {
    Time = getTime();

  } //END of    restartTIMER()

  //****************************************
  //function to force this TIMER to expire ex: myTimer.expireTimer();
  void expireTimer()
  {
    //force this TIMER to expire
    Time = getTime() - Interval;

  } //END of   expireTimer()

  //****************************************
  //function to set the Interval ofr the TIMER ex: myTimer.setInterval();
  void setInterval(unsigned long value)
  {
    //set the Interval
    Interval = value;

  } //END of   setInterval()

  //****************************************
  //function to return the current time
  unsigned long getTime()
  {
    //return the time             i.e. millis() or micros()
    //*********************
    if (TimerType == MILLIS)
    {
      return millis();
    }

    //*********************
    else
    {
      return micros();
    }

  } //END of   getTime()

}; //END of   struct makeTIMER

//********************************************^************************************************
/*example
  //*********************
  makeTIMER toggleLED =
  {
     MILLIS/MICROS, 0, 500ul, ENABLED/DISABLED, YES/NO  //.TimerType, .Time, .Interval, .TimerFlag, .Restart
  };

  function examples...
  toggleLED.checkTIMER();
  toggleLED.enableTIMER();
  toggleLED.disableTIMER();
  toggleLED.enableRestartTIMER();
  toggleLED.expireTimer();
  toggleLED.setInterval(100ul);         //sets the timeout interval to 100ms
*/

//*********************
makeTIMER heartbeatTIMER =
{
  MILLIS, 0, 500ul, ENABLED, YES         //.TimerType, .Time, .Interval, .TimerFlag, .Restart
};

//*********************
makeTIMER pauseTIMER =
{
  //10 seconds
  MILLIS, 0, 10ul * 1000, ENABLED, YES   //.TimerType, .Time, .Interval, .TimerFlag, .Restart

  //60 seconds
  //MILLIS, 0, 60ul * 1000, ENABLED, YES   //.TimerType, .Time, .Interval, .TimerFlag, .Restart
};

//*********************
makeTIMER stepperTIMER =
{
  MICROS, 0, motorSpeed, ENABLED, YES    //.TimerType, .Time, .Interval, .TimerFlag, .Restart
};


//********************************************^************************************************
void setup()
{
  Serial.begin(115200);

  //declare the motor pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);

  pinMode(heartbeatLED, OUTPUT);

}


//********************************************^************************************************
void loop()
{
  //************************************************              T I M E R  heartbeatLED
  //condition returned: STILLtiming, EXPIRED or TIMERdisabled
  //is it time to toggle the heartbeat LED ?
  if (heartbeatTIMER.checkTIMER() == EXPIRED)
  {
    //toggle the LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //************************************************              T I M E R  pause
  //condition returned: STILLtiming, EXPIRED or TIMERdisabled
  //is it time to toggle motor movement ?
  if (pauseTIMER.checkTIMER() == EXPIRED)
  {
    //******************
    //toggle the stepper TIMER Flag
    if (stepperTIMER.TimerFlag == ENABLED)
    {
      stepperTIMER.TimerFlag = DISABLED;

      //turn OFF current to the stepper windings
      digitalWrite(motorPin1, LOW);
      digitalWrite(motorPin2, LOW);
      digitalWrite(motorPin3, LOW);
      digitalWrite(motorPin4, LOW);
    }

    //******************
    else
    {
      //toggle the direction
      directionFlag = 1 - directionFlag;

      stepperTIMER.TimerFlag = ENABLED;
    }
  }

  //************************************************              T I M E R  stepper
  //condition returned: STILLtiming, EXPIRED or TIMERdisabled
  //is it time to move the motor ?
  if (stepperTIMER.checkTIMER() == EXPIRED)
  {
    //******************
    if (directionFlag == clockWise)
    {
      setOutput(counter);

      counter++;

      //are we finished with the stepper sequence ?
      if (counter > 7)
      {
        counter = 0;
      }
    }

    //******************
    else
    {
      setOutput(counter);

      counter--;

      //are we finished with the stepper sequence ?
      if (counter <= 0)
      {
        counter = 7;
      }
    }
  }

}  //END of   loop()


//********************************************^************************************************
void setOutput(int out)
{
  //set the stepper motor outputs
  digitalWrite(motorPin1, bitRead(lookup[out], 0));
  digitalWrite(motorPin2, bitRead(lookup[out], 1));
  digitalWrite(motorPin3, bitRead(lookup[out], 2));
  digitalWrite(motorPin4, bitRead(lookup[out], 3));

}  //END of   setOutput(int out)