BMW Steering Wheel Buttons: The Universal Adapter
Switch whatever you want
Components and supplies
1
Arduino Pro Micro
Tools and machines
1
Soldering kit
Apps and platforms
1
Arduino IDE
Project description
Code
MFL Adapter
c
Ino File
1// BMW Steering Wheel Buttons Universal Adapter 2// It decodes the original signals from the buttons to on/off 3// signals and steers a programable resistor for modern radio headers 4 5//Target: Pro Micro 6// 7#include <MCP4151.h> 8#include "IbusTrx.h" 9#define DEBUG 10 11#ifdef DEBUG 12 #define DEBUG_PRINTLN(x) Serial.println (x) 13#else 14 #define DEBUG_PRINTLN(x) 15#endif 16 17#define CS 10 18#define MOSI 16 19#define MISO 14 20#define SCK 15 21 22const int POT_VOLMINUS = 255 - 0; 23const int POT_VOLPLUS = 255 - 1; 24const int POT_CHNMINUS = 255 - 2; 25const int POT_CHNPLUS = 255 - 3; 26const int POT_PHONE = 255 - 4; 27const int POT_SPMINUS = 255 - 6; 28const int POT_SPPLUS = 255 - 9; 29const int POT_IO = 255 - 13; 30const int POT_CC = 255 - 19; 31const int POT_RT = 255 - 26; 32const int POT_MAX = 256 - 38; 33 34 35const int INTERRUPTPIN = 2; 36const int PIN_CHNPLUS = 3; 37const int PIN_CHNMINUS = 4; 38const int PIN_VOLPLUS = 5; 39const int PIN_VOLMINUS = 6; 40const int PIN_PHONE = 7; 41 42const int PIN_CC = 8; 43const int PIN_IO = 9; 44const int PIN_SPPLUS = 20; 45const int PIN_SPMINUS = 19; 46const int PIN_RT = 18; 47 48IbusTrx ibusTrx; 49long m_EndTime; 50long m_Duration; 51int m_CCReceivedBuffer; 52volatile int m_CCReceived; 53volatile bool m_CCNewData; 54bool m_SuppressRT; 55bool m_WasCC; 56 57MCP4151 pot(CS, MOSI, MISO, SCK); 58 59void PinInterrupt(){ 60 delayMicroseconds(234); 61 int bit = digitalRead(INTERRUPTPIN); 62 delayMicroseconds(234); 63 if(digitalRead(INTERRUPTPIN) == HIGH){ 64 m_CCReceived = m_CCReceivedBuffer>>1; 65 m_CCReceivedBuffer = 0; 66 m_CCNewData = true; 67 }else{ 68 m_CCReceivedBuffer = (m_CCReceivedBuffer<<1) + bit; 69 } 70} 71 72void setup() { 73 74#ifdef DEBUG 75 Serial.begin(9600); 76 delay(600); 77 Serial.println("Start"); 78#endif 79 80 m_Duration = 100; 81 m_EndTime = 0; 82 m_CCReceived = 0; 83 m_CCReceivedBuffer = 0; 84 m_CCNewData = false; 85 m_SuppressRT = false; 86 m_WasCC = false; 87 pinMode(PIN_CHNMINUS, OUTPUT); 88 pinMode(PIN_CHNPLUS, OUTPUT); 89 pinMode(PIN_VOLMINUS, OUTPUT); 90 pinMode(PIN_VOLPLUS, OUTPUT); 91 pinMode(PIN_PHONE, OUTPUT); 92 pinMode(PIN_RT, OUTPUT); 93 pinMode(PIN_CC, OUTPUT); 94 pinMode(PIN_IO, OUTPUT); 95 pinMode(PIN_SPMINUS, OUTPUT); 96 pinMode(PIN_SPPLUS, OUTPUT); 97 pinMode(INTERRUPTPIN, INPUT); 98 attachInterrupt(digitalPinToInterrupt(INTERRUPTPIN), PinInterrupt, RISING); 99 ibusTrx.begin(Serial1); 100 pot.writeValue(POT_MAX); 101} 102 103void loop() { 104 if(m_EndTime != 0 && millis() > m_EndTime){ 105 digitalWrite(PIN_RT, LOW); 106 digitalWrite(PIN_VOLPLUS, LOW); 107 digitalWrite(PIN_VOLMINUS, LOW); 108 pot.writeValue(POT_MAX); 109 m_EndTime = 0; 110 DEBUG_PRINTLN("EndTime!"); 111 } 112 113 if (m_CCNewData){ 114 m_CCNewData = false; 115 ccEvent(); 116 m_CCReceived = 0; 117 } 118 119 if (ibusTrx.available()) radioEvent(); 120} 121 122void radioEvent(){ 123 IbusMessage message = ibusTrx.readMessage(); 124 if(message.source() != 80)return; 125 126 if(message.destination() == 176 || message.destination() == 208) m_SuppressRT = true; 127 128 if(message.destination() != 104 && message.destination() != 200) return; 129 130 if(message.b(0) == 1){ 131 if(m_SuppressRT){ 132 m_SuppressRT = false; 133 return; 134 } 135 m_EndTime = millis() + m_Duration; 136 pot.writeValue(POT_RT); 137 digitalWrite(PIN_RT, HIGH); 138 DEBUG_PRINTLN("RT"); 139 return; 140 } 141 142 switch(message.b(0)<<8 | message.b(1)){ 143 case 0x3211: 144 m_EndTime = millis() + m_Duration; 145 pot.writeValue(POT_VOLPLUS); 146 digitalWrite(PIN_VOLPLUS, HIGH); 147 DEBUG_PRINTLN("PIN_VOLPLUS_DOWN"); 148 break; 149 150 case 0x3210: 151 m_EndTime = millis() + m_Duration; 152 pot.writeValue(POT_VOLMINUS); 153 digitalWrite(PIN_VOLMINUS, HIGH); 154 DEBUG_PRINTLN("PIN_VOLMINUS_DOWN"); 155 break; 156 157 case 0x3B01: 158 pot.writeValue(POT_CHNPLUS); 159 digitalWrite(PIN_CHNPLUS, HIGH); 160 DEBUG_PRINTLN("PIN_CHNPLUS_DOWN"); 161 break; 162 163 case 0x3B21: 164 pot.writeValue(POT_MAX); 165 digitalWrite(PIN_CHNPLUS, LOW); 166 DEBUG_PRINTLN("PIN_CHNPLUS_UP"); 167 break; 168 169 case 0x3B08: 170 pot.writeValue(POT_CHNMINUS); 171 digitalWrite(PIN_CHNMINUS, HIGH); 172 DEBUG_PRINTLN("PIN_CHNMINUS_DOWN"); 173 break; 174 175 case 0x3B28: 176 pot.writeValue(POT_MAX); 177 digitalWrite(PIN_CHNMINUS, LOW); 178 DEBUG_PRINTLN("PIN_CHNMINUS_UP"); 179 break; 180 181 case 0x3B80: 182 pot.writeValue(POT_PHONE); 183 digitalWrite(PIN_PHONE, HIGH); 184 DEBUG_PRINTLN("PIN_PHONE_DOWN"); 185 break; 186 187 case 0x3BA0: 188 pot.writeValue(POT_MAX); 189 digitalWrite(PIN_PHONE, LOW); 190 DEBUG_PRINTLN("PIN_PHONE_UP"); 191 break; 192 } 193} 194 195void ccEvent(){ 196 switch(m_CCReceived){ 197 case 127: 198 if(m_WasCC) pot.writeValue(POT_MAX); 199 digitalWrite(PIN_CC, LOW); 200 digitalWrite(PIN_IO, LOW); 201 digitalWrite(PIN_SPPLUS, LOW); 202 digitalWrite(PIN_SPMINUS, LOW); 203 m_WasCC=false; 204 break; 205 206 case 55: 207 pot.writeValue(POT_CC); 208 digitalWrite(PIN_CC, HIGH); 209 m_WasCC=true; 210 DEBUG_PRINTLN("PIN_CC_DOWN"); 211 break; 212 213 case 109: 214 pot.writeValue(POT_IO); 215 digitalWrite(PIN_IO, HIGH); 216 DEBUG_PRINTLN("PIN_IO_DOWN"); 217 m_WasCC=true; 218 break; 219 220 case 91: 221 pot.writeValue(POT_SPPLUS); 222 digitalWrite(PIN_SPPLUS, HIGH); 223 DEBUG_PRINTLN("PIN_SPPLUS_DOWN"); 224 m_WasCC=true; 225 break; 226 227 case 126: 228 pot.writeValue(POT_SPMINUS); 229 digitalWrite(PIN_SPMINUS, HIGH); 230 DEBUG_PRINTLN("PIN_SPMINUS_DOWN"); 231 m_WasCC=true; 232 break; 233 } 234}
Downloadable files
MFL Decoder source files
Includes Eagle schematics and PCB layout
file.None
Documentation
BMW MFL Adapter Schematic
Eagle schematic file
Decoder_SMD.sch
BMW MFL Adapter PCB
Eagle PCB file
Decoder_SMD.brd
Comments
Only logged in users can leave comments