February 12, 2017

E-Mount to Sinar View Camera Adapter

Bayley has a pretty cool Sinar view camera.  I'm not going to go into exactly what a view camera is (go read wikipedia), but the gist is that you add a bunch of degrees of freedom between the camera's sensor (or film) and the lens, allowing you to shift the plane of focus to somewhere not parallel to the plane of the sensor or lens.

Unfortunately, using his CCD camera back requires tethering the camera to a sketchy old PowerBook G4, because that's all the software to read it runs on, and tolerating the painfully slow ~1 Hz live-view updates.  Focusing can literally take an hour if it's a tricky shot.

To improve the view camera experience, I made an adapter for mounting my own Sony α6000 camera body to the view camera's motion stages.  Because the sensor is much smaller and recessed more into the camera body, you don't get the extreme range of motion in tilt and swing like you do with the giant sensor, but it's sufficient to get the view-camera effect.

In retrospect, I should have flipped the side I thinned down to gain some extra travel, but it's not worth redoing at this point.

To get the e-mount mounting features, I bought an E-mount to Canon adapter and did some post-machining to it.  The E-mount side of the adapter was machined in, but the Cannon side screwed on.  I used the removable piece and screws to fasten the adapter to the machined aluminum plate.

The bellows locate in the pocket, and the 8 neodymium magnets around the edge hold the bellows on.

I made a stainless steel thumbscrew to replace the flat-headed setscrew the original camera used to attach the camera body mount.  The taper at the end of the screw draws the mount down onto some locating pins.  The knurling turned out poorly- I'm not sure what I was doing wrong, but one of the two wheels just wouldn't locate properly and made a double-pattern.

Here's the assembly in-action:

And here are some sample pictures:

Harbor Freight brushless chainsaw motor:

Another motor:

One of my small motor controllers.  I did something dumb and blew up the top-left FETs, which is why there's black goo in that corner:

January 27, 2017


A quick build which is incredibly useful.  Somehow I only thought of this now.

Recently Bayley and I were helping the FSAE team do some motor-debugging.  To get a good oscilloscope shot of their motor's phase currents, I borrowed the big LEM closed-loop hall current sensor from the motor dyno buck converter, wired into a ±15V supply and a sense resistor.  It proved to be extremely helpful, and in the process I realized that having a small, high-current, medium-bandwidth current probe would be incredibly handy, especially for motor/motor control stuff.

I threw together a simple current probe made from a smaller LEM current transducer powered by a 9V battery and DC-DC converter IC.  Pass your wire through the LEM, and the current signal goes out the SMA connector in the back straight to your oscilloscope.  The particular sensor I used is good for ±70A at DC to 200 kHz, making it fast enough to see effects like current ripple from switching on electric motors.

Since it's around the Chinese new year, I couldn't order boards from 3PCB in any reasonable amount of time, so I etched a board on the MITERS mini-CNC router to test the design:

I forgot to add the power switch to the Digikey order, so I tested with a piece of wire, and replaced that with a jumper later.

Here are the Digikey bits for populating one, minus the actual current sensor.  I used an LA 55-P (because I scavenged 3 a while ago),  but it could be populated with a variety of transducers depending on your desired measurement range.

I 3d-printed a little box for it:

Here are some random scope shots from an assortment of motors and controllers lying around MITERS.

This one's from someone's electric skateboard, which has an airplane ESC and a small outrunner on it.  Just spinning the wheel, the switching ripple is the same amplitude as the phase currents, thanks to the combination of slow switching frequency and very low inductance motor.  Not a good-looking waveform.

And this funny looking one is a sensorless Jason trying to commutate a small internal permanent magnet motor.

Once 3PCB comes back from holiday I'll get some proper boards made and assemble a couple more.  Here are the Eagle and gerber files if you're interested in building your own.

January 21, 2017

Motor Dyno: The Talk-To-Everything Board, and Other Updates

Here's the Talk-To-Everything Board.  The idea is that I want to be able to plug arbitrary motor controllers into the motor dyno, and control them from the UI on the computer.  There's an FTDI chip for USB to serial, with a digital isolator and isolated DC-DC converter, so that the computer is electrically isolated from whatever motor controller gets plugged in.  My favourite STM32 is broken out to a CAN tranceiver, a small buck for 0-5V output, I2C, RC PWM, TTL Serial,  differential 5V serial (like RS422), and SPI.  Even if I don't end up ever using several of these, it wasn't much extra effort to break out more interfaces, so I figured I might as well.

I moved the 'Everything-Board, plus DAQ and other sensitive analog stuff into an aluminum box with shielded cables in, to fix some more noise problems.  I also now have a big LEM closed-loop hall current sensor for measuring the buck output current.

Here's a look at the current user interface.  Notice all the extra doodads for controlling some of the test-motor interfaces.  I've also added "Profile Mode", which takes in a csv series of speeds, buck voltages, and test-motor commands with time-stamps, and plays them back on the hardware.  This way I can easily automate cycles like efficiency maps.

I'm currently in the progress of designing a new buck converter from scratch, to replace the awful pile of Prius power electronics that is the current buck.  Progress is slow, because I have very little experience with analog electronics and hardware controls (for regulating the buck voltage and current).

January 14, 2017

Return of the Snow Bike: It actually works now

It snowed rather a lot last Saturday, so I was finally motivated to get the snow bike up and running again.  Last episode, the rollers inside the treads kept jamming with snow.  I actually fixed this problem shortly after (almost a year ago now), but never quite got the electrical system to be solid.  The motor/controller was still plagued with position sensor errors, so the vehicle never lasted more than a couple minutes without breaking down.  For now, I've replaced the big 40V, 150A Kelly motor controller with a much more modest 50A sensorless e-bike controller borrowed from Dane.

Here it is wired-up and ready to go:

A closer look at the e-bike controller.  This is a 50V one Dane cracked open and modified the UVLO setpoint on:

Most of the streets were well-plowed by the time this thing got working, but fortunately someone had opened the gates to the courtyard of the Novartis building across the street from MITERS, and there was 6-8 inches of snow everywhere:

We also brought out the Atomic Thing and got to mess around on both vehicles for quite a while, until we got cold/were kicked out.

It's a bit underpowered right now - you end up holding the throttle all the way open the entire time, but still a good time.

December 21, 2016

Some Motor Math and Simulation

While waiting for boards and parts for the motor dyno to show up, I got distracted by doing some motor modeling and simulation. Having a decent motor-modeling platform is an incredibly useful tool, because it lets you quickly test out motor control stuff in simulation, before actually implementing it on hardware and testing it for real.

I wanted a model which could encompass controller effects like sample time,  switching, PWM resolution, A/D resolution, sensor noise, etc, and generally be, well, as general as possible, so that I can use it for arbitrary motors and motor controllers.  I started out doing most of the model in the D-Q frame, but realized to get what I want, it really makes more sense to do all the motor modeling at the phases, and then just use the transformations as necessary for control purposes.  You know, like how motors work in real life.

In working through this problem, I finally sat down and did a bunch of motor modeling math by hand, which I should probably have done a while ago.  Fortunately Bayley  was semi-coincidentally working through similar problems at the same time, to do some optimization for controlling hybrid car motors for a go kart, so we did some back-and forth to sanity check results.

Rather than putting it all here, I spent the time to write up a nice Latex-ed document with my notes, which can be found here.  This is just the analytical portion of the modeling - i.e. coming up with the equations that actually get solved by a computer.

Here you go.

With that part of the problem out of the way, I could actually implement the equations in MATLAB, and do interesting things with them.

Here are a couple useful sanity checks for making sure the motor equations were behaving like I expected them to once implemented, and some other experimentation.

Open Circuit Back-EMF
i.e., spin the motor with the phases floating, and measure the voltage between terminals.  This is the classic test I use all the time to quickly estimate motor parameters of random motors.  The next few plots are for the hybrid car motor being used in the go-kart.

Short-Circuit Torque Vs Speed
i.e. Short the motor terminals together and spin the motor.  For low speeds, the motor looks behaves like a resistor, so expected result is that there's a damping torque proportional to angular velocity.  But as speed increases, the motor behaves like an inductor, not a resistor, so damping should drop off to a constant value.  The crossover speed should be right around the motor's R/L break frequency.  And so it is:

The plot above, and those following are per pole pair.  This is a 3 pole pair motor, so actual torque and speed get multiplied and divided by 3 respectively.

PM and Reluctance Torque vs Current Angle
Looking at the permanent magnet and reluctance components of torque vs the relative angle of the stator current to the rotor, the expected plot looks like this.  Here's the result for the same hybrid motor (this plot's actually a little out-of-date, but it gets the picture across)

Auto-Generate "Optimal" Current Trajectories
Unlike for the classic surface-permanent-magnet "brushless" motor, where you typically want to just put all the current on the Q-axis (neglecting field-weakening), internal permanent magnet motors (like those in most hybrid cars) needed to be treated differently.  I wrote a script which sweeps operating speeds, and for every speed and current setpoint finds the current phase angle which produces the most torque.  A pretty cool thing about this method is that it automatically produces the correct field-weakening trajectory for operation above base speed. No need to think about how to move through current circles and voltage ellipses.

Here's the whole positive-torque, positive-speed operating region, for the same hybrid car motor as above, with a 160V bus and 200 phase amp limit.  This map can be used to generate a lookup table for motor controller - for a given speed and torque command, what are the best d and q axis currents.  In this case I've formatted it as current magnitude and phase, instead of d and q current, because that makes the table a little more convenient to generate.

(currents numbers are larger than 200A peak just because of the way I've defined my dq0 transform, but this corresponds to 200 peak phase amps)  The dark-blue regions are unreachable operating points.

Switching Effects
I added a naive implementation of switching to the model.  I implemented this very much like how a microcontroller does PWM, with an up-down counting counter, like this.  Unfortunately this method means I have to simulate way more timesteps than necessary - 40 kHz pwm with 12 bits of PWM resolution, this method has to simulate 1/(40,000 * 2^12) steps per second, which is way faster than the actual dynamics of the motor behave.  There are cleverer ways around this, but I haven't gotten around to trying anything else yet.

Here's what phase currents look like with 40 kHz switching on one of my MultiStar Elite 5208 motors.  You can see the fuzz on top of the sinusoids from the switching.

Zooming in, you can see the double-peaked ripple caused by the center-aligned PWM:

Here's a link to all the repository of MATLAB code:  Beware, it's kind of an organizational disaster right now, but eventually it'll get organized and commented better, I promise.

Don't worry, I'll be back with more dyno progress and more building physical things soon.

October 31, 2016

Small Motor Controllers, Round 2

A few minor differences on this revision:

  • Switched to lower-ESR through-hole electrolytic capacitors, from surface mount ones
  • Added a MCP 2562 CAN transceiver, to make it more straightforward to build robots with lots of motors on them.
  • Moved all the connectors to the edges of the board, and made them right-angle, for neater wiring
  • 2 oz copper instead of 1 oz.
  • Sweet white solder mask
Stack o' boards from 3pcb:

One assembled (minus electrolytics):

And fully assembled attached, with a motor and absolute + encoder position sensing, programming header, and serial port attached:

And some files:

October 9, 2016

Motor Dyno Updates, First Tests

It's somehow already been over a month since I last posted motor dyno documentation, so a lot has happened in the meantime.

The basic architecture of the system looks like this:

Most importantly, the absorber and the test motor are run off the same power supply.  This means that the power supplies only have to output the losses in the system, not the absolute power of each motor.  And since the buck converter powering the test motor is synchronous, the dyno supports full 4-quadrant operation.

Absorber Testing

Here's the test setup for getting the absorber controller up and running.

There's a lot going on there.  The absorber is driving an even bigger brushless motor, which has a 3-phase rectifier on its phases.  The output of the rectifier is fed into the MITERS Dynaload to dissipate the power.  The torque sensor is fed into a USB DAQ (MCC USB-1608FS) and logged and plotted by some python scripts, and commands are sent to the absorber controller over serial from my laptop.

I had a crisis for a couple days while testing the absorber.  Inexplicably, I measured about 2 times less torque than I expected for a given phase current.  I went through my code and triple checked all the hardware gains.  I physically measured the torque sensor gain with a lever and a weighing scale, and it perfectly matched its datasheet.  Similarly, passing known current through the current sensors produced the expected output.  I checked the absorber's back-emf on the scope for the nth time, and it checked out.  After many hours of confusion, I realized that I was editing  the DAQ-sampling function in an old version of the python file, which was no longer being called.  So my display was showing just the raw torque sensor voltage, and not multiplying it by the 2.26 N-m/Volt scaling I thought I had entered.  Saved.  For a brief while I was worried I had somehow been fundamentally misunderstanding something about motors this whole time.

Buck Converter

The test motor is powered through a synchronous buck converter.  I targeted a power range of 200+ amps at 5-48 volts, to make it useful for powering a wide range of motors and controllers.  A buck converter of that size is a non-trivial design problem, so in the interest of having a working dyno, I skipped all the buck converter designing and hacked something together out of used Prius power electronics.  Everything is extremely oversized and poorly suited for my needs, but the parts are so oversized I at least know I probably won't blow anything up.  Eventually I'll get around to designing a more appropriately sized buck converter out of reasonable components.

The switching is done by a Prius half-bridge module, which in the car is used for the boost converter which steps up the battery voltage to 500-ish volts to run the motors.  Nick Kirkby has an excellent writeup of the boost module, and how to turn it on.  Output voltage is measured with an isolated voltage measurement module Peter found.  DC current is measured with an Allegro current sensor similar to the ones I used on the GigaTroller.  Eventually I plan on replacing this with a LEM (closed loop hall) current sensor to squeeze a bit more resolution out.

A Nucleo receives voltage commands over serial to set the duty cycle of the buck.  Right now the buck operates open-loop - I simply haven't had a chance to close the voltage loop yet.

Debugging the buck:

User Interface

To control they dyno, I've been putting together a UI which runs on a computer to control all the setpoints and log data.  Right now, it looks like this:

The GUI is built with QT in Python, with the library pyqtgraph (which is built on top of PyQt) used for the real-time plotting.  Data to and from the absorber controller are passed over serial, and the DAQ is sampled with a Python wrapper for MCC's Universal Library.

The dyno has a couple different operating modes right now:  Road load and speed control.

Road load simulates a mechanical load - an inertia, and two friction coefficients (coulomb, viscous).  It does so by measuring the torque on the torque sensor, computing what the net torque should be (measured torque - viscous friction - coulomb friction), computing what the acceleration should be (net torque/inertia), and integrating the velocity command with the acceleration.  This loop isn't incredibly responsive, as it only runs at the 100 Hz of the python gui, but it does work pretty well.

Speed mode just sets the velocity command to whatever value you want.

I plan on adding another operating mode which takes a CSV timeseries of operating points (speed setpoint, buck voltage setpoint, test motor command) and following that, to make running tests like  efficiency maps easy.

Here's a video demoing the inertia simulation of the road load mode:

Electrical Noise Problems

The torque sensor alone is an incredibly precise instrument.  There's less than 1/1000th of a Newton-meter of noise on its output, and it (when plugged into a nice 16-bit DAQ) can easily resolve few-1000'ths of a N-m torques.  Which I find incredibly impressive for a sensor which can measure >10 N-m peak.  The story changes, however, when all the power electronics in the dyno get turned on.  Plugging in the inverter for the absorber increased the noise on the torque sensor to a few 100'ths of a newton meter.  And plugging in the buck converter gave me another order-of-magnitude of noise.

Fixing the buck converter noise was relatively straight-forward.  The logic ground of the buck converter was connected to the ground of the DAQ through a USB cable.  Since the serial communication to the buck can be slow, and is only in one direction, I just stuck an opto-isolator on the TX line of the st-link I'm using for serial communication.

Inverter noise was much trickier.  The basic symptom was that, as soon as the inverter had power on the bus, the noise appeared.  The bus voltage was completely isolated from the DAQ and torque sensor, as was the logic voltage.  The noise appeared even when the inverter logic wasn't plugged in over USB.  So there was literally no shared ground or power between the DAQ/torque sensor and the inverter.  Fortunately, Kramnik was around while I was trying to debug, and was able to almost completely solve the problem.  It seems the problem was the motor windings capacitively coupling to the motor housing and metal frame of the dyno.  The solution was to 1:  put a common-mode choke on the windings, right next to the inverter, and 2: add shielding braid around the windings, which is connected at each end to the motor housing and inverter heatsink.  Doing this reduced the noise down to ~4/1000ths of a newton meter, which is definitely  acceptable, although there's a little room for improvement.

Magmotor Testing

To test everything, I've been using some big brushed DC motors, including one of the combat-robotting-favorite Magmotor S28-200.

These plots were generated in the simplest way possible: have the absorber simulate an inertia, and apply a voltage step to the DC motor.  Each line in the 3D scatter plot corresponds to a voltage step.  This only worked up to ~20 volts, at which point the initial power draw tripped the power supplies.  Either current limiting on the buck, or a current-controlled driver between the buck and dc motor would fix this.

Here's the same information, but re-scrambled for power vs speed.  Keep in mind, this is actual mechanical power coming out of the motor, not power going in.

In the long run, the more intelligent way to produce an efficiency map would be to automatically sweep torques and speeds at steady-state, by controlling the absorber speed and the torque command to the test motor.  The data above is a little bit wrong, because the test motor is accelerating - the measured torque is going to be off by the angular acceleration times rotor inertia of the test motor.

Such science.  Next steps include adding more automation to the test process, so I don't have to sit there and babysit the dyno to run tests.