Worked example: Stepper driving second hand of clock

This is the example that we looked at in class last week, in which a stepper motor is driving the second hand of a clock. The stepper drives the second hand forward by (approximately) 6 degrees once a second. I should point out that this example is intended to illustrate the basic method of controlling a stepper with a dsPIC – as it stands, it’s certainly not a very accurate clock!

Ok, here’s the code:

//
// dsPIC30F4011 Stepper clock second hand example
// Written by Ted Burke
// Last updated 10-10-2012
//

#include <xc.h>
#include <libpic30.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

// Function prototypes
void rotate(double degrees);
void step_forward();
void step_back();

// global variables
double rotor_angle;
double step_angle;
long step_time;

int main()
{
	// Make all port D pins outputs
	TRISD = 0;

	// Use initial position as angle origin
	rotor_angle = 0;

	// Stepper properties
	step_time = 300000L; // 10ms
	step_angle = 0.17578125; // 360.0 divided by 2048

	// Now rotate the stepper 6 degrees once every second
	while(1)
	{
		rotate(6.0); // Move forward 6 degrees
		__delay32(19760000); // Delay for rest of second
	}

	return 0;
}

void rotate(double degrees)
{
	// The target angle is the current angle
	// plus the requested angle of rotation.
	double target_angle = rotor_angle + degrees;

	// Now keep stepping in the appropriate
	// direction until the target is reached.
	if (degrees > 0)
	{
		while(rotor_angle < target_angle) step_forward();
	}
	else
	{
		while(rotor_angle > target_angle) step_back();
	}
}

void step_forward()
{
	// Turn off the previous phase and turn
	// on the next one.
	if (LATD == 0b0001) LATD = 0b0010;
	else if (LATD == 0b0010) LATD = 0b0100;
	else if (LATD == 0b0100) LATD = 0b1000;
	else if (LATD == 0b1000) LATD = 0b0001;
	else LATD = 0b0001;

	// Increment the global angle tracker.
	rotor_angle = rotor_angle + step_angle;

	// Delay to allow rotor to move.
	__delay32(step_time);
}

void step_back()
{
	// Turn off the previous phase and turn
	// on the next one.
	if (LATD == 0b0001) LATD = 0b1000;
	else if (LATD == 0b0010) LATD = 0b0001;
	else if (LATD == 0b0100) LATD = 0b0010;
	else if (LATD == 0b1000) LATD = 0b0100;
	else LATD = 0b0001;

	// Decrement the global angle tracker.
	rotor_angle = rotor_angle - step_angle;

	// Delay to allow rotor to move.
	__delay32(step_time);
}

The circuit is as follows:

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

1 Response to Worked example: Stepper driving second hand of clock

  1. Pingback: Stepper motor | Jonathan Baldwin Robotics

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s