It follows on from my previous post, showng the results of some initial testing on the feasability of good motor control using just a Raspberry Pi (i.e. without an arduino or other micro controller).
I very much liked the approach described by David Anderson explaining his approach to basic robot control, so the overall approach I used was to write software that is called from a regular timer function to run the control loop.
Such software can then be run directly from some higher level control loop, or wrapped up to provide a freestanding process controlled through a pipe or web service.
My usual approach to time / function critical software is to start with Python and get to a point where:
- it all works well - great - job done.
- it is hopeless - its never going to work this way - try something completely different or give up.
- its working, but not quite well enough - perhaps a couple of small key parts can be re-implemented -possibly in C.
I have a couple of repositories on github with the code for this, but these are still very much a work in progress.
motor drivers are here.
simple robot control is here. - So far this only does remote control from a web browser.
building from the bottom up
monitoring the rotary encoderOne key part of the problem is capturing the output from the rotary encoder such that it is reliable, accurate and doesn't consume too much resource.
While pulse counting was key, I didn't need to track the phasing as I already know which way the motor is turning, this means all I need to do is detect and count edges.
Pigpio's tally capability - part of the callback function - does exactly this and should provide accurate counting up to at least 50,000Hz pulses which is a good margin above what I expect to need (10,000 rpm, 3 pulses per rev).
My control loop can then read this counter 20 times (or thereabouts) per second and any minor jitter will not result in lost pulses - merely some jitter in the feedback which should correct itself next time around the loop.
low level control - duty cycle and pulse frequencyI found early on that at high frequencies meant that the motor would not move at all until quite high duty cycles were used - and consequently quite fast motor speeds. At very low pulse frequencies, low duty cycles - and low rpm - could be achieved, but the motion even through a fairly big reduction ratio gearbox was noticably jerky.
The motor controller therefore provides low level methods to set both the frequency and duty cycle used to drive the motor.
providing a linear speed controlDC motors usually provide a very non-linear response to increasing pulse width - in fact the curve is pretty much asymptotic. This means that at low %age duty cycles a small increase gives a huge increase in speed, whereas at high %ages there is hardly any change.
Also there is variation between forwards and backwards as well as the differences in response at different frquencies: