10/28/2016 at 10:37 •
Since the core purpose of this system is to control a number of motors, deciding how that should be done is key.
There are a variety of ways to control motors out there, but they essentially boil down to the following levels:
- Build your own H-bridge with MOSFETs and feed it PWM control signals (being careful not to cause shorts!)
- Off the shelf motor driver IC, which implements the H-bridge and associated protection circuitry - eliminating some components in your circuit, but still retaining the timing requirements from the processor.
- Off the shelf motor controller IC, which takes data inputs (SPI, I2C, parallel buses, (RS232, CAN, Ethernet, RS485) - offloading even more logic and timing requirements from your processor, and all motor driving circuitry from your circuit.
To avoid needing to reinvent the wheel, so to speak, (which we did not have time for), we went for the last option. That gives us the ability to concentrate our coding effort on the desired outputs (i.e. motor commands) without needing to be concerned with the practicalities of driving a motor.
Choosing a motor controller module that has the ability to be controlled using a protocol which can be extended over a long distance means we can put the driver really close to the motor itself - meaning the high frequency, high current PWM of the drive signals only needs to go the few cm between the controller and the motor, rather than between the central controller and the motor, which alleviates many electrical noise concerns. Of course, the power is still coming from the central location, and the PWM control of the voltage to the motor will cause current draw to also follow - for this reason a large capacitor is placed near to the motor controller such that sudden changes in current draw will be fed by the capacitor discharging first, and the long wire back to the power source will only see the current required to recharge the capacitor, keeping the voltage of the power supply reasonably consistent.
There are many motor controller modules, but the most hacker friendly appeared to be the Pololu Simple Motor Controllers - which have a USB interface for configuration, a TTL serial interface and GPIO. The serial interface is well documented, can be either ASCII based, or straight binary commands. They support a decent speed resolution, will brake and coast, and can have an acceleration profile programmed into them to prevent peaks in torque when the speed is changed suddenly - which with a heavy load could cause the axel or other part of the drive chain to break in operation.
The other neat thing about these controllers is that their serial ports can be daisy chained. The Rx can be bussed, and each command you send identifies which motor you wish to address and the ones it's not addressed to ignores the message. For feedback from the motor, each controller has a Tx out and a Tx in - the Tx in can be connected to the Tx out of the previous controller - allowing each controller to pass back messages from any of the controllers before it in the chain, eventually making it's way back to the source.
The one problem is that the serial interface is TTL - which whilst simple to interface with being baseband 0-5V logic, it doesn't have a particularly great range and is susceptible to interference. If we want the controllers to be several meters away, then we need something a bit more robust, like RS232.
The interesting thing about RS232 is that the limitation for how far you can drive it is not defined by distance, but by cable capacitance - with a maximum capacitance connected to a single port not being more than 2500pF. Everyone's favourite communications cable, CAT5e - cheap and delicious - specifies a maximum capacitance of 52pF/m in each conductor, which means in theory you can get serial data to travel over 43m of a CAT5e conductor. Which for my application is more than sufficient. And the reality is by reducing the baud rate you can increase that range further - since the effect of the capacitance is to round off the corners of the pulses - if you make the pulses longer, the curved edges matter less. Additionally, if you're able to isolate both ends from the equipment (with transformers/optoisolators) then you can pretty much eliminate any issues due to ground loops between devices. This is also has the added benefit of decoupling any local ground issues and interference due to the spikey motor current draw. If I needed much longer distance than that, then we're looking at a differential signal like RS422. But that's significantly more difficult, and not really necessary for my application.
With that in mind, I needed to make some daughter boards with an isolated version of a MAX3232 that both fed the Pololu SMC's, as well as passing on the signal from the previous SMC in the chain. Seeing as my transciever has two ports, I may as well regenerate the signal coming from the controller as well. Seeing as I've got a bunch of unused conductors, I may as well supply the boards with 5V too - and a virtual ground connected to the controller's isolated port ground. I need to pass the ERR and RST signals back too, so that's another pair. One wire left so... lets stick a 1wire port on it as well so we can do temperature sensing too. Why not!
The connectors are RJ45, since I'd rather not be doing too much soldering when wiring this stuff up. Though this turned out to be a bit irritating as the connectors were board mounted, and meant I was forced to make a hole in the enclosure rather than bolting it to the enclosure. I would have used Ethercon passthroughs, but the space I had for the boxes wasn't big enough to fit such things. Maybe if I did this again I'd have used a D connector instead, or maybe even screw terminals. Or a single connector with two tails? It depends on how small the enclosure needed to be.
The enclosure had two glands on it, to allow a flying lead for 12V power in to the SMC and from the SMC to the motor to be hooked up, with XT60 connectors of the appropriate gender to prevent inadvertantly plugging the supply into the motor output. The wire for this was thick, 2.5mm^2 Tri rated cable from RS as the peak current was going to be fairly high. In black and ... pink. So that you don't get it confused with... err, something... no, mainly because I ordered the wrong colour from RS.
This setup worked well, with controllers working at a distance of 10's of meters from the master control.
10/26/2016 at 22:02 •
Having decided that an embedded system was the way to go, we needed to decide what the brains of it was going to be. Since the turnaround time was short, a lot of it was informed by things I was familiar with that I could get up and running with, without spending too long getting a tool chain set up, or learning a new architecture. Also, something with a good ecosystem of libraries was a must to speed development up.
You know where this is going.
The Arduino environment made complete sense. It's a tool chain in a box which needs no extra setting up. So that narrows it down to boards that use that environment. That's still quite a few!
I could go for a chip on it's own, or I could go for a module. The latter means I'm not limited to things I can reasonably solder myself (at least, without excessive amounts of cursing - DAMN YOU BGAs!).
If I'm going for a module, it'd be best to be a small one to save board space (which == £££).
The Arduino Mini/micros seemed like a good (physical) fit, however, they're not exactly high powered. Working out how much SRAM I'm likely to need to hold a reasonably complicated schedule and list of sequences, I'd easily fill the 2K available on the ATmega328 or 2.5k on the ATmega32U4. Also at 16MHz, operating several serial interfaces at once, as well as processing a schedule was going to be a bit taxing.
I could have gone down the route of the xmega based boards like the Arduino MEGAs - but they're not small by any means, and if anything they're over powered, and quite pricey.
One of the things that I obviously was going to need was an RTC - didn't need to keep time really well - but can't loose more than a minute or two over a month. Of course, I could put one on the board myself, but the less I have to integrate the better.
And then I remembered the Teensy 3.1, based on the 32-bit NXP MK20DX256VLH7. It's about $20, has 64k of RAM (plenty), has 3 hardware serial ports, a built in RTC, and with Teensyduino can be programmed using the Arduino environment, and is compatible with many Arduino libraries (providing no AVR specific assembly is used inside them), or versions of them have been ported to the Teensy. Also, it's got a USB controller built into it, which'll be handy for diagnostics. Also it runs at 72 MHz! Seventy. Two. That's way more power than we'll ever need, so we can do loads of things at once without worries we'll overload ourselves.
That'll do nicely.
10/24/2016 at 19:52 •
The problem this project was aiming to solve was this: how can you automate the control of a number of motors (around 12), DMX lighting and various other devices, based on a schedule that runs over the course of several weeks without any human intervention?
The particular application of this system was for an large installation, which housed a number of motors which drove some elements of a sculpture around at a low speed. The installation also had lighting, controlled via DMX, which needed to change based on the motions of the sculpture. There were to be a number of sequences of motor runs, to change the speeds in a pattern which was interesting for viewers, based on a schedule.
The system needed to be reliable, and run for days and weeks at a time without any attention. It should also automatically turn off overnight.
A number of solutions were considered, with varying degrees of complexity. They boiled down to the following:
PC Based System
A PC running an OS with some custom code could be used to send commands to motors, and with a DMX interface could also control lighting.
- Hardware is mostly COTS (Common Off the Shelf) products
- Industrial enclosures already exist for PCs (ATX rackmount cases)
- Several possibilities for maintenance using common system admin software
- Power distribution would be required as a separate element
- Integrating isolated DMX and GPIO would require interfacing with pre-existing hardware may take some time.
- Reliability limited by OS, not totally within my control.
An embedded system could be used to perform the same tasks - including custom designed I/O which meets our exact specs.
- Only running the code we write - we have (almost) complete control.
- Interfaces can be designed to spec, not relying on a COTS interface with USB/serial.
- Power distribution can be integrated and monitored as part of the same system.
- Requires a fair amount of PCB design/manufacture
- More tricky to debug (needs a serial connection to a laptop, for example)
Based on the fact that our needs were fairly specific, it was decided that a better approach would be to design the system from an embedded platform - which we know isn't going to decide to reboot itself in the middle of the night for to updates or something (*cough*windows*cough*), and if it does, then it's our fault :). Also it would alleviate the pain of writing software to interface with a variety of interfaces relying on the OS's selection of drivers, and generally not have to worry about the myriad of other things that go on in a modern PC apart from running our code.
I'll go into more details about the choice of processor in a future log, but this seemed like the best way forward. Or at least a way forward!
10/24/2016 at 17:03 •
This was a project for a job I did last year some time, and there's no reason why I shouldn't publish it for others to learn from - it's just sitting around on my hard drive gathering dust otherwise!
I will, however, need to spruce things up and re-document the project - and explain why I've made the design choices I did, and whether there was anything to be learnt from those choices or that I'd have done differently if I were to take it on today.