XPD: open-source keywin e-bike lab replacement

anpaza

10 W
Joined
Dec 7, 2010
Messages
69
Hello guys (and girls, any here? :shock:)!

Last week I had some fun with a couple of Infineon controllers recently purchased from Ed Lyen, and while playing with it I managed to intercept the serial protocol between the software and the controller. The protocol is quite simple, and since I was fed up by launching windows in a virtual machine every time I want to re-program the controller, I sat and wrote a open-source alternative to the Parameter Designer software. Since it allows for a bit larger control over the controller parameters I named it eXtended Parameter Designer, or XPD for short.

The program is written in Python and will run on Linux and Windows; it could run on Mac but the serial-port library I use (PySerial) does not support MacOS. If somebody cares to fix the library, XPD should run there as well.

The protocol itself is documented here (for Infineon version 2) and here (Infineon version 3). Now if somebody doesn't like my program, he can always write his own :)

The XPD itself is hosted at SourceForge (previously hosted on now-dead BerliOS.de, then on now-dead Google Code). People using Linux should be able to use it without too much hassle; for Windows users I'll explain a bit in details how to install & run it:

a) Download everything from the support directory (the files may be deleted after they are used):
* python-2.7.1.msi - This is Python interpreter, install it first.
* pygtk-all-in-one-2.22.6.win32-py2.7.msi - This is the GTK+ llibrary (the graphical user interface library) and the Python bindings for it, install this after Python.
* pyserial-2.5.win32.exe - Run this to install the PySerial library

b) Now download the latest version of XPD (the Windows executable ends with "-windows.zip"), and unzip it to C:\Program Files\ (or any other place at your choice).

d) Open the xpd-x.x.x folder (created when you extract the archive), you will see two icons: the XPD program and the XPD icon. Run the program (not the icon :)) with a double-click. If all goes well, it should start and you will see a window like the left one:

screenshot.png


e) If you intend to use it often, create a shortcut for it (Ctrl+Shift and drag the program to desktop), then you may change program's icon to the one provided in xpd' directory.

If you still have troubles with installation, look at this video tutorial:
http://www.youtube.com/watch?v=Lgb_KMBwFxM

---

I hope program usage scenarios should be obvious to anybody who can deal with the original "e-bike lab".

Also note that every parameter has a pop-up explanation that appears if you keep mouse cursor over a parameter longer than a few seconds. I wrote those explanations off the top of my head, after reading the endless-forums and some other sources; as you may imagine the contents of my head right now remembers a saucepan of vegetable soup rather than a glass of clear water. If you see any incorrect statements (and even language errors - my native language is Russian) - please report, either via the bugtracker on the XPD site, or by email, or here. If you find any bugs - please report. If you add any new features (for example, translate it to a new language) - please submit patches :D
 
Holy Cow Batman!
That looks like an awesome alternative to the "standard" e-bike lab. And you seem to have put a lot of effort into researching the protocol and the variables.
I haven't downloaded XPD yet because somebody borrowed my netbook I use to program, but as soon as it magically appears back on my desk, I'll try it and see if it works.
 
knew it was about to happen.


Two thumbs up anpaza!


coments:

Overcurrent (BlockTime) = option to set it to 0, to disable overcurrent complety
EBS limit with a higher voltage would be diserable for thoses using lipo hi voltage.
24,32 fets controller profiles
Hidden settings??

BTW would I be able to program a 3077 9fet controller or a 9fet 4110 controller using the same profile?

hehe
 
Cool :)
 
Excellent work. And thank you for your doc on reverse engineering the infineon protocol.

Your english is very clear. Thank you for your work.
 
If the controller has the capability to send this info, it isn't done with any of the PD type software so far extant. Because there isn't any s/w that does it yet, there's no way to reverse-engineer or sniff out the command necessary to cause it to do so (if it even can).

So at the moment, AFAIK, there's no way to do it at all. Maybe the factory can, but I doubt it--they don't care what the controller *used* to be set to, only what they are setting it to *now*. So I doubt the capability was even built into it.

I wish it was, though.


BTW: The concept of XPD is awesome, and very useful. I have not tested it yet, but it's downloaded and waiting for when I have time and a functional spare controller I can verify it with. ;)
 
i do not know if it is possible, but can the following function be added?

i would like to see a advanced screen that can be enabled. (if you do not know the actual shunt resistance you do not enable this option)
in this window you can set the actual shunt resistance. so when you set the controller for 70A it will actually be 70A.
the program than has to calcualate what current limit to set the controller to. the controller uses standard shunt values. so i think this would be fairly easy

all this is to compensate for shunt modding, or for instance programming a 6 fet controller with 18 fet controller settings.

i hope you understand. (if not i will try to explain it more thoroughly)

Niels
 
Very good info, thanks for sharing it !!!

I am just wondering about two things:
1) hows the speed 1,2,3 settings. Did not get that formula from the spec ?
2) hows the checksum exactly calculated ? Sum of elements negated ?

Been hacking several engine management protocols in past, therefore interested just for curiosity. It should be very easy for someone to make a small portable handheld programmer for on field use.
 
Thanks guys for the feedback, that's what I need to further improve the program. I'll make changes according to your comments, and they all will go into the next release.

gensem:

Overcurrent (BlockTime) = option to set it to 0, to disable overcurrent complety
Thanks, I've extended the range of values to start at 0. If you need it before the next release takes place, it's easy: just open the file xpmd/infineon.py (it's a regular text file), search for "BlockTime" and a little below you will see the range for this value - "Range" : (10, 100). Modify the range to (0, 100) and you're set. Of course, as you might guess, the max range is (0, 255), that stands to block times up to 25.5 seconds. But I'm not sure it's sane to let user choose such big values... this could be dangerous for the motor.

EBS limit with a higher voltage would be diserable for thoses using lipo hi voltage.
Unfortunately, 77V is the top limit for the whole range of values (e.g. 255 corresponds to 77V). If you want higher values, you'll have to modify the voltage divider used by the MCU to measure battery voltage, then add a new controller description to xpmd/infineon.py with a different formula for converting raw values (in the range 0-255) to actual Volts and vice versa.

BTW would I be able to program a 3077 9fet controller or a 9fet 4110 controller using the same profile?
If they use same shunt and battery voltage resistor divider as the standard EB206..EB218 model line, then sure.
It is very easy to add new controller descriptions to the program, this is something that even one without almost any Python knowledge should be able to do.
If someone provides me with proper details for other widespread controller models (e.g. the shunt resistance etc), I can add them as well. But of course I can't add every single modded controller in the world, so for those with modded controllers I can write a short tutorial how to modify XPD for their needs.

full-throttle:
Is there a way of reading the parameters on a controller?
As far as I know, there is not. And given the manner how the whole controller programming protocol is implemented on the controller side, the chances are high that this is really not possible.

nieles
As said above, you may easily create your own controller description and add them to XPD (it's Python, and this means the whole program consist of clear text files, not obscure binary stuff). Perhaps oneday I'll write some short explanation how to modify XPD to suit your modded controller.

PetriK
1) hows the speed 1,2,3 settings. Did not get that formula from the spec ?
The docs says:

Code:
Speed1: The speed “1” setting. The actual value to program can be computed from the speed percent (30-120%) with the following formula:

V = SL * 100 / 126
So, 'V' is the actual value programmed into the controller (always in the range 0..255), and SL is the speed limit setting in the graphical user interface (e.g. from 0 to 120 percent). For example, if you want to program a speed limit of 110%, you would actually need to program the value V = 110 * 100 / 126 = 87.

2) hows the checksum exactly calculated ? Sum of elements negated ?
Ahem, do you really read the same doc I wrote? In my document I clearly see this:
Code:
The exclusive disjunction (XOR) of the previous 31 bytes (a kind of check sum).
So, for example, in C you would do:

Code:
crc = 0; for (int i = 0; i < 31; i++) crc ^= data [i];
 
Thx, my chinese interface does not have a flash button as its referred in the text.

I assume the usb is providing +5v and gnd in addition to tx/rx, so there may even be room for one additional wire for reset ?
 
Oh, no...now that means I have to build up a third computer again...Windows, Linux (Ubuntu OK? ) and still have the Mac.
That will be three in the living room plus two in the workshop...the girlfriend is so going to kill me :D

Great work
 
You don't have to, XPD runs on both Linux and Windows. See the part of my first message starting with "... for Windows users I'll explain a bit in details how to install & run it".
 
anpaza said:
Thanks guys for the feedback, that's what I need to further improve the program. I'll make changes according to your comments, and they all will go into the next release...

PetriK
1) hows the speed 1,2,3 settings. Did not get that formula from the spec ?
The docs says:

Code:
Speed1: The speed “1” setting. The actual value to program can be computed from the speed percent (30-120%) with the following formula:

V = SL * 100 / 126
So, 'V' is the actual value programmed into the controller (always in the range 0..255), and SL is the speed limit setting in the graphical user interface (e.g. from 0 to 120 percent). For example, if you want to program a speed limit of 110%, you would actually need to program the value V = 110 * 100 / 126 = 87.
I wonder where the "126" comes from. It seems far more likely that the value would be a "binary" number such as 127. Of course this would not change the calculation hardly at all.

I'm looking forward to giving this a try. However, right now I'm running 132V to a Lyen 24FET controller, so I'm unsure what values to use in your program in its current state.

Thank you very much for creating such a great open source tool! I've grown tired hex-edit patching that old Keywin program.

FA
 
Excellent work!
I'll try this as soon as I get a chance.

Did you manage to find any other parameters we can fiddle with or does your intercept only pick up what the existing software is sending ?
It'd be great if we could up the regen power. Better still I'd love to see switchable current modes like we have for the speed modes now. I'm guessing that'll take more than a bit of software redesign.

Oh and welcome to ES, way to make an entrance :)
 
Thanks for your work!

Excellent job!

You have under 10 post here and already contribute alot!.. I like that!

like some suggested, it would be interesting to have the option for the 24 and 36 fets controller!

Doc
 
I missed this one earlier. Excellent work!
I wish there was a way to hack the actual code in the controller, but can't have everything.

I like the intuitive, user friendly interface.
 
I am browsing it right now... and again... THIS IS AN EXCELELNT WORK!!

Something you could add is the version that would make it perfect is displaying the version.. ex: V1.0 with the date and also the possibility for those who modified the R12 to select a factor or directly the resistor they modded so that the EBS HV and LVC value to allow higher selectable value would be automaticaly rescaled!! and the value selectable would be coresponding to the right active value!

ex. while the max EBS limit voltage is 77.7V with the OEM resistor value of around 1200ohms , we could be able to select or enter a new resistor value... or scale factor that correspond to the R12 mod so when we select the EBS, LVC or otehr affected parameters, they would be displayed with the true value! :D

Kinfish already made some calculatio for exemple:

ormulas:
Ohms = ((V / 36) * 500) – 400; slope given as y = 500x – 400
LV = (V / Vn) * Vl; (V / 3.7) * 3.0
HV = (V / Vn) * Vh; (V / 3.7) * 4.16
where V = Volts, Vn = Cell-Volts nominal, Vh = Cell Volts-high limit, Vl = Cell-Volts low limit

Table:
Volts Ohms LV HV LiFePO4 LiPo
36 100 29.19 40.48 x
37 113.89 30 41.6 10S
43 197.22 34.86 48.35 12S
48 266.67 38.92 53.97 x
55 363.89 44.59 61.84 15S
56.8 388.89 46.05 63.86 16S
60 433.33 48.65 67.46 x
64 488.89 51.89 71.96 18S
72 600 58.38 80.95 x
74 627.78 60 83.2 20S
85 780.56 68.92 95.57 24S

and also Hyena that made an XLS calculator for that so you can use the formula or if you already know how it work ... as well
http://www.endless-sphere.com/forums/viewtopic.php?f=2&t=23745&p=390978&hilit=r12+calculator#p390978

Doc
 
Floont said:
I wonder where the "126" comes from. It seems far more likely that the value would be a "binary" number such as 127. Of course this would not change the calculation hardly at all.
Yes, I was thinking like you, but the reality is that the constant is 126. I double checked-that :)

The coefficients are calculated with a linear regression in a spreadsheet. I just build a small table with "user-visible value : programmed controller value" and then build a linear regression based on these values. The resulting formulas may be not absolutely exact, but should be close, and, anyway, the controller is not a high-precision device, so even its native formulas may get way off the real values.

Floont said:
I'm looking forward to giving this a try. However, right now I'm running 132V to a Lyen 24FET controller, so I'm unsure what values to use in your program in its current state.
Is this a stock controller, or self-made? What program are you using to program it? If it is a widespread model, you can give me a link to the modified "E-Bike Lab", I will reverse-engineer the formulas like I did for EB206-218. However, if it is self-made from any stock controller by just adding extra FETs and modifying some resistor values (including the shunt), you may tweak the file xpdm/infineon.py and add your own controller. For example, let's suppose you modified an EB212 by adding 12 extra FETs and chopping down the battery voltage measuring resistor twice. In this case you would copy the section starting with <<"Name" : "EB212",>> and copy it to the end of the ControllerTypeDesc array, like this:

Code:
    {
        "Name"             : "EB224-floont",
        "PhaseCurrent2Raw" : lambda I: I * 0.625 - 7,
        "Raw2PhaseCurrent" : lambda V: 11.2 + (1.6 * V),
        "BattCurrent2Raw"  : lambda I: I * 0.624 - 1.5,
        "Raw2BattCurrent"  : lambda V: 2.404 + (1.603 * V),
        "Voltage2Raw"      : lambda U: U * 3.283,
        "Raw2Voltage"      : lambda V: V / 3.283,
    },

Now you will want to modify the formulas used to convert raw values to volts, volts to raw, and same for phase & battery current. For example, if you chopped the shunt twice, you will want to change the PhaseCurrent2Raw formula so that the resulting value will be twice lower for the same Amps:

Code:
    "PhaseCurrent2Raw" : lambda I: I * 0.625 / 2 - 7,

The 'lambda' keyword defines a one-line function in Python, so "lambda I:" defines a single-line function with one argument named I.

Now the reverse formula must be changed symmetrically:

Code:
        "Raw2PhaseCurrent" : lambda V: (11.2 + (1.6 * V)) * 2,

('V' here stands for the raw Value).

Also, since the current shunt will also affect the battery voltage calculations inside the controller, we must change the formulas for the battery current as well:

Code:
        "BattCurrent2Raw"  : lambda I: (I * 0.624 / 2 - 1.5),
        "Raw2BattCurrent"  : lambda V: (2.404 + (1.603 * V)) * 2,

Now for the voltage measurements. If you change the ratio of the resistor divider that is used to sense battery (and regeneration) voltage, you must change the formula so that it is true for the new ratio. Let's suppose the original controller uses 1200 Ohm for the lower resistor in the divider, and you changed it to 600 ohm, so the actual values on the microcontroller ADC will get twice smaller for the same voltage. In this case, you will need to change the formulas for the voltage to raw and raw to voltage conversions like this:

Code:
        "Voltage2Raw"      : lambda U: U * 3.283 / 2,
        "Raw2Voltage"      : lambda V: V * 2 / 3.283,

So, the whole final variant would look somehow like:

Code:
    {
        "Name"             : "EB224-floont",
        "PhaseCurrent2Raw" : lambda I: I * 0.625 / 2 - 7,
        "Raw2PhaseCurrent" : lambda V: (11.2 + (1.6 * V)) * 2,
        "BattCurrent2Raw"  : lambda I: I * 0.624 / 2 - 1.5,
        "Raw2BattCurrent"  : lambda V: (2.404 + (1.603 * V)) * 2,
        "Voltage2Raw"      : lambda U: U * 3.283 / 2,
        "Raw2Voltage"      : lambda V: V * 2 / 3.283,
    },

I hope this is not very complex to understand for the average user that does controller mods, thus I don't have to write a user interface for all this stuff :D

Perhaps, I can add support for a user config file (in "C:\Documents and Settings\%User%\My Documents\xpd") that adds additional controller types. With it you may easily upgrade XPD without having to modify its source code every time.
 
Hyena said:
Did you manage to find any other parameters we can fiddle with or does your intercept only pick up what the existing software is sending ?
You may look at the protocol description and see yourself what parameters you can fiddle with :) The physical range of any raw value is from 0 to 255, but some parameters use smaller range (for example, the "Speed1-3" parameters use raw values from 24 to 95; while I may assume that extending the range down to 0 will just give you smaller speeds, I don't know what will happen if you'll try to program values above 95 (e.g.120%).

Hyena said:
It'd be great if we could up the regen power.
This *could* be possible. You may see the comment on the "EBS Level" in protocol description:

As of today it is unknown how values other than 0, 4, 8 behave.

So, I don't even know what will happen when using intermediate values, not speaking of values higher than 8.

You may try to modify xpdm/infineon.py to allow a finer control over the EBS braking level. For this, open the file in a text editor, and find the "EBSLevel" parameter description:

Code:
    "EBSLevel" :
    {
        "Type"        : "i",
        "Name"        : _("EBS level"),
        "Description" : _("""\
Electronic braking level. Choose 'Moderate' for smaller wheel diameters, \
and 'Strong' for 26" and up. The larger is the level, the more effective \
is braking.\
"""),
        "Default"     : EBS_DISABLED,
        "Widget"      : PWT_COMBOBOX,
        "Range"       : (0, 2),
        "GetDisplay"  : lambda prof, v: EBSLevelDesc [v],
        # This member, if defined, tells how to translate setting to raw value
        "ToRaw"       : lambda prof, v: v * 4,
    },

Now, to allow fine-grain control, I would modify it like this:

Code:
...
        "Default"     : 0,
        "Widget"      : PWT_SPINBUTTON,
        "Range"       : (0, 32),
        "GetDisplay"  : lambda prof, v: v,
        "SetDisplay"  : lambda prof, v: v,
    },
After this you can choose EBSLevel as a numeric value between 0 and 32. Maybe only powers of two work (e.g. 0, 4, 8, 16, 32), maybe intermediate values work too. I haven't tried this yet.

Hyena said:
Better still I'd love to see switchable current modes like we have for the speed modes now. I'm guessing that'll take more than a bit of software redesign.
I don't understand this. Could you elaborate, or give a link to a thread that discusses this?
 
Doctorbass said:
Something you could add is the version that would make it perfect is displaying the version.. ex: V1.0 with the date
You might like the "About" button :)

Doctorbass said:
and also the possibility for those who modified the R12 to select a factor or directly the resistor they modded so that the EBS HV and LVC value to allow higher selectable value would be automaticaly rescaled!! and the value selectable would be coresponding to the right active value!
I explained the required black magic incantations for this above :)

Doctorbass said:
and also Hyena that made an XLS calculator for that so you can use the formula or if you already know how it work ... as well
http://www.endless-sphere.com/forums/viewtopic.php?f=2&t=23745&p=390978&hilit=r12+calculator#p390978
By the way... what's the upper resistor value in the voltage divider? 1200 ohm is, as I understand, the bottom resistor, the upper resistor should be something like 50-100kOhm?

This basically brings the question: what's the ADC reference voltage used in "Infineon" controllers? Perhaps my formula might be changed to reflect the actual schematics and real component values, rather than using the heuristic formula as I did.
 
Better still I'd love to see switchable current modes like we have for the speed modes now. I'm guessing that'll take more than a bit of software redesign.
I don't understand this. Could you elaborate, or give a link to a thread that discusses this?

i think he would like to use the 3-speed switch for different current limit levels, instead of the normal speed levels eg. 40% 100% 120%
 
I hope everybody realizes that this is hard to do with current controller firmware. Well, as soon as anybody gets its hands on the microcontroller firmware source code, let me know :)

If we turn on fantasy mode, this could be done by using some portable computer, even a smartphone, by reprogramming the controller (and some software has to be written for it yet) on the go, but anyway you'll have to reset the microcontroller for programming, thus the "RESET" wire has to be soldered too (the normal programming header doesn't contain the RESET wire). Then the smartphone will have to RESET the microcontroller, then program the values, then (perhaps) to reset the microcontroller again (maybe the last step is not needed). I'm not sure what will happen if you RESET the microcontroller while some FETs are open... I hope the schematics is smart enough to avoid the short circuit.
 
Back
Top