LIN communication with automotive switch that is a slave node

Hi there,

I'm fairly new to the LIN networking protocol so please bear with me. I want to read data that is sent from a climate control switch in my Toyota. Based on Toyota's repair manuals, I believe the switch is a slave node in their LIN network implementation. Therefore, if I want to read any input from the switch, I'm assuming that the Arduino would have to assume the role of master, and send a particular frame to the switch in order to elicit a response from it. Toyota's documentation does not give a breakdown of the data sent/received by the switch. I have a decent high-level understanding of LIN message frames, but I'm not sure exactly how they're formatted, aside from having sync and identifier fields.

Obviously there is no way to figure out the contents of the entire frame based on the information I provided, but I'm wondering if anyone has any pointers that might help me narrow it down. For example, if I knew what the sync field would be, I could just take a brute force approach and try every byte combination for the identifier field until I can read a response from the switch.

I'm using an MCP2004A LIN transceiver to communicate with the switch, and it seems to be working successfully, as if I send sequential bytes, i.e. 0x0000000000000, 0x0000000000001... etc. I can read a response from the switch, but it's the same response which I assume means it detected invalid input. Here is the code I'm using to test. Any insights, or just a nudge in the right direction, would be appreciated. Thanks!

#define PIN_CS 10
#define PIN_TXE 12 //Tx !Error pin of the MCP2004

uint8_t rxByte[4];

int sendByte[13] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
bool readSomething = false;

void setup() {
  // put your setup code here, to run once:
pinMode(PIN_TXE,OUTPUT);
pinMode(PIN_CS,OUTPUT);
digitalWrite(PIN_TXE,HIGH);
digitalWrite(PIN_CS,HIGH);
Serial1.begin(9600, SERIAL_8E1); //LIN Serial Rx, 8E1 is BMW iBus standard
Serial.begin(9600); //debug serial
Serial.println("Due debug Comms");

delay(100);
}

void loop() {
while(Serial1.available()) {
  delay(5);
  readSomething = true;
  byte actuallyRead = Serial1.readBytes(rxByte, 4); //Read UP TO 4 bytes
   if(actuallyRead > 0)
   {
      for (uint8_t i=0; i<actuallyRead; i++)
      {
         Serial.print("Byte ");
         Serial.print(i);
         Serial.print(": ");
         Serial.println(rxByte[i], HEX);
      }
   } else {
    delay(5);
    for (int i = 0; i < 13; i++) {
      Serial1.print(sendByte[i], HEX);
    }
    Serial.print("Sent ");
    for (int i = 0; i < 13; i++) {
      Serial.print(sendByte[i], HEX);
    }
    Serial.println(" to LIN");
   }
  Serial.println();
}
if (!readSomething) {
    delay(5);
    for (int i = 0; i < 13; i++) {
      Serial1.print(sendByte[i], HEX);
    }
    Serial.print("Sent ");
    for (int i = 0; i < 13; i++) {
      Serial.print(sendByte[i], HEX);
    }
    Serial.println(" to LIN");
    Serial.println();

    for (int i = 12; i >= 0; i--) {
      sendByte[i]++;
      if (sendByte[i] == 16) {
        sendByte[i] = 0;
        sendByte[i-1]++;
      } else {
        break;
      }
    }
}
readSomething = false;
}

I'm afraid your 'knowledge' is quite flawed based of the code you shared...


(source: https://www.csselectronics.com/pages/lin-bus-protocol-intro-basics)

good idea :+1: except that its not the sync field that its the Identification field (ie you need to send the header only) that you would need to change :wink:

if you need a library, have a look at my git. I have stored a library there to read/write LIN msgs for AVR arduino boards.

hope that helps...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.