iBusTrx problem... lag?

Hy, i have problem with iBusTrx...
This is an example that simulates steering wheel "previous" button to the radio, it will eventualy become a part of my diy radio for BMW E39...

I want it to send a messages over tx pin:
1.) When I press the button it must send ibusTrx.write(prevButton);
2.) When I release the button it must send ibusTrx.write(prevButtonR);

The problem is that the behaviour is laggy... sometimes I need to hold button pressed for few seconds, before the message gets sent, sometimes it doesnt recognize that button has been released and it doesn`t send message to the radio that button was released...

Tx pin goes to transceiver chip (MCP2025) that converts 5v logic to 12v logic for ibus, but that part isn`t the problem, I have osciloscope at tx pin and I can see that message is not sent.

Any help would be appreciated

/*
example IBUS message:
50 04 68 32 11 1F (volume up button pressed on the steering wheel)
|  |  |  |  |  | 
|  |  |  |  |  checksum (xorsum of all previous bytes)
|  |  |  |  one or more data fields
|  |  |  message type/command type
|  |  destination address
|  length of message (including destination address and checksum)
source address 
*/

// this example shows how to transmit a message over the IBUS

#include <IbusTrx.h> // include the IbusTrx library
const int prevPin = 5;     // the number of the previous button pin
const int nextPin =  6;      // the number of the next button pin

IbusTrx ibusTrx; // create a new IbusTrx instance

// define the message that we want to transmit
// the message must be defined as an array of uint8_t's (unsigned 8-bit integers)


uint8_t prevButton[6] = {
  M_MFL, // sender ID (diagnostic interface)
  0x04,  // length of the message payload (including destination ID and checksum)
  M_RAD, // destination ID (body control module)
  0x3B, // the first parameter (the IO line that we want to manipulate)
  0x08, // second parameter
  0x0F
  // don't worry about the checksum, the library automatically calculates it for you
};
uint8_t prevButtonR[6] = {
  M_MFL, // sender ID (diagnostic interface)
  0x04,  // length of the message payload (including destination ID and checksum)
  M_RAD, // destination ID (body control module)
  0x3B, // the first parameter (the IO line that we want to manipulate)
  0x28, // second parameter
  0x2F
  // don't worry about the checksum, the library automatically calculates it for you
};
int prevWasPressed = 0;
void setup(){

    pinMode(prevPin, INPUT_PULLUP);
    pinMode(nextPin, INPUT_PULLUP);
 
  ibusTrx.begin(Serial); // begin listening for messages
}

void loop(){

  
if (ibusTrx.available()) { 
int prevState = digitalRead(prevPin);
if(prevState == LOW) {
    ibusTrx.write(prevButton);
    prevWasPressed = 1;
}
else
{
  if (prevWasPressed == 1){
  ibusTrx.write(prevButtonR);
  }
  prevWasPressed = 0;
  }
  }
 

}
  
  // remember to never use a blocking function like delay() in your program,
  // always use millis() or micros() if you have to implement a delay somewhere

I find no obvious reasons, no long delays in the code, for latency.
Is suggest using Serial Monitor in the IDE and Serial.println(millis()) in strategic points to find out where time is lost.

I will have to use software serial because I have nano and I need hardware serial for iBus.
I'm actually already waiting for usb to ttl converter and will be able to use it for this when I get it.
So I insert Serial.println(millis()) before and after suspicious command, right?

I'm not familiar with the library.

Why do you check if a data is available and

  1. Never read it?
  2. Only send data if a message is received?

Thats a good point.
I was thinking the same... for some reason it didn`t work at all when I removed if available statement... Will try one more time now...

I tried one more time and it doesn`t work at all. I took some time to source another arduino after accidentally shorting d5 pin to 12v.

Hello! I'm currently trying to use that same library with my Arduino Nano. Just to ask, where did you connect your Arduino? I split the wires behind the middle radio screen and connected it there (a wire with yellow dots and a brown ground wire). I used the circuit mentioned in the library readme. It uses a resistor voltage divider to get the high-signal to max 5 volts. That is not of course a best option for any faster signal but I suppose it should still work. I'm not getting any responses with those library examples on my E39 BMW. It is hard to see what's happening there without any additional serial connection. I was hoping to get those examples working at least so I could then tweak the library and the code.

It seems that you got it working at least to some extent .

You need transceiver chip, I tryed with voltage divider in the first place and it didn`t work for me either. You have the correct wire (white / yellow).

1 Like

Okay thanks! Then I'll have to find one too and not to waste any more time with that circuit. I was planning to emulate a CD changer which I don't have. Then it would activate those audio inputs behind the radio unit. That library needs some tweaking of course because it didn't include any CD changer related things.

No problem. Do you need just aux input? if so you don`t need to do that ibus stuff.

While troubleshooting I had make the loop as small as possible and added WAKE pin13... so I can see the LED and it also enables ICs tx, rx is always enabled...

void loop(){

digitalWrite(WAKE, HIGH);
  if (ibusTrx.available()) { 

    ibusTrx.write(prevButton);
digitalWrite(WAKE, LOW);
  }
}

if I put digitalWrite(WAKE, HIGH); after the if (ibusTrx.available()) { line it never gets high...

if I remove if (ibusTrx.available()) { data doesnt get sent... but I dont understand why... if (ibusTrx.available()) { is for rx not tx....

I might be onto something...
This is what I had found in ibustrx

// assume bus is clear for sending after a short period of inactivity
 if (tx_msg_waiting && millis()-t_last_rx_byte >= 32) { // send all bytes in the transmit buffer
 for (uint8_t b = 0; b < tx_bytes; b++) { serialPort->write(tx_buffer[b]); } 
tx_msg_waiting = false; // clear tx wait flag }

Condition millis()-t_last_rx_byte >= 32 cant become true if there wasn't any rx byte at all.... Will try to remove that, but I'm not at home right now.

I made it!
In originaly posted code I just moved curly bracked

if (ibusTrx.available()) {
.code
.code
.code
.code
}

to

if (ibusTrx.available()) {}
.code
.code
.code
.code

EXPLANATION:
Part of ibustrx code:

// assume bus is clear for sending after a short period of inactivity
 if (tx_msg_waiting && millis()-t_last_rx_byte >= 32) { // send all bytes in the transmit buffer
 for (uint8_t b = 0; b < tx_bytes; b++) { serialPort->write(tx_buffer[b]); } 
tx_msg_waiting = false; // clear tx wait flag }

That would mean that iBusTrx.available() must be false for atleast 32 miliseconds, before tx will work... but I put tx write command under if iBusTrx.available.... it shouldn`t work at all.
But iBusTrx.available must be there in order to get at least first message, so 32miliseconds can pass in order to send message.

1 Like

Great, we'll done.

Under each reply is a solution checkbox. Click the one under the most useful reply (your last one) to let others know that it is solved.

I only need aux input but as far as I know, it cannot be done without this. If I had a CD changer, then I could just insert some CD into that and connect my own audio source into those line level signal wires. But without that, those inputs behind the radio unit cannot be activated. True AUX input works only for late 2002 or 2003 model year or something like that but mine is a bit older.

Ps. Glad that you found the issue for your problem. I'll have to keep that solution in my mind too.

If you have business tape (Becker be3350) as I do:


After you remove tape player find those 4 blue capacitors.

Desolder two ones on the right.

Solder capacitors back only to pinholes in the front

One capacitor is right channel and the other one is left channel.
Use ground from the casing or pcb.

Now you need to trick the radio into thinking cassete is inserted.


Cut this thin line with a knife (black arrow).

Thats it, put it back together and install it in the car. Tape mode is now aux.

Sound quality is excellent, there is no hum or noise.

1 Like

Sadly I have the Business CD unit made by Blaupunkt. I tried to do something similar to that. I tried to find the line level wires from the CD unit to the main board. Plan was to connect my wires there and then cut the traces from the CD unit board. I didn't have my oscilloscope or multimeter with me so I used a little speaker to find those connector pins (risky method). I only found one pin with audio signal but I didn't get any sound to the speakers using that one. Maybe there is some offset in the signal? Anyway, I couldn't find datasheets for the CD player controller (Made by Technics. I found a datasheet from almost similar one but those output pins were not connected in this.) or the DSP made by Motorola. Harsh method would be to connect the wires straight to the final stage amplifier input but then I would lose sound settings and volume knob etc. so don't want to do that. I did a mod like this to another Blaupunkt unit from Mercedes and it was easy.

This one seems to be a bit more complicated or maybe I missed something obvious. I didn't find any information online about this. Usually CD players using pretty basic design because they can just copy paste it to another unit.