A collection of my personal engineering projects including small electric vehicles, motor controllers, robots, flying things, and other fun electromechanical stuff!
Earlier this year, I got to do some TinyCross ice racing on a frozen lake: Thanks to Dane for organizing the event; there were over a dozen crazy ice vehicles. TinyCross wasn't the fastest, but the combination of four-wheel-drive, independent suspension, and traction control really helped it get off the line quickly and pull itself through ruts left in the slushy top layer by other vehicles.…
In its original design, TinyCross used four identical Alien Power System 6374 170rpm/V brushless motors. But with the weight distribution being heavily biased to the rear, it really makes more sense to use larger motors there. I had seen some examples of electric power steering motors that might be suitable, so I did some eBay exploration to see what was available. I settled on a Hyundai part…
In a half-bridge configuration, the power loop is the path from the DC bus capacitor positive terminal to the output switch node and back to the capacitor negative terminal. This is the path of high dI/dt, passing through both FETs in the half-bridge. It's important to keep this loop as small as possible, to reduce the amount of parasitic inductance interacting with the high dI/dt. This applies to…
It's been a while since I've attempted a new motor drive design, the last one being TinyCross's dual-motor 50V/100A drive about six years ago. I still really like that design, and those drives have worked well for TinyCross so far. But one of my favorite pastimes is looking for new components that might change how I would build something. And in the last six years, there's been an interesting…
In Part 2 , I described PCIe as a bi-directional memory bus extension and looked at some factors that contribute to the efficiency of the link. A PCIe 3.0 x4 link, with 8GT/s on each lane and an efficiency of around 90%, can support bidirectional data transfer of around 3.6GB/s. But this assumes both sides of the link can consume data that quickly. In reality, a PCIe function is subject to other…
The Link Training and Status State Machine (LTSSM) is a logic block that sits in the MAC layer of the PCIe stack . It configures the PHY and establishes the PCIe link by negotiating link width, speed, and equalization settings with the link partner. This is done primarily by exchanging Ordered Sets, easy-to-identify fixed-length packets of link configuration information transmitted on all lanes in…
This post continues an exploration into the inner workings of PCIe. The previous post presented a top-level view of the PCIe Controller as a memory bus extension, with discussion of the various overheads associated with wrapping memory transfers into serial data packets. In this post, I want go to the other extreme and look at one of the low-level logic mechanisms that PCIe depends on for reliable…
Before getting too caught up in the inner workings of PCIe, it's probably worth taking a look at the high-level architecture - how it's used in a system and what the PCIe controller stack looks like. PCIe is fundamentally a bi-directional memory bus extension: it allows the host to access memory on a device and a device to access memory on the host. When a PCIe link is established between the host…
Over the past few years, I've been developing and improving very fast standalone NVMe-based storage capability for the Zynq Ultrascale+ architecture, to keep up with the absurd speeds of modern SSDs. (Drives like the Seagate Firecuda 530 and Sabrent Rocket 4 Plus-G can now hit 3GB/s+ sustained TLC write speeds, with much higher pSLC cache peaks.) But my knowledge pretty much ended at the interface…
This is a quick follow-up to my original post on speed testing bare metal NVMe with the Zynq Ultrascale+ AXI-PCIe bridge. There, I demonstrated a lightweight NVMe driver running natively on one Cortex-A53 core of the ZU+ PS that could comfortably achieve >1GB/s write speeds to a suitable M.2 NVMe SSD, such as the Samsung 970 Evo Plus. That's without any hardware acceleration: the NVMe queues are…
In the last post , I finally did some actual data logging with TinyCross set up in 4WD, 80A peak per motor, which is the rated current. Based on tinyKart , I know they can handle a a bit more for short durations, maybe even up to 120A. But the data logs (and many instances of having rocks flung into my face) demonstrate that the front wheels reach their traction limit somewhere around 60A on…
It's been a long time since I did a proper test drive with TinyCross, although I've taken it out just for fun a few times. Since I completed the weight/width reduction pass last week, I wanted to get it out again and do some proper data logging in 4WD, with the peak current set to 80A for all four motors. This is still below the ultimate target of 100-120A (for short bursts), but plenty for…
It's summer, which means it's time to work on go-karts. This round, it's a modification to TinyCross that I've been wanting to make ever since I first got it together about two years ago. The main issue is that I designed it around stock rear 12.5" scooter wheels . These are almost symmetric and have threading on both sides of the hub that are meant for mounting the drive sprocket and brake disk.…
Now that I've got a continuous multi-Gpx/s image capture pipeline running, it's time to rearrange some things to break the 1000fps barrier: For this clip I'm using the CMV12000's X/Y subsampling mode to trade resolution for frame rate, hitting 1440fps at 2048x1088. The overall pixel rate is a little lower than in 4K (3.2Gpx/s vs. 3.8Gpx/s), so it's feasible to send this through the same Zynq…
If I were to rank the components of this project in terms of the ratio of their actual vs. expected difficulty, the NVMe interface would probably be lowest, since it was nowhere near as hard as I thought it would be. The CMV12000 input (easy, expected to be easy) and wavelet engine (hard, expected to be hard) would be somewhere in the middle. And the new top of the list, the hardest module that…
In the original Freight Train of Pixels post, I laid out three main technical challenges to building a continuous recording 3.8Gpx/s imager. All three have now been dealt with, using a Zynq Ultrascale+ SoC as a hardware base. The detailed implementations for each one has its own post: [ The Source ] - Full-speed read-in of the CMV12000's 64 LVDS channels. [ The Pipe ] - Hardware wavelet…
Blue wire PCIe REFCLK still hanging in there... It's time to return to the problem of sinking 1GB/s of data onto an NVMe drive from a Zynq Ultrascale+ SoC. Last time, I benchmarked the Xilinx Linux drivers and found that they were fast, but not quite fast enough. In the comments of that post, there were many good suggestions for how to make up the difference without having to resort to a hardware…
I've gotten a lot of mileage out of my v0.1 (very first version) camera PCB. Partly that's because there's not much to it; it's mostly just power supplies, connectors, and differential pairs. But I'm still surprised I haven't broken it yet, and it's only had some minor design issues. I also made a front enclosure for it with an E-mount flange stolen from a macro extension tube ( Amazon's cheapest…
I finished building up the second dual motor drive for TinyCross, which means that the electronics and wiring have finally caught up to the mechanical build and both are 100% complete! That's not to say that the project is 100% complete; there's still some testing to be done to bring it all the way up to full power, as well as some weight reduction and weatherproofing tasks. But there are no more…
The next stop on the Freight Train of Pixels is the wavelet compression engine. Previously, I built up the CMV12000 input module , which turned out to be easier than I thought. The output of that module is a set of 64 10-bit pixels and one 10-bit control signal that update on a 60MHz pixel clock (px_clk). This is too much data to write directly to an NVMe SSD, so I want to compress it by about 5:1…
After the second Jool launch window , I still had 196 days to get a few extra ships off Kerbin before its destruction on Year 3, Day 0. They couldn't transfer to Jool until the third launch window - around Year 3, Day 260 - but they could still get out of harm's way. I hadn't specified exactly how Kerbin is destroyed, but since this entire scenario is based on Seveneves , I think it was reasonable…
Normally, to get the phase angle of a set of (assumed balanced) three-phase signals, I'd do a Clarke Transform followed by a atan2 (β,α). This could be atan2f(), for single-precision floating-point in C, or some other approximation that trades off accuracy for speed. The crudest (and fastest) of these is a first-order approximation atan(x) ≈ (π/4)·x which has maximum error of ±4.073º over the…
With the front wheel drive complete and the steering wheel control board working, it's finally time for a first test drive: I've been waiting over a year to see if this mountain bike air shock suspension setup would work, and it looks like it does! I haven't done any tuning on it besides setting the preload, but it handles my pretty beat up parking lot nicely, absorbing bumps that would have…
In my original Freight-Train-of-Pixels post, I explored three main challenges of building a 3.8Gpx/s imager: the source, the pipe, and the sink. Working backwards, the sink is an NVMe SSD that ( hopefully ) will be capable of 1GB/s writes. The pipe is a ~5:1 wavelet compression engine that has to make 3.8Gpx/s = 1GB/s in realtime, with minimal effect on image quality. And the source is the…
Where I left off, TinyCross was at the rolling chassis stage. Mechanically, it went together relatively smoothly, most of the issues having been worked out in CAD. There are a few minor tweaks I'd like to make to make it lighter and narrower, but they're low priority compared to getting a first test drive in. So, on to the electronics. It always looks so clean until you start adding wires. I've…