1/6
26/9/2015
that the 5v Vcc is somehow connected to the 12v Vss, but it shouldnt be! Even if the Arduino was
separately powered, if I tried to change the motors speed from 0 to 100%, it would go into an
endless cycle of resetting the Arduino. The solution to this was to run the motor at reduced power.
This actually worked pretty well, however after a while I decided that taking ~40 seconds to raise or
lower the door was not quite to my liking, so I tried to have the motor accelerate to full power, and
then decelerate back to half power before stopping. Now the good thing is that when controlling the
motor with L9958 at half power, it would stop on a dime. However, even though it would happily
switch speeds from 0% to 50%, 50% to 100%, and 50% to 0%, it would halt and become
unresponsive when commanded to switch from 100% to 50%! In this case the SPI interface didnt
provide any useful debugging information. Resetting the device did cure the problem, but that is
undesireable. Also, the L9958 caused the the motor to shake when run at other speeds besides
0%, 50% and 100%, so gradually ramping the speed from 50% up to 100% didnt work well, and
ramping the speed from 100% down to 50% always caused the lockup. Argh! This drove me to try
the L298N.
The L298N simply worked. It worked at a wide variety of speeds, it
smoothly ramped between speeds, and the only problem I had was
that I couldnt find a speed where it would reliably lift and lower the
door, and stop on a dime. To solve this problem, I decided to start at
a slow initial speed (a brushed DC motor draws the maximum
current when starting, so starting it slowly keeps it from initially
drawing too much current), and ramping up to full speed within a
second, and then down to an extremely slow speed, before stopping
and reversing for a brief period (to avoid overrunning where I wanted
it to stop). This raises or lowers the door in less than 10 seconds.
So in summary, the advantages of the L9958 are:
Handles a lot more power: 240 watts vs. 25 watts, or 8.6 amps vs. 3 amps.
Vss was somehow connected to Vcc, which caused multiple mysterious problems, and
ultimately made me abandon using this controller!
Unable to smoothly and reliably drive my motor at arbitrary speeds. There is something odd
about the way the PWM cannot smoothly control the motors speed.
SPI interface can provide debugging information.
SPI interface can configure the maximum current to supply to the motor.
Protection from over voltage, under voltage, etc.
At half-power, the motor stopped on a dime it didnt coast at all.
At half-power, the motor raised and lowered the door at exactly the same speed.
At half-power, the motor had sufficient torque to reliably move the door both up and down.
At full power it ran the motor substantially faster than the L298N could.
Works with both 5v and 3.3v devices
One thing to note: whenever the L9958 detects a problem, like under voltage, it sets an error
flag and wont to drive the motor until the flag is reset!
The advantages of the L298N are:
Can independently control two 2 amp motors, or you can gang the inputs/outputs to drive one
motor which uses up to 3 amps.
http://www.nlogn.com/blog/
2/6
26/9/2015
3/6
26/9/2015
4/6
26/9/2015
0.2A and 1/16 microstepping, which yields 200*16=3200 steps per revolution.
For power, I used an old ATX power supply. By connecting pin #14 (green) to ground (pin #15,
black), it turns on when plugged in. Here is the reference I used:
http://pinouts.ru/Power/atxpower_pinout.shtml
Here is the Python program I used to test it with:
#!/usr/bin/python
#
# Written by Haydn Huntley (huntley@nlogn.com) on 08/16/2013.
# Feel free to use this code any way you want.
# Runs on a Raspberry Pi and drives an HY-DIV268N-5A stepper motor controller.
#
# Note: this program must be run as root in order to use the GPIO calls.
import time
import RPi.GPIO as GPIO
enablePin
= 4 # Note enable is active low!
directionPin = 18
pulsePin
= 23
pulseState = 0
delay = 0.000001 # 1 microsecond
def setup():
GPIO.setmode(GPIO.BCM)
GPIO.setup(enablePin,
GPIO.OUT)
GPIO.setup(directionPin, GPIO.OUT)
GPIO.setup(pulsePin,
GPIO.OUT)
GPIO.output(enablePin, 0)
return
def forward(steps):
global pulseState
print "forward delay=%0.3fms steps=%d" % (delay * 1000, steps)
GPIO.output(directionPin, 1)
for i in range(steps):
pulseState += 1
GPIO.output(pulsePin, pulseState % 2)
time.sleep(delay)
pulseState %= 2
return
def backwards(steps):
global pulseState
print "backwards delay=%0.3fms steps=%d" % (delay * 1000, steps)
GPIO.output(directionPin, 0)
for i in range(steps):
pulseState += 1
GPIO.output(pulsePin, pulseState % 2)
http://www.nlogn.com/blog/
5/6
26/9/2015
time.sleep(delay)
pulseState %= 2
return
def main():
# For the NEMA 14 12v 350mA (#324) stepper motors from AdaFruit:
# http://www.adafruit.com/products/324
# Driving it with 12v using a delay of 1 microsecond.
revolutions = 3
steps = revolutions * 200 * 16
setup()
forward(steps)
time.sleep(0.5)
backwards(steps)
GPIO.cleanup()
return
try:
main()
except:
print "something went wrong!"
GPIO.cleanup()
raise
GPIO.cleanup()
exit(0)
It steps the motor at 1 microsecond per step, which is the fastest I could get it to work with Python's
time.sleep() function for the delays. With 1/16 microstepping and 200 steps/revolution, it does
about 136RPM, which is much better than when I tried this using an LM293D!
For about 20 years I've had a dream of building my own CNC machine for milling wood, plastic,
etc., and I'm finally making it happen! :-)
I hope this proves useful to others. If you have any questions, just email me...
huntley@nLogN.com
http://www.nlogn.com/blog/
Last
Modified:
6/6