After three days (nights, whatever) of troubleshooting, Pneu Scooter and the 3ph HD controller have been reunited:
This is the controller configuration for which the scooter was designed, so it fits perfectly under the deck, behind the LiFePO4 battery pack and fuse. In Singapore, I ran into two flavors of trouble with the controller: the current sensor signals were mostly noise and the microcontroller would spontaneously jump out of valid code execution, resulting in a hiccup when the watchdog timer forced a reset. Both were load-dependent phenomena, likely caused by power/signal interference.
This board isn't as nicely isolated as the higher-power controllers I've built; there are no optocouplers or isolated DC/DC supplies. Everything runs on a common ground, though I did my best to avoid ground loops and keep the power and signal sections as separate as possible. In a later board revision, I will explore some options of explicitly isolating the logic power. For now, though, I broke out the box of capacitors and started adding them wherever I thought some extra filtering might help:
The interesting structure on the left is a row of 10nF ceramic capacitors acting as local filters for the current sensor analog signals. This was the solution I explored in the last post for cleaning up the current signals. It did the trick nicely, and so I'll integrate them onto the next revision of this board. With the current sensors back to a reliable state, I had no trouble implementing the field-oriented current control algorithm that I've come to love. If you missed that part of my life, here's a summary.
Unfortunately, the current sensor fix didn't eliminate the spontaneous resets. These seem to be caused by the processor losing its place in the code. It's not completely shutting down; sometimes the PWM peripheral keeps running in the background. The STM32F103 has a wonderful trick whereby it can tell you what the cause of the most recent reset was (page 109 of 1072 in the FM). Using this, I confirmed that the hiccups are watchdog timer resets, and if it comes down to it, I can actually handle the problem with a clever software fix, as outlined in AN1015.
Fixing a hardware problem in software isn't beneath me, but I first wanted to exhaust all other options. I tried increasing the size and quantity of local bypass capacitors on the signal board. Adding a bunch of 4.7uF ceramic caps to power pins seemed to help, but didn't completely eliminate the problem. I was also only running 20A at the time, and the end goal for this controller and motor is 40A or more peak for hill climbing. To test at higher loads, I added 1mΩ resistors in parallel with the ACS714 current sensors.
These resistors effectively increase the range of the sensor (normally +/-30A) by halving the amount of current that actually flows through it. This is a more compact solution, I find, than using larger current sensors. At 40A drive current, the hiccups came back in full force. I tried other small tricks like setting all unused pins to ground and selectively disabling non-critical features. But nothing seemed to make a significant difference.
The breakthrough was a trick that I learned from...actually I have no idea when or where I learned it. Some time ago, I started naming my ground nets differently to keep them separate in my head and in the schematic. There's the physical connection to the negative battery terminal, which is power ground. Ideally, all of the motor's return current goes this way. There's a gate drive ground, which in many cases is the same as power ground. And there's the logic ground, which should be kept as clean as possible. I connect them all with zero-ohm resistors so that I know they are tied together at one and only one place.
That is...unless there are unintended couplings in ICs or on the board or in free space or whatever. The trick is to quasi-isolate the three grounds by changing the zero-ohm resistors to 10Ω. There's nothing special about this value; it's just the largest resistance that results in less than 1/10W dissipation with 100mA flowing through it. (That's about how much the gate drive and logic draw, most of which goes straight into the XBee transmitter.) The extra bit of resistance, combined with the bypass capacitors on each power supply, creates an RC filter that suppresses high-frequency power transients.
This relatively minor change brought the hiccup frequency down from "every time you throttle past 50%" to "every once in a while at full throttle" at 40A. So, it didn't completely solve the problem but it definitely hints at a path to a complete solution: total isolation of the logic supply. While I explore this option for a board revision, though, the current solution is very ridable. With the sine-wave drive engaged, the scooter is virtually silent. It's actually not unbearably cold yet in Cambridge, so I'll be able to test drive it outside this week and take some performance data. For now, though, here's some video at our favorite indoor vehicle test facility: