LudoMTR (Part 3)

Part 123456

Code

The code for the driver is pretty simple. The set up section contains the instructions for setting PORTB and PORTD selected pins as output pins.

  /* Set ports directions */
  DDRD |= (maskD);
  DDRB |= (maskB);

Some place in the skecth we’ll find a function which will be responsible for switching PRTB and PORTD pins levels

void setCurrent(char value)
/* Set current flow between PORTB and PORTD pins */
{
  switch(value) {
	case CUR_REVERSE:
		PORTD |= (maskD);		
		break;
	case CUR_NONE:
		PORTB &= ~(maskB);	
		PORTD &= ~(maskD);	
		break;
	case CUR_FORWARD:
		PORTB |= (maskB);			
		break;
	}
};

The loop function will start with this line

pulseInterval = map(analogRead(0),0, 1023, 150000, 50000);

The position of the potentiometer is read and translated in a cycle time. This is the duration of half a revolution of the rotor. This cycle time ranges from 50 to 150 ms.

Next is a wait for next cycle start (based on previous cycle)

	/* Set next cycle time */
	long nextCycleTime = (lastCycleTime + cycleInterval);
	/* Wait next pulse */
	long now;
	do
		now = micros();
	while(now < nextCycleTime);

At pulse start, current is supplied to the flipping coil and preset in opposite direction for next pulse

	/* Set current flow */
	setCurrent(currentDirection);
	/* Flip current direction for next pulse */
	currentDirection *= -1;

The current flows as long as the pulse time has not elapsed. The pulse width is a fraction of the cycle duration

	/* Record last pulse time */
	lastCycleTime = now;
	/* Set pulse stop time */
	long pulseStopTime = (lastCycleTime + long(cycleInterval * 0.6));
	/* Wait until pulse duration has elapsed */
	do
		now = micros();
	while(now < pulseStopTime);

Finally, the current flow is stopped until the next cycle

	/* Cancel current */
	setCurrent(CUR_NONE);

And so on, and so on…

Add these lines in the header of the sketch and try it!

#define maskD 0xFC /* Port D digital pins 2 to 7 */
#define maskB 0x3F /* Port B  digital pins 8 to 13 */

#define CUR_REVERSE -1 /* Current flows from port D to port B */
#define CUR_NONE 0
#define CUR_FORWARD 1 /* Current flows from port B to port D */

long lastCycleTime = micros();
long cycleInterval = 50000; 
char currentDirection = CUR_FORWARD; /* Default current direction */

Recommendations for starting the motor:
– Set the potentiometer to half way
– Gently spin the rotor. Be patient, in the absence of sensor for the rotor position, the synchronisization of the rotor with pulses requires a little luck!

Next post on same subject

3 Comments

  1. mike31416 says:

    Are there any issues with back EMF that could harm the I/O pins?

    • Didier says:

      The magnetic field is pretty weak and thus will not permit large back EMF to build up across the coil. The major risks are related to the “high” current sunk from the Arduino board…

Leave a Reply

You must be logged in to post a comment.