Corn-Troller: Tassel

Look­ing around at the hoppin’ elec­tric vehi­cle scene happen­ing at certain insti­tu­tions, I real­ized that pretty soon I’d be play­ing catch-up to more than just Jamo when it comes stuff-strut­ting unless I started build­ing some­thing ridicu­lous, and quickly too.

So in typi­cal son-of-an-accoun­tant behav­ior, instead of build­ing my own scooter, I decided to go the manic whacky sneaky route and build some­thing to sell to the scooter builders. So now I’m announc­ing the corni­est, trol­liest brush­less motor controller of them all: Corn­troller.

Corn­troller is a result of me completely ripping off Shane Colton and Dan Strother to build an extremely feature-bloated brush­less motor controller. All of the follow­ing will be devoted to driving just a single motor:

  • Modu­lar corn-inspired design, stack­ing a logic board (called Tassel) onto a power board (called HexHusk)
  • 10V–45V oper­a­tion with two switch­ing regu­la­tors for logic power (LT3991-5, LT3970-3.3)
  • At least 40A of current capac­ity through IXYS GWM160-0055X1 3-phase MOSFET power modules
  • Way too much process­ing power from a 100-pin STM32F103VG, one of the top parts in the STM32 F1 series of ARM Cortex M3 micro­con­trollers
  • Full volt­age and current sens­ing on every­thing (motor phases and power bus), so I can imple­ment vector control or sensor­less­ness
  • Compact three-phase N-chan­nel FET driving through dedi­cated gate driver IC (A4935)
  • Motor hall sensor inputs to micro­con­troller capture timer
  • microSD card slot inter­faced through SDIO (not MMC over SPI) for data­log­ging
  • Full speed USB inter­face… just because
  • Two 7-segment LED displays… also just because
  • Full 9-degrees-of-measure IMU (accelerom­e­ter, gyro­scope, magne­tome­ter) with the some of the best dumb1 MEMS sensors (BMA180, IMU3000, HMC5883L) avail­able… just $@#%ing because

I’m only half-joking about that last one; I designed Tassel, the logic board on Corn­troller, as a replace­ment for my (yet to be writ­ten up) Maizure Cortex M3/MEMS sensors board. Maizure has served as my general dev board, and its succes­sor is so full featured and has such overspec’d compo­nents because of that. But, I can choose to not popu­late compo­nents for unused features. So when Tassel is used as a part of Corn­troller, it will not have its 3-axis MEMS sensor foot­prints popu­lated2).

By the way, I started naming my projects after corn. Just—you guessed it—because.

Tassel was laid out with only surface mount compo­nents (prefer­ring 06033 chip resis­tors and capac­i­tors), all on the top side. Layout was actu­ally fairly straight­for­ward, since a lot of the work required just rout­ing directly from STM32 pins to head­ers (which I could reas­sign anyways).

The hard part was figur­ing out which periph­er­als I could route out of the STM32. The orig­i­nal plan was to use a 48-pin device; this grew to 64-pin and then 100-pin as I real­ized that all the “good” periph­er­als I wanted in the STM32 were actu­ally shar­ing the same pins.

For exam­ple, USART1 and TIM1 (with its useful three-phase comple­mented PWM with soft­ware dead­time inser­tion) shared the same pins. I had to spend a solid week assign­ing pins to their func­tion­al­i­ties, restart­ing all over each time I had to up the pin count and move to a bigger device. Through all of this I also had to make sure to fan every­thing out prop­erly so wires route cleanly from µC pin to head­ers and devices.

That’s really how I ended up with 7-segment displays; switch­ing to 100 pins meant I had a lot of I/O pins left over that I didn’t want to go to waste. With the deci­mal point, each King­bright 0.2″ display fills up 8 pins: perfect for half a GPIO port, and thus nice to control in soft­ware.

Plus, 7-segment displays and resis­tor arrays are way easier to solder than indi­vid­ual 0805 LEDs and 0603 resis­tors.

So I ended up with a long list of nets to route well before even start­ing a schematic in EAGLE (see appen­dix)!

Since Maizure had a bit of prob­lems with noise and stabil­ity, I made Tassel a four-layer design. This means extra layers of copper on which to route signals, but more impor­tantly to serve as ground planes for surface signals. This isn’t neces­sar­ily needed, but it certainly lends me extra noise immu­nity I figure I’d want on such a densely routed board.

A four-layer design meant I had way fewer choices in PCB fabri­ca­tion: I went with Dork­bot Portland’s group PCB order, but also consid­ered 4PCB’s/Advanced Circuits’s $66 each service and BatchPCB’s 4-layer group order. For me, Dork­bot­PDX just turned out to be the best bang for the buck.

Why do I just have photos of unpop­u­lated boards? Because (a) they’re pretty and (b) I sent these out before I finished design­ing the power stage, in an attempt to pipeline the proto­typ­ing process. I wanted to send these out, complete HexHusk, order parts for both from Digi-Key, and have the compo­nents before Tassel’s boards arrived. That didn’t happen… the Digi-Key order is just now in the mail. Guess I failed at pipelin­ing.

Design files for every­thing and a HexHusk post are coming. I promise.

Appen­dix
Partial pin assign­ments:

Outputs
=======
# Q1
15 PC0 V_P
16 PC1 V_A
17 PC2 V_B
18 PC3 V_C
23 PA0 I_A
24 PA1 I_B
25 PA2 I_P

# Q2
26 PA3 AN_0
29 PA4 SPI1_NSS
30 PA5 SPI1_SCK
31 PA6 SPI1_MISO
32 PA7 SPI1_MOSI
- V+
- V-

- 3.3V
39 PE8 PWM1~ # remap
40 PE9 PWM1 # remap
41 PE10 PWM2~ # remap
42 PE11 PWM2 # remap
43 PE12 PWM3~ # remap
44 PE13 PWM3 # remap

# Q3
68 PA9 USART1_TX
69 PA10 USART1_RX
# Q4
86 PD5 H1 # 5V
87 PD6 H2 # 5V
88 PD7 H3 # 5V
92 PB6 I2C1_SCL
93 PB7 I2C1_SDA

JTAG
====
- 3.3V
PB4 JTRST
PA15 JTDI
PA13 JTMS
PA14 JTCK
PB3 JTDO
NRST RESET
- V-

USB
===
PA11 USB_D-
PA12 USB_D+
- V+
- V-

SDIO
====
PC8 SDIO_D0
PC9 SDIO_D1
PC10 SDIO_D2
PC11 SDIO_D3
PC12 SDIO_CK
PD2 SDIO_CMD

MEMS
====
PB10 I2C2_SCL
PB11 I2C2_SDA
PB12 SPI2_NSS
PB13 SPI2_SCK
PB14 SPI2_MISO
PB15 SPI2_MOSI
  1. Read: non-intel­li­gent, where “intel­li­gent” is a tech­ni­cal term []
  2. Or maybe it will… what elec­tric vehi­cle could use an IMU? ; []
  3. That’s 63 mils by 31 mils or 0.063″×0.031″ []