Bafang M500/M600 thread

bikelpl said:
I've changed the translation from Chinese to English in every section to be more readable:

Please tell me if this is useful to anybody? Or this is already well known?

This is certainly pretty interesting and not something I was aware of! Are you able to read your current values in to the various boxes? It's very good that it shows which bit things translate to as well. Reminds me of VCDS.
 
cr3 said:
Are you able to read your current values in to the various boxes?

I've just ordered my new bike with m600.
For now I do not have bike with motor and I do not have BESST tool to test if this works.

I have experience with development so for now I'm playing with source code for BESST app.

I can tell here how to get to these pages and perhaps somebody could check if this works?

The validation logic for displaying these pages is:
Code:
isCan && (org.type === Core.Const.ORG_TYPE.COMPONENT || org.id === 1340 || org.id === 1341 || org.id === 1212 )

So if you enter in loginbypass.py the organisation id e.g. 1340 it will show you these setup pages, but every name is in chinese.
line 20:
Code:
userdata = json.dumps( {'code':0,'data':{'account_type':[1,2,3,6,7],'user':{'status':6,'org': {'id': 1340, 'type': 6}},'token':123}} )


Other logic for displaying "Write" button is to login with user name that contains "fqc"
Code:
 v-if="userName.indexOf('fqc') > -1"

Please somebody try if this works and let all of us know :)
 

Attachments

  • login-fqc.jpg
    login-fqc.jpg
    133.9 KB · Views: 1,529
patdam said:
"well known?"

I don't think so, i'm not soft master but i never seen these pages ?
If you can really change all these parameters it will be dangerous for sorcerer's apprentices. i predict it will apper a lot off motors failures in the future.

@casainho has them documented (or at least enumerated) here in his M500/M600 software project. The question is not whether you can change them, but whether you have a motor firmware that allows them to be changed. Those parameters showed up in BESST recently, and it stands to reason that they only apply to equally recent firmware, which most of us probably don't have.

Since Bafang controls on a per-login basis who can access what firmware, we're still stuck on zero without someone that has access to recent firmware.
 
boudin said:
@casainho has them documented (or at least enumerated)

Oh, I didn't noticed that - thank you for the information.

I have one more question - there is indeed documentation in github repo done by @casainho or other developer, but there is no information how to combine all these bits all together - maybe there is some missing piece that is hidden in souurce code? e.g. checksum calculation?

Do you guys had access to this source code before?

Code:
conParamsCombine(type, ctrlParams){
                let data = '';

                let dataIndexLast = 0;
                let firstIndex = 0;

                ctrlParams.forEach((item,index)=>{
                    let len = item.length;
                    let dataArr = item.data.split("-");
                    let dateTem,hexTemp;
                    let dataIndex = parseInt(dataArr[0]);

                    if(index === 0 && dataIndex !== 0){
                        firstIndex = dataIndex;
                        dataIndexLast = dataIndex;
                        data = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".substr(0, firstIndex * 2) + data ;
                    }
                    let dataSupply = "";
                    if(dataIndex - dataIndexLast > 1) {
                        dataSupply = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".substr(0, 2*(dataIndex - dataIndexLast - 1));
                    }

                    if(len === 1){
                        dataIndexLast = dataIndex;
                    }else{
                        dataIndexLast = parseInt(dataArr[len-1])
                    }

                    if(item.set_value){
                        dateTem = parseInt(item.set_value);
                    }else{
                        dateTem = 0x00;
                    }

                    hexTemp = this.addLength(dateTem.toString(16),len);
                    data += dataSupply + Buffer.from(hexTemp,'Hex').reverse().toString('Hex');

                });

                data = (data + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff').substr(0, 126);
                let checkSum = Core.Util.calculateChecksumFF(data);
                console.log(checkSum);
                let value = data + Buffer.from([checkSum]).toString('Hex');
                switch(type){
                    case "6011":
                        this.conParamsWrite_11 = value;
                        break;
                    case "6012":
                        this.conParamsWrite_12 = value;
                        break;
                    case "6013":
                        this.conParamsWrite_13 = value;
                        break;
                    case "6014":
                        this.conParamsWrite_14 = value;
                        break;
                    case "6017":
                        this.conParamsWrite_17 = value;
                        break;
                    case "6018":
                        this.conParamsWrite_18 = value;
                        break;
                }

            },

            addLength(hexData,len){
                let hex = hexData || '';
                let step = len*2;
                let hexLength = hex.length/2;
                if(len === hexLength){
                    return hex
                }else if( len > hexLength ){
                    return ('000000'+hex).substr(-step);
                }else{
                    return ('------').substr(-step)
                }
            },
            conParamsUpdate_6011(){
                if(this.conParamsWrite_11 == ''){
                    this.conParamsCombine_6011();
                }
                Controller.port.usbSDK.machineInformation.update.conParams_1(0x05, 0x02, this.conParamsWrite_11)
                    .then(res => {
//                        console.log(res);
                        if (res.can === 'NORMAL_ACK') {
                            this.$message({
                                message: this.$t('cNam.writeSuccess'),
                                type: 'success'
                            });
                        }else{
                            this.$message({
                                message: this.$t('cNam.writeFail'),
                                type: 'error'
                            });
                        }
                    }).catch(err =>{
                    console.log(err);
                    this.usbErrorCheck(err);
                }).finally(()=>{
                });
            },

I succesfully reverse engineered all source code from source map files in BESST - I made a pull request. I hope it has any value to you. It is done in VUE framework.
 
all known firmwares need to be checked for 'write' command of hidden parameters.

few years ago when we rev-enged the DJI phantom 3 we checked every single firmware till once the DJI forgot to encrypt one, and that was the base for altering some special things.
We need one to have unlocked, then we will have everything.
 
So after doing 4 full days riding, the only 2 big things I really wish to improve are the customize assist levels and have walk assist.

I also saw that M500 EBike battery SOC and M500 assist level are recorded on Garmin activity, meaning I can analyze the progress over the entire activity -- see here:



And here an example of one of the days where I charged at lunch time. I can now see when, how much battery SOC I used and how much was charged:



Note also the assist levels graph:



And here comparing the assist levels with the elevation - as seen, I always use the minimum level 1 and I usually increase only on hills to level 3 or 5, but never to level 9. Level 1 is to much for me and is a barrier for me to improve my fitness:



We rode on rainy days, with some mud and my gears were hard to correctly change on the last days. I am now thinking in upgrading to Shimano electric gears DI2, since seems it always correct shift gears -- and these electronic gears also use ANT+ and integrates with the Garmin Edge, meaning I can have all electronics of my EBike integrated.

 
Hey @bikelpl, briefly read through your findings. WOW, thanks for contributing. Can you share your translated BESST version?

Since you managed to restore the source code, do you think it's possible to create our own BESST version for public use? A lot people struggle with setting up the loginbypass method and simply want to make basic changes like circumference, voltage or max speed.

btw: Are you already member of our telegram group? Sent you an invite.
 
I concur with @Tomblarom. Appreciate the contributions @bikelpl! Not sure I've seen such a thorough breakdown of the BESST commands and options so far.

Ultimately, it would be nice to have a "DIY BESST" - something that could be assembled from off-the-shelf CAN readers, microprocessors, etc. I'm pretty far from knowing what that would take on the programming side. but willing to help if any of my (admittedly feeble) circuit board design skills can help!
 
4πr^2 said:
I concur with @Tomblarom. Appreciate the contributions @bikelpl! Not sure I've seen such a thorough breakdown of the BESST commands and options so far.

Ultimately, it would be nice to have a "DIY BESST" - something that could be assembled from off-the-shelf CAN readers, microprocessors, etc. I'm pretty far from knowing what that would take on the programming side. but willing to help if any of my (admittedly feeble) circuit board design skills can help!
We already have it!! It is just a generic USB-CAN device that we can buy on Ebay/AliExpress.

What is missing is our own PC software that needs to be developed.
 
casainho said:
We already have it!! It is just a generic USB-CAN device that we can buy on Ebay/AliExpress.
What is missing is our own PC software that needs to be developed.

Well, true. Possibly I should rephrase that - "... a DIY BESST that can upload firmware and make tweaks just like the real thing - and is simple enough for a lug nut like me to use!" :D I can flash PIC chips and arduinos, and write a small smattering of code, but if it goes much beyond that...

I got stuck with the 'crappy' 14.5 firmware on my X1, so level 1 and 2 are borderline worthless, 3 kicks in like a rocket ship and 4 and 5 are just tiny boosts above that. I measured the power vs assist level once and it was something like 200, 300, 1500, 1700 and 1850W across the 5 levels. So hoping one of these days, I can flash some better firmware.
 
Anyone knows what is the smaller and bigger possible sizes for the chainring?

And would be possible to install a double chainring? (I am using Dengfu E10 frame).
 
casainho said:
Anyone knows what is the smaller and bigger possible sizes for the chainring?

And would be possible to install a double chainring? (I am using Dengfu E10 frame).

Its a standard 104BCD spyder, you can use any of the narrow wide chainrings available.

Over the winter months I was having trouble with mud getting caught up in the chain guide and eventually derailing the chain and loosening up the guide. Eventually I took the guide off and this winter I've not had a single problem.

I ended up with a 34T front and 11 - 48 rear cassette, gives me about 40kph top end ( 27.5 x 2.8 rear ) and climbs like a billy goat at the other. Do you really need a double chainring with all the offset problems ?
 
Waynemarlow said:
casainho said:
Anyone knows what is the smaller and bigger possible sizes for the chainring?

And would be possible to install a double chainring? (I am using Dengfu E10 frame).

Its a standard 104BCD spyder, you can use any of the narrow wide chainrings available.

Over the winter months I was having trouble with mud getting caught up in the chain guide and eventually derailing the chain and loosening up the guide. Eventually I took the guide off and this winter I've not had a single problem.

I ended up with a 34T front and 11 - 48 rear cassette, gives me about 40kph top end ( 27.5 x 2.8 rear ) and climbs like a billy goat at the other. Do you really need a double chainring with all the offset problems ?
I am using a 32T chainring and a 11S cassette of 11T-52T, on a 29 x 2.4 wheels.

I am happy but I am curious to go with 30 or 28T chainring for the big hills (but for doing fitness and have lowest motor assistance.

I am using a 50T chainring and a 9S cassette of 11T-46T, on a 27.5 x 2.25 wheels, on my TSDZ2 EBike and I wish to have the same high speeds on my M500 EBike. Maybe that is not possible with this frame... maybe I need to forget this idea to be able to pedal up to 60km/h as I do on my TSDZ2 EBike.
 
The additional weight, width of tyre and size of the E10 will probably always limit your top speed. I’m surprised you can pedal any full suspension wide tyred EMtb of any form to 60kph other than on a pretty steep downhill, where the gearing becomes almost irrelevant.

I tried a 30T to get better climbing but quite quickly worked out that an EMtb has so much torque in the 50T gear you would get loss of traction on the really steep stuff + so much less top speed that I went the other way and settled on the 34T as a good compromise as I was needing + 40kph on rare occasions. The 34T - 50T with the torque of the motor makes for only expert level climbing, the steepness you can climb is way way outside of the average riders comfort zone.
 
casainho said:
... I wish to have the same high speeds on my M500 EBike.


Its also good to use cadency calculator and compare it to maximum rpm of engine.
https://www.bikecalc.com/speed_at_cadence

In my case in due of cadence and RPM its hard to exceed 53 kph, around ~100 is max M500 rpm.
(40T Front, 11-36T rear, 27.5x2.8 tyre)
My set:
cadence.png



To make it faster, for your case, you need an engine with higer RPM, more tooth on front, or less (for example 10) on rear.
casain.jpg
at 40 kph at now you're on max M500 RPM.
 
On my M600 running at 48volts it was quite hard to push up to the 110rpm cadence.

I reduced the cranks to 155mm and now run it on 52 volts.It was surpising just how much better the motor and bike now feels, almost how it should be in some ways. Its quite comfortable to push into that 110rpm, which I think is about my max that I can carry for anything more than a few seconds :D
 
Waynemarlow said:
On my M600 running at 48volts it was quite hard to push up to the 110rpm cadence.

I reduced the cranks to 155mm and now run it on 52 volts.It was surpising just how much better the motor and bike now feels, almost how it should be in some ways. Its quite comfortable to push into that 110rpm, which I think is about my max that I can carry for anything more than a few seconds :D

I have 170mm cranks. Forgot to add - i have M600 controller in M500.
 
Quite interesting on that gearing to see @50rpm ( about best torque from rider to keep the motor running at full power ) that @ 50T on the rear its 4.6kph.
 
bikelpl said:
cr3 said:
Are you able to read your current values in to the various boxes?

I've just ordered my new bike with m600.
For now I do not have bike with motor and I do not have BESST tool to test if this works.

I have experience with development so for now I'm playing with source code for BESST app.

I can tell here how to get to these pages and perhaps somebody could check if this works?

The validation logic for displaying these pages is:
Code:
isCan && (org.type === Core.Const.ORG_TYPE.COMPONENT || org.id === 1340 || org.id === 1341 || org.id === 1212 )

So if you enter in loginbypass.py the organisation id e.g. 1340 it will show you these setup pages, but every name is in chinese.
line 20:
Code:
userdata = json.dumps( {'code':0,'data':{'account_type':[1,2,3,6,7],'user':{'status':6,'org': {'id': 1340, 'type': 6}},'token':123}} )


Other logic for displaying "Write" button is to login with user name that contains "fqc"
Code:
 v-if="userName.indexOf('fqc') > -1"

Please somebody try if this works and let all of us know :)

Awesome work thanks, I have the M600 and Besst tool but I am missing a couple of steps to try this out.
1. Do I need to import vue along with simplejson and socket server?
2. Where do I place the statement v-if="userName.indexOf('fqc') > -1"
Alternatively could you provide an updated login bypass
 
Waynemarlow said:
On my M600 running at 48volts it was quite hard to push up to the 110rpm cadence.

I reduced the cranks to 155mm and now run it on 52 volts.It was surpising just how much better the motor and bike now feels, almost how it should be in some ways. Its quite comfortable to push into that 110rpm, which I think is about my max that I can carry for anything more than a few seconds :D
I didn´t know of that limit of 110RPM cadence on M500/M600.

I could only pedal at 60km/h with TSDZ2 because of our OpenSource firmware that cadence goes up to 120RPM. And that was on long small descents and I had to pedal like that because I was in a group of road cyclists. If I could have this M500 EBike pedaling at 60km/h, then I could trash my TSDZ2 EBike otherwise I will need to keep it to ride with the road cycling group. I have low space at home and low time, I wish to have only one EBike.
 
casainho said:
Waynemarlow said:
On my M600 running at 48volts it was quite hard to push up to the 110rpm cadence.

I reduced the cranks to 155mm and now run it on 52 volts.It was surpising just how much better the motor and bike now feels, almost how it should be in some ways. Its quite comfortable to push into that 110rpm, which I think is about my max that I can carry for anything more than a few seconds :D
I didn´t know of that limit of 110RPM cadence on M500/M600.

I could only pedal at 60km/h with TSDZ2 because of our OpenSource firmware that cadence goes up to 120RPM. And that was on long small descents and I had to pedal like that because I was in a group of road cyclists. If I could have this M500 EBike pedaling at 60km/h, then I could trash my TSDZ2 EBike otherwise I will need to keep it to ride with the road cycling group. I have low space at home and low time, I wish to have only one EBike.

sry M500 have around 110 and M510, M600 around 130
 
Kyokushin said:
M500 have around 100 and M510, M600 around 115
Would be great to add this information on the github.
 
casainho said:
Kyokushin said:
M500 have around 100 and M510, M600 around 115
Would be great to add this information on the github.

Its already done.
https://github.com/OpenSourceEBike/Bafang_M500_M600/blob/main/BAFANG_Workbook_OEM_2021-2.pdf
https://github.com/OpenSourceEBike/Bafang_M500_M600/tree/main/Hardware

its n0(rpm) parameter
 
Tricky said:
Awesome work thanks, I have the M600 and Besst tool but I am missing a couple of steps to try this out.
1. Do I need to import vue along with simplejson and socket server?
2. Where do I place the statement v-if="userName.indexOf('fqc') > -1"
Alternatively could you provide an updated login bypass

No, you don't need anything of that.

You just need to login with "user-fqc" to BESST software (with loginbypass.py running in background)
but first in loginbypass.py in line no 20 you have to change 'id': from 25 to 1340
so the whole line no 20 in loginbypass.py will look like:
Code:
userdata = json.dumps( {'code':0,'data':{'account_type':[1,2,3,6,7],'user':{'status':6,'org': {'id': 1340, 'type': 6}},'token':123}} )
thats all
 
Back
Top