Stepper Motors (Part 9)
Part 1, 2, 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