The BMW Navigation 'Accept Screen'
By Travis Kent Beste
May 20, 2006



01. Intro
02. Faulty Attempts
  02.01 Faulty Attempt 1
  02.02 Faulty Attempt 2
  02.03 Faulty Attempt 3
03. iBus Packets
04. Variables
05. Functions
06. Algorithm
07. Timelines
08. Terms
09. Lingering Thoughts
10. Credits
11. Donate (even if it's only a buck, there was a lot of time and effort invested in this effort, and you'd make me feel like it was all worth it.)

Intro
Before I get started, alot of different people have tried many different routes attempting to solve the issue of the BMW 'Accept Screen'. Even me. I don't know different things other folks have tried, but I believe the one thing that forces everyone to fall short in their goal of getting 'rid' of this annoyance, and something that I continually have to remind myself, is that the BMW navigation computer is a Real Time Operating System, or RTOS for short. (
RTOS Wiki, OS-9 Wiki)

The 'Accept Screen' is a disclaimer screen that appears everytime the navigation computer reboots. This means that after every power down of the navigation computer (located in the left rear of the car) this screen will appear before you can use the entertainment system. This means you cannot see your radio/cd/tape/SIRIUS screen, the navigation or other functions before you click the right navigation know to 'accept' the disclaimer. This article deals with a full-proof method of removing it.

Things that you'll need is an interface to the cars 'iBus'. I'll detail that in a later article, but if you check out Rolf Reslers' website you can order one that does either USB or serial port output. Then you'll need to have some savvy about how to decipher the data that transmits. Check out my iBus page that details information about the iBus packet and information about how to do just that.

There is a known fix for those slightly skilled in computers. You can download an older and newer version of the navigation software and burn them to CD. Once you have succeed there, you perform a version download and then upload. What this really achieves is that your navigation computer get reset to it's default coding settings. The default area for the drive is Europe, which doesn't have an 'Accept' screen. The downfall to this approach is that you have to deal with your distances in metric rather than the english system of measurement. Now you can get a version that is greater than v28 and then the accept screen goes away after 8 seconds of display time. Much nicer and pretty much why this article is moot.

I have tried 3 distinctly different approaches before the solution dawned on me. All seemed to work specifically for one BMW series. One worked for 5-series, one for 3-series. I couldn't never figure out the perfect combination of packets to listen for. The problem that I had initially was that I was listening for packets that would tell me when to press the button. After alot of testing, I was able to determine that it was the wrong approach. I was going to have to figure out a method to determine a method for diving that the screen was comming up. Or had already come up and not press the button. The final solution is able to detect that the car is 'on' following pretty much how the navigation computer does. It also then waits a determined amount of time before it presses the nav-rotate button, accepting the warning disclaimer screen. Of course, it also doesn't press it if you've grown accustomed to reaching over ever time that you start your car.


Faulty Attempts
Don't do what I did, learn from my mistakes. Here are my attempts and even though I attempted to market one of them, they definately do not work!

 Faulty Attempt 1
    Premise: The I could send the button push, release by timing it right somewhere around 14 seconds (for a MKIII and MKIV).
    Fault: This doesn't work because even though the nav starts up in a predetermined amount of time, you could turn off before the button press happens and then turn back on w/o getting your button press to acknowledge the accept screen.

Board monitor buttons
  F0 04 3B 48 05 82 nav turn knob button push
  F0 04 3B 48 85 02 nav turn knob button release

 Faulty Attempt 2
    Premise: The I could listen for a ping response from the cluster, on the 6th, I would send the button push/release.
    Fault: This doesn't work on E36 (3-series) cars because the cluster ping/reply seemed to work on high clusters and not low clusters. The difference between high/low clusters is the ability to display text (high cluster).

Telegram 1
  00 04 BF 02 00 B9 I called this the 'long power off'
Telegram 2
  80 04 BF 11 01 2B I called this the 'monitor keep alive'
Telegram 3
  3B 03 80 01 B9 I called this the 'cluster ping request'
  80 04 3B 02 00 39 I called this the 'cluster ping reply'
Board monitor buttons
  F0 04 3B 48 05 82 nav turn knob button push
  F0 04 3B 48 85 02 nav turn knob button release

  Faulty Attempt 3
    Premise: Nav screen appears as a sequence of telegrams - in this case I boiled it down to three.
    Fault: Telegrams are different for different clusters. The E39 (5-series) and E36 (3-series) have different clusters. In turn they send different communication packets. I thought that I could differentiate between the two, but there were cases when the telegrams that I was looking for would not show up in the sequence that I was expecting. Which, of course, people naturally complained about.

Telegram 1
  00 04 BF 02 00 B9 general status request
  80 04 BF 02 00 39 general status request
Telegram 2
  80 04 BF 11 00 2A auxiliary off, ignition off, crank off
  80 04 BF 11 03 2B auxiliary on, ignition on, crank off
  80 04 BF 11 07 2B auxiliary on, ignition on, crank on
Telegram 3
  3B 04 68 45 11 03 board monitor status
  7F 04 43 AB 21 B2 nav status
Board monitor buttons
  F0 04 3B 48 05 82 nav turn knob button push
  F0 04 3B 48 85 02 nav turn knob button release


iBus Packets
Ignition telegrams
  80 04 BF 11 00 2A auxiliary off, ignition off, crank off
  80 04 BF 11 03 2B auxiliary on, ignition on, crank off
  80 04 BF 11 07 2B auxiliary on, ignition on, crank on
Board monitor buttons
  F0 04 3B 48 05 82 nav turn knob button push
  F0 04 3B 48 85 02 nav turn knob button release


Variables
  delay_type
    0 = we have attempted to send the nav push, car is working.  We use this so that
        we can differntiate our state from the other two.
    1 = we have timed out for 60 seconds. We are waiting for 26 seconds before we
        send the button press/release. Other factors influence the actual button press.
    2 = attempting to set timer and time out - timer is for 60 seconds

  timeout_26_seconds
    true  = we have timed out for 26 seconds
    false = we haven't timed out for 26 seconds

  timeout_60_seconds
    true  = we have timed out for 60 seconds
    false = we haven't timed out for 60 seconds

  ignition
    true  = we have the car on (ignition on)
    false = we have the car off (ignition off)

  saw_button_push
    true  = we have seen the button push (only push telegram)
    false = we have not seen the button push (only push telegram)

  saw_button_release
    true  = we have seen the button release (only release telegram)
    false = we have not seen the button release (only release telegram)


Functions
// set if we have seen the ignition off iBus packet
void set_ignition_off() {
	ignition = false;
}

// set if we have seen the button push iBus packet
void set_nav_button_push() {
	saw_button_push = true;
}

// set if we have seen the button release iBus packet
void set_nav_button_release() {
	saw_button_release = true;
}

// set ignition on telegram, but don't forget to change the value of off
// !! multiple possible executions
void set_ignition_on() {
	ignition = true;

	// we have execute the 26 second timeout but the ignition was
	// not on, so we need to pick up the slack and perform the button
	// push/release and reset of variables
	if (timeout_26_seconds) {
		// We found out that we were too quick on the draw, wait for
		// 1 seconds then press button
		delay_type = 0; // need to turn off the main timer
		start_timer(DELAY_1_SECOND, push_button);
	}
}

// !! executed only once per cycle - remember that!
void _26_second_timeout() {
	// we need to signify that we've execute this function
	// also needed for verify and setting of saw_button_(push/release)
	timeout_26_seconds = true;

	// Now that we're done using the timer, move it back to looking for
	// 60 seconds
	delay_type         = 2;

	// if the ignition is on, then it's easy, push/release and reset
	if (ignition) {
		push_button();
	}

	// else variables look like this:
	// ignition           = false;
	// saw_button_push    = false;
	// saw_button_release = false;
	// timeout_26_seconds = true;
	// timeout_60_seconds = false;
	// delay_type         = 2;
}

// !! executed only once per cycle - remember that!
void _60_second_timeout() {
	ignition           = false; // ignition is off
	saw_button_push    = false; // unset button press
	saw_button_release = false; // unset button release
	timeout_26_seconds = false; // needs to be reset?
	timeout_60_seconds = true;  // only time it gets set to true is here !!
	delay_type         = 1;     // this means that we are going to be looking
	                            // for the 26 second delay
}

void push_button() {
	// They might have beaten us to it - not likely though
	if ( (!saw_button_push) && (!saw_button_release) ) {
		ibus_send_packet(button_push);
		ibus_send_packet(button_release);
	}

	// reset variables
	saw_button_push    = true;
	saw_button_release = true;
	timeout_26_seconds = false;
	timeout_60_seconds = false;   // this gets set in where you look for valid packets
	delay_type         = 2;       // this gets set in where you look for valid packets
}


...Your packet gathering loop...
.
.
// Here it looks like we've found valid data on the bus
if (delay_type == 2) {
	// Continuously set this timer
	start_timer(DELAY_60_SECONDS, 60_second_timeout);
} else if (delay_type == 1) {
	// We've timed out and we're starting back up again
	start_timer(DELAY_26_SECONDS, 26_second_timeout);

	// we've no longer timed out for 60 seconds at this point
	// it's the first executed statement after the start up and only
	// executed once because of the 'next' variable
	timeout_60_seconds = false;

	// so we don't go through this again, but not the 'delay_type == 2' either
	delay_type = 0;
}
.
.
...Your packet gathering loop...


Algorithm
We're going to start from a known state, but this works after you power down your nav computer the first time after plugging in something that implements this algorithm. The other thing to note is that if the user pushes the button, before our 26 second delay then if we reach the point where we would like to, it cancels our push and release telegrams. I'll detail some of the time lines below in the
timelines section.
  1. Car is off
  2. Nav drive is off (led on front of drive is off)
  3. Receive ignition on.
  4. Set timer for 26 seconds.
    1. If we receive an ignition off, we're still okay. We still wait for the 26 seconds.
    2. 26 seconds elapse and we either send the button press if the ignition is still on or...
    3. simply wait until an ignition on then wait a second and send button push, then release
  5. Press button push, then release if ignition is on.
  6. No telegrams after 60 seconds, then reset our state variables and start at the beginning
    1. If we're somewhere in or after the timer we'll reset


Timelines
Scenario timelines are here. The ticks are in seconds. I used a Mk3 drive, these will be slower for a Mk2 and faster for a Mk4.

This is the perfect case scenario.  
  Ignition Off prior to 0 seconds
Ignition On at 0 seconds
Splash Screen shows up at 7 seconds
Accept Screen shows up at 14 seconds
 
This is the shut down scenario.  
  Ignition On prior to 0 seconds
Last Packet Received at 0 seconds
State State Data at 10 seconds
Nav Drive Shutdown at 50 seconds
Drive is off from 50 seconds on



Terms
Power Down: All nav drives have a light on the front that shows activity. This light turns off after a certain period of time. What is that time might you ask? After the ignition is turned off (see ignition off telegram) a timer is initiated. After 10 seconds the current state data is saved to flash. After 50 seconds, the powerdown happens. Think I'm full of it? Time it. Heh, well the real truth of it is that I've actually looked in the nav computer and seen this setting. When I did my initial testing, I wanted this time to be different and I changed the setting in the config.


Lingering Thoughts It would be so good to finally get a copy of the source code for the BWM navigation computer. I know that this is never going to be a posiblity - even if it's for the now defunct platform of the OS-9 operating system. I'm going to try to see about figuring out a way to write code that will run on this platform, but the issue that I'll continue to face is drivers needed to communicate with the system and memory locations.



Credits
Credit to this web page is pretty narrow. I tried to put out a module that implemented this but followed the
second faulty attempt method. The website that I created generated alot of chatter in the BMW forums - it was bmw-accept.com. I'll admit that I had an issue with managing a new business and faulty modules that were having issues. Of course I had my day job to worry about too. I also knew that people were hungry for a solution that didn't modify their BMW navigation drive functions. My partner at the time was David Zeckhausen and I regret having tarnished his good name in the process. He is a very stand up guy and fun to work with. I ended up working with Parag Garg for a while to develop a better solution. We were able to develop a better solution (second faulty attempt) but Parag stopped answering my phone calls when he left the midwest to work at Microsoft. I was using his hardware solution and now I am in the process of developing my own. Sad thing is that now I have a good working solution (currently in my M5) and there is no longer any real interest. So, to benefit the community, here is the all of the software components. I would really appreciate it if you would give me credit if this works for you. Of course, if you'd like to paypal me a few bucks, that would be great too.


Donate
I have been told that I should probably charge for this information, but instead, I thought it would benefit the community. But, if you find this useful, you can either send me a note via my
contact page or...