Go Down

Topic: Automotive OEM rotary controller as driverless USB device (Read 46663 times) previous topic - next topic


Ascanio can you explain how can we set a custom bit rate?
What is the meaning of 9,7,3... numbers?


I'd like to see a post presenting this knowledge.


Hi guyz!

I am trying to figure out how to interface my Arduino UNO R3 with an OEM rotary controller device (in my specific case it is a BMW iDrive device from an X3).

My intention is to use Arduino as a proxy, so to be able to use the rotary controller without drivers on any computer, by emulating a keyboard and mouse.

Devices such as the iDrive rotary controller are interfaced via CAN bus (in fact the connector has 4 pins, which I guess will read out to VIN, GND, CAN-H, CAN-L).

I have already purchased the Sparkfun CAN-bus Shield, but haven't had time to try the CAN libraries available on the web.
I know such libraries are usually directed at connecting to an existing CAN network (through the OBD-II diagnostic port on vehicles). Has anybody successfully INITIATED a network with this shield (I guess the iDrive rotary device will in turn try to connect as a slave)?

Cheers to all! May you spend a lovely time with your families this Christmas :)

how did i go? i have the same plane, but using a rpi


I have used an arduino to control a turbo.. It's been a while since i looked at the specific code for that section though.. I do know that I was able to sniff the packets sent by the turbo telling me it's current parameters.. I used the standard CAN bus library.

Code: [Select]

MCP CAN1(10); 'pin 10 is the SPI SS pin

#define VGTaddress  0x0CFFC600UL      //CAN bus address of the VGT controller
#define StatusMessageID  0x18FFC502UL //this is the message id of the messages we're concerned with
#define BreakMessageID  0x18FF0A02UL  //This is the message id of a 'terminator' string, or something... no relevant information it seems
#define ErrorMessageID  0x18EEFF02UL  //Seems to be an error message ID when low voltage is triggered?

void loop(){

void ReadCanMessage() {
//This is from the MCP examples, modified to work for what I need
unsigned long ID;                                       // assign a variable for Message ID
byte length;                                            //assign a variable for length
byte data[8];                                           //assign an array for data

if (CAN1.msgAvailable()) {                      // Check to see if a valid message has been received.

CAN1.read(&ID, &length, data);                        // read Message and assign data through reference operator &

if (ID == StatusMessageID) {
VgtCommandPosition = ((data[6] * 256) + data[5]);
VgtRealPosition = ((data[2] * 256) + data[1]);
VgtMotorCommandSpeed = data[7] - 127;
VgtRawTemp = data[3];
else if (ID == BreakMessageID) {
//do nothing.. it's an unimportant message
else if (ID == ErrorMessageID) {
PrintCANmessage(ID, length, data);
else {
//we got a new message type.. lets figure it out
//PrintCANmessage(ID, length, data);

void PrintCANmessage(unsigned long ID, byte length, byte* data) {
Serial.print("CanMessage = ID");
Serial.print(" | 0x");
Serial.print(ID, HEX);                                 // Displays received ID
Serial.print(" | ");
Serial.print("Data Length DEC");
Serial.print(" | ");
Serial.print(length);                               // Displays message length
Serial.print(" | ");
for (byte i = 0; i < length; i++) {
Serial.print(" | ");
if (data[i] < 0x10)                                   // If the data is less than 10 hex it will assign a zero to the front as leading zeros are ignored...
Serial.print(data[i], HEX);                          // Displays message data


Hope this helps a little

Just noticed how darned old this thread is!

Go Up