Archive for the 'Reference Posts' Category

 

Loose Odds and Ends from the Past Week or so

Jun 19, 2013 in Beyond Unboxing, Electric Vehicle Design, mikuvan

Things have been getting exciting in the last week or so as the SUTD Summerkarts Global Leadership Program students have arrived, and we’re now well under way into the Silly Vehicle design phase all over again. Global Leadership Program. That’s such an epic name for 2.00gokart, guys. To be fair, there’s plenty of other things going on for the students too, most of which are ‘leadership’ flavored. In this running of the class, since I’m not being watched over by The Department and need to make sure everyone has paper lab notebooks, the student groups will be blogging their builds! I’ll post a list of links once everyone gets set up.

mikuvan

I’m currently at 380 miles.

Having essentially reached the limit of things that have been going wrong, I’ve been faced with no choice but to start attacking rust. This thing hasn’t even so much as hiccuped a single time since Operation: Bad Timing. I would say that at this moment, having checked everything I think is important, I’d trust a trip out to at least New York City (about 240  miles).

I’ve mostly been spending the past 2 weeks psyching myself out and picking up some materials.

 

Based on estimating the clooooouuuuuud Internet and asking friends, I got a pile of things from Eastwood – panel sheets, a bucket of sealer, and some rust converter. I was skeptical about the “rust converter” – it allegedly converts iron oxide (“rust”) to iron phosphate or iron tannate, which is some shit I’ve never heard of and only appears in product descriptions plagiarized from Wikipedia. This sounded shady, and success seems to be hit or miss. However, it’s relatively cheap, so we’ll see what this magical potion does. That, plus another haul of random abrasive and sheet metal banging tools from Harbor Freight, ought to round out the basic non-sketchy rust patch. I’m going to try the pound-and-weld-metal route – falling short of soldering since it sounds a tad too hardcore at the moment – instead of throwing fiberglass at it.

All that, and waiting for several days of hot and dry weather to do the majority of the work, just to smoke out any residual moisture from the body holes. Recently, it’s actually been hard to come by, with the Northeast in its Periodic Random-Ass Storm Season (PRASS). There’s no point in tying a puddle up inside my work. Worse come to worst, I’ll point a space heater at the trouble spots for a day before doing anything.

What I’ll do first is probably do all the sanding and grinding; the full-depth investigation, basically, and then post it publicly to get some opinions and appraisals. The idea is to cut or grind off what I can get to, covert and cover over what I can’t abrade off, and then slather external underbody repairs in sealing compound. I also managed to find a matching Chrysler color at Advance Auto Parts to repair the exterior paint afterwards, tested by blasting random areas and staring at it a few minutes later. This may backfire horribly.

Part of the reason I’m hesitant to start is because I have the feeling that things will get more and more Death Race 3000 if I mess something up or discover more structurally unsound areas than I previous anticipated. What you can’t see….

Though, in the limit of Death Race 3000 style modifications, this thing will probably look more and more like a classic wedgebot.

testing the mini-jasontroller

I replaced the full-size caseless Jasontroller in RazEr REV2 with the mini version detailed last week.. I’m definitely a big fan of these now – they’re basically the same as the full size, in a much more useful package.

This is the smaller controller uncased and fully cleaned. I essentially took out every wire I didn’t need, and also locked the speed setting to high internally by jumping the right side orange wire; by default, the “3 speed range” switch comes in the medium range, which means it divides down the throttle input) This has no bearing on its upper speed limit which is still around 540-550 eHz or so, but for low speed motors the throttle response will be substantially retarded otherwise.

These controllers have a discrete logic power switch, unlike the full size Jasontroller, so I also hardwired that internally (left).

I discovered that the entire controller case fit inside the space where my old full size Jasontroller went, minus one corner. So, instead of redrilling the mounting holes for the smaller heat spreader bar, I cut the entire case into an L shape with the board resting in its stock location…

…shrink wrapped the whole thing, and Velcro-mounted it in. Clean and waterproof, and the additional aluminum should still offer some thermal capacity.

The overall height of the controller when stripped of its case is under 0.8″ (in my configuration, it’s not much shorter due to the existing case outline remainder), which opens up the potential to be stuffed into even more things.

I’ve noticed no difference in riding behavior between the mini-Jasontroller and full size, once again confirming they’re basically the same thing. I’ve noticed some slight difference in starting behavior – the mini doesn’t twitch backwards, at least not often. More observation will be needed to discern the differences. In the mean time, I’m officially qualifying the mini-Jasontroller as Certified Legit. You can buy it on this page, and maybe soon from Equals Zero. If you make something using one, post it!

I’ve added this controller to my Scooter Instructable in the EV controllers section.

more silly rideable things

One of the downsides of having 160 cubic feet of self-motive cargo volume is Oh man, this free stuff on Craigslist looks awesome. I’ve previously been limited by what I felt like carrying back on Melonscooter, or worst case, ride back independently. That’s no more.

What you see here is a most-relevant-to-my-interests free Craigslist haul of two nonfunctional electric bike (-like-objects) from a closing e-bike shop. The one on top, as it turned out, is quite the machine. It’s a TidalForce IO cruiser bike, from another one of those small EV companies with an illustrious but ultimately short lived existence, in complete condition. The bottom red pile is a generic Chinese “电动车” or “Chinese moped”. These are sold here and there under various names (here’s one example, and most likely the company that retailed it since it says GREENPOWER on it!). Its condition was a little more beat up, but seemingly just devoid of batteries.

Here’s a better shot of both of them. Being me, I’m actually more a fan of the little red moped – it’s a little weirder and has that Chinese charm to it, but the Tidalforce was much more complete, so I began messing with it first.

The backstory of this machine was that the customer dropped it off for battery service and abandoned it. Apparently, these bikes were notorious for having their NiMH cells degrade very quickly.

Lacking a legitimate charger, I jacked it in on a power supply to 45 volts CV and fed it at about 0.8 amps for basically the better part of a day. The cells inside are nominally 8Ah, so the charge rate is a nice C/10 trickle charge. In case any of the cells were permanently toast, it wouldn’t cause thermal runaway. The battery came off nice and warm, and I rode around until the bike shut down from undervoltage. This charge lasted basically 5 miles with very little pedaling. The original advertised range was 15 or 20, but according to the storytellers realistically 6 or 8 miles, so it didn’t seem that far off the mark.

The termination condition is dictated by the battery management system onboard, and this is where things got difficult. No matter what, I couldn’t convince the charge-o-meter to go above 20%, even when I’ve clearly left the battery on slow trickle for many hours! I suspected that this artificial BMS meddling is what shut the bike down in the first place, since it didn’t feel like it was about to slow down.

I did some research online and came upon this useful page for decyphering the onboard controller for the bike, as well as this flamewar thread on Endless Sphere where someone mentioned that the battery needs to be discharged to under 32v to resynchronize the charge indicator.

This battery is too damned smart. I couldn’t get any output voltage from it unless the bike was on, since it has internal FET switches to shut off the cells from the pack output, so I couldn’t artificially drain it. And even at 44 volts off the charger, I couldn’t get the bike to move more than a couple dozen feet before the BMS shut me down. I hate it when batteries are too smart – I’m forced to crack them open.

Off the front wheel comes. It’s on a quick release, so a latch and some cable pulling later and it comes cleanly off.

Removing the case screws and side, check out this holeaphobia-inducing lotus flower of cells! The terminals all had bits of corrosion on them, but there were no signs of leakage that I could observe.

Hammering on the opposite side of the wheel makes the entire battery structure fall out. This is the important side of things – the BMS board. My mission was to artificially brick the pack via the CELL tabs, draining them to under 32 volts, hoping the BMS would reset or something.

I used this shady arrangement of power resistors, totalling 15 ohms, to drain down the pack over the course of about 3 hours, getting the whole array down to about 30v. Afterwards, I immediately closed everything up and threw it back on the charger. It did exactly jack shit.

The battery meter blinked 20% the whole time! I’m going to guess I did this wrong somehow, or more likely, forgot that Ni batteries bounce back in voltage very well after an initial discharge. By the time I was done connecting things back up, the battery voltage could have been well in excess of 32v, making the BMS think everything was still skullfucked. But it should at least recognize the 7Ah I dumped back into the battery, right?! No such deal.

As of now, I’m currently riding this thing around day to day to burn down the charge in a useful fashion. Apparently, the charge meter blinks in its entirety when the BMS reset point is reached, so I’ll hopefully be ready then.

Why am I trying so hard to use this proprietary-ass stock battery when I could very well just hack the “B” battery with any number of potential long running packs? I’m hesitant to do that because I don’t actually like this thing. It weighs nearly 60 pounds and is enormous, clearly built for a much Manlier Man than I. Plus, I can barely stuff it inside my front door. I guess I’m used to smaller and more portable scooters which can be rolled inside – this sucker is going to need the bike rack. Not really my style.

For now, though, it’s alive and working as yet another Craigslist impulse that turned out to be a little neurotic but otherwise livable day to day. What’s with me and that kind of thing lately?

Let’s move onto the Little Red Moped.

After diddling around with the TidalForce for a few days, I decided one night to get this contraption running along with Adam. I cleaned up the mechanicals and repaired the existing wiring while he created an impromptu brick of 12V7 modules I have on standby for the summer EV design class.

Look at that beautiful… 20 gauge? wire going to the hub motor! This machine is capable of Real Power.  The hub motor appears to be a 48v, 500W (or 750W) brushless type, like this.

Unhitching the electronics box, I discover this wad of wires. If you ever wonder what Jasontrollers and their ilk are actually used for, this is the answer. As you are reading, millions of Asian moped bros are cruising about on machines exactly like this one.

During my wiring cleanup, I found a spider!

Someone clearly was derping around with this after-market and the controller is likely not the original. Someone was also terrible at this. There were plenty of examples of wires just twisted together and electrical taped up, and solder joints like that.

Whatever. It worked, and all I really did was replace some of the decomposing electrical tape and resplice some of the signal wires appropriately.

With the impromptu 48v battery and a random found bike seat, it was ready to roll!  And roll it did. The acceleration was brisk and utilitarian, and the suspension was a bit underdamped but compliant even when riding up curbs. It’s very quiet, and there’s a pedal assist sensor which almost sent me into the wall a few times when I instinctively kicked the pedal out of the way.

Riding it in this form makes me envision myself wearing a straw hat and dark brown Mao suit, riding along a dusty Chinese road to my factory job. With a cage of chickens on the back to be sold at the market later that day.

We agreed it would be more amusing once completely rewired and running on 72 volts, but sadly, Mao’s Little Red Moped did not see that day. For at Swapfest, I was riding around aimlessly for no more than 10 minutes before someone bought it off me on the spot. Sans batteries, but still.

So my net wheel gain for the past few weeks has been 2, both won by the TidalForce bike. Unfortunately, that may increase again, because I’m considering…

a playmate for mikuvan

Your job, Internet, as the guardians to my sanity, is to tell me I do not need another one of these.

Let’s face it. I was originally looking for a science project with Mikuvan, but elected to put in an honest repair effort to have me some of that thar “auto tech” larnin’ y’all kids are into these days. But now it’s running too well, and a few of us are basically invested emotionally in it, and I have a harder time with the thought of tearing everything down again than when it wasn’t running.

Mere weeks after I stated my life goal Passive Non-Career-Derailing Desire was to collect the Legendary Van Trifecta, I discover that I might have a chance to nab the rarest of them all: the USDM Nissan Vanette. Yes, the one which was well known for lighting on fire.

The back story for this find is quite circuitous indeed. It wasn’t by weeks of stalking Craigslist, or a “Hey, I hear you like derpy vans” referral from my “Hey, I heard you like trashy electric scooters” network. Instead, while doing research on the other members of the trifecta, I found this Jalopnik post for a Nissan Van (-shaped-object) in North Carolina. Some link hunting led me to the original sellers album…from 2011.  Out of sheer shits and giggles morbid curiosity, I emailed the seller what amounted to “lol do you still have this”. MFW the answer was yes:

I’m at a loss about what to do.

On the one hand… Whoa, a chance to capture the rarest Legendary Pokévan and train it make it the base for this electric drive project. After all, the way the world apparently works, as I’ve handily found out in the past few months, is you have a functioning car, then you get an explicitly nonfunctional one to mess around with. This van is so explicitly nonrunning the FCC and ASE are about to join forces to erase it from reality. The chassis mechanicals appear to be comparatively rust free (then again, so I thought with Mikuvan).

The downside? Space. Parking. Not even counting the (once yearly) cost of registration and (fairly low) monthly insurance premiums once it’s operational, there’s no such thing as a little empty grassy patch to stick a nonrunning vehicle here. I was lucky with Mikuvan that my one allotted parking spot was open. What I cannot justify is paying hundreds of dollars a month for a parking spot or garage space for a van-shaped lump without the knowledge that I will immediately be able to attend to it, rare or not.  I’m currently in the process of exercising my social network™ to see if anyone is willing to put up with my bullshit. Ideally, there’s a back alley of a nearby industrial space somewhere that I can slip into, or someone’s back yard who thinks this is all too hilarious. I’m not going to try very hard.

So the dilemma goes. I will probably not see one of these in such a complete condition for many years, but maybe in said years I’d be in a better position to start Big Chuck’s Van Adoption Service.

 (All pictures above of the vehicle were provided by the seller)

I’m filing this post also under Beyond Unboxing since so many things were taken apart in one way or another.

Beyond Unboxing: Mini-Jasontroller, 8-FUN Bike Hub Motors, and Other Goodies from ELifeBike

Jun 12, 2013 in Beyond Unboxing, Reference Posts

Whoa, hey! Haven’t done one of these in a while, though I’ve definitely taken apart a host of things recently that should be written up. I’m doing this now because, as usual, I hope I’ve come upon a useful source of parts for both my own projects and those of anyone else who considers themselves connoisseurs of fine sketchy electric rideable implements. This time interval’s report brought to you in part by Jamison, who I’m glad to announce has joined the ranks of us MIT hoodrats and has been pulled out of the south to become a dirty Yankee. Though, given that he is from Florida, was probably always one to begin with.

The foundations of this chapter of Beyond Unboxing began several weeks ago as Jamison was completing his melonscooter-equivalent, Guavascooter. For the record, the Collegiate Silly Vehicle League nomenclature for the SK3 59 series of motors is guava, following in the 80mm C-series (e.g. the C80/100 and C80/85) being the melon and short melon. Always on the hunt for new shady Chinese vehicle products, Jamison informed me of the existence of what is basically the most shady Chinese parts supplier website I’ve ever seen: eLifeBike.

I think the engrish on the shopping cart software alone is the source of 20 new inside jokes in our crew up here.

What struck awe into me is the sheer absurdity of the prices. How the hell are they so low? What is this stuff actually made of – recycled human hair and potato starch like everything else from China?! We were interested particularly in their line of 6-FET controllers, which seemed to be in the same bloodline as the revered (…) Jasontroller. According to Jamison’s report, it seemed to behave basically like the Jasontroller, but was about 60% of the volume.  Seeing such other joys as $66 hub motors and $28 battery chargers, I decided to front some money to offer, once again, to the Gods of Silly Rideable Things. I went ahead and bought said $66 hub motor, a “250W” model; two of the 24V 250W controllers (basically equivalent of the Jasontroller model I buy the most, which can actually run up to 40v reliably), and a 10A 36v battery charger. If any of this stuff so much blinks when I turn it on, I’ll be happy.

As usual, with these exclusively Chinese vendors, the base price is deceptive. Shipping on items can often reach $30-50, if not more! After a week (Fedex International Priority was somehow the cheapest shipping option), I found out why the prices were so low:

Paddy Fields Street? Damn, is this just some guy working out of his straw shack in the middle of a field of rice? Turns out if you Google Maps the postal code 518108, it’s a small industrial neighborhood in northwestern Shenzhen (are there any other kinds?). Given the name, it probably used to be paddy fields.

Here’s all the goods! I can confirm that, at least superficially, they are made of metal and have wires sticking out of them. So I’ve at least gotten these items discerned into one of two categories: small bombs, or electric vehicle products. As far as the NSA is concerned, it’s all the same anyhoo. Hello NSA!

I ordered a 36v 10A charger because most of my daily commuter tools run 36v (or 38.4v) electrical systems, so at least one of ‘em ought to benefit from this quicker charger. My currently fastest charger is 5 amps.

Let’s start with this hub motor. As everyone probably knows, I am a purveyor of fine hub motors. This style of hub motor is generally known as the “8FUN” or “Bafun” or “Bafang” motor. In the 250/350W size, they’re around 6″ diameter and are designed for bicycle front wheels, to offer pedal assist and not explicit propulsion power. I’ve been eyeing them for a while, since they are readily available on the Internet of Things, but never sprung for one until now.  Since I’m not a big bicycle person, I’m of course interested in how to adapt them to drive smaller wheels such as scooter wheels, or some kind of robot appendage. Or vans.

8fun motor

Six Phillips-head case screws layer, the 8-FUN motor is cracked open. This was suprisingly pleasant and easy.

The observant might note that, in a divergence from my hub motor designs or those of full-size e-bike motors, it’s a geared motor! That’s right – the outrunner style motor on the left actually spins on the stationary center steel shaft, and it has a steel pinion which engages with…

PLASTIC….

…gears in the planetary gear set.

Alright, hold on a second here. Somehow, the Chinese are able to turn a few lumps of dirt, a rock, and maybe a cup or two of oil into a beautifully machined cast aluminum case, ball bearings, laminated steel stator, neodymium magnets, copper wire, internal and external gear teeth, and laminated lacquer-coated iron stamped shapes, then sell it to me for all of $66 (which is not that much these days, considering the steadily rising Chinese RMB exchange rate)…

…but use PLASTIC gears  to complete the great circle of e-Bike life?

I would have gladly paid 10 cents more for some sintered steel, guys.

All over the Internet, the weak link in these motors and the source of much frustration are those little blue (or off-white, or black) nylon gears. The design itself is quite robust, from my appraisal, besides those damned gears. The gears ride on common 608 skate bearings and are retained solidly to the carrier by snap rings, so they never rub on the motor. Typically, small planetary gearboxes just throw you a big wear washer for the gears to mash against and be done with it.

A little more table-bumping and the other endcap pops off, exposing the backside of the motor. The construction of this motor is pretty solid. A full circle of magnets, tight airgap, and an actual PCB that holds the Hall sensors. By itself, this motor is worth the price if I had a specific application for it. It’s extremely utilitarian – for the same price, you’d get a much smaller but much shinier R/C aircraft motor. One of the product lines I’ve wanted to a start is a line of extremely plain, Brutalist styled motors which aren’t all chromed out and sticker-plastered, but, like, actually do work.

In this motor, the stator is rigidly fixed to the shaft, and the can has a short bearing section in it which rides single-supported on the shaft. Not unlike a huge version of Pop Quiz’s weapon motor.

Closeup of the gearset. The motor pinion and outer ring are all metal, but the planetary gears are PLASTIC. Count on the Chinese to cut the 1 corner that would make the product actually worthwhile! The gears seem to be metric module 1, a common size, so perhaps similarly sized metal gears already exist for it – I haven’t done extensive research into this facet of Chinese e-bike parts, since I’m not heavily involved in the crazy e-bike hacker community.

It’s interesting to note that the carrier has an integrated freewheel. That way, you can pedal-power override the motor’s propulsion force. I, for one, actually hate freewheels and like my motor inertia to be a continuous function.

Closeup of the motor, showing the workmanship and method of stator attachment to the hub. The winding-bindings are a nice touch.

Overall, fuck plastic gears I think this is a pretty solid product if you run it within its ratings – basically 350W limited power systems for pedal assisting. And in this application, I’m sure it rocks hard or the design wouldn’t be commonplace, but fuck plastic gears I definitely don’t see much overpowering potential in it due to the fuck plastic gears.

I don’t have an application lined up for this little thing, so I put it back together and just ran it on a table for kicks. It’s very quiet – surely the plastic gears gear-like substance helps with noise absorption. However, one thing Jamison and I talked about, but I have yet to investigate, is whether or not this motor is small enough in diameter to jam into other cored-out wheels. Instant DIY small hub motor!

mini-Jasontroller

One of the things that caught my eye when Jamison popped the top on Guavascooter was how small the controller was. It was advertized, yes, as miniature, and I should have look at the size specifications. But the real kicker was when I pulled out a spare Jasontroller:

The QQ 6-fet series is basically a hair more than 2/3 he volume, with the best decrease being on width. The standard 6-FET Jasontroller is 105mm long, 35mm tall, and 66mm deep, compared to 100mm x 30mm x 52mm.

Here’s my Sciencing Rig all set up with a SK3 motor (feat. Sensor Boards). I neglected to take a close-up of the board inside, but the construction is of much higher quality than the corresponding full size Jasontroller. More smaller SMT components are used, resulting in a tighter board, and – my favorite part – the FETs are mounted to the heat sink bar much closer together and at the very base of their leads. There’s no gap between the FET body and the board, so the whole assembly is not wobbly. But it also means I couldn’t just fold back the FET rail to read the part number.

After some very careful light and mirror tricks, I, in my classic habit, found the FET part number: the RU7088R. A bit better than the usual offerings!

As far as I could tell from inspection, the circuitry is exactly the same as the full size Jasontroller, and the chipset is also the same (X8M06-C with a comparator frontend for sensorless operation).

This controller has no “auto-train” wire. Instead, like the full size Jasontroller, any existing motor Hall sensor mapping is erased if you run sensorless. Then you plug in the (hopefully well-placed) Hall sensor rig and run the motor again to full speed, back to zero speed, and cycle power. These things are smarter than I am.

And like the full size, it also has a roughly 550Hz commutation frequency limit. The shown waveform is 15.625kHz PWM frequency on top of the commutation frequency. If the motor wanders above this speed, unlike the full size Jasontroller it doesn’t keep beasting current into it, but rather it shuts down. Upon return of the throttle to zero, it can start up again. So, it seems to be an improvement – instead of grenading itself and your motor, it soft-kills.

550Hz-electrical translates for most 7-pole-pair outrunners to 4714 RPM maximum (550 times a second / 7 electrical rotations per mechanical rotation, then * 60 seconds per minute). Hitting the “3 speed selector switch” into high speed made no difference – again, it’s a processor limit. Sadly, these processors seem to be using their internal oscilltors, so it’s nontrivial to overclock. If the oscillator were external, you could potentially just make it faster.

In summary, for most purposes, the mini-Jasontroller is exactly the full size, but just cuter. The smaller package means you can shove it into many smaller vehicles (specifically scooter frames) where it would otherwise be unwieldy.  I’m an immense fan of these things already, but need to get in some more hardcore testing and detonate a few before making a decision on recommending them. But if you’re interested, you can get one from eLifeBike for about $38 minimum (66% of that price is shipping alone). As the purchase quantity approaches infinity, the price appears to settle close to $14-15 a unit. Yes, I tested this on their Engrish-laden cart software.

These two controllers I bought might end up on Chibikart2 for robustness testing.

This concludes another chapter of Beyond Unboxing! If you end up using any of these generic Chinese EV products in anything, feel free to drop a comment. The reason I love to mess around with these parts so much is how care-free they are. There’s no proprietary system or brand or manufacturer’s artificial limits to deal with, the price is right, and they work. One of my beliefs is that the next big EV revolution is quietly taking place in China: the millions of these nameless e-bikes carrying people and goods every day publicity-free, while we scurry around with shiny, low volume, tax-break subsidized people-bubbles built around big money personalities.

(There go my chances of working at Tesla or any other electric car company, ever.)

 

The Forthcoming RageBridge: Stick Calibration

Feb 02, 2013 in Bots, Motor Controllers, Project Build Reports, Reference Posts

They’re here!

All of the RageBridges! All of them ever!

Or rather, 100 of them, in neatly packaged panels of two. Here’s what one of the manufactured panels looks like.

Pretty cool.

Okay, so these actually got in last week, but I’ve been doing some background and infrastructural work since then. I’m planning on gathering a few friends and flashing, populating headers, and testing all of these this coming weekend. I decided to leave the chips unflashed because I was not yet satisfied with the firmware (and the flashing was a few hundred extra dollars), and the headers are purposefully left unpopulated because many people prefer soldered-on pigtails or their own wiring configuration. It’s definitely a little more legwork on our end, but for such a small run (100, maybe with a few duds) I think it’s still manageable, and will allow the fine settling into best practices that inevitably accompany any parts business. Time to be a little adventurous.

From a firmware perspective, the only thing RageBridge has been missing since the last board revision is a way to calibrate the servo PWM range. This is generally preferred because not all radios are created equally, and some may have more stick travel & adjustable PWM endpoints than others. For instance, my (nice for 2006) Spektrum radio can hit the full 1000-2000uS servo range if I navigate through the menus and tell it to stretch its range a bit. But my cheesy Hobbyking 6 channel radios can’t do the same unless connected to a computer to program them – the stock range is more like 1200 to 1800us. So, any fixed input range will inevitably be a compromise – for some people, the stock settings will be too twitchy (i.e. stick travel range is greater than the board’s accepted input range), or you might not ever hit full throttle (because the radio stick travel doesn’t go far enough to match the controller input range).

Calibration has always been one of those things that I accepted as working, but never thought about implementing. Depending on how it’s done, it can be relatively simple, or a mess of state machine code.

One of the most common modern calibration paradigms is the “stick-high” method, used by most R/C model controllers, whether air, sea, or ground. This involves powering on the controller with a receiver attached (and generally, already powered and outputting valid pulsewidths) and you commanding full positive travel. If the first thing that the ESC sees, or sees within 1-2 seconds, is a full positive signal, then it waits for a few seconds and checks again. If you are still holding full positive, then it beeps or blinks (accepting the full positive position), and then you back off to full negative and hold for a few seconds, then back to neutral. For single channel ESCs without many other features, it’s pretty much the way to go.

I decided to implement stick-high calibration for RB, except modifying it for both channels at once. This entailed adding a timed loop in the middle where normally you would just check for full positive and full negative signals. The idea is that during the timed loop, the user just swirls the sticks around all at once and the controller will capture both ranges simultaneously. At any point, if the signal returns to neutral for more than 2 seconds, the calibration routine exits and writes the results to EEPROM so it is persistent.

Of course, there’s other little touches to make the system more robust like checking for pulse validity (rejecting malformed or misread pulses) and fail-safe performance if the user bails out in the middle. In all, it took me a few hours of planning and a few hours of beasting Arduino code, and I’m quite pleased with the final result.

So, in a completely out of context brain bump, here’s RageBridge’s stick calibration code. When I ship it through e0designs.com, the full source code will be released along with board files, but I’m putting this early because I’m particularly proud of it.

I subscribe to the Expository Essay school of code commenting – I literally write what every line and every procedure does, in detail, and in natural english. To hardcore and experienced coders this might seem like a waste of characters, but I find it particularly easy to read my way back through old code and decipher what the hell I thought I was doing when I wrote it. So there’s actually plenty of paragraphs in the comments.

As a bit of backstory since I didn’t post all the variable definitions, anything with a _1 or _2 is referring to the channel of RB it is relevant to. The code is written with Arduino 1.0.1 using the PinChangeInt and EEPROM libraries (PCI is not used in this section as the interrupt procedures that capture servo pulsewidths are not shown).

  • RCMAX, et. al. are all declared as signed integers at the beginning of the code (not shown).
  • CALIBRATION_CONSTANT is a fraction of the total stick travel, right now 0.66. In other words, anything ABOVE 66% of the current maximum travel is grounds for entering calibration mode. This is one of the tricks I added to prevent calibrating yourself out of your own radio travel bounds. So, basically what it entails is each time you calibrate you could reduce the range by 1/3rd if you had to.
  • neutral_counter and NEUTRAL_CYCLES_MAX refer to how many iterations of the neutral signal checking routine can run before the calibration procedure is declared to be done.
  • NEUTRAL_DELTA is the pulse width deviation around the current neutral point that can be recognized as a new valid neutral point. For instance, the default neutral pulsewidth for servo PWM is 1500us. If NEUTRAL_DELTA is defined as 100, which it is, then anything from 1400 to 1600 may be set as a new neutral point. This is to make sure you cannot drift the center stick zero throttle point too far, even on purpose. You can, of course, do so by running multiple calibration cycles. But why!?
  //Collect the user calibration endpoints from EEPROM. If the EEPROM values return 255
  //then calibration has never occurred, so use defaults.
  RCMAX_1 = (signed int)EEPROM.read(100);
  RCMAX_1 += (signed int)(EEPROM.read(101) << 8);
  RCMIN_1 = (signed int)EEPROM.read(102);
  RCMIN_1 += (signed int)(EEPROM.read(103) << 8);
  RCCENTER_1 = (signed int)EEPROM.read(104);
  RCCENTER_1 += (signed int)(EEPROM.read(105) << 8);
  RCMAX_2 = (signed int)EEPROM.read(106);
  RCMAX_2 += (signed int)(EEPROM.read(107) << 8);
  RCMIN_2 = (signed int)EEPROM.read(108);
  RCMIN_2 += (signed int)(EEPROM.read(109) << 8);
  RCCENTER_2 = (signed int)EEPROM.read(110);
  RCCENTER_2 += (signed int)(EEPROM.read(111) << 8);

  //Bytes will return 255 if they were never read; full 16 bit result is 65535
  if(RCMAX_1 == 0xffff ) {
    RCMAX_1 = RCMAX_DEFAULT;
  }
  if(RCMIN_1 == 0xffff) {
    RCMIN_1 = RCMIN_DEFAULT;
  } 
  if(RCCENTER_1 == 0xffff) {
    RCCENTER_1 = RCCENTER_DEFAULT;
  }
  if(RCMAX_2 == 0xffff) {
    RCMAX_2 = RCMAX_DEFAULT;
  }
  if(RCMIN_2 == 0xffff ) {
    RCMIN_2 = RCMIN_DEFAULT;
  } 
  if(RCCENTER_2 == 0xffff) {
    RCCENTER_2 = RCCENTER_DEFAULT;
  }  

  delay(1000); //Just chill for a bit to make sure radios have bound and begun sending out good signal.

  //Calibration mode procedure.
  //After initialization, check for good signal on channels 1 and 2
  //If the signal is above the calibration threshold on both channels, keep waiting. If not, enter main program loop.
  //If at the end of 5 seconds the stick has been held, enter calibration mode. If it has not, enter main program loop.
  //Even if there is no good signal, proceed to main loop anyway - the main loop begins in failsafe mode. 
  if(is_pulse_good(vol_ch1_pw,RC_ABS_MAX,RC_ABS_MIN) && is_pulse_good(vol_ch2_pw,RC_ABS_MAX,RC_ABS_MIN)) {
    signed int init_calib_threshold_1 = (signed int)(CALIBRATION_CONSTANT*(RCMAX_1-RCCENTER_1))+RCCENTER_1;
    signed int init_calib_threshold_2 = (signed int)(CALIBRATION_CONSTANT*(RCMAX_2-RCCENTER_2))+RCCENTER_2;

    if(vol_ch1_pw > init_calib_threshold_1 && vol_ch2_pw > init_calib_threshold_2) {

      //To check for stick hold, begin the timer and set a flag that will be cleared if the stick is released
      unsigned long calibration_timer = millis();
      boolean entered_calibration = true;

      //Enter 5 second wait loop, constantly checking for stick release. Invalid signal also constitutes "stick release".
      while(millis() - calibration_timer < 5000) {
        if(is_pulse_good(vol_ch1_pw,RC_ABS_MAX,RC_ABS_MIN) && is_pulse_good(vol_ch2_pw,RC_ABS_MAX,RC_ABS_MIN)) {
          if(vol_ch1_pw < init_calib_threshold_1 || vol_ch2_pw < init_calib_threshold_2) {
            entered_calibration = false;
            break;
          } //End stick release check
        } else {
          entered_calibration = false;
        } //End pulse good check

      } //End wait for 5 seconds to check for stick hold

      //If the flag is still true, then the user has held the stick for > 5 seconds above the threshold
      //Calibration mode description:
      //Resetting the old max and min bounds to a lower threshold (CALIBRATION_CONSTANT * RCMAX_n)
      //If a newly captured value exceeds the thresholds, save it. 
      //If a newly captured value is within a certain % of neutral (NEUTRAL_CONSTANT * RCCENTER_n above or below RCCENTER), start a timer
      //After 3 seconds of this, assume the user has returned stick to desired neutral and take several samples for neutral position
      //If any pulse is invalid, bail out of calibration and retain old values.
      if(entered_calibration) { 

        digitalWrite(BLINK_FURIOUSLY,HIGH); //Set the LED on solid to let the user know that calibration has begun

        //Set initial thresholds to exceed. The thresholds are a certain % of the current set of maxes and mins
        //such that the controller can never be "calibrated out". By only exceeding the threshold very slightly
        //subsequent iterations of calibration can narrow the range of signals too, if it is necessary.
        signed int rcmax_1_temp = (signed int)(CALIBRATION_CONSTANT*(RCMAX_1-RCCENTER_1)) + RCCENTER_1;
        signed int rcmin_1_temp = RCCENTER_1 - (signed int)(CALIBRATION_CONSTANT*(RCCENTER_1-RCMIN_1));
        signed int rcmax_2_temp = (signed int)(CALIBRATION_CONSTANT*(RCMAX_2-RCCENTER_2)) + RCCENTER_2;
        signed int rcmin_2_temp = RCCENTER_2 - (signed int)(CALIBRATION_CONSTANT*(RCCENTER_2-RCMIN_2));
        signed int rccenter_1_temp = RCCENTER_1;
        signed int rccenter_2_temp = RCCENTER_2;

        boolean am_calibrating = true;
        boolean commit_calibration = false;

        byte neutral_counter = 0;

        //Set the main calibration loop going. 
        //First, check for good pulses. If any are bad, the routine is immediately ended and changes are NOT saved.
        //Next, check for pulses near neutral. If any are, increment a counter. If the counter is over a threshold,
        //then the user has returned the stick to netural and calibratoin can exit/changes be saved.
        //If any subsequent pulses are outside of the neutral bound, zero the counter. 
        //Next, expand the pulse range if the new set of pulsewidths are greater in magnitude deviation
        while(am_calibrating) {

          //Sanity check - if any pulses are out of range or invalid, exit.
          if(is_pulse_good(vol_ch1_pw,RC_ABS_MAX,RC_ABS_MIN) && is_pulse_good(vol_ch2_pw,RC_ABS_MAX,RC_ABS_MIN)) {

            //Save a copy of the current "volatile" pulsewidths (which can change randomly due to the interrupt)
            ch1_pw = vol_ch1_pw;
            ch2_pw = vol_ch2_pw;

            //Neutral check. If the signal is within the box of valid neutrals for enough cycles, exit and save changes.
            if(ch1_pw < (RCCENTER_1 + NEUTRAL_DELTA) && ch2_pw < (RCCENTER_2 + NEUTRAL_DELTA)) {
              if(ch1_pw > (RCCENTER_1 - NEUTRAL_DELTA) && ch2_pw > (RCCENTER_2 - NEUTRAL_DELTA)) {
                if(neutral_counter > NEUTRAL_CYCLES_MAX) {
                  am_calibrating = false;
                  commit_calibration = true;

                } else {
                  neutral_counter++; //Within bounds, but not exceeding number of allowed cycles, so increment and move on.
                  rccenter_1_temp = ch1_pw;
                  rccenter_2_temp = ch2_pw;
                }
              } else {
                neutral_counter = 0; //If any of the within-bounds checks fails, reset the counter since the stick has moved.
              }
            } //End neutral check

            //Bounds check; If the new pulses exceeds the current set of temporary calibration bounds in either direction
            //set them as the new bounds.
            if(ch1_pw > rcmax_1_temp) rcmax_1_temp = ch1_pw; else if(ch1_pw < rcmin_1_temp) rcmin_1_temp = ch1_pw;
            if(ch2_pw > rcmax_2_temp) rcmax_2_temp = ch2_pw; else if(ch2_pw < rcmin_2_temp) rcmin_2_temp = ch2_pw;
          } else {
            am_calibrating = false;
            commit_calibration = false; //Something has gone wrong and caused the calibration loop to terminate early...
          } //End sanity check
          delay(20);
        } //End main calibration loop

        //Save changes?
        if(commit_calibration) {

          //First, reassign the constants for this power cycle...
          RCMAX_1 = rcmax_1_temp;
          RCMIN_1 = rcmin_1_temp;
          RCCENTER_1 = rccenter_1_temp;
          RCMAX_2 = rcmax_2_temp;
          RCMIN_2 = rcmin_2_temp;
          RCCENTER_2 = rccenter_2_temp;

          //Next, write these new values to EEPROM!
          byte rcmax_1_lowbyte = (RCMAX_1 & 0x00ff);
          byte rcmax_1_highbyte = ((RCMAX_1 >> 8) & 0x00ff);
          EEPROM.write(100,rcmax_1_lowbyte);
          EEPROM.write(101,rcmax_1_highbyte);

          byte rcmin_1_lowbyte = (RCMIN_1 & 0x00ff);
          byte rcmin_1_highbyte = ((RCMIN_1 >> 8) & 0x00ff);
          EEPROM.write(102,rcmin_1_lowbyte);
          EEPROM.write(103,rcmin_1_highbyte);

          byte rccenter_1_lowbyte = (RCCENTER_1 & 0x00ff);
          byte rccenter_1_highbyte = ((RCCENTER_1 >> 8) & 0x00ff);
          EEPROM.write(104,rccenter_1_lowbyte);
          EEPROM.write(105,rccenter_1_highbyte);

          byte rcmax_2_lowbyte = (RCMAX_2 & 0x00ff);
          byte rcmax_2_highbyte = ((RCMAX_2 >> 8) & 0x00ff);
          EEPROM.write(106,rcmax_2_lowbyte);
          EEPROM.write(107,rcmax_2_highbyte);

          byte rcmin_2_lowbyte = (RCMIN_2 & 0x00ff);
          byte rcmin_2_highbyte = ((RCMIN_2 >> 8) & 0x00ff);
          EEPROM.write(108,rcmin_2_lowbyte);
          EEPROM.write(109,rcmin_2_highbyte);

          byte rccenter_2_lowbyte = (RCCENTER_2 & 0x00ff);
          byte rccenter_2_highbyte = ((RCCENTER_2 >> 8) & 0x00ff);
          EEPROM.write(110,rccenter_2_lowbyte);
          EEPROM.write(111,rccenter_2_highbyte);
        }

        //We're done with calibration! Flash the LED a few times to indicate success.
        for(byte caliblink = 0; caliblink < 10; caliblink++) {
          PORTB |= (1 << 5);
          delay(BLINK_DURATION);
          PORTB &= ~(1 << 5);
          delay(BLINK_DURATION);
        } 
      } //End of master calibration routine

    } //End of check signal over calibration threshold

  } //End of check signal good

Beyond Unboxing: Sensorless Chinese e-Bike Controller Roundup

Nov 05, 2012 in Beyond Unboxing

It’s time for SCIENCE!

As promised in my last post about the Jasontroller’s seemingly language-barrier-impeded sentience (it is screaming to be heard, but we (mostly) cannot hear its 16kHz switching frequency?), I have a pile of different Chinese electric bike controllers purchased from several eBay sellers. They were pretty much all purchased about a month or more ago with the goal of eventually exploring this functionality. This perhaps betrays the planning of this post for a long time.

I’m generally more willing to accept the sketchiness of generic Chinese products than most people. There really is no one company, dealer, seller, or support website for dealing with these controllers. They’re made to fit one or several models of electric bikes and mopeds, one-for-one, no questions asked or answered. All of the information on them on the Internet, in the Western electric vehicle hacker world, is pretty much in the form of blog posts, forums, and wikis. This isn’t something I expect to change any time soon, because there are about as many variants of the controllers as models of derpy electric mopeds. Plenty of companies exist that stand by their products and offer support and usage advice, and they are pretty much the go-to if you need something that will undoubtedly work (though this assumption can be a bit challenging at times…). But  half the fun of projects is the hackery, in my opinion, and it never hurts to expand your resource horizon.

So, this post is not intended as a definitive reference on Chinese e-bike controllers. I think I could test a different one every day for more than a year, guaranteed, and still not be through with all the variants. Some of this info might become totally irrelevant if the company turns over or the seller on eBay disappears. The goal is both more immediate: these are specifications that are known to be good RIGHT NOW, but may not be this time of next year, so buy it now; and more general: to elucidate some of the Chinese controller marketing words such that everyone can look out for future variants and understand what goes inside of one, and why they are not bad, per se (You can’t sell millions of abad thing that people have to use day to day…. or can you?!), but that we, weird brushless scooter and go-kart and e-bike guys, use these devices generally far out of their original design specification.

Which, given how much the same commercial, street-legal electric bikes and things are, is likelyvery very narrow. A recurring trend of the lineup is that they pretty much use the same components in various permutations – things which have stood the test of time and probably stochastic layout design selection. I now present…

(more…)

How to Tame Your Shady Chinese e-Bike Controller: Self-Learn Hall Sensor Calibration Mode

Nov 03, 2012 in Beyond Unboxing

In my continued quest to discover new ways to EV on the cheap for builders, I’ve worked on demystifying several types of sketchy Chinese motor controllers to assess how applicable they are to little electric rideable things. My most recent favorite has been the “Jasontroller” electric bike controller. Like every other generic Chinese electromechanical product – it has no actual real name (the “Jason” moniker started as an inside joke in our EV contingency and is a bit of a satire on companies like Kelly), no well-known company with customer support to back it, nor any real details about hookup and operation.

(Scheduled plug: By the way, I still have alot of stuff for sale!)


Do you guys, like, know eachother?

Most of these generic Chinese e-bike controllers are pretty much the same functionality and firmware-wise, but what appealed to me specifically regarding that model is that it has a reasonably competent sensorless mode, complete with motor current limiting, for driving inertial loads, specifically vehicles. R/C type aircraft and car ESCs just aren’t the same in this regard; more details can be found in my Instructable on the matter. I’ve found that the sensorless mode on the Jasontroller is fine enough for scooters (and their design target, electric bikes) because you can always move just a little to avoid the zero-speed condition that sensorless is worst at. For things where you don’t get to push off, like Chibikart and DPRC, they’re somewhat hopeless. The algorithm is very simplistic and typical of ‘block’ commutation startup – just open-loop power the motor phases until a valid phase voltage waveform is detected. Usually in the case of an inertial load, the slow bobbing of the rotor is not strong enough to cause any significant motion and the startup fails. In the case of a cheap R/C type controller with no current limiting, the controller explodes from having to power a stalled motor.

While the controllers usually do have a Hall sensor connection, the hard part is adding sensors to the motor itself and connecting them correctly. In the past, I’ve accomplished this by both putting them inside the motor as well as outside on 3D printed mounts and cute sensor holder rings. Then, explaining the process of lining up the 3 sensor bits with the 6 internal states of the 3 phase motor usually takes at least half an hour and much confusion – without knowing the way the motor was wound (i.e. you didn’t wind it), there’s 12 possible ways to hook up motors and sensors and some times you have to brute force them all before finding the right one.  Additionally, sensors aren’t optimal at anything except low speed anyway because they suffer from hysteresis-induced timing lag.

Optimally, you’d have a controller that uses the Hall sensor feedback just to kick off. Even if the sensor combo was total bullshit, actively driving the motor in one direction and getting some kind of positive position change is enough to begin ramping the motor sensorlessly up to speed.

What I’ve been kind of hiding is that many of the latest generation e-bike controllers, including the Jasontroller (I have enough of an emotional connection with the thing to name it), has this exact functionality. I’ve never explored it until recently when curiosity got the best of me, and I think this is a total boon for everyone who is building small EVs. It is now my goal to explain how the mode is used and what its limits are. There appears to be some confusion on how the mode is used (example and another), and as a result I haven’t seen it frequently mentioned.

We begin with a picture of the rear of a Jasontroller, where the mysterious Chinese sticker is located.

For your entertainment, I’ve fansubbed the Jasontroller below. I’m not gonna claim perfection with my several-versions-out-of-date Chinese language drivers, but hey, who else is gonna give you an English manual?

All of the Chinese e-bike controllers you can find are probably generally wired the same way. The funny thing is, as amusing as these devices are to me and many other EV hackers, I’m willing to bet that literally millions of people use them on a day to day basis and find them nothing too ordinary. These are generic replacement controllers for electric bicycles, moped, and scooters made and used by the millions in China. To people who have one of those things, it’s like changing windshield wipers or something.

Take note of the “Self Learn” wire in the lower right. The instructions on the bottom are basically how to use the self-calibration mode of the controller.

The magic green (may be other colors on your specific variant) wire is usually embedded in the forest of wires these things come with. It’s terminated in a small snap-on connector.

Basically, the controller recognizes that this pin is connected when you first power on. It attempts to run the motor sensorlessly and captures what the Hall sensor waveform looks like, saves it to memory, and then when throttle is commanded, it will power the phases according to what state the motor is in and what it ‘saw’. You can indicate that the motor is being learned in the wrong direction (by unplugging and reconnecting the self-learn wire once) and it will reverse the direction and record the states again, saving that and associating that direction with “forward”.

Nifty. That’s so much software I can’t imagine ever doing it myself. Luckily, some smart Chinese guy has figured it out (and probably got pirated).

Here’s my Rig of Science that I set up. A 63mm outrunner with my custom Hall holder rig, externally adjustable so I can try and confuse the Jasontroller. The jumper wires that connected the sensor board to the controller was also rearrangeable. Basically, I wanted to see how much bullshit I can feed it and still have the thing work.

The process was basically to train it on a specific sensor arrangement, then swap the sensor combination around and move the board such that the timing is terribly off, and combinations thereof.

What I found was the following:

  • If sensors are present and the controller hasn’t been trained before, it will use the factory programmed motor state model.
  • The sensors must be 120 or 60 degree space electrically – if there is significant inequality in the spacing, the process incrementally gets worse and worse with spacing error until it just errors out.
  • If the sensors are incorrect (do not result in continuous motion) or throw an error for any reason, it will automatically try to switch to sensorless mode.
  • Once “trained” for a specific sensor arrangement, it will retain that and use it for any other motor it is connected to until trained otherwise, pursuant to the above rule.
  • The sensors are only used for low-speed and stall conditions. There is an audible transition to sensorless mode – the motor sounds “smoother”, lacking the hard-switched sound of the sensored mode.
  • Sensored mode does not bypass the internal hardware “speed limit” as a result – the processor is still only capable of running the motor to a relatively modest speed.

There were moments where I got the controller “stuck” in sensored mode, but I can’t consistently replicate the problem. It seems to happen only when the sensors are horrifically off-timing that, I assume, the sensorless algorithm cannot lock in, but why it doesn’t just ditch the sensors at that point is not known to me.

Additionally, another weird symptom that happened several times but I cannot replicate reliably is that if only 2 sensor wires are swapped, it catches on and figures the problem out. The first start is false and runs sensorlessly, but the next start is properly adapted to the new sensor arrangement.

The fuck? Are these things actually sentient and just messing with me instead of vice versa?

Basically, what I found is that if you line up any sensor with a slot (placed in the middle), the controller will figure it out just fine. For any sensor over a slot, there’s a valid combination that will result in motion, maybe not in the intended direction (but that is what the “reverse learn” switch is for, right?). In the above picture, the rightmost sensor is centered over a slot. I don’t have any info on how this motor wound, so which slot it is is completely not known!

If a sensor is not centered in a slot, then the startup gets rougher and rougher with increasing error until it just switches to sensorless. The transition between sensored and sensorless mode also becomes less smooth.

summary

Here’s a video where I demonstrate how to use the auto-calibration as well as illustrating what happens if a sensor is not located over one slot.

conclusion

Suddenly, the Jasontrollers have become alot more favorable to me. I’ve had a few of them die running all-sensorless into an R/C type outrunner because the current limiting circuit is just not fast enough for those motors, which are generally super-low inductance (current changes very quickly).

Not even Kelly controllers can do this sensor auto-recognition thing right now, and they are currently my go-to for when someone asks me what controller to use for their brushless setup. Calibrating sensors and adjusting timing is one of the worst “black box” magic processes that people have to do, and they matter alot in having smooth vehicle operation.

This neat little feature will save alot of time and effort in vehicle construction. All you really need now is a way to mount sensors to the motor.While I now favor external sensors for outrunners due to their ease of adjustment, the controllers having an automatic sensorless switchover after a certain speed means that embedding sensors in the middle of a slot (inside the motor, by taking it apart) is completely reasonable. This would be an option for people who do not have, or want to make, an external sensor-holding jiggie thing.

I’m probably going to try throwing Halls in DPRC‘s 50mm outrunners in order to truly test this hypothesis under load.

Of course, now I also really want to start selling these sensor holders and boards. Perhaps that will be a product line parallel to RageBridge


Seeds for your melon

In conclusion,

Why should I go to the length of adding sensors to my motor to use this feature?

Most commercial sensorless motor controllers usually fail at zero and low speed because they depend on having a voltage feedback from the motors to determine rotor position, only possible with continuous motor motion. This means you have to be moving before you can move. While this is okay for, say, scooters and bikes because it is totally reasonable to push off with a foot before hitting the throttle, the same is not true of go-karts, robots, wheelchairs, etc. which you cannot really push off without compromising the function of the vehicle. These MUST have a “zero speed” torque on demand.

What should the motor and sensor arrangement be?

The sensors should be spaced 120 or 60 electrical-degrees (both industry standards), mostly because they divide equally into 360 degrees. Incorrect spacing will probably just result in the controller bailing out to sensorless mode anyway. The way to tell is if the motor has very little startup torque or just twitches helplessly. One sensor should be aligned with 1 slot between the windings on the stator and the controller will be able to figure out the rest. This is true for a standard 12-tooth stator with fractional magnet to slot ratio, anyway – other motors are currently not determined. If the sensor is not aligned with the slot, the startup and switchover transition become rough and rougher with positioning error.

Is this really simpler than running a normal, all-sensor-commutated controller like a Kelly?

Oh hell yes. There is no more playing the keep-it-change-it-flip-it game with sensor vs. phase combinations.

So, simpler, and I believe potentially better. Hall sensors introduce significant timing lag at higher speeds, and the optimal sensor position also changes with speed and load. Having the sensors there only for startup solves the low end torque issue, while driving the motor sensorlessly at high speeds effectively means you drive the motor more according to how it wants to be driven at a given speed and current draw.

Note that your shady-ass generic Chinese e-bike controller may be different. I can only account for the controllers retailed by “bobzhangxu” on eBay at the moment. However,

That lead image. Be prepared for a massive Beyond Unboxing post in the next few days where I will attempt to catalog several different shady e-bike controllers and see which ones can perform this training routine! I literally went on eBay and bought 1 of every controller that was under $30 with free shipping or under $40 with shipping. There are 7 in total. The intention is to make an index like my copier motors spreadsheet.