Stepper Motors (Part 9)

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

Let’s go back with an easier application. Still for my friend Valerio, the puppets magician, who built this adorable model-phonograph:

It is all wooden made and powered by… a stepper motor, using the electronics which has been described in previous post and showed again here

A switch is attached to the needle’s arm

The code had to match the following expectations:

  • The turn table should slowly start when the needle leaves its rest position
  • The turn table should reach its nominal speed and stay there has long as the needle is above  the record.
  • When the needle goes back to the rest position, then the turn table should slowly slowdown, down to a minimal speed and  then stop.
  • The turn table should re-accelerate if the needle goes to the rest position and back on top of “record”.

Here is the result of our long lasting fab-lab session…

/*
Basic stepper motor driver
Used in the context of Valerio's magic phono
- At rest, the swicth is released the motor is stopped
- When the switch is activated, the motor starts and constantly gains speed up 
  to its nominal speed
- If the siwtch is released, whatever the speed of the motor, the motor is 
  slow down and stops
- If the switch is actived again while the motor has not stopped, the motor is 
  accelerated again up to its nominal speed
  
  Didier Longueville 2017
*/

/* User defined variables */
/* Pins configuration */
const uint8_t _pinDir = 2;
const uint8_t _pinStep = 4;
const uint8_t _pinSwitch = 8;
/* Timing constants */
int16_t _pulsesWidthStop = 7000;
int16_t _pulsesWidthStart = 5000;
int16_t _pulsesWidthMaxSpeed = 2000;
uint8_t _pulsesIncrements = 3;
uint8_t _pulsesDecrements = 3;

/* Application variables */
/* Timing variables */
uint32_t _now;
uint32_t _lastTime;
/* motor state */
const uint8_t STOPPED = 0;
const uint8_t UNSTABLE = 1;
const uint8_t STABLE = 2;
uint8_t _motorState = STOPPED; 
/* switch state */
const uint8_t REST = LOW;
const uint8_t PLAY = HIGH;
uint8_t _switchState; 
/* Step pulses */
int16_t _pulsesInterval;

void setup(void)
{
	/* Configure pins */
	/* Direction */
	pinMode(_pinDir, OUTPUT);
	digitalWrite(_pinDir, LOW);
	/* Step */
	pinMode(_pinStep, OUTPUT);
	digitalWrite(_pinStep, LOW);
	/* Switch */
	pinMode(_pinSwitch, INPUT_PULLUP);
}


void loop(void)
{
	do {
		/* read switch state */
		_switchState = digitalRead(_pinSwitch);
		/* record now */
		_now = micros();
	} while ((_now - _lastTime) < _pulsesInterval);
	_lastTime = _now;
	/* Interpret switch state according to motor state */
	if (_switchState == REST) {
		if (_motorState != STOPPED) {
			/* Slow down motor speed by increasing intervals between pulses */
			_pulsesInterval += _pulsesIncrements;
			/* Force motor state */
			motorState = UNSTABLE;
			if (_pulsesInterval > _pulsesWidthStop) {
				/* motor has reached its minimal speed before stopping */
				_motorState = STOPPED;
			}
		} 
	} else if (_switchState == PLAY) {
		if (_motorState == STOPPED) {
			/* Set default pulse width for motor start */
			_pulsesInterval = _pulsesWidthStart;
			/* Set motor state */
			_motorState = UNSTABLE;
		} else if (_motorState != STABLE) {
			/* Speed up motor by decreasing intervals between pulses */
			_pulsesInterval -= _pulsesDecrements;
			if (_pulsesInterval < _pulsesWidthMaxSpeed) {
				// Motor has reached its stationary speed
				_motorState = STABLE;
				_pulsesInterval = _pulsesWidthMaxSpeed;
			}
		}
	}			
	/* Send pulse */
	if (_motorState != STOPPED)	{
		/* generate positive pulse for at least 1 us */
		digitalWrite(_pinStep, HIGH);
		delayMicroseconds(2);
		digitalWrite(_pinStep, LOW);		
	}
}

For a change, it features standard pin control functions and standard timers for bit-bang control of pulses.

Are you interested in Valerio’s performances ? Here are his contact information:

Mue – Valerio Point
Association Mue Marionnettes
Mairie – 86600 Celle l’Evescault
+33 6 20 39 23 11
contact@muema.org
www.muema.org

 

Leave a Reply

You must be logged in to post a comment.