Skip to main content
2 of 2
fixed link
Ghanima
  • 15.9k
  • 16
  • 63
  • 120

Actually the pigpio Python module can do this quite easily for a single stepper.

You would use the wave functions in combination with wave chains.

Say you want a ramp of 20ms, 10ms, 5ms, 2ms, 1ms.

You could create separate waves with 10ms on 10 ms off, 5 ms on 5 ms off, ..., 500 µs on, 500 µs off. You could then use a wave chain to send the first wave 100 times, the second 90 times, the third x times, etc.

Here is some code which may help show the sort of thing I mean. It is for a stepper driver which requires pulsing the separate stepper coils. If you are using a pulse/direction stepper driver it would be quite a bit simpler.

#!/usr/bin/env python

import pigpio # http://abyz.me.uk/rpi/pigpio/python.html

class stepper:
   """
   A stepper class to return step pulses.
   """

   def __init__(self, pi, g1, g2, g3, g4, delay=1000):
      """
      """
      self._pi = pi

      self._g1 = g1
      self._g2 = g2
      self._g3 = g3
      self._g4 = g4

      self._delay = delay

      self._all = (1<<g1 | 1<<g2 | 1<<g3 | 1<<g4)

      self._g1_mode = pi.get_mode(g1)
      self._g2_mode = pi.get_mode(g2)
      self._g3_mode = pi.get_mode(g3)
      self._g4_mode = pi.get_mode(g4)

      pi.set_mode(g1, pigpio.OUTPUT)
      pi.set_mode(g2, pigpio.OUTPUT)
      pi.set_mode(g3, pigpio.OUTPUT)
      pi.set_mode(g4, pigpio.OUTPUT)

      self._forward_wid = None
      self._backward_wid = None

      self._forward_wave_init(delay)
      self._backward_wave_init(delay)

   def _step_on(self, pos):
      if   pos == 0: return (1<<self._g4)
      elif pos == 1: return (1<<self._g3 | 1<<self._g4)
      elif pos == 2: return (1<<self._g3)
      elif pos == 3: return (1<<self._g2 | 1<<self._g3)
      elif pos == 4: return (1<<self._g2)
      elif pos == 5: return (1<<self._g1 | 1<<self._g2)
      elif pos == 6: return (1<<self._g1)
      elif pos == 7: return (1<<self._g4 | 1<<self._g1)
      else:          return 0

   def _step_off(self, pos):
      return self._step_on(pos) ^ self._all

   def _forward_wave_init(self, delay):
      if self._forward_wid is not None:
         self._pi.wave_delete(self._forward_wid)
         self._forward_wid = None

      p=[] # pulses to drive stepper 1 cycle forward

      for i in range(8):
         p.append(pigpio.pulse(self._step_on(i), self._step_off(i), delay))

      self._pi.wave_add_generic(p)

      self._forward_wid = self._pi.wave_create()

   def _backward_wave_init(self, delay):
      if self._backward_wid is not None:
         self._pi.wave_delete(self._backward_wid)
         self._backward_wid = None

      p=[] # pulses to drive stepper 1 cycle backward

      for i in range(8):
         p.append(pigpio.pulse(self._step_on(7-i), self._step_off(7-i), delay))

      self._pi.wave_add_generic(p)

      self._backward_wid = self._pi.wave_create()

   def forward_wid(self):
      return self._forward_wid

   def backward_wid(self):
      return self._backward_wid

   def set_delay(self, delay):
      self._forward_wave_init(delay)
      self._backward_wave_init(delay)

   def cancel(self):
      self._pi.wave_delete(self._forward_wid)
      self._pi.wave_delete(self._backward_wid)

      self._pi.set_mode(self._g1, self._g1_mode)
      self._pi.set_mode(self._g2, self._g2_mode)
      self._pi.set_mode(self._g3, self._g3_mode)
      self._pi.set_mode(self._g4, self._g4_mode)

if __name__ == "__main__":

   import time

   pi = pigpio.pi()

   pi.wave_clear()

   delay = 2000

   s1 = stepper(pi,  2,  3,  4, 17, delay)
   s2 = stepper(pi, 14, 15, 18, 23, delay)

   for i in range(5):

      pi.wave_chain([
         255, 0, s1._forward_wid, s2._backward_wid, 255, 1, 0, 2,
         255, 0, s2._forward_wid, s1._backward_wid, 255, 1, 0, 2,
         ])

      while pi.wave_tx_busy():
         time.sleep(0.1)

      delay -= 200

      s1.set_delay(delay)
      s2.set_delay(delay)

   s1.cancel()
   s2.cancel()

   pi.stop()
joan
  • 71.6k
  • 5
  • 74
  • 107