Shop OBEX P1 Docs P2 Docs Learn Events
Driving an analog gauge with a small stepper directly from the Propeller — Parallax Forums

Driving an analog gauge with a small stepper directly from the Propeller

JohnR2010JohnR2010 Posts: 431
edited 2015-05-23 13:03 in Propeller 1
In yet another project I would like to drive this small stepper motor directly from my Propeller's pins. https://www.tindie.com/products/TheRengineer/analog-gauge-stepper-breakout-board/
I plan on making a custom analog gauge with it. The coils only require 20mA so this is doable. Anyone done this before? I see there are tons of stepper objects but they are all talking to a stepper controller. I want to go direct to the Propeller's pins. I don't think I need all the fancy ramp up and ramp down times a full blown controller would have.

Thought I would check before I created one.

Thanks.

Comments

  • Heater.Heater. Posts: 21,230
    edited 2015-05-20 09:44
    Great, I have thought about making such an "analogue" gauge like that on and off over the years.

    No way would I ever drive a stepper straight from the Prop pins. Being old fashioned I would use a few little transistors to do the current drive. Or perhaps a chip that contains such driver transistors like the old faithful: http://www.ti.com/lit/ds/symlink/uln2803a.pdf
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-05-20 11:15
    Heater. wrote: »
    Great, I have thought about making such an "analogue" gauge like that on and off over the years.

    No way would I ever drive a stepper straight from the Prop pins. Being old fashioned I would use a few little transistors to do the current drive. Or perhaps a chip that contains such driver transistors like the old faithful: http://www.ti.com/lit/ds/symlink/uln2803a.pdf

    Since this thing is so small, only requires 20mA per coil, and I plan on using diodes to protect the pins from inductive kickback, I was thinking I would be okay. Can you technically share your concern? Or is it a best practice / gut feeling that's telling you to not do it?

    This will be another battery powered ZigBee Home Automation project so I'm trying to keep energy usage and PCB real estate to a bare minimum.
  • Heater.Heater. Posts: 21,230
    edited 2015-05-20 11:52
    JohnR201,
    Can you technically share your concern? Or is it a best practice / gut feeling that's telling you to not do it?
    Good question. To be honest, no. I have no idea what stepper motor you want to drive there.

    If I was you I'd be testing if that motor actually moves as expected with a 3.3 volt supply. Checking what current it actually requires. And so on.

    Kick back diodes is of course a good idea.

    In general I like to keep high current circuits away from logic circuits, but if you can convince yourself it's OK then it might be.
  • idbruceidbruce Posts: 6,197
    edited 2015-05-20 11:55
    JohnR2010

    If you want to go the transistor route, try combining a 74HC595 and a ULN2803.

    If I am not mistaken, the code below was originally written by someone besides me, but I believe I modified it for two motor operation.
    CON
      PinHigh       = 1
      PinLow        = 0
    
      Clock         = 0             ' shift clock (74HC595.11)
      Serial_Data   = 1             ' serial data (74HC595.14)
      Latch         = 2             ' output latch (74HC595.12)
        
    VAR
      Long Coil_Index
      Byte Coil_Array[9]
      Byte HC595_Data_Block
      
    
      'The HC595 can sequence two motors.  The first four bits are for the
      'first motor and the remaining four bits are for the second motor.  The
      'Coil_Array variable holds the coil sequences for full steps of both CW and CCW rotation
      'of stepper motors.  Refer to InitTwoMotorHC595 for further definition.
      
    PUB InitTwoMotorHC595
      outa[Latch] := PinLow
      outa[Clock] := PinLow
    
      dira[Clock] ~~
      dira[Serial_Data] ~~
      dira[Latch] ~~
    
      'motor one - coil one energized, motor two - all coils deenergized
      Coil_Array[0] := %00110000
    
      'motor one - coil two energized, motor two - all coils deenergized
      Coil_Array[1] := %01100000
    
      'motor one - coil three energized, motor two - all coils deenergized
      Coil_Array[2] := %11000000
    
      'motor one - coil four energized, motor two - all coils deenergized
      Coil_Array[3] := %10010000
    
      'motor one - all coils deenergized, motor two - coil one energized
      Coil_Array[4] := %00000011
    
      'motor one - all coils deenergized, motor two - coil two energized
      Coil_Array[5] := %00000110
    
      'motor one - all coils deenergized, motor two - coil three energized
      Coil_Array[6] := %00001100
    
      'motor one - all coils deenergized, motor two - coil four energized
      Coil_Array[7] := %00001001
    
      'motor one - all coils deenergized, motor two - all coils deenergized
      Coil_Array[8] := %00000000
      
    
    PUB Rotate_Stepper_One_By_Steps(Steps, Direction, StepDelay, Hold)
      Coil_Index := 4
    
      repeat Steps     
      
        if Direction == 0 'CW
    
          Coil_Index++
    
          if Coil_Index > 7
            Coil_Index := 4      
    
        if Direction == 1 'CCW
          Coil_Index--
    
          if Coil_Index == 3
            Coil_Index := 7
    
        HC595_Data_Block := Coil_Array[Coil_Index]
    
        'Write 8 bits of data.  Data byte is output MSB first.
        HC595_Data_Block ><= 8 'bitwise reverse the lsbs                     
    
          repeat 8 'shift out 8 bits
            outa[Serial_Data] := HC595_Data_Block 'shift out next bit
            outa[Clock] ~ 'clock low then high then to cycle the bit out
            outa[Clock] ~~ 
            waitcnt(StepDelay + cnt)       
    
            HC595_Data_Block >>= 1 'shift next bit
    
        outa[Latch]~ 'cycle low-high-low to cycle the latch
        outa[Latch]~~ 'toggle the Latch pin to latch the output
        outa[Latch]~
    
      if Hold == FALSE
    
        HC595_Data_Block := Coil_Array[8]
      
        'Write 8 bits of data.  Data byte is output MSB first.
        HC595_Data_Block ><= 8 'bitwise reverse the lsbs                     
      
          repeat 8 'shift out 8 bits
            outa[Serial_Data] := HC595_Data_Block 'shift out next bit
            outa[Clock] ~ 'clock low then high then to cycle the bit out
            outa[Clock] ~~ 
          
            HC595_Data_Block >>= 1 'shift next bit
    
        outa[Latch]~ 'cycle low-high-low to cycle the latch
        outa[Latch]~~ 'toggle the Latch pin to latch the output
        outa[Latch]~ 
     
    PUB Rotate_Stepper_Two_By_Steps(Steps, Direction, StepDelay, Hold)
      Coil_Index := 0
    
      repeat Steps     
      
        if Direction == 0 'CW
    
          Coil_Index++
    
          if Coil_Index == 4
            Coil_Index := 0      
    
        if Direction == 1 'CCW
          Coil_Index--
    
          if Coil_Index < 0
            Coil_Index := 3
    
        HC595_Data_Block := Coil_Array[Coil_Index]
    
        'Write 8 bits of data.  Data byte is output MSB first.
        HC595_Data_Block ><= 8 'bitwise reverse the lsbs                     
    
          repeat 8 'shift out 8 bits
            outa[Serial_Data] := HC595_Data_Block 'shift out next bit
            outa[Clock] ~ 'clock low then high then to cycle the bit out
            outa[Clock] ~~ 
            waitcnt(StepDelay + cnt)       
    
            HC595_Data_Block >>= 1 'shift next bit
    
        outa[Latch]~ 'cycle low-high-low to cycle the latch
        outa[Latch]~~ 'toggle the Latch pin to latch the output
        outa[Latch]~     
    
      if Hold == FALSE
    
        HC595_Data_Block := Coil_Array[8]
      
        'Write 8 bits of data.  Data byte is output MSB first.
        HC595_Data_Block ><= 8 'bitwise reverse the lsbs                     
      
          repeat 8 'shift out 8 bits
            outa[Serial_Data] := HC595_Data_Block 'shift out next bit
            outa[Clock] ~ 'clock low then high then to cycle the bit out
            outa[Clock] ~~ 
          
            HC595_Data_Block >>= 1 'shift next bit
    
        outa[Latch]~ 'cycle low-high-low to cycle the latch
        outa[Latch]~~ 'toggle the Latch pin to latch the output
        outa[Latch]~ 
    
  • idbruceidbruce Posts: 6,197
    edited 2015-05-20 11:58
    Or you could just use a ULN2803
  • kwinnkwinn Posts: 8,697
    edited 2015-05-20 12:09
    Using transistors or a ULN2803 between the prop and stepper protects the prop pins. I always use a transistor and diode or ULN/TPIC in my designs when driving an inductive load.
  • redheadedrodredheadedrod Posts: 78
    edited 2015-05-20 23:39
    Hmm, I have a few GM gauge motors... I believe they are stepper motors. All of the GM gauges from 2003-2006 used these. Basically the dash cluster is connected to the CANBUS/GMLAN and pulls the information from there. The Microprocessor on that circuit board then drives each of the motors which have needles on them to display a value.

    The motors have 4 separate connections to them so I am unsure how they are driven but they are very easy to get and very cheap. I would expect them to run off 12 volts but can't be 100% sure.
  • idbruceidbruce Posts: 6,197
    edited 2015-05-21 04:38
    redheadedrod
    The motors have 4 separate connections to them so I am unsure how they are driven but they are very easy to get and very cheap. I would expect them to run off 12 volts but can't be 100% sure.

    Well now, that brings up a very important point. Four wires definitely indicate a bipolar stepper motor, whereas more than four wires indicate a unipolar stepper motor. Bipolar motors are much more difficult to control than unipolar motors, because they require h-bridges, whereas the unipolars just require four transistors and perhaps four current limiting resistors.
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-05-21 04:39
    Heater. wrote: »
    If I was you I'd be testing if that motor actually moves as expected with a 3.3 volt supply. Checking what current it actually requires. And so on.

    Kick back diodes is of course a good idea.

    That's the plan. I have seen discussion where people are driving it directly from the Arduino's 5v pins. I ordered one and will bread board it to my propeller and report back.
  • idbruceidbruce Posts: 6,197
    edited 2015-05-21 04:56
    I missed the link in the first post. I now see the motor is part of a breakout board. Interesting.
  • Heater.Heater. Posts: 21,230
    edited 2015-05-21 05:40
    I could get into this stepper gauge idea. As I said above I had often considered it when looking at my old collection of stepper motors. It never occurred to me that we could get steppers specially made for vehicle guages.

    BUT, that breakout board is far too expensive. Those steppers can be had for a dollar or two from many places, or by a bunch of them here : http://www.wholesalesteppermotors.com/


    I found a data sheet for those steppers here: http://www.jukenswisstech.com/JSTFiles/downloads/2011/06/X27_Flyer_v1.3.pdf

    They suggest driving it with 5 to 9 volts. At 260 ohms coil resistance you will only draw 13ma from a Prop pins 3.3v. Might work.
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-05-21 05:48
    idbruce wrote: »
    I missed the link in the first post. I now see the motor is part of a breakout board. Interesting.
    I did some more digging and found the schematic and art work for the breakout board. Yes it looks like it is a 4 pin stepper I thought it was a 6 pin as that is what the breakout board header has.

    Schematic
    attachment.php?attachmentid=114257

    PCB for above Schematic
    attachment.php?attachmentid=114256
    722 x 550 - 83K
    982 x 494 - 43K
  • Heater.Heater. Posts: 21,230
    edited 2015-05-21 05:53
    Here is the technical spec. for that motor, including details on how to drive it.
    http://wenku.baidu.com/view/ba7fed6e4b73f242336c5f4c.html
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-05-21 05:54
    Heater. wrote: »
    I could get into this stepper gauge idea. As I said above I had often considered it when looking at my old collection of stepper motors. It never occurred to me that we could get steppers specially made for vehicle guages.

    BUT, that breakout board is far too expensive. Those steppers can be had for a dollar or two from many places, or by a bunch of them here : http://www.wholesalesteppermotors.com/


    I found a data sheet for those steppers here: http://www.jukenswisstech.com/JSTFiles/downloads/2011/06/X27_Flyer_v1.3.pdf

    They suggest driving it with 5 to 9 volts. At 260 ohms coil resistance you will only draw 13ma from a Prop pins 3.3v. Might work.

    Thanks Heater I was having trouble finding the spec sheet. Totally agree with you on the breakout board cost. I ordered one anyway so I can use it in my bread board. Heck the guy put his Dip Trace files up on his GitHub site so I don't have a problem giving him some business. If I get it working I will order several of the motors and incorporate it into my existing projects.

    Just sticking this link here so I can find it down the road http://guy.carpenter.id.au/gaugette/blog/page/2/ They have some good test results on this stepper.
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-05-21 06:52
    Heater. wrote: »
    Here is the technical spec. for that motor, including details on how to drive it.
    http://wenku.baidu.com/view/ba7fed6e4b73f242336c5f4c.html

    Another great document! They even say in the above document "The stepper motor has an accurate and repetitive movement and can operate directly with digital signals from a micro-controller or an ASIC." It looks like it has two coils and can be run with single 3.3v power or in micro steep mode by supplying +3.3 and -3.3 to the two coils.

    idBruce any thoughts now, on an existing Spin object? I don't have experience in driving steppers other than helping my son drive one for his senior project. Based on the examples in Heater's last document I should be able to create an object if one doesn't exist. I like the way you use an array to sequence the coils in your above example. I will probable do the same thing, good stuff.
  • AJMAJM Posts: 171
    edited 2015-05-21 08:27
    John,

    I have used the X27.168 stepper motor with a L293D and 5 volts. I tried using 3.3v early on but it didn't provide a very fast response. I'm not at home right now but I can tell you that I used "something" like this in a repeat loop:
    if reverse
      stepindex := (stepindex + 5) // 6
      outa[4..1] := Steps[stepindex]
    else
      stepindex := stepinddex // 6
      outa[4..1] := Steps[stepindex]
    
    DAT
    Steps byte %1001, %0001, %0111, %0110, %1110, %1000 ' step table
    

    where pins 1 through 4 are used for the stepper motor as outputs. I did not ever try to add acceleration.

    This motor has 315 deg of rotation due to internal stops. I think each full step was one degree and each full step had three partial steps for a total of 945 steps (stop to stop) but I could be wrong here.

    I can also say that I wanted something smoother at slow speeds. Not knowing where to being to program microstepping for the propeller, I purchased the AX1201728SG from ebay (available in small quantities) which will microstep this motor and only needs two propeller pins.

    Hope this helps
    AJ
  • Heater.Heater. Posts: 21,230
    edited 2015-05-21 08:41
    JohnR2010,

    Yes, looks like driving these little guys straigt from the Prop pins is probably going to work. With a bit less torque but it should move just not so fast perhaps.

    About that +3.3 and -3.3. All you have to do is connect a coild to two pins on the Prop, call them P1 and P2. Now you can drive the pins like so:
    P1    P2
    ----  ----
    LOW   LOW     All off both at zero.
    LOW   HIGH    Coil sees plus 3.3 volts
    HIGH  LOW     Coil sees minus 3.3 volts
    HIGH  HIGH    All on, pretty pointless.
    

    So there you have your positive and negative drive for the coils and can get the thing moving.

    Next up is micro-stepping. Use 4 PWM outputs and output modulated "levels" rather than the LOW and HIGH above.
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-05-21 10:24
    Heater. wrote: »
    JohnR2010,

    Yes, looks like driving these little guys straigt from the Prop pins is probably going to work. With a bit less torque but it should move just not so fast perhaps.

    About that +3.3 and -3.3. All you have to do is connect a coild to two pins on the Prop, call them P1 and P2. Now you can drive the pins like so:
    P1    P2
    ----  ----
    LOW   LOW     All off both at zero.
    LOW   HIGH    Coil sees plus 3.3 volts
    HIGH  LOW     Coil sees minus 3.3 volts
    HIGH  HIGH    All on, pretty pointless.
    

    So there you have your positive and negative drive for the coils and can get the thing moving.

    Next up is micro-stepping. Use 4 PWM outputs and output modulated "levels" rather than the LOW and HIGH above.

    Thanks. I have done that with several other circuits don't know why it didn't occur to me to use two pins here. I think I was looking at the breakout board schematic and they have VCC and VSS already tied to the diodes... I just wasn't thinking. Thanks.
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-05-21 10:27
    AJM wrote: »
    John,

    I have used the X27.168 stepper motor with a L293D and 5 volts. I tried using 3.3v early on but it didn't provide a very fast response. I'm not at home right now but I can tell you that I used "something" like this in a repeat loop:
    if reverse
      stepindex := (stepindex + 5) // 6
      outa[4..1] := Steps[stepindex]
    else
      stepindex := stepinddex // 6
      outa[4..1] := Steps[stepindex]
    
    DAT
    Steps byte %1001, %0001, %0111, %0110, %1110, %1000 ' step table
    

    where pins 1 through 4 are used for the stepper motor as outputs. I did not ever try to add acceleration.

    This motor has 315 deg of rotation due to internal stops. I think each full step was one degree and each full step had three partial steps for a total of 945 steps (stop to stop) but I could be wrong here.

    I can also say that I wanted something smoother at slow speeds. Not knowing where to being to program microstepping for the propeller, I purchased the AX1201728SG from ebay (available in small quantities) which will microstep this motor and only needs two propeller pins.

    Hope this helps
    AJ

    Thanks AJ that is similar to what Bruce was doing. I think I will be fine with the code. I just wanted to check if there was an object for driving this stepper out there and I don't think there is. I would more than likely rewrite it anyway.
  • redheadedrodredheadedrod Posts: 78
    edited 2015-05-21 17:17
    These stepper motors ARE the same ones that I mentioned above that are in GM gauge clusters. It appears to be the latest revision as well. The older ones would wear out rather quickly and I believe the ones you are listing are the third generation that are supposed to not. I actually just had the dash cluster in my truck rebuilt and these are the motors they used. He offered a lifetime warranty so he obviously believes in their durability. Although for less than $3 a motor I am sure he doesn't worry much.

    Rodney
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-05-21 23:29
    I did something similar years ago with a low-current stepper. Be sure to put a pin for the needle to rest on at the zero point. That way you can always zero the needle at startup, regardless of where it starts, just by driving it backwards the maximum number of steps.

    -Phil
  • idbruceidbruce Posts: 6,197
    edited 2015-05-22 19:50
    JohnR2010

    I do not believe the forementioned code listings will work for you, but I could be wrong. As is well known, I am not an electrical genius :) but I do believe that you will need a dual h-bridge to drive that stepper. AJM mentioned the L293D in an earlier post, but the specs would have to be reviewed. For such a small motor, I believe I would try constructing the h-bridges from several small transistors, but even then you may need a step translator.

    I will get back to you.
  • Heater.Heater. Posts: 21,230
    edited 2015-05-22 23:17
    Four Propeller pins configured as outputs are a dual h-bridge.

    The only question is do they have sufficient current drive capacity for the load.

    In this case it looks like they might.
  • AJMAJM Posts: 171
    edited 2015-05-23 10:42
    I did something similar years ago with a low-current stepper. Be sure to put a pin for the needle to rest on at the zero point. That way you can always zero the needle at startup, regardless of where it starts, just by driving it backwards the maximum number of steps.

    -Phil

    Phil is right but this stepper has internal stops. No additional mechanical pin is needed.

    Can we upload datasheets to the forum or is that frowned upon?

    AJ
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-05-23 10:48
    AJM wrote:
    Can we upload datasheets to the forum or is that frowned upon?
    As long as it's not copyrighted material, there's no problem. A link to an offsite PDF works fine, too.

    -Phil
  • AJMAJM Posts: 171
    edited 2015-05-23 13:03
    I've attached the datasheet for the X27's predecessor (X25) and have used the pulse sequence in it without issue. You can see from the datasheet that the motor will run on 3.3v but it was a bit slow for what I was doing. The latest datasheet can be found here: http://www.jukenswisstech.com/?page_id=109 for registered users.

    The Ardiuno library can be found in github under: https://github.com/clearwater/SwitecX25

    The file I was using (attached) to drive the stepper was a slightly modified version of Johnny Mac's stepper code from an old article of his on stepper motors. All credit goes to him.

    I haven't been on this forum in a long time but remember that it being a good community. If someone is interested in writing a proper object for this I would gladly ship a spare motor and a loose TSOP quad-driver chip.

    Hope this helps,
    AJ
Sign In or Register to comment.