pootle
Posts: 190
Joined: Wed Sep 04, 2013 10:20 am
Location: Staffordshire
Contact: Website

feedback for stepper motor control using pigpio

Wed Jun 15, 2016 12:59 pm

I've got a very simple python bit banging program driving a Pololu A4988 carrier through pigpio, and it works pretty well, but is clearly limited in step speed terms and also liable to glitches when python or linux go off to do better things for short periods.

While it looks fairly straight forward to use either a waveform or even a pigpio script to do the low level work, I need a feedback control method, and both waveforms and scripts will glitch if I have to stop and restart them to change parameters.
(I am planning to use this to guide a telescope mount).

Is there any way I can communicate with a running pigpio script? e.g. set a register or variable value from outside that it can pick up in order to fine tune the step frequency?

If not, I thought perhaps I could read a couple of gpio pins in the pigpio script and set them from the higher level control software? This would be fairly crude, but could well be sufficient.

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

Re: feedback for stepper motor control using pigpio

Wed Jun 15, 2016 1:29 pm

Have a look at pigpio wave chains. Steppers were a main motivation in introducing wave chains.

With those you can give a count of pulses, start the chain, and then just forget about the stepper.

E.g. 100 pulses at 100 Hz, followed by 1000 pulses at 200 Hz, followed by 12345 pulses at 1000 Hz.

A chain is glitch free.

You can also use ordinary waveforms in a glitch free way, but that needs more care, basically you sync the new wave with the old one using wave_send_using_mode with a sync mode. That allows the new waveform to start seamlessly as the old one completes.

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

Re: feedback for stepper motor control using pigpio

Wed Jun 15, 2016 1:33 pm

An example of generating a ramp.

Code: Select all

#!/usr/bin/env python

# ramp_frequency.py
# 2016-01-21
# Public Domain

import time
import pigpio

def generate_ramp(GPIO, ramp):
   l = len(ramp)
   wid=[-1] * l
   pi.set_mode(GPIO, pigpio.OUTPUT)

   # generate a wave per frequency

   for i in range(l):
      f = ramp[i][0]
      micros = int(500000/f)
      wf=[]
      wf.append(pigpio.pulse(1<<GPIO, 0,       micros))
      wf.append(pigpio.pulse(0,       1<<GPIO, micros))
      pi.wave_add_generic(wf)
      wid[i] = pi.wave_create()

   # generate a chain of waves

   chain = []

   for i in range(l):
      steps = ramp[i][1]
      x = steps & 255
      y = steps >> 8
      chain += [255, 0, wid[i], 255, 1, x, y]

   print(chain)

   pi.wave_chain(chain) # Transmit chain.

   while pi.wave_tx_busy(): # While transmitting.
      time.sleep(0.1)

   # delete all waves
   for i in range(l):
      pi.wave_delete(wid[i])

pi = pigpio.pi()

if not pi.connected:
   exit(0)

generate_ramp(4, [[5000, 1000], [10000, 2000], [20000, 20000], [1000,13], [500,3]])

pi.stop()

pootle
Posts: 190
Joined: Wed Sep 04, 2013 10:20 am
Location: Staffordshire
Contact: Website

Re: feedback for stepper motor control using pigpio

Wed Jun 15, 2016 1:48 pm

joan wrote:
E.g. 100 pulses at 100 Hz, followed by 1000 pulses at 200 Hz, followed by 12345 pulses at 1000 Hz.

You can also use ordinary waveforms in a glitch free way, but that needs more care, basically you sync the new wave with the old one using wave_send_using_mode with a sync mode. That allows the new waveform to start seamlessly as the old one completes.
A wave chain doesn't quite hot the spot as I need to do things like:
run forever pulses at 200hz
dynamically increase / decrease the the frequency a few hz.

wave send using mode looks like the answer though - I hadn't spotted that method.

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

Re: feedback for stepper motor control using pigpio

Wed Jun 15, 2016 1:55 pm

Perhaps have a look at viewtopic.php?p=904341#p904341 and the V46 code I posted a few posts in. That may be a better template.

pootle
Posts: 190
Joined: Wed Sep 04, 2013 10:20 am
Location: Staffordshire
Contact: Website

Re: feedback for stepper motor control using pigpio

Wed Jun 15, 2016 10:46 pm

Thanks, it's all starting to make sense now, I have the stepper motor running nicely with simple ramping using wave chaining.

It is running well using 1/2 steps (this gives the fastest absolute speed) at just over 400 full steps per second. I expect to be able to increase this with a higher input voltage, but a need a new power supply first.

I did bump into both the dma control block limit and the loop limit along the way, but some judicious coding and parameter tweaking got round these. I haven't yet run 2 motors in parallel, but I expect to be able to step both together at this speed.

This is all a big improvement over using the Adafruit motor hat which as standard can only manage about 80 steps per second (and those have to be full steps) shared between the 2 motors. Even my hacked version of their code could only manage around 280 full steps per second on a single motor. Much less jitter as well!

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

Re: feedback for stepper motor control using pigpio

Thu Jun 16, 2016 8:09 am

It would be nice if there was a way to chain wave chains, but I'm afraid that doesn't work. Everything boils down to a compromise eventually.

pootle
Posts: 190
Joined: Wed Sep 04, 2013 10:20 am
Location: Staffordshire
Contact: Website

Re: feedback for stepper motor control using pigpio

Thu Jun 16, 2016 10:32 am

How true, I'll use chains for fast slewing and I'll try wave_send / wave_send_using_mode for slow stuff (which is where I need the continual adjustments), the low level guiding is so slow though that even bit banging would probably be OK.

rdagger
Posts: 10
Joined: Tue Oct 07, 2014 7:48 pm
Contact: Website

Re: feedback for stepper motor control using pigpio

Sat May 20, 2017 10:26 pm

joan wrote:An example of generating a ramp.

Code: Select all

#!/usr/bin/env python

# ramp_frequency.py
# 2016-01-21
# Public Domain

import time
import pigpio

def generate_ramp(GPIO, ramp):
   l = len(ramp)
   wid=[-1] * l
   pi.set_mode(GPIO, pigpio.OUTPUT)

   # generate a wave per frequency

   for i in range(l):
      f = ramp[i][0]
      micros = int(500000/f)
      wf=[]
      wf.append(pigpio.pulse(1<<GPIO, 0,       micros))
      wf.append(pigpio.pulse(0,       1<<GPIO, micros))
      pi.wave_add_generic(wf)
      wid[i] = pi.wave_create()

   # generate a chain of waves

   chain = []

   for i in range(l):
      steps = ramp[i][1]
      x = steps & 255
      y = steps >> 8
      chain += [255, 0, wid[i], 255, 1, x, y]

   print(chain)

   pi.wave_chain(chain) # Transmit chain.

   while pi.wave_tx_busy(): # While transmitting.
      time.sleep(0.1)

   # delete all waves
   for i in range(l):
      pi.wave_delete(wid[i])

pi = pigpio.pi()

if not pi.connected:
   exit(0)

generate_ramp(4, [[5000, 1000], [10000, 2000], [20000, 20000], [1000,13], [500,3]])

pi.stop()
I'm testing this ramp code with a stepper driver and it works, but the frequency is consistently 86% low. For example 2000 Hz produces 1720 Hz. This 86% shortfall is reproducible over a range of frequencies and I've verified it with a scope and laser tach. On the other hand, the pwm methods pi.hardware_PWM() and pi.set_PWM_frequency() both generate accurate frequencies. Any insight into the discrepancy in frequency would be greatly appreciated. Thanks for this great library.

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

Re: feedback for stepper motor control using pigpio

Sun May 21, 2017 3:41 am

I'd guess you have a Pi3 and HDMI is involved.

This is a known fault which I have failed to reproduce on my Pi3. I can't see any useful way of debugging this issue until I can reproduce the fault.

Have a look through https://github.com/joan2937/pigpio/issues/80 for some ideas.

rdagger
Posts: 10
Joined: Tue Oct 07, 2014 7:48 pm
Contact: Website

Re: feedback for stepper motor control using pigpio

Sun May 21, 2017 8:26 am

joan wrote:I'd guess you have a Pi3 and HDMI is involved.

This is a known fault which I have failed to reproduce on my Pi3. I can't see any useful way of debugging this issue until I can reproduce the fault.

Have a look through https://github.com/joan2937/pigpio/issues/80 for some ideas.
Actually, it's a headless freshly wiped Pi2 running the latest updated version 8 of Raspbian Jessie. Problem also occurs on older Pi B+ (Jessie 8).

I tried running your pt.sh script and got the following results on the Pi2:
126516 pigpio-log
126492 pigpio-log

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

Re: feedback for stepper motor control using pigpio

Sun May 21, 2017 8:52 am

rdagger wrote:
joan wrote:I'd guess you have a Pi3 and HDMI is involved.

This is a known fault which I have failed to reproduce on my Pi3. I can't see any useful way of debugging this issue until I can reproduce the fault.

Have a look through https://github.com/joan2937/pigpio/issues/80 for some ideas.
Actually, it's a headless freshly wiped Pi2 running the latest updated version 8 of Raspbian Jessie. Problem also occurs on older Pi B+ (Jessie 8).

I tried running your pt.sh script and got the following results on the Pi2:
126516 pigpio-log
126492 pigpio-log
It's interesting that the error is also present on other Pi models.

I am not sure if I have asked but could you try using a different timing clock?

By default pigpio uses PCM as the main timing clock and PWM for the secondary.

Do you get the same or a different error if you start pigpio with the other clock (sudo pigpiod -t 0)?

rdagger
Posts: 10
Joined: Tue Oct 07, 2014 7:48 pm
Contact: Website

Re: feedback for stepper motor control using pigpio

Sun May 21, 2017 10:15 am

joan wrote:
rdagger wrote: I tried running your pt.sh script and got the following results on the Pi2:
126516 pigpio-log
126492 pigpio-log
It's interesting that the error is also present on other Pi models.

I am not sure if I have asked but could you try using a different timing clock?

By default pigpio uses PCM as the main timing clock and PWM for the secondary.

Do you get the same or a different error if you start pigpio with the other clock (sudo pigpiod -t 0)?
That fixed the problem. The RPM on the motor is exactly what I expected and the script shows:
144000 pigpio-log

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

Re: feedback for stepper motor control using pigpio

Sun May 21, 2017 10:30 am

Strange, and very probably very helpful.

Is normal PWM now wrong?

E.g. pigs p 4 128 is meant to give a 800 Hz square wave on GPIO 4.

rdagger
Posts: 10
Joined: Tue Oct 07, 2014 7:48 pm
Contact: Website

Re: feedback for stepper motor control using pigpio

Sun May 21, 2017 4:18 pm

joan wrote:Strange, and very probably very helpful.

Is normal PWM now wrong?

E.g. pigs p 4 128 is meant to give a 800 Hz square wave on GPIO 4.
Yes it is wrong.
I'm getting about 712 Hz with (sudo pigpiod -t 0). Otherwise 800 Hz with (sudo pigpiod).

rdagger
Posts: 10
Joined: Tue Oct 07, 2014 7:48 pm
Contact: Website

Re: feedback for stepper motor control using pigpio

Sun May 21, 2017 11:56 pm

Also with (sudo pigpiod -t 0) I can't use hardware PWM. The method hardware_PWM() raises the error message: 'illegal, PWM in use for main clock'

Return to “Automation, sensing and robotics”

Who is online

Users browsing this forum: No registered users and 12 guests