LIN-BUS, MCP2004, Serial write does not work

Ian,
Let's say I want to skip arduino and connect ttl usb converter to mcp and to car just to check wiring.
Will it work? If yes should I cross tx/rx lines of converter and mcp?

Edit: I got device status request from mid to radio captured with this setup(no crossing) so I guess it works. Looks like pull up resistor on rx was the case.
Thanks!!

Ian,
I need your help!
Last time - it didn't work, I just hadn't got time to test post about results.
After 2 months I finally got back with the project. Today I tried hooking UP MPC2004 to TTL to USB converter and nav coder(in car). I hooked it up and it WORKED. I got messages from the car. But sending didn'work. After I checked wiring i noticed I did connect RX of MCP to RX of converter and TX of MCP to GND of converter. After I hooked TX to TX and RX to RX it stopped working, what is the case?! What I have to do to transmit messages to car? Why don't I get messages when I hook it up correctly?

BTW Ian,
If I wil visit Your country one day(I guess it is UK) you will have unlimited amount of beer on my cost.
I am from Poland so it will likely happen.
Thanks!!!!

Without a circuit diagram, it's hard to say for sure, but I suspect you don't have a shared ground.

Does the TTL to USB converter share the same ground as the MCP2004?

Yeah I connected ground from car to ground of MPC and I left GND from converter hanging. Should I connect it to gnd of the car? Won't it damage anything?

BTW, what are the adventages of using arduino in between CAR and Android? Why is it better than straight bluetooth RS232 converter connected to android device?

mp1337:
Yeah I connected ground from car to ground of MPC and I left GND from converter hanging. Should I connect it to gnd of the car? Won't it damage anything?

No, it will be fine. Unless the serial data shares a common ground, you will have trouble.

BTW, what are the adventages of using arduino in between CAR and Android? Why is it better than straight bluetooth RS232 converter connected to android device?

It depends what you plan to use on the android device to decode the iBus. If you can program the Android device to do it, then you don't need the Arduino.

Ian.

Ok mate,
One more question since I got hardware problems all sorted out.
How to check if data has been sent correctly to ibus? Try to read the same packet? How ofted try to resend it? Is it possible to resend so often that the bus will be filled only with my message(no car communication because of that)?

mp1337:
How to check if data has been sent correctly to ibus?

If I'm honest, It's not something I've ever had to consider. I don't recall ever having a situation where the message didn't get sent correctly (apart from the early days where the collision detection wasn't in place). For the most part, the car doesn't know if all it's messages have been sent correctly either. Certain status request messages will require an answer, and if it doesn't get one, it will re-send the message several more times.

How often try to resend it? Is it possible to resend so often that the bus will be filled only with my message(no car communication because of that)?

If you leave about 10 milliseconds between messages, you should be fine. There's apparently some sort of hierarchy to the devices, and some can take the bus quicker than others. If you send with smaller gaps, you do risk interfering with the flow of messages around the car.

I use a circular buffer in my system. I load messages into the buffer, and it will send them out whenever it finds a suitable gap. If the car takes the bus in the gap between my messages, it just waits for the next available gap to send the next message.

Ian.

Ian,
What I meant by checking if message has been sent correctly was that I want to stop sending message after it is sent on the bus(no contention), so I was wondering if I will receive my sent message back(is it broadcasted) so I can stop sending it or if not, how will I know that I succesfully sent message?
How do I detect contention on MCP2004 since it has no hardware detection?
Should I count time after every received message and if for example 10ms passes I mark line free and start transmitting?

I am also wondering about parsing incoming messages. What is the size of smallest size of the received message? Does it come byte by byte or bigger chunks come in at one time?
How do I detect full message, right know I am thinking about storing everything that comes in a buffer and once I receive stop bit i go back and check if my message is correct by calculating the check sum. Is it a right way to do it?

Sorry for may be trivial questions but it is my first time working with serial connection.

mp1337:
What I meant by checking if message has been sent correctly was that I want to stop sending message after it is sent on the bus(no contention), so I was wondering if I will receive my sent message back(is it broadcasted) so I can stop sending it or if not, how will I know that I succesfully sent message?

Each message has a defined structure, and is of a known length before you send it. You just send the correct number of bytes. You don't need to monitor what's being sent to decide when to stop. It will only send the number of bytes you specify.

How do I detect contention on MCP2004 since it has no hardware detection?
Should I count time after every received message and if for example 10ms passes I mark line free and start transmitting?

Although you don't have a pin on the MCP2003/2025, you can simulate this signal with the Arduino. If you loop the Rx pin into one of the interrupt pins (2 & 3 on an Uno), you can simulate this pin. Every time the Rx pin (and therefore the interrupt pin) goes low, you set a flag that signals that the line is busy. This flag will stay set until it sees the Rx pin stay high for 10us or more.

This is a logic analyser plot that shows this signal. The top trace is an IBUS message being received on the Rx pin, and the bottom trace is the signal that indicates the bus is busy. You can only send when this signal is low.

What is the size of smallest size of the received message? Does it come byte by byte or bigger chunks come in at one time?

The smallest message is 5 bytes, and it comes in one byte at a time. I think the longest message is around 36 bytes

How do I detect full message, right know I am thinking about storing everything that comes in a buffer and once I receive stop bit i go back and check if my message is correct by calculating the check sum. Is it a right way to do it?

The biggest problem with an IBUS message, is that it doesn't have anything nice and simple to indicate the start or end of the message. What you do have though, is the second byte of the message that indicates the length, and the last byte that's the checksum.

I did initially (with the help of Robin) try to detect the gap between messages, and although it worked to a point, I was never able to reliably read all messages this way. That's not to say it can't be done that way, more that I'm not bright enough to do it :confused: .
My current method reads in the first two bytes, and given the second (length) byte, I read in the remaining bytes, calculate the checksum and compare it with the last byte in the message. If they match, it's a good message. If they don't, I discard the first byte, read in another (length) byte and try again. You obviously discard a number of bytes during the initial synchronisation, but once in sync, it stays in sync.

Ian.

Nice hack with the interrupt/message gap timing. Perhaps I am gonna use arduino after all.
Just to be sure, when I connect arduino to mcp do I connect the GNDS? And then also should I connect gnds of arduino and ttl usb converter?

Edit://
I connected TCP to Arduino and USB to TTL converter to Arduino using CODE from first page. I read your posts and changed all the debug to software serial. I tried writing message in the main loop - it hanged. Then i tried interrupt with low parameter attached on RX or TX (tested both) it hanged AS well. Without writing message the program received everything on the bus.
I then tried connecting interupt pin to 5v and it started working. I got messages and also was sending.

What am I doing wrong?

For reading the IBUS, try the code I posted here:

http://forum.arduino.cc/index.php?topic=234125.75

Sorry it's not hyperlinked, but Safari on my iPad crashes if I press the link button. Also note that the changes to the HardwareSerial files are based on Arduino 1.0.5. They may need tweaking for later versions.

I think this should work for the contention detection. I wrote it a while back, and I'm pretty sure I tested it. I'm away from home (and my PC), so cannot confirm. Luckily I had a copy in my Dropbox.

You'll need to splice both together, and only send when clearToSend == true

Ian.

I managed to get it working with your code, thanks!!!
I have two questions, though. Why do you start timer when both RX AND TX are HIGH?
What is RX loopback for? I can't see it used anywhere.

mp1337:
Why do you start timer when both RX AND TX are HIGH?

When both are HIGH, after a change of state, the timer is started. If after approx 10ms there hasn't been another change of state, the timer interrupt fires and sets the clear to send flag. If the timer starts, and a change of state happens before the 10ms interval (another byte arrives), the timer is stopped, and only starts again when both are HIGH again.

It's just a way of keeping the clear to send flag false for the entire duration of a message being received, plus an extra 10ms. Without the timer, the flag would toggle every time the Rx line changes, and you wouldn't be able to send reliably.

There may well be better ways of doing it, but I couldn't come up with anything better.

What is RX loopback for? I can't see it used anywhere.

It's used for the interrupt 0 on pin 2. It's the attachInterrupt command that uses it.

Ian.

Ian,
One more question. Your arduino code detects valid ibus messages. If I send these messages to android device using serial connection(otg cable and serial adapter) I will have to detect them again. How can I utilize already detected messages when I send them to android device? Should I add some kind of stop sequence or what?

mp1337:
Ian,
One more question. Your arduino code detects valid ibus messages. If I send these messages to android device using serial connection(otg cable and serial adapter) I will have to detect them again. How can I utilize already detected messages when I send them to android device? Should I add some kind of stop sequence or what?

What are you using them for on the android device ?

I am replacing MID with nexus 7 and I want to emulate all of its options + some other cool features I can implement using IBUS.

There's probably not much point decoding with the Arduino and then having to decode again with Android.

I'm not familiar with android programming, but is it possible to re-write the Arduino code to run on the Android directly ?

Alternatively, you can decode with the Arduino and then send the decoded messages in a completely different format that the Android can work with. Either way, it sounds like you will need to write some Android code to decode serial data (either IBUS direct, or from the Arduino).

I can certainly help with anything on the Arduino side, but you're on your own with Android :slight_smile:

Ian.

Well, I could send raw data to android and then rewrite your code to java, but since I have already working packet detection on arduino I will try to add some sequence at the end of every packet and then send it to android. If it doesn't work - Then rewriting :smiley:
Thanks anyway.

You could get the Arduino to send simple text strings to Android if it's easier to decode in Java.

Hi,

I have just started looking at reading the IBUS of my BMW 3 Series. I am using a Mega 2560 with an MCP2004. I am getting data coming in on the RX but there is never a 'quiet' period, the serial.read() seems to always be reading '10'.

If I only look for the steering wheel (0x50) and radio (0x68) I do see them, however, it is not always read consistently, i think this is because of the never ending '10'.

I should note I have an AppRadio rather than a standard head unit and that the cd changer is not connected.

Any Ideas,

Thanks!