User avatar
AidanTek
Posts: 10
Joined: Thu Nov 17, 2016 8:55 am
Location: UK
Contact: Website

Stepper Motors and the L293D

Thu Nov 17, 2016 9:35 am

Hi there, first post on this forum - should have got here sooner!!

I just wanted to get some general feedback from anyone with experience, I'm working on an automated telescope project that uses a pair of 4 wire bipolar stepper motors for azimuth and altitude control, the steppers are driven with an L293D module each and supplied from a 5V 6A supply. I have written a python script that should sequentially increment the steppers with full step / two phase logic.

Everything is working pretty well but I have a couple of motor issues I really need to iron out before I progress - I expect they are all related to some extent:
Big problem first - the motors can sometimes become unresponsive and worse, seem to loose all torque as if I sent 0 0 0 0 to the coils - but the only condition I send 0 0 0 0 is during start up and shut down of the script - this problem only happens when the motors being incremented (never when still).

Little problem - the motors don't seem to increment equally, a bit like step, step, jump, step etc

At the moment, both the motors and the L293D modules get very hot, the modules have a chunky (stock) heatsink on them - I am wondering if the L293Ds are actually being pushed a bit to hard and have some kind of thermal shutdown? But if so, why wouldn't they shutdown when the telescope is just being held in a position of strain? Otherwise I guess there is a possibility that wiring is getting moved a bit much and actually loosing connection, but I have been monitoring this quite carefully. I find it hard to believe that the Pi would be the cause of this as even if you hard exit the program with a ctrl-c the GPIO won't automatically go low. Early on I tried reducing the delay between sequence steps but that didn't make a difference - my head is telling me that it is an electronic issue.

I'm wondering (though I have quadruple checked) if my logic is right but my wiring is wrong so the motors aren't being sequenced correctly, which might explain the odd jumps in the movement - the mistake might just be down to me misinterpreting the motor wiring or something similar.

I'm not on my Pi right now so can't drop the code, but it is pretty straight forward, just sequencing the GPIO high and low in sets of four - not a lot to go wrong!!

Next on my try list is to try going to wave drive / one phase sequencing as this should reduce the current demand and step size at the cost of some torque - I think there is a little too much torque anyway so it seems like a good way to go.


yeah I know, just go do it etc etc but any thoughts and insight would be appreciated! :D

sparkyhall
Posts: 168
Joined: Mon Aug 27, 2012 9:14 am

Re: Stepper Motors and the L293D

Thu Nov 17, 2016 12:57 pm

If it is not a sofware issue then it may be an electrical noise issue. Here are a few initial thoughts:

-The L293D is a 5V logic device so if you are driving directly from the Pi GPIO you will have reduced noise immunity.
-Have you kept the L293D 5V logic supply seperate from the motor supply?
-Have you fitted de-coupling caps for both supplies as close as possible to the L293D, you need to keep the lead length as short as possible otherwise the caps will do little.

User avatar
DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Stepper Motors and the L293D

Thu Nov 17, 2016 1:17 pm

What Sparkyhall said takes care of half of what I was going to say.

If you did do the logic shifting up to 5v for the input of the drivers, what method did you use to do so?

Also could you post your step sequense.

And then there is the potential issue of stepping to fast. Steppers will over heat and fail when pushed to fast, and sometimes skip steps.

So what type of steppers are you using and how fast are you attempting to drive them? And are you remembering to accellerate up to speed?
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

User avatar
joan
Posts: 15282
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Stepper Motors and the L293D

Thu Nov 17, 2016 2:58 pm

The L293D is rated at 0.6 amps per channel. I expect it will get hot if you try to pump 6 amps through it.

User avatar
Ferdinand
Posts: 236
Joined: Sun Dec 01, 2013 2:24 pm
Location: Leiderdorp, NL

Re: Stepper Motors and the L293D

Thu Nov 17, 2016 3:52 pm

Hi AidanTek,

Which stepper motor are you using?

Perhaps this link can provide you more info:
viewtopic.php?f=63&t=157745
Success with your project!
Ferdinand

User avatar
AidanTek
Posts: 10
Joined: Thu Nov 17, 2016 8:55 am
Location: UK
Contact: Website

Re: Stepper Motors and the L293D

Fri Nov 18, 2016 1:54 pm

Hi everyone, first of all thanks for all the replies - I would have got back sooner but didn't have auto notifications turned on - fixed now.

I just realised as I was writting this that I'm actually using the L298N in a module form, not the L298D which is a fairly different package even if it does the same thing! Datasheet for the actual chip on the module is here: https://www.sparkfun.com/datasheets/Rob ... Bridge.pdf

Ferdinand: I'm using a pair of these steppers: http://www.zappautomation.co.uk/images/ ... -1684A.jpg

Joan: I'm not forcing 6A through the L293N modules, that's just the current capacity of the supply

DavidS / Sparkyhall: Ok interesting stuff...

First of all, no I haven't decoupled the supply on the modules - I have perhaps wrongly assumed it is already on the PCB, will check this pm.

Yes the logic supply is seperate to the motor supply (your answer might be different as I had the wrong chip in thread description): The L293N modules have a logic supply input which I thought, in part would set the logic threshold (looking over the datasheet, I haven't decoupled here either if it isn't already on the board) - I'm inputting 3.3V to this as I thought the Pi GPIO logic level was set at 3.3V (I'm on RPi 3B by the way).

--- as I write this I am looking over the L298N datasheet and yeah it looks like the logic supply level minimum is 4.5V so that's certainly a problem, but 3.3V logic otherwise looks like it should be sufficient to register a high state.

The rated current of the stepper (1.68A), as far as I can see, is within the max output of the L293N, listed as 2A on page 2 of datasheet - I wouldn't go over that - but I realise that I am driving the steppers with 5V so the rated current has probably gone up as well. - hopefully going to one phase stepping will help here otherwise will need a new supply

I can't remember the specific delay I have put between steps, but I am turning them pretty gradually (I know that comment is meaningless) as we are talking about a telescope that's designed to point at things under magnification :) - however, I didn't know about acceleration so I will read up on that thankyou!!

sorry, away from Pi but I will see if I can post the code this afternoon...

My to do list:

1. Check for decoupling caps on l298n modules, add if necessary
2. Provide a 5V logic level to the l298n, (I'm guessing I can just use the Pi 5V rail?)
3. Adjust code for one-phase stepper movement
4. Add acceleration

User avatar
joan
Posts: 15282
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Stepper Motors and the L293D

Fri Nov 18, 2016 2:28 pm

Plenty of people drive L298N modules from the Pi's 3V3 GPIO (myself included). I've seen no report of someone saying 3V3 doesn't work.

Your steppers are rated at 2.8V. They will overheat if you pump 5V through them. You probably need to find a current limiting stepper driver module rather than the dumb (in this context) L298N.

User avatar
AidanTek
Posts: 10
Joined: Thu Nov 17, 2016 8:55 am
Location: UK
Contact: Website

Re: Stepper Motors and the L293D

Fri Nov 18, 2016 4:06 pm

Thanks Joan - the only thing I would raise there is why don't I see problems occuring if coils are active but not being cycled - when the telescope is on but not being moved? In this case the motor is pulling max current is it not? It seems that failure only occurs when the coils are being cycled

User avatar
joan
Posts: 15282
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Stepper Motors and the L293D

Fri Nov 18, 2016 4:19 pm

AidanTek wrote:Thanks Joan - the only thing I would raise there is why don't I see problems occuring if coils are active but not being cycled - when the telescope is on but not being moved? In this case the motor is pulling max current is it not? It seems that failure only occurs when the coils are being cycled
I don't know, perhaps in the rest states you are only energising one phase whereas when stepping you are energising both.

User avatar
DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Stepper Motors and the L293D

Fri Nov 18, 2016 4:48 pm

AidanTek wrote:Thanks Joan - the only thing I would raise there is why don't I see problems occuring if coils are active but not being cycled - when the telescope is on but not being moved? In this case the motor is pulling max current is it not? It seems that failure only occurs when the coils are being cycled
Well using the higher voltage could deffinitely be contributing. It would be much better to drive them within there rated voltage.

I use 12Volt rated Nema 17 steppers for everything,a and have no issue.

How is the telescope balanced to the pivot points where the steppers are? If the balance is off a little it could be that those particular stepers are a little weak for the job, and you need to add a gear box to gear it down a bit (there are plenty of gearboxes available to print from thingiverse).
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

User avatar
AidanTek
Posts: 10
Joined: Thu Nov 17, 2016 8:55 am
Location: UK
Contact: Website

Re: Stepper Motors and the L293D

Fri Nov 18, 2016 7:54 pm

Thanks DavidS - actually the steppers are being geared up with a belt system at the moment to improve the step resolution - and it's a bit too jumpy at the moment as it is - I think if going to single phase sequencing doesn't improve things to a good extent I'll have to look at replacing them, thanks for the brand suggestion

User avatar
Ferdinand
Posts: 236
Joined: Sun Dec 01, 2013 2:24 pm
Location: Leiderdorp, NL

Re: Stepper Motors and the L293D

Sat Nov 19, 2016 4:33 pm

Hi AidanTek,

The coil current, in this case, is about 1.4 Amp (typical specs of L298).
However, the power dissipation (L298) is about 4.6 W for 1 stepper motor. If both motors are running then the max. dissipation is 9.2 W. The conclusion is that you need to mount the L298 bridge on a well designed heatsink with a thermal resistance of 2 K/W or less. That means that the temperature of the junction is about 5 x 9.2 = 46 °C above room temperature. (3 K/W thermal resistance case-junction bridge and 2 K/W thermal resistance case-air of heatsink => 5 Kelvin per Watt, less is better). See specs datasheet of L298 bridge.

The thermal resistance without heatsink is 35 K/W. That means 321 °C (35 K/W x 9.2 W) above room temperature and bye bye bridge.

The coil current of 1.4 Amp means less torque as specified, see datasheet of stepper motor.
That could mean a poor stepper response.
The total current is 1.4 x 4 = 6.4 A. Your powersupply 5V/6A is too small and could cause a voltage drop. You have to redesign your bridge because Vsat of the transistors are too high.

The best solution is a current controlled stepper motor driver or a H bridge based on power mosfets (low Drain-Source voltage => less power dissipation). Then you can achieve max torque as specified in the datasheet of the stepper motor.
Success with your project!
Ferdinand

User avatar
AidanTek
Posts: 10
Joined: Thu Nov 17, 2016 8:55 am
Location: UK
Contact: Website

Re: Stepper Motors and the L293D

Tue Nov 22, 2016 12:59 pm

Hi everyone, thanks for your support - I modified my code for single phase / wave drive sequencing and this has totally fixed the problem, the motors hardly get luke warm now under constant use and I can even touch the heatsink on the L298N boards (not recommended by the way, I cooked the nerve endings in my fingers a long time ago :lol: )

Sorry it took so long to get round to it, but this is the current instance of my code which includes the Pi Camera, a 4x4 keypad for control and has a basic implementation of the LSM303 accelerometer/magnetometer which doesn't do anything but spit out fairly useless numbers at present - I hope this maybe of some use to someone:

Code: Select all

# AutoTelescope by Aidan Taylor
# Move a telescope with 2 stepper motors
# Includes piCamera, Keypad Controls and LSM303 sensor for positioning
# Please note will run in Python 2 only

# include the following libraries

from picamera import PiCamera
import RPi.GPIO as GPIO
import Adafruit_LSM303
import time

# create Camera instance
camera = PiCamera() #activate the camera
camera.hflip = True

# create LSM303 instance

lsm303 = Adafruit_LSM303.LSM303()

#GPIO main setup
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

#Stepper GPIO
delay = 0.06 #sets how fast the steppers can sequence
steps = 100 #only used to test the steppers now

azCoilA1Pin = 11
azCoilA2Pin = 12
azCoilB1Pin = 13
azCoilB2Pin = 15

alCoilA1Pin = 16
alCoilA2Pin = 18
alCoilB1Pin = 19
alCoilB2Pin = 21

GPIO.setup(azCoilA1Pin, GPIO.OUT)
GPIO.setup(azCoilA2Pin, GPIO.OUT)
GPIO.setup(azCoilB1Pin, GPIO.OUT)
GPIO.setup(azCoilB2Pin, GPIO.OUT)

GPIO.setup(alCoilA1Pin, GPIO.OUT)
GPIO.setup(alCoilA2Pin, GPIO.OUT)
GPIO.setup(alCoilB1Pin, GPIO.OUT)
GPIO.setup(alCoilB2Pin, GPIO.OUT)

stepAzNum = 0
stepAlNum = 0

#Keypad GPIO
rowPins = [31,32,33,35]
colPins = [36,37,38,40]

GPIO.setup(40, GPIO.OUT)
GPIO.setup(38, GPIO.OUT)
GPIO.setup(37, GPIO.OUT)
GPIO.setup(36, GPIO.OUT)
GPIO.setup(31, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(33, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(35, GPIO.IN, pull_up_down=GPIO.PUD_UP)

digits = [["1","2","3","A"],
          ["4","5","6","B"],
          ["7","8","9","C"],
          ["*","0","#","D"]]

keyLatch = [[0,0,0,0],
            [0,0,0,0],
            [0,0,0,0],
            [0,0,0,0]]

key = 0
lastKey = 0
keyMode = 0

#Controls to switch the stepper coils
def setAzStep(w1, w2, w3, w4):
    GPIO.output(azCoilA1Pin, w1)
    GPIO.output(azCoilA2Pin, w2)
    GPIO.output(azCoilB1Pin, w3)
    GPIO.output(azCoilB2Pin, w4)

def setAlStep(w1, w2, w3, w4):
    GPIO.output(alCoilA1Pin, w1)
    GPIO.output(alCoilA2Pin, w2)
    GPIO.output(alCoilB1Pin, w3)
    GPIO.output(alCoilB2Pin, w4)

#Controls to move the steppers backwards and forwards
def azForward():
    global stepAzNum

    stepAzNum = stepAzNum +1

    if(stepAzNum <= 3):
        if(stepAzNum == 1):
            setAzStep(0,0,1,0)
            time.sleep(delay)
        if(stepAzNum == 2):
            setAzStep(0,1,0,0)
            time.sleep(delay)
        if(stepAzNum == 3):
            setAzStep(0,0,0,1)
            time.sleep(delay)
    else:
        stepAzNum = 0
        setAzStep(1,0,0,0)
        time.sleep(delay)
    
def azBackward():
    global stepAzNum

    stepAzNum = stepAzNum -1

    if(stepAzNum >= 0):
        if(stepAzNum == 0):
            setAzStep(1,0,0,0)
            time.sleep(delay)
        if(stepAzNum == 1):
            setAzStep(0,0,1,0)
            time.sleep(delay)
        if(stepAzNum == 2):
            setAzStep(0,1,0,0)
            time.sleep(delay)
    else:
        stepAzNum = 3
        setAzStep(0,0,0,1)
        time.sleep(delay)

def alForward():
    global stepAlNum

    stepAlNum = stepAlNum +1

    if(stepAlNum <= 3):
        if(stepAlNum == 1):
            setAlStep(0,0,1,0)
            time.sleep(delay)
        if(stepAlNum == 2):
            setAlStep(0,1,0,0)
            time.sleep(delay)
        if(stepAlNum == 3):
            setAlStep(0,0,0,1)
            time.sleep(delay)
    else:
        stepAlNum = 0
        setAlStep(1,0,0,0)
        time.sleep(delay)
        
def alBackward():
    global stepAlNum

    stepAlNum = stepAlNum -1

    if(stepAlNum >= 0):
        if(stepAlNum == 0):
            setAlStep(1,0,0,0)
            time.sleep(delay)
        if(stepAlNum == 1):
            setAlStep(0,0,1,0)
            time.sleep(delay)
        if(stepAlNum == 2):
            setAlStep(0,1,0,0)
            time.sleep(delay)
    else:
        stepAlNum = 3
        setAlStep(0,0,0,1)
        time.sleep(delay)

#Used to test the steppers
def stepTest():

    time.sleep(2)

    for i in range(0, steps):
        azForward()

    time.sleep(2)

    for i in range(0, steps):
        azBackward()

    time.sleep(2)

    for i in range(0, steps):
        alForward()

    time.sleep(2)

    for i in range(0, steps):
        alBackward()

    time.sleep(2)

#Scan the KeyPad
def controls():
    
    global keyLatch
    global key
    #For Loop polls columns to check pressed rows
    for col in range(0, 4):
        GPIO.output(colPins[col],0)
        time.sleep(0.001)
        for row in range(0, 4):
            inputState = GPIO.input(rowPins[row])
           # print("col: ",col, "row: ",row)
            if inputState == False and keyLatch[row][col] == False:
                keyLatch[row][col] = True
                key = (digits[row][col])
                #print(digits[row][col]) #uncomment to debug
                time.sleep(0.001)
            elif inputState == True and keyLatch[row][col] == True:
                keyLatch[row][col] = False
                key = "z"
        GPIO.output(colPins[col],1)
        time.sleep(0.001)

def freeMove():
    
    global keyLatch
    global key
    #For Loop polls columns to check pressed rows
    for col in range(0, 4):
        GPIO.output(colPins[col],0)
        time.sleep(0.001)
        for row in range(0, 4):
            inputState = GPIO.input(rowPins[row])
           # print("col: ",col, "row: ",row)
            if inputState == False:
                key = (digits[row][col])
                #print(digits[row][col]) #uncomment to debug
                time.sleep(0.001)
        GPIO.output(colPins[col],1)
        time.sleep(0.001)

# MAIN PROGRAM STARTS HERE
print("Program Starting")

#Unlock the steppers
setAzStep(0,0,0,0)
setAlStep(0,0,0,0)

print("Position telescope and press return/enter to start")
raw_input()
azForward()
alForward()
    
print("Press 2,6,8,4 to move, B and C for camera * to test, D to quit")

while True:

    accel, mag = lsm303.read()
    accel_x, accel_y, accel_z = accel
    mag_x, mag_z, mag_y = mag

    if keyMode == 1:
        camera.annotate_text = 'FREEMOVE Accel X={0}, Accel Y={1}, Accel Z={2}, Mag X={3}, Mag Y={4}, Mag Z={5}'.format(
                    accel_x, accel_y, accel_z, mag_x, mag_y, mag_z)
    else:
        camera.annotate_text = 'Accel X={0}, Accel Y={1}, Accel Z={2}, Mag X={3}, Mag Y={4}, Mag Z={5}'.format(
                    accel_x, accel_y, accel_z, mag_x, mag_y, mag_z)
    
    if keyMode == 0:
        controls()
        if key != lastKey:
            lastKey = key
            #print(key)
            if(key == "2"):
                alBackward()
            elif(key == "8"):
                alForward()
            elif(key == "4"):
                azForward()
            elif(key == "6"):
                azBackward()
            elif(key == "*"):
                stepTest()
            elif(key == "B"):
                camera.stop_preview()
                print("Camera Exit")
            elif(key == "C"):
                camera.start_preview()
                camera.vflip = True
                camera.crop = (0.25, 0.25, 0.5, 0.5) # This line crops the camera but reduces resolution
            elif(key == "#"):
                print('Accel X={0}, Accel Y={1}, Accel Z={2}, Mag X={3}, Mag Y={4}, Mag Z={5}'.format(
                    accel_x, accel_y, accel_z, mag_x, mag_y, mag_z))
            elif(key == "A"):
                print("Free Move")
                time.sleep(1)
                keyMode = 1
                key = "z"
            elif(key == "D"):
                camera.stop_preview()
                print("Now Quitting, support Telescope")
                time.sleep(5)
                setAlStep(0,0,0,0)
                setAzStep(0,0,0,0)
                print("Finished")
                break
    else:
        freeMove()
        if(key == "2"):
            alBackward()
            key = "z"
        elif(key == "8"):
            alForward()
            key = "z"
        elif(key == "4"):
            azForward()
            key = "z"
        elif(key == "6"):
            azBackward()
            key = "z"
        elif(key == "A"):
            print("Ending Free Move")
            time.sleep(1)
            keyMode = 0


Return to “General discussion”