LIN-BUS, MCP2004, Serial write does not work

alex3322:
Could it be helpful to give you a list of connected controllers ?

Probably not :slight_smile:

I'm only really familiar with the BMW IBUS protocol, which is loosely based on the LIN standard. Unless you know a bit more about the way Vauxhall/Opel, it's going to be hard to help.

Assuming they stuck a bit closer to the standard, this may be of some help:

Cheers,

Ian.

It's difficult to create a lin bus sniffer?

alex3322:
It's difficult to create a lin bus sniffer?

At the hardware level, it's quite easy. Any of the LIN transceiver chips (MCP 2003,2004 or 2025) will do the job.

Writing the software is the hard(er) part, but the code from the link I posted before would probably work. This is all dependent on Vauxhall/Opel sticking to the LIN standard though.

Ian.

Hi guys!

So i'm new here, but my problem is similar to this topic.

So I have Mitsubishi EVO X ECU and switches from steering column, and they communicate by LIN-BUS. My goal is to get rid of ECU and read switch positions using arduino mega. So the thing I need to do is to send header to switches and then read the answer.

I have bought LIN analyzer and usb logic analyzer, so I pretty much know the bytes which are changing.

Also I have MCP2003, but it doesn't seem to be working as I don't receive any activity on Rx pin, when LIN is attached.

So if anyone can help me, please reply. As I am new to coding this is pretty hard to do.

All my experience is with the BMW iBus, which is 'based' on the LIN standard, but not identical.

Do you have details of the Mitsubishi LIN message format, or even some sample messages ?

Also a diagram that shows how you have the MCP2003 connected/wired would help.

Cheers,

Ian.

In the attachment I have added my schematics, how I connected MCP2003 to arduino and lin message in logic levels.

Here is the information bytes for the same message.
32 00 00 00 0D 00 00 00 00 F2

32 is the identifier, F2 - the checksum. the rest is data bytes.

I need to read the first 4 bytes because they are only ones changing.

But basically what I need is to send sync break,sync frame and slave ID from my arduino. I have been having trouble doing that as I can't realy get it to send sync brake and sync frame correctly I guess.

Oh and also lin voltage is little below 1V. Is that normal or it some kind of factory modification?

linconnection.png

I think your current problems are hardware based.

You appear to be pulling the Rx line up to 12v. This is not good! You can pull it up to 5v if you like, but pulling up to 12v is likely to damage the UART.

Assuming you haven't blown anything, try putting a 1K resistor between the LIN bus and 12V. You need to have the LIN bus at 12v when idle, and it gets pulled low when it transmits. The line is usually pulled high by the master node, but if you've removed the original ECU, or are running on the bench, you've probably removed the pull up.

I think the fact your LIN line is less than 1V, shows you need to pull the bus up to 12v.

Cheers,

Ian.

Hi again!

So I've been workning on my lin bus and I got 3 different types of transceivers to see if that changes anything, but unfortunately I still cant receive messages.

The setup now is like this:

I have original ECU connected so my arduino is acting like a slave. Also there is these 12V in the lin bus.

I've added my lin setup, how it's connected and also my code.
The resistors are 1k on the rxd pin and 5k on wake pin.

Also I just checked the serial.write function and it works.
It appears that I can't get it to read messages.

lin setup.png

manslin.ino (344 Bytes)

Well also the real problem for me is to send this header exactly the way it needs to be, that is:
13bit spaces sync break
1bit space sync break delay
0x55 sync byte
and 0x32 identifier

And I can't figure out how to get sync break to be 13bitspaces. When I send it like 2 bytes there is this one stop bit which is the reason I can't get it to work.

And also if I switch to 8E1 which I need, then there are 2bits which are messing up my message.

Hope you can help me with this.

Richard.

I don't think the standard Arduino UART can generate the sync break you require.

You could try disabling (or not enabling) the serial port, and drive the Tx pin low for the 13 bitspace duration, and then high for the 1 bit sync break delay. Then enable serial, and send the rest of the frame.

If that doesn't work, you may have to forget the hardware serial port, and bit bang the entire message. Failing that, choose a different board that has native LIN capability. I think the Teensy does.

Cheers,

Ian.

Hi again!

So I was working with the project and came to that I started to use bit bang method. And I succesfuly sent my message, but now I have to read the answer. Is there an option to do that with software serial method? Like as soon as I stop sending I start to receive?

Regards,
Richard.

1 Like

Hello PorinsR,

Do you have any example of code to send messages trhough the UART or Software Serial?
Can you manage the Break state before to send the Sync Byte?

Many thanks

PorinsR:
Well also the real problem for me is to send this header exactly the way it needs to be, that is:
13bit spaces sync break
1bit space sync break delay
0x55 sync byte
and 0x32 identifier

And I can't figure out how to get sync break to be 13bitspaces. When I send it like 2 bytes there is this one stop bit which is the reason I can't get it to work.

And also if I switch to 8E1 which I need, then there are 2bits which are messing up my message.

Hope you can help me with this.

Richard.

Sorry to bring up an old post but I have just been having the same issue - I did this on a Leonardo to get around it:

void syncBreak(){
  Serial1.end(); //End Serial1
  digitalWrite(1,LOW); // Force the Tx pin LOW
  delayMicroseconds(1400); // LIN spec says Sync Break should be >=13 bit length (1354.16usec)
  Serial1.begin(9600,SERIAL_8N1); // Re-enable Serial1 (in my case 8N1 rqd)
  delayMicroseconds(100); // Allow Serial to pull Tx High - sync break delay
}

and call syncBreak(); before writing the sync byte, data and checksum.

I hope that helps.

Adam

I know this post is old but I am having a real hard time finding documentation anywhere. I am trying to communicate with an ATmega2560 master and multiple Atmega328p's as slaves. I would like to use the LIN Bus Protocol but I cannot for the life of me get this set up. If anyone has some working code and schematic for the setup I would appreciate it very much. It looks like most of the things needed have been talked about but they are all scrambled up and incomplete. Thanks in advance for any help!

I'm using the ATmega2560 and had terrible trouble getting this to transmit on the K-Bus.

I got it working accidentally when poking around with a scope probe and shorting the Rx pin to the CS pin. This took Rx high during Tx ( I had a pull up on rx but this did not seem to work). I double checked it was definitely the Rx pin going high which made this work by tying it to 3.3V, which also worked (obviously not very useful if you want to receive data).

This previously worked with SoftSerial, but I guess the Rx line got pulled high in the driver, possibly..

I will have to also connect a digital line to the rx pin and set it to output mode and HIGH when I want to transmit, otherwise set it back to input mode.

Any ideas what has gone on here, the datasheet for the MCP2004 says Rx is an input only?