2004 BMW 330 with SMG/SSG Gearbox

Tell us about the project you do with the open inverter
arber333
Posts: 3261
Joined: Mon Dec 24, 2018 1:37 pm
Location: Slovenia
Has thanked: 80 times
Been thanked: 231 times
Contact:

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by arber333 »

mdrobnak wrote: Tue Nov 03, 2020 5:09 pm HAHA don't I feel dumb.
What's the 5V on them used for, then? Is there a most-positive pin line a most-negative pin, as well? Or just most-negative + cell 1-6/12?
I'll finish wiring up the first connector and try again. :)

-Matt
Just connect the cell modules. When you have everything connected you only need to provide 5V for the separation across opto barriers and power to the main chip on slaves.
If you provide the original BSM master module and power it up system also works and we could read CAN between modules. Of course that only works when connected to battery modules.
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Eek.
Well, that 'worked' -- I've got all 4 modules hooked up - an aside - how does it know the difference between 2/3? (They're literally labeled 1, 2/3, and 4).

This is what I was iniitally presented with:

Code: Select all

BMS Status : 5 Error 3  |Balancing Active  12
Out:0000 Cont:0000 In:0000


Modules: 2 Cells: 12 Strings: 1  Voltage: 42.861V   Avg Cell Voltage: 3.572V  Low Cell Voltage: 1.695V   High Cell Voltage: 4.992V Delta Voltage: 3298mV   Avg Temp: 9.692C 

Module #14  21.70V   Cell0: 3.62V   Cell1: 3.62V   Cell2: 3.62V   Cell3: 0.00V   Cell4: 3.62V   Cell5: 3.62V   Cell6: 3.62V               
 Temp 1: 10.84               
Module #15  21.16V   Cell7: 3.62V   Cell8: 3.62V   Cell9: 3.62V  Cell10: 0.00V  Cell11: 3.62V  Cell12: 4.99V  Cell13: 1.69V               
 Temp 1: 8.54               
CANbus   0.00mA  0% SOC -108000.00mAh
Which is wrong, scary, and stop! :D

Changed the balance threshold to 9999 mV, unplugged the 5V power, restarted the BMS, and now have:

Code: Select all

BMS Status : 1 Ready     12
Out:0000 Cont:0000 In:0000


Modules: 2 Cells: 12 Strings: 1  Voltage: 43.400V   Avg Cell Voltage: 3.617V  Low Cell Voltage: 3.614V   High Cell Voltage: 3.619V Delta Voltage: 5mV   Avg Temp: 13.839C 

Module #14  21.70V   Cell0: 3.62V   Cell1: 3.62V   Cell2: 3.62V   Cell3: 0.00V   Cell4: 3.62V   Cell5: 3.62V   Cell6: 3.62V               
 Temp 1: 10.84               
Module #15  21.70V   Cell7: 3.62V   Cell8: 3.62V   Cell9: 3.62V  Cell10: 0.00V  Cell11: 3.62V  Cell12: 3.62V  Cell13: 3.61V               
 Temp 1: 16.84               
CANbus   0.00mA  50% SOC 22950.00mAh
which is better, but I'm real confused as to why I'm missing two cells. Err, there's twelve cells, which is right. Why "Cell3 and Cell10" are wrong is beyond me. Temperatures are wrong because they're not connected.

CAN Debug shows:

Code: Select all

842342,0x46D,false,6, 0x8B, 0x4B, 0x0B, 0x4D, 0x0B, 0x4F
842343,0x47D,false,6, 0x8B, 0x4D, 0x0B, 0x4D, 0x0B, 0x4C
842344,0x7ED,false,8, 0x0F, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC6
842346,0x46E,false,6, 0x8B, 0x4D, 0x0B, 0x4D, 0x0B, 0x4E
842347,0x47E,false,6, 0x8B, 0x4C, 0x0B, 0x4C, 0x0B, 0x4C
842348,0x7EE,false,8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E
But, progress nonetheless :)
Unplugging it all for now.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Inspired by a different post, I just picked up:
https://www.ebay.com/itm/324295404839 - Model 3 PCS - which will probably need more parts later, but... I iniitally thought the CODA charger did DC-DC as well, but I was unaware that A) The Lear charger only does it during charging, and B) The Volt version does, and the CODA version does not. Yay.

So, plan B - get a PCS + supporting items for the 330. The CODA charger will be used in the M3 Hybrid.

Haven't done anything on the Motec side, all the time is going to the charge port project. I'm so close but that voltage command is evading me...

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

The PCS has arrived in a upright vacuum cleaner box. :D

I also am back to trying to get data on the 330 to be more reasonable.

Item 1 is friction.

Looks like I've zigged when I should have zagged:
zig-zag.png
Looks like I messed up with a sign somewhere.

After this, revisit idle control so that the revs don't fall quite as quickly as they are now. I think the fact that I'm falling past the target RPM is what is giving me trouble.

If necessary, implement PID control on airflow target.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Ok lets try that again, shall we?

* Engine Coolant Temperature "Firmware ##" value was completely wrong - because it was in use by the Bosch Racing integration module. Moved it to Firmware 31 (max value) and now I have coolant temperature readings.

* As a result of coolant temperature readings now being correct, friction from temperature should be closer to correct.

* Base values are much, much closer now.
friction2.png
Is it perfect? Nope. Is it a lot closer? Yes!

Voltage values for the MAF seem lower than they should be. This may be affecting the base values a bit as well. As long as I can get values which are in the right ballpark as the stock ECU when under my control, then I'll consider that successful. Not going to go crazy here.

Lambda sensors are not showing up. CAN wiring may have gotten upset. Need to look at that tomorrow.

Then revisit idle control. That's going to be fun.

But, one thing at a time. That's how I'm going to get this done in the next 3 months. I have 4 to get it either all working or converted to an EV as that's when my emissions test is due :)

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Lambda sensors working. One of those cases of I looked at it, breathed on it, and it works again. :D Not sure what happened. There was a wire that seemed out of place that I put heat shrink on to isolate from issues.

I tried to get actual grams/sec from the MAF via OBD2, but my ECU is too old to do it over CAN. Need to get some ELM327->CAN thing from somewhere. In the meantime, a slight voltage offset hack (add an offset due to different 5V reference voltage) has done pretty well:
tq_vals_closer.png
I used a 3rd order polynomial fit in Excel to try and clean up the MAF curve a little, will test that out tomorrow more.

Friction is missing something - now that I'm sure engine load is right, and the values are right (I found a dump of the software I know is on my car, yay!), something is still off. Need to see if there's something I left out by accident.

In some ways this is going to be easier with the EV when I can target a specific RPM, in other ways other things will be more difficult - like getting it to engage the clutch quickly on take-off.

Work in progress:
* Friction
* Idle / "dashpot"

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Ok so the missing item is...the alternator. Apparently there's a table which correlates alternator torque / output to the friction losses. Since I have no idea how much power is being generated, my initial guestimate of 15 Nm is going back in. But now accounted for in the right spot. :)

Now on to idle control. That'll be a bit more involved.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Just drove around a little.
* Values until warmed up seem quite incorrect. Table should be correct, so I wonder if my Oil Temp values are wrong...
* Warm-up values match quite well.
* Torque values are within 10%, which is the approximate error of the stock ECU at the moment, so that looks good.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

More precisely - values at _idle_ aren't quite right. No other new info yet. Still need to unbox the PCS. I made an inventory of all my wiring parts and I need to order some more.

So much to do :)
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Ran the car on the Motec today. Ehhhh. So looks like some of my MAF math was quite bad. Super rich at idle. Oops.
Shift from 1 to 2 still fails. I think the main issue is the RPMs are falling too rapidly.

So close:
so_close.png
The lines in white are from a run on my code.


But..just kidding.
just_kidding.png
I'll have to take a look at this more closely, per channel, to see what is going on, but...yeah, not quite there yet.


Action items:
1. Fix MAF curve to actually be right.
2. Ensure the only limiting going on is the Engine Speed Limit
3. Try again. :)
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

1. Eh, not awful, but what was really killing me was too much Proportional error correction on the idle routine. Fixed that and the car idles much better now.
2. Nope, need to fix that.

I think I need to step back, look at the code and try and generate a general flow of the stock ECU.
I need to break up my existing code into functions, and then fit in whatever I'm missing (like controlling the rate of engine RPM fall, that's a problem.)
I think I want to decouple the torque model calculation to be different from the implementation piece. I have two different airflow models, one for the M3 and one for the 330, ideally I could control with one and calculate the other, so that I can unify it into one.

So it's one of those things where lots of quiet background work, then hopefully a large leap forward.

Here goes.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

For my torque management script, the previous build was 417 lines, and I've put things into enough functions that it is down to 94 lines, of which the first 20 or so are various setup fluff. Now it should be easier to compare to the stock (Siemens MS45) ECU setup.

I also started looking over the MS45 assembly:

Main fn
  • Engine speed setpoint calculation 1 – Output of Idle Setpoint, and (Engine Speed / Idle Setpoint)
    • Calculate idle setpoints under the following conditions:
      • Neutral
      • Neutral AC On
      • Drive
      • Drive AC On
      • After start time dela for drive-off-support idle speed
      • Neutral Limp Home
      • Drive Limp Home
      • Cataylst heating
      • Drive-Off support
  • Engine speed setpoint calculation 2 – Output of (Idle Setpoint - Engine Speed), Weighted version of same information.
  • Idle speed control - Main idle routine
  • Idle speed tq reserve
  • Aux start
  • Tq Mgmt 1
    • BN2000 (Not applicable)
    • Gear ratio detection
    • Drivetrain engaged
    • Clutch switch detection (If manual)
    • Engine Start Torque
    • Engine Speed Limit Controller
    • Torque loss / reserve for Air Conditioner
    • Torque Loss for Power Steering
    • Torque Loss for Secondary Air Pump
    • Calculate remaining Torque Losses
    • Torque Losses 1
    • AMT Clutch Torque (SSG Gearbox)
    • Minimum clutch torque
    • Pedal value interpretation
    • Torque request at clutch
    • Torque transient
    • Dynamic Torque Request coordination
    • Minimum torque at trailing throttle
    • Reference calculation
    • Traction Control Torque
  • Tq Mgmt 2
  • Tq Pattern Calc 1 (Inc setpoints)
  • Lambda ratio calculation
  • Ignition setpoint calculation
  • Tq Mgmt 3
  • Closed Loop Fuel feedback
  • TQM Torque based lambda setpoint calculation
  • .. lots of other stuff
As I figure this stuff out I'll flesh out the details in this post.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Gone through more. Not done yet lol.
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Ok, idle speed control routine:

Code: Select all

signed int ISC_Idle_speed_control_2()
{
    signed int result; // r3@1
    int v1; // r30@1
    char v2; // xer_ca@3
    __int16 v3; // r31@6
    unsigned __int16 v4; // r31@18
    __int16 v5; // r3@20
    signed __int16 v6; // r29@22
    __int16 v7; // r3@26
    signed __int16 v8; // r29@28
    int v9; // r30@35
    __int16 v10; // r29@38
    unsigned __int16 v11; // r3@38
    __int16 v12; // r3@43
    signed __int16 v13; // r30@45
    signed int v14; // r30@50
    __int16 v15; // r30@53
    unsigned __int16 v16; // r3@53
    __int16 v17; // r3@59
    signed __int16 v18; // r31@61
    signed int v19; // r31@66
    unsigned __int8 v20; // r3@70
    signed int v21; // r3@70
    unsigned __int8 v22; // r3@71
    signed int v23; // r3@71
    __int16 v24; // r30@71
    signed int v25; // r31@80
    __int16 v26; // r31@81
    signed int v27; // r31@83
    __int16 v28; // r31@84
    __int16 v29; // r31@89
    unsigned __int16 v30; // r3@90
    unsigned __int16 v31; // r3@95

    result = set_lv_and_state_req_isc();
    v1 = lc_n_grd_fil_p_d_swi;                    // 0 here.
    if ( !lc_n_grd_fil_p_d_swi || !lc_n_grd_fil_i_swi )// Both lc items are 0. (therefore true if statement)
    {
        result = sub_C3D0(word_3FE49E, n_grd << 8, c_crlc_n_grd);// Filter by 0.1 effectively
        word_3FE49E = result;
        n_grd_fil_is = BYTE2(result) + v2;
    }
    if ( lc_tq_dif_p_d_inh_as || lc_isc_inh )     // Both 0
    {
        tq_dif_p_d_is_fast = 0;
        tq_dif_p_d_is_slow = 0;
        tq_dif_p_d_slow_is = 0;                     // Slow or Driveoff
        v3 = 0;
    }
    else
    {
        if ( !state_p_d_isc )
        {
            if ( lv_req_isc )
            {
                state_p_d_isc = 1;
                lv_tq_p_d_act_fast = 0;
                lv_tq_p_d_act_slow = 0;
            }
            tq_dif_p_d_is_slow = 0;
            tq_dif_p_d_is_fast = 0;
        }
        else if ( state_p_d_isc != 1 )
        {
            if ( state_p_d_isc == 2 )
            {
                if ( !lv_es && (tq_dif_p_d_is_fast || tq_dif_p_d_is_slow) )
                {
                    if ( lv_req_isc )
                    {
                        state_p_d_isc = 1;
                        lv_pas_ramp_act_p_d_is = 0;
                        lv_tq_p_d_act_fast = 0;
                        lv_tq_p_d_act_slow = 0;
                    }
                }
                else
                {
                    state_p_d_isc = 0;
                    lv_pas_ramp_act_p_d_is = 0;
                }
                v25 = absolute_value(tq_add_p_d_ramp_fast);
                if ( absolute_value(tq_dif_p_d_is_fast) >= v25 )
                v26 = add_r3_r4_min_neg_32768_max_7fff(tq_dif_p_d_is_fast, tq_add_p_d_ramp_fast);
                else
                v26 = 0;
                tq_dif_p_d_is_fast = v26;
                v27 = absolute_value(tq_add_p_d_ramp_slow);
                if ( absolute_value(tq_dif_p_d_is_slow) >= v27 )
                v28 = add_r3_r4_min_neg_32768_max_7fff(tq_dif_p_d_is_slow, tq_add_p_d_ramp_slow);
                else
                v28 = 0;
                tq_dif_p_d_is_slow = v28;
                if ( isc_p_d_ramp_time_counter > 0 )
                --isc_p_d_ramp_time_counter;
            }
        }
        else
        {
            if ( lv_es )
            {
                state_p_d_isc = 0;
            }
            else
            {
                if ( !lv_req_isc )
                {
                    state_p_d_isc = 2;
                    if ( lv_dt )
                    v4 = c_t_ramp_lim_p_d_dt_is;
                    else
                    v4 = c_t_ramp_lim_p_d_is;
                    
                    v5 = a1_minus_a2_min_neg_32768_max_7fff(0, tq_dif_p_d_is_fast);
                    tq_add_p_d_ramp_fast = a1_div_a2(v5, v4);
                    if ( tq_dif_p_d_is_fast <= 0 )
                    {
                        if ( tq_add_p_d_ramp_fast <= 1 )
                        {
                            v6 = 1;
                        }
                    }
                    else if ( tq_add_p_d_ramp_fast >= -1 )
                    {
                        v6 = -1;
                    }
                    else
                    {
                        v6 = tq_add_p_d_ramp_fast;
                    }
                    tq_add_p_d_ramp_fast = v6;

                    v7 = a1_minus_a2_min_neg_32768_max_7fff(0, tq_dif_p_d_is_slow);
                    tq_add_p_d_ramp_slow = a1_div_a2(v7, v4);
                    if ( tq_dif_p_d_is_slow <= 0 )
                    {
                        if ( tq_add_p_d_ramp_slow <= 1 )
                        {
                            v8 = 1;
                        }
                    }
                    else if ( tq_add_p_d_ramp_slow >= -1 )
                    {
                        v8 = -1;
                    }
                    else
                    {
                        v8 = tq_add_p_d_ramp_slow;
                    }
                    tq_add_p_d_ramp_slow = v8;
                    lv_pas_ramp_act_p_d_is = 1;
                    isc_p_d_ramp_time_counter = v4;
                }
            }

            if ( state_p_d_isc != 1 )
            {
            }
            else
            {
                if ( v1 )
                v9 = byte_3FEC71;
                else
                v9 = n_grd_fil_is;
                n_grd_p_d_is = v9;
                if ( !lv_dt )
                {
                    v20 = sub_E2DC(&off_25C8, tco, t_ast);
                    fac_n_grd_is = v20;
                    v21 = a1_mult_a2_min_neg_128_max_127(n_grd_p_d_is, v20);
                    tq_dif_p_d_is_fast = sub_EFC0(&off_1E74, (sub_8000 + n_dif_cor) & 0xFFFF, (v21 + 128) & 0xFF) + -32768;
                    byte_3FEC7B = 0;
                    if ( lc_p_d_slow_fast_sel_ena )
                    {
                        v22 = sub_E2DC(&off_25D4, tco, t_ast);
                        fac_n_grd_is_slow = v22;
                        v23 = a1_mult_a2_min_neg_128_max_127(n_grd_p_d_is, v22);
                        v24 = sub_EFC0(&off_1E80, (sub_8000 + n_dif_cor) & 0xFFFF, (v23 + 128) & 0xFF) + -32768;
                    }
                    else
                    {
                        v24 = tq_dif_p_d_is_fast;
                    }
                    tq_dif_p_d_is_slow = v24;
                    byte_3FEC7C = 0;
                }
                else
                {
                    v10 = sub_EFC0(&off_1E5C, (sub_8000 + n_dif_cor) & 0xFFFF, (v9 + 128) & 0xFF) + -32768;// ip_p_d_dt_is
                    sub_D210(ldpm_gr_mt_2, gr_mt);
                    v11 = sub_D38C(id_fac_p_d_dt_is);
                    tq_dif_p_d_dt_is_1 = a1_mult_a2_rsh_15_plus_xer_ca(v10, v11);
                    if ( tq_dif_p_d_dt_is_1 > tq_dif_p_d_is_fast )
                    lv_tq_p_d_act_fast = 1;
                    if ( lv_tq_p_d_act_fast )
                    {
                        tq_dif_p_d_is_fast = tq_dif_p_d_dt_is_1;
                        byte_3FEC7B = 0;
                    }
                    else
                    {
                        if ( !byte_3FEC7B )
                        {
                            v12 = a1_minus_a2_min_neg_32768_max_7fff(0, tq_dif_p_d_is_fast);
                            tq_add_p_d_ramp_fast = a1_div_a2(v12, isc_p_d_ramp_time_counter);
                            if ( tq_dif_p_d_is_fast <= 0 )
                            {
                                if ( tq_add_p_d_ramp_fast <= 1 )
                                {
                                    v13 = 1;
                                }
                            }
                            else if ( tq_add_p_d_ramp_fast >= -1 )
                            {
                                v13 = -1;
                            }
                            else
                            {
                                v13 = tq_add_p_d_ramp_fast;
                            }
                            tq_add_p_d_ramp_fast = v13;
                            byte_3FEC7B = 1;
                        }
                        v14 = absolute_value(tq_add_p_d_ramp_fast);
                        if ( absolute_value(tq_dif_p_d_is_fast) >= v14 )
                        {
                            tq_dif_p_d_is_fast = add_r3_r4_min_neg_32768_max_7fff(tq_dif_p_d_is_fast, tq_add_p_d_ramp_fast);
                        }
                        else
                        {
                            tq_dif_p_d_is_fast = 0;
                            byte_3FEC7B = 0;
                        }
                    }
                    v15 = sub_EFC0(&off_1E68, (sub_8000 + n_dif_cor) & 0xFFFF, (n_grd_p_d_is + -128)) + -32768;// ip_p_d_dt_is_slow
                    sub_D210(ldpm_gr_mt_2, gr_mt);
                    v16 = sub_D38C(id_fac_p_d_dt_is_slow);
                    tq_dif_p_d_dt_is_1_slow = a1_mult_a2_rsh_15_plus_xer_ca(v15, v16);
                    if ( tq_dif_p_d_dt_is_1_slow > tq_dif_p_d_is_slow )
                    lv_tq_p_d_act_slow = 1;
                    if ( !lc_p_d_slow_fast_sel_ena )
                    {
                        tq_dif_p_d_is_slow = tq_dif_p_d_is_fast;
                    }
                    if ( lv_tq_p_d_act_slow )
                    {
                        tq_dif_p_d_is_slow = tq_dif_p_d_dt_is_1_slow;
                        byte_3FEC7C = 0;
                    }
                    else
                    {
                        if ( byte_3FEC7C )
                        {
                        }
                        else
                        {
                            v17 = a1_minus_a2_min_neg_32768_max_7fff(0, tq_dif_p_d_is_slow);
                            tq_add_p_d_ramp_slow = a1_div_a2(v17, isc_p_d_ramp_time_counter);
                            if ( tq_dif_p_d_is_slow <= 0 )
                            {
                                if ( tq_add_p_d_ramp_slow <= 1 )
                                {
                                    v18 = 1;
                                }
                                else
                                {   
                                    v18 = tq_add_p_d_ramp_slow;
                                }
                            }
                            else if ( tq_add_p_d_ramp_slow < -1 )
                            {
                                v18 = tq_add_p_d_ramp_slow;
                            }
                            else
                            {
                                v18 = -1;
                            }
                            tq_add_p_d_ramp_slow = v18;
                            byte_3FEC7C = 1;
                        }
                        v19 = absolute_value(tq_add_p_d_ramp_slow);
                        if ( absolute_value(tq_dif_p_d_is_slow) >= v19 )
                        {
                            tq_dif_p_d_is_slow = add_r3_r4_min_neg_32768_max_7fff(tq_dif_p_d_is_slow, tq_add_p_d_ramp_slow);
                        }
                        else
                        {
                            tq_dif_p_d_is_slow = 0;
                            byte_3FEC7C = 0;
                        }
                    }
                }
            }
        }
        
        result = sub_CFC8(ldpm_tco_is_1, tco);
        if ( lc_tq_p_d_slow_inh_as )
        {
            v29 = 0;
        }
        else
        {
            v30 = sub_D44C(ip_fac_p_d_slow_tco_is);
            result = a1_mult_a2_rsh_15_plus_xer_ca(tq_dif_p_d_is_slow, v30);
            if ( lv_isc_off_drof )                      // 0 here.
            {
                result = limit_between_values(result, c_tq_min_isc_tq_drof_slow, c_tq_max_isc_tq_drof_slow);
                v29 = result;
            }
            else
            {
                v29 = result;
            }
        }
        tq_dif_p_d_slow_is = v29;
        if ( lc_tq_p_d_fast_inh_as )                  // 0 here.
        {
            v3 = 0;
        }
        else
        {
            v31 = sub_D44C(ip_fac_p_d_fast_tco_is);
            result = a1_mult_a2_rsh_15_plus_xer_ca(tq_dif_p_d_is_fast, v31);
            if ( lv_isc_off_drof )
            {
                result = limit_between_values(result, c_tq_min_isc_tq_drof_fast, c_tq_max_isc_tq_drof_fast);
                v3 = result;
            }
            else
            {
                v3 = result;
            }
        }
    }

    tq_dif_p_d_fast_is = v3;                      // Fast or Driveoff
    state_pas_ramp_act_p_d_is = (lv_pas_ramp_act_p_d_is | 2 * state_pas_ramp_act_p_d_is) & 0x1F;
    return result;
}
1. This was autogenerated code from the decompiler. With GOTOs all over (30 of them). It was 323 lines. Unravelling the GOTOs, and it's 340 lines.

Output is basically the Proportional Error correction portion of the idle speed controller, both the "fast" and "slow" (ignition and airflow) values.

I'll actually analyze that tomorrow.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Nope, decided to go back and look into items before this first.

1. Engine Idle Speed setpoint calculation:
Inputs:
- lv_acin – AC (Request or active?)
- lv_dly_n_sp_is – Delay fufilled
- Tester Offset
- Cat Heating offsets
- Extra power requests
- Heating requests
Outputs:
- n_sp_is = Engine Speed Setpoint for Idle
- n_sp_is_ratio = Engine Speed / n_sp_is
- n_max_tol_st (table lookup)

For now do basic tests only:

Code: Select all

	if ( lv_acin )
	{
		if ( lv_dly_n_sp_is )
		v0 = drive_ac_sp_is;
		else
		v0 = neutral_ac_sp_is;
	}
	else if ( lv_dly_n_sp_is )
	{
		v0 = drive_sp_is;
	}
	else
	{
		v0 = neutral_sp_is;
	}
2. Engine Idle Speed setpoint 2:
Inputs:
- lv_is
- c_n_dif_crlc (0.074)
- c_n_dif_fac (0.227)
- n_max_tol_st
- n
- n_sp_is
Outputs:
- n_dif = n_sp_is – n
- n_dif_mmv = Moving average of n_dif
- n_dif_cor - Idle speed control value – N_DIF – (n_dif_mmv * c_n_dif_fac?)
- n_dif_st - Engine speed deviation N_MAX_TOL_ST - N


3. Idle Speed Control Function 1:
Inputs:
- lc_n_grd_fil_p_d_swi
- lc_n_grd_fil_i_swi
- n_grd = Engine Speed Gradient
Outputs:
- n_grd_fil_1_is – Average of n_grd over c_nr_buf_n_grd_fil samples.
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Took some of the notes and reconstituted C code and starting putting it into place:
ms45_idle_deux.png
Turns out I did some of this before, so the ISCRequest routine was already there. That's immediately called in the Idle Speed Control 2 routine. Looked it over as I read through the decompiler output, and it seemed sane.

* Basic idle setpoint done
* Engine Speed Ratio calculated
* n_max_tol_st done
* n_grd done
* n_grd_filtered done

I'll look through the rest tomorrow.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Idle Speed Control 2 is pretty much done with a few questions that hopefully don't happen too often.
I had to invert some of the logic in places due to the way the GOTO labels in the decompiled code that was generated were used. Sometimes it's easier to understand for a human to invert some of the 'faster' logic.

Tomorrow will look into Idle speed tq reserve routine.

On another note I've finally redone my resume again. Going to try for some high profile companies. :)

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

The values I was worried about in comparisons were listed as "-1", which when I looked at the original disassembly, was 0xFFFF. So I'm confident that my interpretation of the data is correct. As I said, on to the next function. :)

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Idle setpoint 2 done:
Inputs:
lv_req_isc = Idle Speed Control requested
Outputs:
tq_dif_p_d_is_fast = 0; // PD-Component before fast/slow split
tq_dif_p_d_is_slow = 0; // P-D component before fast/slow split
tq_dif_p_d_slow_is = 0; // Slow or Driveoff
tq_dif_p_d_fast_is = 0; // Fast or Driveoff

---
Idle Speed Torque Reserve:
Inputs:
lv_is
lv_at
lv_n_sp_is_cs
n_sp_is
tco
tia
tol
vs_fil
maf
Outputs:
tq_add_is_bol
tq_dif_add_is_tol

There's an issue with this one - and actually engine speed setpoint 2 - which I think I skipped for the moment - lv_is - Are we in idle state?

To figure that out, we need to find out:
* Is the driver passive
* Do we meet other conditions

So for now, I'm working on the functions to provide that information before we can move forward. One thing to note about the torque reserve is the method they use to fade the idle torque reserve out, something that'll probably make an appearance in other places when transitioning from lv_is=true to lv_is=false.

On another note, the battery was low enough that the car alarm went off, and wouldn't disarm via the remote. I had to run over to the car and manually unlock the door. Just slightly embarrassing! :D

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Car is happily charged again.

Passive driver detection code written. Didn't even need any local variables:

Code: Select all

if (Parent.Tunables.Driver Pedal Torque Request < Parent.Idle MS45 Deux.Activate.Torque Percentage.Threshold)
{
	if ( 
        ( Parent.Idle MS45 Deux.Activate.Torque Percentage.Threshold - Parent.Idle MS45 Deux.Activate.Torque Percentage.Hysteresis ) >= 
          Parent.Tunables.Driver Pedal Torque Request
       )
	{
		Parent.Driver.Passive = Universal Switch State.On;
	}
}
else
{
	Parent.Driver.Passive = Universal Switch State.Off;
}
Idle state code mostly written.

Code: Select all

static local <Boolean> isIdle = false;

if (not isIdle)
{
	if ( 
		 (Parent.Parameters.Engine State.AsInteger() >= 2) and
         (Parent.Driver.Passive eq Universal Switch State.On) and
         (Parent.Parameters.Engine Speed < (Aim + Activate.Engine Speed Hysteresis)) and
         // In addition, not in gear shift and or MSR request
         (Engine.Overrun.State neq Engine Overrun State Enumeration.Retard Ignition)
        )
    {
		isIdle=true;
	}
}
else
{
	if (Parent.Parameters.Engine Speed >= (Aim + Activate.Engine Speed Hysteresis))
	{
		isIdle = false;
	}
}
Out = isIdle;
This.State = (isIdle) ? Idle State Enumeration.Enabled : Idle State Enumeration.Disabled;
Need to bring in the checks for gear shift / traction control. But that's probably it for today. But now we have input for other functions, which is great.

Also noted a large difference to the Motec algorithm - there's a single, fixed value for hysteresis as to when you are in "idle control" - so if for some reason you get the engine RPMs stuck above that...you need to kill the ignition for a moment to bring the revs down. It's...not great.
The Bosch / Siemens method uses a table with a hysteresis that varies depending upon engine RPM rate of change...except I'm now just seeing that it's rate of change not just current RPM. So..yeah that's not quite done yet. :D

But I think I'm done for the night. :)

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Good news is I got the first of the two transient torque functions done.
Bad news: open up function number 2, and am greeted with 159 lines. Oh, not so bad...line 130... transient_torque_decision_tree();... Uh oh, that's a function *I* put a name to...
decision_tree.png
~400 lines of code that's a bit of a mess.

But a lot of the conditionals are for automatic transmission and 4wd / low range... so out that goes for now. :)

I think another week or so and this will drive 10x better.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Well, I got everything integrated and flashed. I turned on the option to use the new code, and...
idle_first_start.png
A. What a difference a little filtering makes. ;) (Engine Speed Gradient vs Filtered version)
B. I wasn't sure the car was going to idle at all. So, quite happy.

I took a spin around the block and I need to fix the fueling first, it'll stall sometimes coming to a stop. Still doesn't shift to second gear yet. :( But I haven't touched any gear shift stuff recently, so not entirely shocked there.

Still more to go, but goal for today (start car, get it to idle) - achieved.

-Matt
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

Well, I'm alive, and slowly returning back to this stuff.

I actually recently found a bug in my wheel speed code:

This:

Code: Select all

	local frontCanAndRPMScaler = 60 / ( Wheel Speed.Front.Circumference * Constants.rpmTOdegsec);
	local rearCanAndRPMScaler  = 60 / ( Wheel Speed.Rear.Circumference * Constants.rpmTOdegsec);

	// Compute wheel speed.
	local <Floating Point> frontLeft  = ( (( byte0 + ((byte1 & 0x1F) * 256) ) / 16) / BMW.Wheel Speed.kmhrTOmsDivisor);
	local <Floating Point> frontRight = ( (( byte2 + ((byte3 & 0x1F) * 256) ) / 16) / BMW.Wheel Speed.kmhrTOmsDivisor);
	local <Floating Point> rearLeft   = ( (( byte4 + ((byte5 & 0x1F) * 256) ) / 16) / BMW.Wheel Speed.kmhrTOmsDivisor);
	local <Floating Point> rearRight  = ( (( byte6 + ((byte7 & 0x1F) * 256) ) / 16) / BMW.Wheel Speed.kmhrTOmsDivisor);
	
	// Mask wheel speeds if close to 0.
	frontLeft  = ((frontLeft  * 16) < 10) ? 0.0 : frontLeft; // If < 10, Set to 0.
	frontRight = ((frontRight * 16) < 10) ? 0.0 : frontRight; // If < 10, Set to 0.
	rearLeft   = ((rearLeft   * 16) < 10) ? 0.0 : rearLeft; // If < 10, Set to 0.
	rearRight  = ((rearRight  * 16) < 10) ? 0.0 : rearRight; // If < 10, Set to 0.
and

This:

Code: Select all

	local <Unsigned Integer> frontLeftUint = ((byte1 & 0x1F) << 8) | byte0;
	frontLeftUint = (frontLeftUint < 10) ? 0 : frontLeftUint;
	local <Unsigned Integer> frontRightUint = ((byte3 & 0x1F) << 8) | byte2;
	frontRightUint = (frontRightUint < 10) ? 0 : frontRightUint;
	local <Unsigned Integer> rearLeftUint = ((byte5 & 0x1F) << 8) | byte4;
	rearLeftUint = (rearLeftUint < 10) ? 0 : rearLeftUint;
	local <Unsigned Integer> rearRightUint = ((byte7 & 0x1F) << 8) | byte6;
	rearRightUint = (rearRightUint < 10) ? 0 : rearRightUint;
	
	local <Floating Point> frontLeft = (frontLeftUint * 1.0) / (16.0 * BMW.Wheel Speed.kmhrTOmsDivisor);
	local <Floating Point> frontRight = (frontRightUint * 1.0) / (16.0 * BMW.Wheel Speed.kmhrTOmsDivisor);
	local <Floating Point> rearLeft = (rearLeftUint * 1.0) / (16.0 * BMW.Wheel Speed.kmhrTOmsDivisor);
	local <Floating Point> rearRight = (rearRightUint * 1.0) / (16.0 * BMW.Wheel Speed.kmhrTOmsDivisor);

	// Make sure you have floating point values by putting .0 on it.
	local <Floating Point> frontCanAndRPMScaler = 60.0 / ( Wheel Speed.Front.Circumference * Constants.rpmTOdegsec);
	local <Floating Point> rearCanAndRPMScaler  = 60.0 / ( Wheel Speed.Rear.Circumference * Constants.rpmTOdegsec);
should be functionally equivalent. Except, it's not.

Turns out integer rounding will bite your butt. Because I had 60 / ... and not 60.0 / ... and using 16 and 256 in other places..I was getting wheel speeds that were only accurate to 1 km/h. Oops.

Also, that code was written before I had a better handle on bit shifting and ORing stuff together. The new code makes more sense, and probably faster, too.

Slowly returning to this stuff, I've got someone who's actually placing orders for my MoTeC M3 package, which is where I found this issue.

I'm dealing with some 'life events' and also trying to help repair my grandmother's house in NY, so there's still unfortunately a larger-than-I'd-like number of things going on, but I should be able to dedicate a >0% of time to the forum, Zombieverter code, and eventually getting my stuff squared away and working.

With respect to my commercial MoTeC stuff, these two BMW packages and my Porsche 996/997 package will probably be the last stuff I work on. Just too much time in - not nearly as fun as it was in the past. I have good people I think I can hand it off to, so at least there will be something good that comes out of it.

I plan on carrying out the EV conversion of the 330. The M3 may not get the hybrid setup in the end, that might be too much effort.

I'll try and catch up on other posts.

-Matt
User avatar
Jack Bauer
Posts: 3563
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 1 time
Been thanked: 87 times
Contact:

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by Jack Bauer »

Good to see you back Matt:)
I'm going to need a hacksaw
User avatar
mdrobnak
Posts: 692
Joined: Thu Mar 05, 2020 5:08 pm
Location: Colorado, United States
Has thanked: 1 time
Been thanked: 5 times

Re: 2004 BMW 330 with SMG/SSG Gearbox

Post by mdrobnak »

So, I reached out and finally got some final info on the motor I was looking at.

It's not 480 Nm at 700A.
It's not 480 Nm at 900A.
It's 439Nm at 905A. Ouch.

The price for the motor is $3500. It's ENGIRO GmbH 260W-08011-ABC motor.

I recently sold the LG Batteries I had. I was going to get the OxDrive Energy modules from ElectricGT..But that would have limited me to 600A. The additional current draw to get less torque than originally thought definitely dampened my enthusiasm.

Then came the bombshell:
Electric GT wrote: Matthew,

Thank you for contacting Electric GT. We are no longer offering battery sales, we are focused on delivering complete turn key EV systems only.

Best,

Juan Ossa
Damn. Ok then.

After fiddling with all the numbers and assumed weight and such, I think the right solution is:
CALB L173F163B 163Ah batteries + Orion2 BMS

108 cells gets me 345 V @ 3.2V, and 394V @ 3.65V.. 345V x 163Ah = 56.3 kWh, which in theory should get me around 150 miles usable (5-95% Soc)

That's plenty usable. Only downside is 722 lbs of batteries, or 122 lbs more than the OxDrive Energy ones.

Upside: 163A max charging current! 1300A 10s discharge current! And being Lithium Iron Phosphate they're safer than the NCM ones.


I took a step back from the path I was going down before with the code. The torque control code for the M3 is fairly reasonable. So I'm going back to that as a base and adding on strictly what's necessary to make things better or more correct. I'm working on getting the efficency calculations for the final torque numbers reported correct. I'm so much closer to getting this part right than I ever was in the past. So many intermediate steps to get to the end though LOL.

Anyone know the max current we can shove through the Leaf motor? :)

-Matt
Post Reply