CAN AC and CEL for MSV70

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Striker01
    Grease Monkey
    • Jul 2011
    • 335

    #1

    CAN AC and CEL for MSV70

    I started trying to figure out CAN stuff to get the ECU to control AC and a CEL.

    I will probably use the wrong terminology or put out some bad info, bear with me. Posting here because I know some of you are probably good at this stuff.

    It looks like MSV70 uses the e46 CAN addresses(ARBIDs?), some of which are fairly well documented. It also has two that aren't listed in the e46 stuff, maybe for valvetronic.

    https://www.bimmerforums.com/forum/showthread.php?1887229-E46-Can-bus-project#:~:text=Hello.%20There%20has%20been%20much ,creating%20a%20Can%20Bus%20solution

    Here is what I see with Savvycan and just the ECU and EKP on the CAN network.

    Click image for larger version  Name:	IMG_2606.jpg Views:	0 Size:	194.0 KB ID:	10153446

    I have verified that 0x00545 byte 0 is for the CEL, bit 1 is emissions light and 4 is EML. So by monitoring for HEX 10, 02, or 12 on byte 0 we should be able to power on a CEL. Byte 3 bit 3 (08 HEX) is supposed to be an overheat indication, I need to hook up a variable resistor to test that one.

    I have an arduino and sketch written to monitor the bus but can't get it to work. It is wired according to the arduino documentation. I have some hardware hoveringuy recommended on the way to try.

    The sketch is written to turn off the LED when those messages are present, just to verify the board is actually working. The LED comes on with power up but I'm still trying to figure out if its actually listening to the bus. If any of you guys are familiar will you look over my sketch and make sure it is correct, I used AI to write it.

    #include <Arduino_CAN.h>
    const int LED_PIN = 3;
    void setup() {
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, HIGH); // LED starts ON
    Serial.begin(115200);
    delay(200);
    Serial.println("CAN LED control - UNO R4 Minima");
    if (!CAN.begin(CanBitRate:: BR_500k)) {
    Serial.println("Starting CAN failed!");
    while (1);
    }
    Serial.println("CAN initialized @ 500 kbps");
    }
    void loop() {
    // Check if a new message is available
    if (CAN.available()) {
    CanMsg const &msg = CAN.read();
    // We only care about ID 0x545 (1349 decimal)
    if (msg.id == 0x545 && msg.data_length >= 4) {
    uint8_t b0 = msg.data[0];
    uint8_t b3 = msg.data[3];
    // Condition for TURNING LED OFF
    bool shouldBeOff = (b3 == 0x08) &&
    (b0 == 0x02 || b0 == 0x10 || b0 == 0x12);
    if (shouldBeOff) {
    digitalWrite(LED_PIN, LOW);
    // Optional: debug
    // Serial.printf("OFF - %02X %02X\n", b0, b3);
    } else {
    digitalWrite(LED_PIN, HIGH);
    // Serial.printf("ON - %02X %02X\n", b0, b3);
    }
    }
    // Any other message ID or too short message → LED stays ON
    }
    // Small delay is recommended when using CAN.read() in a tight loop
    delay(5);
    }



    For the AC I managed to isolate the bit that signals the "aircon input request" in INPA, idle jumps up when it happens so that is a positive sign! 0x00615 byte 0 Hex 80 from the above link doesn't work for me.

    Click image for larger version  Name:	IMG_2627.jpg Views:	0 Size:	173.6 KB ID:	10153447

    I used the Savvycan send frame function to try every HEX combination on 0x00615 byte 0 to figure out which bit signals the ECU. Bit 7 @ 1 turns it on. Here is the table:
    AC INPUT ON AC INPUT OFF
    HEX BINARY BINARY HEX
    _1________ _0________
    40 01000000 00000000 00
    41 01000001 00000001 01
    42 01000010 00000010 02
    43 01000011 00000011 03
    44 01000100 00000100 04
    45 01000101 00000101 05
    46 01000110 00000110 06
    47 01000111 00000111 07
    48 01001000 00001000 08
    49 01001001 00001001 09
    4A 01001010 00001010 0A
    4B 01001011 00001011 0B
    4C 01001100 00001100 0C
    4D 01001101 00001101 0D
    4E 01001110 00001110 0E
    4F 01001111 00001111 0F
    50 01010000 00010000 10
    51 01010001 00010001 11
    52 01010010 00010010 12
    53 01010011 00010011 13
    54 01010100 00010100 14
    55 01010101 00010101 15
    56 01010110 00010110 16
    57 01010111 00010111 17
    58 01011000 00011000 18
    59 01011001 00011001 19
    5A 01011010 00011010 1A
    5B 01011011 00011011 1B
    5C 01011100 00011100 1C
    5D 01011101 00011101 1D
    5E 01011110 00011110 1E
    5F 01011111 00011111 1F
    60 01100000 00100000 20
    61 01100001 00100001 21
    62 01100010 00100010 22
    63 01100011 00100011 23
    64 01100100 00100100 24
    65 01100101 00100101 25
    66 01100110 00100110 26
    67 01100111 00100111 27
    68 01101000 00101000 28
    69 01101001 00101001 29
    6A 01101010 00101010 2A
    6B 01101011 00101011 2B
    6C 01101100 00101100 2C
    6D 01101101 00101101 2D
    6E 01101110 00101110 2E
    6F 01101111 00101111 2F
    70 01110000 00110000 30
    71 01110001 00110001 31
    72 01110010 00110010 32
    73 01110011 00110011 33
    74 01110100 00110100 34
    75 01110101 00110101 35
    76 01110110 00110110 36
    77 01110111 00110111 37
    78 01111000 00111000 38
    79 01111001 00111001 39
    7A 01111010 00111010 3A
    7B 01111011 00111011 3B
    7C 01111100 00111100 3C
    7D 01111101 00111101 3D
    7E 01111110 00111110 3E
    7F 01111111 00111111 3F
    C0 11000000 10000000 80
    C1 11000001 10000001 81
    C2 11000010 10000010 82
    C3 11000011 10000011 83
    C4 11000100 10000100 84
    C5 11000101 10000101 85
    C6 11000110 10000110 86
    C7 11000111 10000111 87
    C8 11001000 10001000 88
    C9 11001001 10001001 89
    CA 11001010 10001010 8A
    CB 11001011 10001011 8B
    CC 11001100 10001100 8C
    CD 11001101 10001101 8D
    CE 11001110 10001110 8E
    CF 11001111 10001111 8F
    D0 11010000 10010000 90
    D1 11010001 10010001 91
    D2 11010010 10010010 92
    D3 11010011 10010011 93
    D4 11010100 10010100 94
    D5 11010101 10010101 95
    D6 11010110 10010110 96
    D7 11010111 10010111 97
    D8 11011000 10011000 98
    D9 11011001 10011001 99
    DA 11011010 10011010 9A
    DB 11011011 10011011 9B
    DC 11011100 10011100 9C
    DD 11011101 10011101 9D
    DE 11011110 10011110 9E
    DF 11011111 10011111 9F
    E0 11100000 10100000 A0
    E1 11100001 10100001 A1
    E2 11100010 10100010 A2
    E3 11100011 10100011 A3
    E4 11100100 10100100 A4
    E5 11100101 10100101 A5
    E6 11100110 10100110 A6
    E7 11100111 10100111 A7
    E8 11101000 10101000 A8
    E9 11101001 10101001 A9
    EA 11101010 10101010 AA
    EB 11101011 10101011 AB
    EC 11101100 10101100 AC
    ED 11101101 10101101 AD
    EE 11101110 10101110 AE
    EF 11101111 10101111 AF
    F0 11110000 10110000 B0
    F1 11110001 10110001 B1
    F2 11110010 10110010 B2
    F3 11110011 10110011 B3
    F4 11110100 10110100 B4
    F5 11110101 10110101 B5
    F6 11110110 10110110 B6
    F7 11110111 10110111 B7
    F8 11111000 10111000 B8
    F9 11111001 10111001 B9
    FA 11111010 10111010 BA
    FB 11111011 10111011 BB
    FC 11111100 10111100 BC
    FD 11111101 10111101 BD
    FE 11111110 10111110 BE
    FF 11111111 10111111 BF
    Still a long way to go but its a start! Any help would be appreciated!


    Attached Files
    Last edited by Striker01; Today, 01:56 PM.
  • hoveringuy
    R3VLimited
    • Dec 2005
    • 2690

    #2
    I'm glad all of that data is already public knowledge because doing bitwise comparisons is a major PITA! Good work!

    Comment

    • nando
      Moderator
      • Nov 2003
      • 34837

      #3
      you can also set MSV70 to use BN2000 - not sure if that's already been figured out yet though.
      Build thread

      Bimmerlabs

      Comment

      • Striker01
        Grease Monkey
        • Jul 2011
        • 335

        #4
        Originally posted by hoveringuy
        I'm glad all of that data is already public knowledge because doing bitwise comparisons is a major PITA! Good work!
        And I’d have no idea where to start. I just found the MS43 wiki, it has even more data but found some that don’t match what I’m seeing with MSV70. I don’t think it will apply for this project. Just a bit listed as unused that changes when I activate the compressor in INPA on 0x316. I don’t foresee messing with DME produced data, just isolating what changed with it on.
        Last edited by Striker01; Yesterday, 07:40 AM.

        Comment

        • Striker01
          Grease Monkey
          • Jul 2011
          • 335

          #5
          Originally posted by nando
          you can also set MSV70 to use BN2000 - not sure if that's already been figured out yet though.
          Welcome back Nando.

          Just read a little on that. Not sure if it would be any benefit. Have to change my EKP.

          Is that what Hoveringuy is running since his is set to e90 now?
          Last edited by Striker01; Yesterday, 07:50 AM.

          Comment

          • Striker01
            Grease Monkey
            • Jul 2011
            • 335

            #6
            I had a chance to test some of the AC stuff today. I can confirm that x60002 pin 21 is normally high and goes low to cycle on compressor and that once the DME receives the AC on message it keeps the compressor on until a message is received to turn it off. I tested this by stopping the transmission of 0x615 and the compressor stayed engaged. My compressor is an LED for now as my AC isn't plumbed yet.

            The DME keeps the compressor engaged during high RPMs and under full throttle acceleration. I'm assuming turning it off during those conditions is done by the instrument cluster and will have to be added to the arduino code.

            I played around with sending a couple different combinations of messages on 0x615 while driving.

            Here is that message info from the wiki site:

            CAN Arbitration ID for ICL3 is 0x615. I only sent 4 bytes during testing today.

            Its sent out by the instrument cluster at a refresh rate of 200ms
            • Byte 0 - Bitfield =
            • The compressor comes on and stays on with only this byte transmitting. The idle bump changes by adjusting the value of the first 5 bits. With the biggest bump at DF as would be expected.
              • Bit 0 - TQ_ACCIN_CAN [0]
              • Bit 1 - TQ_ACCIN_CAN [1]
              • Bit 2 - TQ_ACCIN_CAN [2]
              • Bit 3 - TQ_ACCIN_CAN [3]
              • Bit 4 - TQ_ACCIN_CAN [4]
                • Torque Offset For Air Conditioning Compressor 0-31nm.
              • Bit 5 - LV_REQ_TCO_L Request For Lowering Cooling Temp (c_tco_bol_ect). With it off my car stayed around 100C, when I turned it on the car immediately went to the 80C target. I also noticed something else strange here: With the tune I have the coolant temps vary greatly from 80 all the way to the hot ECO mode, depending on how I'm driving the car. With the AC engaged it didn't fluctuate at all, regardless of how hard I was driving it.
              • Bit 6 - LV_ACCIN Air Conditioning Compressor Status (0=off, 1=on)
              • Bit 7 - LV_ACIN Air Conditioning Request (0=off, 1=on)
            Byte 1 - Bitfield = 00AC will operate just like the stock e30, fan on with AC. If I can figure out how the last 4 bits adjust the fan speed I my re-visit later.
              • Bit 0 - LV_REQ_HEAT Increased Heat Request
              • Bit 1 - LV_TOW Trailer Operation Mode
              • Bit 2 - LV_LGT Day / Night Lighting
              • Bit 3 - LV_HS Hood Switch
              • Bit 4 - N_ECF [0]
              • Bit 5 - N_ECF [1]
              • Bit 6 - N_ECF [2]
              • Bit 7 - N_ECF [3] Electric Cooling Fan Level
            • Byte 2 - Bitfield = 40 or 00
              • Bit 0 - [0]
              • Bit 1 - [1]
              • Bit 2 - [2]
              • Bit 3 - [3]
              • Bit 4 - [4]
              • Bit 5 - [5]
              • Bit 6 - Request Raised Idle - Turning this on or off doesn't seem to affect idle speed, only byte 0. Will check again when my AC system is plumbed and charged.
              • Bit 7 - unused
            • Byte 3 - TAM_CAN Ambient Temperature = 1E = 30C this at 00 doesn't affect compressor status or idle
            • I didn't transmit anymore than 4 bytes.
            • Byte 4 - Bitfield =
              • Bit 0 - LV_DOOR Door Switch
              • Bit 1 - LV_HBR Hand Brake Switch
              • Bit 2 - LV_SUSP [0]
              • Bit 3 - LV_SUSP [1] Suspension Switch
              • Bit 4 -
              • Bit 5 - LV_REQ_TCO_L -
              • Bit 6 - LV_ACCIN Air Conditioning Compressor Status (0=off, 1=on)
              • Bit 7 - LV_ACIN Air Conditioning Request (0=off, 1=on)
            • Byte 5 - Bitfield
              • Bit 0 -
              • Bit 1 -
              • Bit 2 -
              • Bit 3 -
              • Bit 4 -
              • Bit 5 -
              • Bit 6 - VSS_DIS [0]
              • Bit 7 - VSS_DIS [1]
            • Byte 6 - VSS_DIS [2-9] Displayed Vehicle Speed
            • Byte 7 -
            Last edited by Striker01; Today, 04:12 PM.

            Comment

            Working...