BMW - Windows XP startup - shutdown

On a beautiful day I was thinking, wouldn't it be cool if other devices also had start-up and shutdown tunes, just like your computer? For example, your TV, your car or your motorcycle? Since I was looking for a simple project to that uses an Arduino microcontroller, I decided to add the Windows XP Startup and Shutdown sounds to my BMW F650.

 It took me about 4 hours total to build this.Total cost is about $100. Ways of achieving this cheaper: use regular speakers, build the amplifier yourself, or just leave out all the hardware and try to mimic the sounds with your voice everytime you start or shutdown the bike. This might get you even more attention.There is a little pause in the movie, that is required, because I programmed the microcontroller to wait at least 30 seconds after boot, before responding to the engine cutoff switch.

I used the electric wiring plans for the BMW from the maintenance book to figure out where to find the engine cutoff wire and connected it to Pin 19 on the Arduino.The whole project basically uses three wires, Ground, +12V, that goes into the Arduino (that has a 7805 to reduce that to 5V) and the engine cutoff wire, that is connected to a pull down switch inside the project box.

This project uses the following parts:

  1. An Adafruit Wave shield.
  2. A set of Ebay Marine speakers.
  3. A Cheap Car/MP3 Amp from Ebay.
  4. A Freeduino Serial 2.0 from NKC.
  5. A couple of small parts, resistors and such.
  6. A small SD card from Newegg.

Arduino + Wave Shield
Here you see the brains of the whole operation, the Arduino, with the Wave Shield on top of it, fitted in a small plastic container with lid, underneath the saddle, next to the voltage rectifier.
 

amp

Here you see the  amplifier, glued above the ignition computer. Note the pointless multicolor LED ring. I also managed to break off the treble button when I tried to get rid of the factory default play between the various parts of the amp. I ended up solving it by filling the gaps (and the treble hole) with glue.

 

  Marine Speaker

Marine Speaker, mounted above the rear wheel,
at the location where originally the charcoal canister was located
(The previous owner of the bike performed a canisterectomy)

Here is the code used in the Arduino. I also have code in there so I can add buttons on the handle bar in the future and assign audio samples to them.


#include <AF_Wave.h>
#include <avr/pgmspace.h>
#include "util.h"
#include "wave.h"

#define DEBOUNCE 100

#define swPin 14

AF_Wave card;
File f;
Wavefile wave;

byte onceValue = 0; //Declare number to make sure shut.wav is only played once.

void setup() {
  // set up serial port
  Serial.begin(9600);
 
  // set up waveshield pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
 
  // enable pull-up resistors on
  // switch pins (analog inputs)
  digitalWrite(14, HIGH);
  digitalWrite(15, HIGH);
  digitalWrite(16, HIGH);
  digitalWrite(17, HIGH);
  digitalWrite(18, HIGH);
  digitalWrite(19, HIGH);

  // open memory card
  if (!card.init_card()) {
    putstring_nl("Card init failed!"); return;
  }
  if (!card.open_partition()) {
    putstring_nl("No partition!"); return;
  }
  if (!card.open_filesys()) {
    putstring_nl("Couldn't open filesys"); return;
  }
  if (!card.open_rootdir()) {
    putstring_nl("Couldn't open dir"); return;
  }
      playcomplete("START.WAV");


void loop() {   
  switch (check_switches()) {
    case 1:
      playcomplete("SOUND1.WAV");
      break;
    case 2:
      playcomplete("SOUND2.WAV");
      break;
    case 3:
      playcomplete("SOUND3.WAV");
      break;
    case 4:
      playcomplete("SOUND4.WAV");
      break;
    case 5:
      playcomplete("SOUND5.WAV");
  }

  if (onceValue == 0){
   if (millis() > 30000){
    if (digitalRead(19) == LOW){
      delay(1500);
      playcomplete("SHUT.WAV");
      onceValue = 1;
    }
   }
  }
}
}


byte check_switches()
{
  static byte previous[5];
  static long time[5];
  byte reading;
  byte pressed;
  byte index;
 
  for (byte index = 0; index < 5; ++index) {
    reading = digitalRead(14 + index);
    if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
    {
      // switch pressed
      time[index] = millis();
      pressed = index + 1;
      break;
    }
    previous[index] = reading;
  }
  // return switch number (1 - 5)
  return (pressed);
}

void playcomplete(char *name) {
  playfile(name);
  while (wave.isplaying);
  card.close_file(f);
}

void playfile(char *name) {
  // stop any file already playing
  if (wave.isplaying) {
    wave.stop();
    card.close_file(f);
  }

  f = card.open_file(name);
  if (f && wave.create(f)) {
    wave.play();
  }