Stepper Motors (Part 3)

Part 12, 3, 4, 5, 6, 7, 8, 9

A4988 module

Let’s go into the details of this module through the understanding of its pinout:

pololu_3

The suggested basic wiring is as follows:

pololu_4

  • ~ENABLE: GND
  • MS1, 2 & 3: GND
  • ~RESET connected to ~SLEEP
  • STEP: step pulse
  • DIR: rotational direction
  • GND: same GND for VDD and VMOT
  • VDD: 3.3V to 5V
  • 1A,1B: winding 1
  • 2A, 2B: winding 2
  • VMOT: as per stepper motor specifications

Note: the ~ spanish tilde is used for negating a bit value in C ((~0 | 1) == 1); this sign is also used in Ki

Step pulses must simply comply with the required pulse width as per the A4988 datasheet.

pololu_5

The nice thing about this driver is that you do not have to care about the duty cycle of the step pulse signal. On the other hand, care shall be taken about choosing the appropriate frequency so that it fits the stepper motor requirements (Check the “Torque” paragraph in Part 1). There is no danger at all at using innapropriate frequency. If the frequency is too high, the rotor will erratically move or not move at all. If the frequency is too low, the rotor will move in rough steps and generate a growling sound.

Next is a code sample for running the A4988 module in a basic way:

uint8_t _stepPinMask = (1 << PINB5);
uint8_t _dirPinMask = (1 << PINB4);
uint16_t _pulsesPerRound = 48; /* As per the stepper motor specifications */

void setup(void)
{ 
	/* Initialize ports */
	DDRB |= _stepPinMask;
	DDRB |= _dirPinMask;
}


void loop(void)
{
	/* Rotate motor back and forth */
	Rotate(_pulsesPerRound << 1, 1, 5000);
	Rotate(_pulsesPerRound << 1, 0, 5000);
}


void Rotate(uint16_t steps, uint8_t direction, uint16_t pulseWidth) 
{
	if (direction) {
		PORTB |= _dirPinMask;	
	} else {
		PORTB &= ~_dirPinMask;
	}
	for (uint16_t i = 0; i < steps; i++) {
		/* Generate a step pulse. The pulse width is expressed in microseconds  
		The on state is twice the minimum requirement and it is insignificant 
		versus the off time which is mainly responsible for the frequency 
		setting */
		PORTB |= _stepPinMask;
		delayMicroseconds(2);
		PORTB &=  ~_stepPinMask;
		/* Use the most appropriate delay function */
		if (pulseWidth < 16000) {
			delayMicroseconds(pulseWidth);
		} else {
			delay(pulseWidth / 1000);
		}
	}
}

 

Next post on same subject

Leave a Reply

You must be logged in to post a comment.