My experience with siliXcon's advanced controllers in both the EM Race and the Mecatecno Dragonfly left me highly impressed with the company and their products. This sparked a general curiosity about how these controllers work on a deeper level, which ultimately led to my purchase of their SX controller. Initially, I had no plans to replace the controller in any of our trials bikes. Instead, my experiments were carried out on the bench using a surplus BLDC motor. However, as Cindy grew more comfortable with the Dragonfly, she agreed to part with her EM 5.7, giving me the opportunity to use it for experimentation.
The following is in no way intended to be a step-by-step guide to system integration. It's really just a description of a first-time user's journey.
I selected the SX controller over the SC partly because that's what's being used on the FACTOR-e, and partly because it uses a newer microprocessor (but they don't say what it is). Mostly, I just liked the SX's external connection methodology much better than the SC's.
Initial contact with siliXcon was sometime in December 2024. On December 18th, I got a price quote and expected the shipment could occur prior to the winter holidays. Nope.
I asked for their part number esc5-sx1_24kxa1040-C00_00XTG-000BM, which is a standard product with an 18 kW rating. It is described as having GPIO, USB, CAN, isolated 5V UART, non-isolated 5V UART, LM5008 power supply, analog inputs for sin-cos encoder and Hall sensors. It has a 400A current measure range.
For a quantity of one, I was quoted €425 plus €131 for DHL shipping to the USA (but it came via FedEx). siliXcon does not accept credit cards, so my bank initiated an international wire transfer that cost me $50. I realize there are online businesses that perform those types of transfers, but I really did not want to research them and establish an account for this single transaction. In the end, my bank transfer may not have cost much more, since the dollar/euro conversion rate was probably better than many online places. Total cost was about $625.
I initiated the wire transfer on January 10, 2025, and received the controller on January 23rd.
Bench testing SX controller with Motenergy motor, Dragonfly battery, Magura throttle, and orderly showdown tether kill switch.
siliXcon's online documentation is fabulous! It makes understanding the system much easier than it would have been even 3 years ago (when I first looked at the products). The technical English is nearly flawless, and being web-based it's easy to correct mistakes and keep everyone on the latest information. The following are a few things I found enlightening.
Quote: “Bat+ and Bat- power inputs are not protected against reverse polarity. The power input for logic circuits operating with battery voltage is not protected against reverse polarity.”
Webmaster's comment: Not unexpected. Be careful!
Quote: “If controller does not turn on and has an internal fuse, it is possible that the internal fuse is blown. This can be easily checked by disconnecting the controller from the battery and disconnecting the controller signal wiring. Then, use a multimeter to measure resistance between BATT+ terminal and KEY pin. If the value is not near to 0 ohms, the internal fuse is blown. An external 3A slow blow fuse between BATT+ and KEY pin could be used to temporarily fix the problem.”
Webmaster's comment: Good reminder. I thought that could be a workaround if the internal fuse ever blew. But you have to ask yourself: If the internal fuse blows, is the controller junk anyway?
Quote: “Verify that the LED status indicator on the controller is turned on for a few seconds after start-up and then turns OFF. If the indicator is flashing or steadily turned ON, it indicates an error/warning or other fault condition within the controller.”
Webmaster's comment: Although we don't normally see that LED on our bikes, it would make a good diagnostic aid.
When I purchased the controller, siliXcon wanted €38 for the mating connector and pins that needed to be crimped. They suggested that I could probably obtain the connector less expensively locally. Maybe, maybe not.
The important thing to note is that two styles of this connector are made, one with 3 locating slots and one with 4. The 3-slot version is what's needed (photo at top of page shows this).
The AMP part number for the connector may be 4-1437290-0. It costs about $10 from Mouser Electronics (pins not included). But I'm not certain it's the 3-slot version. There appears to be a disagreement between the parts vendor and siliXcon that I did not bother to reconcile.
AMP part numbers for the pins are:
3-1447221-5 for 22 wire gauge, $36.60 per 100
3-1447221-4 for 20 wire gauge, $33.80 per 100 (This is probably my preferred size.)
3-1447221-3 for 18-16 wire gauge, $33.80 per 100
Fortuitously, I found the correct connector on AliExpress for about $15, which included 30 cm of #20 AWG wire already crimped to each pin. The connector I received was marked AMP and I think it's genuine. I also bought another connector via AliExpress for about $5 that came with thirty-four 3-1447221-3 pins. It was marked IIIB, and is a fine quality too.
One of the things that makes this particular connector so great is that no special tool is required to remove pins. Simply push on the wide white tab (not visible in photo) to unlock. This allows pins to be inserted and removed. When done, push on the two smaller white tabs on the opposite side to lock the connector. This is really handy for experimental work.
Below is a spreadsheet of the connections I made for testing. The various colors indicated related signal groups.
34-pin AMP connector purchased via AliExpress
I bought the motor on eBay for $250 + $34.23 shipping. It's a lot of motor for the money. Although sold as used, it was a brand-new motor still in the manufacturer's original packaging which was marked “Zero Motorcycles, Scott's Valley, CA”. This motor is being sold elsewhere for over $600. The only real disadvantage is that it's not sealed. But I don't care since it will only be used for bench testing. I feel the slow speed is another advantage for bench testing. Interestingly, it's an axial flux design (like the EM 5.7) but the seller never mentioned that.
Specifications from the seller:
Motor has 8 magnets, 4 pole pairs.
Rotor position feedback is a sin-cos sensor made by Renishaw, part number RMB20AC01SS1
Designed to run at 2500 rpm with a 48 VDC battery pack. A 72 VDC battery pack is 3750 RPM loaded, 12.6 kW peak, 16.8 HP.
Maximum continuous current can be 100 amps with proper air cooling, rated for 250 amps for 2 minutes.
Temperature sensor is a KTY84-130 thermistor [ 603 ohms @ 25° C ].
Maximum rotor speed is 5000 rpm. If you exceed this speed, there can be severe damage or personal injury.
Winding is 24 turns per phase, 3-Phase, Y-connected.
The earliest copyright date on siliXcon's LaunchPad software is 2010, so they have been at it a while. It shows.
I was easily able to make the motor spin via either LaunchPad commands or a potentiometer connected to the throttle input.
One thing I found super-cool is that the Terminal includes a command to “play a song,” similar to how the map tones are generated. There are three predefined songs, although none were familiar to me. Interestingly, I managed to get this feature working before making the motor spin. It brought a huge smile to my face! I even suggested that siliXcon create a song that spells out the company name, but there didn’t seem to be much interest in the idea.
Regarding the company name, I started pronouncing it “silly-ex-con” (which is quite pejorative in American English). Jordi Mila pronounces it “sil-icks-con.” That makes a lot more sense, and I will endeavor to say it that way. But it's particularly difficult for me because I inevitably think of the old MOSFET company, Siliconix. I also finally caught on to the fact that the company does not capitalize the S in the name. Also, maybe the X is construed as “cross” in the European tradition? So, a cross of silicon and controller?
This is the same sin-cos encoder that's used on the EM Race. It came installed on the Motenergy motor. Wire colors are as follows:
blue, sine
white, cosine
black, ground
red, Vcc (5VDC)
green, shield
white, thermistor
white, thermistor
Documentation quote: “When connecting to a PC, use galvanically isolated communication devices to prevent potential damage to the PC.”
It is safe to use an un-isolated USB connection when the motor is stopped. However, if you want to monitor signals with the motor running, it's certainly possible that high-voltage spikes can be induced on the wiring.
When I first started experimenting with my EM Race controller, I used a cheap Chinese USB isolator. Frequently, LaunchPad would say the connection was “inconsistent” but seemed to work anyway. Removing the USB isolator fixed this same problem on the SX controller. Peering inside revealed an ADUM3160 isolator that is intended for 0.5 Mbps (low speed) and 12 Mbps (full speed) USB communications.
I eventually acquired an isolator based on the ADUM3165, which is rated for 480 Mbps (high speed). Although I no longer saw the inconsistent communications message when using the 480 Mbps isolator, there was still a lingering annoyance. A siliXcon app note describes the reason:
“To communicate with a controller during operation, you must first connect the controller to a power source (battery) and then connect the USB. Reverse order only leads to activation of the processor without power stage, the driver layer will not initialize.”
siliXcon really wants you to use the CAN bus instead of a USB interface if the motor is running.
ADUM3160 inside cheap USB isolator
After making all electrical connections, the first firmware configuration task is to use identlin from within LaunchPad. This software routine attempts to identify some of the motor's electrical parameters. Quite a lot of data is reported, with values given for all three phases in unbiased, half-biased, and fully biased conditions for both the direct (D) and quadrature (Q) axes. The bottom line numbers for my Motenergy ME-1206 are as follows:
Zero current, phase to phase: 17.9739 milliOhm, D 81.4426 microHenry, Q 101.791 microHenry
The following values are then provided as configuration parameters and automatically sent to the controller:
suggested Rt = 8.98697 milliOhm
suggested Ld = 40.7213 microHenry
suggested Lq = 50.8957 microHenry
We can see that the suggested configuration values are exactly half of the phase-to-phase values. This means that the configuration file values are for a single phase winding — which would be impossible to measure directly unless the motor's wye neutral connection is available.
I found this fascinating because I was never satisfied with my attempt to reconcile the 5.7's Golden Motor datasheet with my measured values and those determined by the VESC.
So what are we seeing? Firstly, the simplest value “Rt” is the DC resistance of a single phase winding including any wiring between the motor and controller plus the on-state resistance of the MOSFETs themselves. Yes, of course it is! How else could the controller make such a measurement? But not until reading siliXcon's documentation did that become crystal clear to me.
The inductance values are a bit more complicated. Consider two facts:
Inductance is inversely proportional to reluctance.
The reluctance of air is much greater than that of a ferromagnetic material.
By definition, in the Direct axis, a magnet is aligned with a motor coil. This implies a lower inductance based on the aforementioned facts. Ld was measured as 40.7 uH.
In the Quadrature (rotated 90 mechanical degrees) axis, a magnet is in-between motor coils. This implies a higher inductance. Lq was measured as 50.9 uH. So far, so good.
But comparing these inductances with those measured by a laboratory instrument introduces yet another complication - that of the measurement frequency. I have a very nice Wayne Kerr 3245 precision inductance analyzer. It can measure inductance at any of 42 frequencies ranging from 20Hz to 300 kHz. A typical cheap handheld inductance meter might use 1 kHz. I have one of those too.
Below are the values given by my Wayne Kerr:
DC resistance of 14.4 milliohms. Remember, this is for two phase windings in series. Even so, it appears a little low. But when the external wire and on-state resistance of the controller's MOSFETs is also considered, it seems right.
As for inductance (again, for 2 windings in series) I measured:
115 uH @ 100 Hz
94 uH @ 1 k Hz
70 uH @ 10 kHz
I assume I was measuring the Direct axis (since that's where the rotor pulls itself into alignment). So I would be expecting a value somewhere around 80 uH. But that neglects the small inductance of the wiring between the controller and motor. So the value of 94 uH at 1 kHz seems fairly reasonable. And remember, the controller specifies quite a wide tolerance for measurement accuracy (several percent error is to be expected).
Finally, these are inductance values reported at zero current. As the current through a coil increases (described as bias current above), its inductance decreases (due to magnetic saturation).
Oh, and note the nice presentation of units — milliohms and microhenries. The values reported in the configuration parameters are a bit harder to decipher because they are expressed in scientific (not engineering) notation using ohms and henries. A verbatim example follows:
/driver/motor/Ld : 4.07213e-5
/driver/motor/Lq : 5.08957e-5
/driver/motor/Rt : 0.008986
The second firmware configuration task is to use identrun from within LaunchPad. idenrun causes the motor to spin-up (accelerate) and attempts to identify some motor parameters while it is coasting to a stop. The rotor angle sensor parameters and flux linkage (Kv) of the motor are measured. The main motor constant /driver/motor/psi and related motor sensor parameters in /driver/rest/ are identified.
The Greek letter psi represents the flux linkage for a BLDC motor. This parameter defines the main motor constant - the relation between voltage and speed, as well as between the current and torque.
Quote: “Turning off the controller during flux weakening should be avoided at all costs, as it can lead to permanent damage.
Do not use a kill-switch that turns off the controller. Instead, set the drive mode to freewheel and allow a controlled deceleration first. For such a purpose, the LYNX implements a seat switch feature. This disables the ride, but keeps the controller alive.”
Comment: This is a potential problem with the Dragonfly, EM's Race (and possibly other) implementations. The “seat switch” option could easily be implemented as a tether kill switch instead. But it would seem impossible for the end-user to retrofit.
My very preliminary experiment with flux weakening worked! Because the base speed of the motor is a function of battery voltage, I purposely used a fairly depleted battery (~51 volts). The Kv constant for the Motenergy motor is about 70 RPM / volt, which produces a base speed of about 3600 RPM. This was very much in line with my actual measurements. I used an optical tachometer to validate the speeds shown in LaunchPad. It's sometimes a bit difficult to get motor RPM directly out of LaunchPad as everything is set up to deal with a final speed in kilometers per hour (KPH).
To initiate flux weakening, I altered one parameter in /driver/dac/fwc (flux weakening current limit). This value is represented as a fraction of Iref. A value of zero turns flux weakening off, which is the default condition. I started with a fairly conservative setting of 0.35. This produced the desired result, and allowed the motor to reach at least 4000 RPM (which is where I had an absolute KPH speed-limiter set).
Because I want to experiment with flux weakening, I implemented a seat switch using a standard trials lanyard kill switch (magnet absent closes switch). I selected GPIO2 (SX pin 30) for this function. siliXcon's documentation was a bit confusing at first, but eventually I figured out that /io/IN_seatswitch needed to be set to 18,0 and /common/ioconf2 needed to be 1 to enable a pull-up on that port. Part of the confusion stemmed from the fact the GPIO2 may be configured as either an analog or a digital input. The seat switch works properly and gently slows the motor while keeping the controller enabled. In fact, the controller causes the motor to constantly emit an error tone while the throttle is open with the lanyard's magnet removed.
Considering that I hate lanyard kill switches, I think my preferred implementation would eventually be a tip-over switch such as those used on the Montesta 4RT. This is also known as a bank-angle switch in the sportbike world. eBay is littered with used ones. I ordered a switch from a 2018 KTM RC390 for experimentation. It's marked JY403604. Unfortunately, KTM's wiring diagrams do not provide any insight as to how things actually work. So I made some educated guesses as to wire functions (which are correct):
Red/Blue = power input (12 VDC)
Yellow/Black = common
Brown/Green = signal output
Supplying 5 VDC power also works. In this case, the output was about 3.5 volts in the upright condition. The output transitions to 0 volts when tipped over (+/- 60 degrees).
A weak pull-up resistor (47k ohms) on the signal output did not change the output voltage.
Tip-over sensor shown in the “tipped over” orientation
My test setup comprises a cable-actuated “accelerator” from a Sur Ron. This is the same setup I used to implement an electronic clutch on Cindy's 5.7. The accelerator is an analog Hall device with a voltage range of about 0.9 to 4.3 volts.
I changed siliXcon's default I/O pin assignment for dynamic braking to match the EM Race. My I/O mapping is presently:
GPIO0 throttle (analog)
GPIO1 brake (analog)
GPIO2 seat switch (digital)
GPIO3 map button (digital)
GPIO4 not used
It's a bit difficult to test dynamic braking on the bench with just the inertia of the motor. The brake action completely overrides the throttle. If the throttle and brake are applied simultaneously, the motor quickly comes to a stop and emits protest beeps.
The only way to really test the progressiveness is to release the throttle and immediately actuate the brake. The deceleration is quite rapid, since the motor spins down fairly quickly on its own anyway.
This same setup could also be used to test siliXcon's electronic clutch implementation.
Dynamic braking controls
The USART that sends data to the WS LED can alternatively send data to three different bicycle displays. The cheapest among them was the KT LCD-3, which I ordered via AliExpress. It was about $30. Although this would not be a drop-in replacement for the WS LED, it seems only one configuration parameter (dispmode = 4) would need to change.
After working with this for a while, I learned it's not really a plug-and-play item. Unfortunately, neither siliXcon nor KT provides much in the way of documentation.
A brief exchange with siliXcon support indicated the SX controller does not just send data to the KT-LCD3, the display must request the data. This requires an additional USART data line. For now, the juice is not worth the squeeze. It would be better to concentrate on getting data via the CAN bus, which would be directly applicable to the EM Race, whereas the KT-LCD3 would not.
Red wire: Anode (up to 72 volts)
Blue wire: Controller Enable (not used)
Black wire: GND
Green wire: RxD (Display RX --> Controller TX, pin 33)
Yellow wire: TxD (Display TX --> Controller RX, pin 32)
A bit of reverse engineering revealed the KT-LCD3 does autonomously send data packets (13 bytes every 100ms). The serial protocol is 9600 baud, 8N1.
KT-LCD Bicycle Display
I'm still trying to figure out how best to document the parameters. Maybe a spreadsheet? For now, here are a few that are easy to describe:
Each map has several individual settings that include maximum ground speed (kph), maximum motor power (pwr), and maximum torque relative to the maximum permitted (trqlvl). They are of the form:
/maps/map1/kph 15.0
/maps/map1/pwr 3000.0
/maps/map1/trqlvl 0.5
This equates to a maximum ground speed of 15 kph, a maximum power of 3000 watts, and half of the maximum possible torque. Torque is directly proportional to motor current. So, a trqlvl of 0.5 would permit delivering up to half of the maximum motor phase current (which is defined elsewhere).
/maps/map1/csc_exp 1.1
This is the throttle exponent. Values greater than 1 soften the initial throttle response. Values less than 1 have the opposite effect. An exponent of exactly 1.0 is linear. Values between 1.1 and 1.25 are probable the most common for a motorcycle, but I think it could depend on a lot of factors, including absolute power available and rider preference.
/gearthr is the number of motor shaft revolutions per single wheel revolution. I chose 13.93 because that it what's used on the EM 5.7 (which has a motor that revs to 4000 rpm).
/odothr is the number of wheel revolutions per kilometer. I used 480 for a trials tire. Very roughly, a loaded trials tire is 2 meters in circumference. So, equally roughly, it takes about 500 revolutions to travel a kilometer.
Below are screenshots of all the parameters I have changed from the defaults so far.
Quote: “At the end of the lifetime, firmware is removed from SRM and is no longer available for upgrade. The lifetime does not affect the functionality of the device if the lifetime ends. You still can have an old release installed on the device. Stable: 2 year, Testing: 6 month, Nightly: 1 month
It is not possible to upgrade only [ some ] of the parameters inside the device.
If the container has a configuration image, all parameters are restored, and the new configuration is applied. For example, this results in the need for new identification of the motor.
The container release can be deployed without a configuration image. In this case, the configuration is not altered.”
Comment: Possibly it was not EM's decision that older bikes can't be fitted with EM Connect?
OBD-II is a firmware option. They say it's only required for vehicle homologation. Regardless, there is a lot of data sent via the CAN port even without OBD-II.
Operating time is recorded in seconds using a 32-bit unsigned value. 2^32 = 4.3 gigaseconds = 136 years. The controller appears to accumulate time just being booted up - the motor does not have to be spinning.
GND, although claimed to be "isolated" is not galvanically isolated. IOGND and GND are only separated by a 47k resistor in parallel with a 100 nF capacitor.
PROBLEM: Controller internal temperature reported as ~40°C, in a ~20°C room from a cold startup.
SOLUTION: “The temperature precision is around +/-3°C. Due to self-heating of the surrounding components, the temperature reaches around 30-40°C in room temperature even in the idle mode (depends on the particular hardware).”
PROBLEM: Have the WS multicolor LED connected. It does light up, and changes colors, but not correctly. Not sure what's wrong there. Have a map push-button connected that cycles though the 3 default maps. The motor emits a different tone as each of the three maps is selected.
SOLUTION: I had the LED connected to the wrong USART (called UART in SC). Signal names for the SX controller are different from the SC controller. Counter to my intuition, it goes on the isolated USART, not the un-isolated USART. Frankly, I'm stunned that it lit up at all!
PROBLEM: Speed limiter not working properly. I created 3 maps with 5, 10, and 15 KPH speed limits. All of them allow the motor to run faster than specified, but are not wrong by the same percentage.
SOLUTION: The parameter rdec (speed limiter decrement function) had a default value of 1000. I set to 100. Now there is a small speed overshoot (a few percent), and the amount is fairly consistent over the various maps. I can see where this might have affected the dynamics of the speed limiter, but don't understand why a steady-state speed limit was not obeyed. Perhaps it makes a difference if the motor is loaded versus unloaded.
PROBLEM: Motor thermistor (Rthermistor) resistance not reported correctly. Actual ohms -> Reported ohms: 100 -> 0, 200 -> 81, 300 -> 115, 400 -> 146, 500 -> 171, 600 -> 196, 700 -> 218, 800 -> 235, 900 -> 253, 1000 -> 268, 1100 -> 283, 1200 -> 295, 1300 -> 308, 1400 -> 318, 1500 -> 331
SOLUTION: Not exactly sure what solved this. Bad connection? I also installed the 22k limiting resistor for the On/Off switch, but this should only be needed with 2 push buttons where both could be pressed simultaneously. I used a SPDT On/Off switch that does NOT make before break.
NOT REALLY A PROBLEM: With repeated invocations of identrun, the values returned should converge. They do for everything but rangle which is the sin-cos sensor angle offset is radians. I see values ranging from about 0.005 to 0.01. I have been using the value from the first parameter identification of 0.006024 radians (this is 0.345 degrees). But all the values are less than 1 degree. Close enough! I guess that is something that bugs me in general. Parameters are “identified” to 6+ significant digits when only 2 or 3 digits are accurate.