Skip to content

Instantly share code, notes, and snippets.

@gzoller
Created September 19, 2021 18:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save gzoller/6c7395789ae377de68c4007477e9406b to your computer and use it in GitHub Desktop.
Save gzoller/6c7395789ae377de68c4007477e9406b to your computer and use it in GitHub Desktop.
Controlling E90 Instrument Cluster (tachometer) via CAN bus (CANBed module)
#include <mcp_can.h>
#include <SPI.h>
#define lo8(x) (uint8_t)((x) & 0xFF)
#define hi8(x) (uint8_t)(((x)>>8) & 0xFF)
const int SPI_CS_PIN = 17; // CANBed V1
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
uint8_t checkSum = 0xE2;
uint16_t rpmValue = 0;
//------------------------------------------------------------------
uint8_t ignition_frame_on[5] = {0x45,0x40,0x21,0x8F,0xE2};
// This message must be sent to the KOMBI every 100ms, but...
// you must be sure to increment the checkSum value every 1.4 sec or
// it won't work. The KOMBI is picky about this!
void sendIgnitionFrame() {
uint16_t CAN_ID = 0x130;
ignition_frame_on[4] = checkSum;
CAN.sendMsgBuf(CAN_ID,0,5,ignition_frame_on);
}
uint8_t rpmFrame[8] = {0x5F,0x59,0xFF,0x00,0x34,0x0D,0x80,0x99};
void sendRPM(uint16_t rpm) {
uint16_t tempRpm = rpm * 4;
uint16_t CAN_ID = 0x0AA;
rpmFrame[4] = lo8(tempRpm);
rpmFrame[5] = hi8(tempRpm);
CAN.sendMsgBuf(CAN_ID,0,8,rpmFrame);
}
//------------------------------------------------------------------
void setup() {
while (CAN_OK != CAN.begin(CAN_100KBPS)) // init can bus : baudrate = 100k for BMW KCAN
}
uint32_t lastTime = 0;
uint32_t secInc = 0;
uint32_t rpmTime = millis();
void loop() {
uint32_t curTime = millis();
if( curTime - lastTime > 99 ) { // 100ms interval
sendIgnitionFrame();
sendRPM(rpmValue);
lastTime = curTime;
}
if( curTime - rpmTime > 4999 ) { // 5 sec interval
rpmValue += 1000;
if( rpmValue > 5000 ) // cycle up 1k RPM every 5 sec until 5K rpm, then reset to 0
rpmValue = 0;
rpmTime = curTime;
}
if( curTime - secInc > 1399 ) { // 1.4 sec interval
checkSum++; // increment checksum ever 1.4 sec
secInc = curTime;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment