Project Code

Earlier this year I developed a prototype board for interfacing with my car. It has 5 relays that control custom add-ons like Angel Eye lights and a Raspberry Pi w/LTE, and communicates with existing GPS and CAN modules.

It is part of an ongoing project I call MDroid.


Go KBus is a golang module designed to interface with the BMW I/K Bus. This protocol is similar to CAN, and controls the non-essential components in the car.

This module can be used to read, write, and interpret BMW serial commands. It’s loosely based on ezeakeal’s excellent pyBus (and my subsequent fork).


  • USB serial interface can be acquired from Other USB interfaces should work just as well, although are untested.
  • Communicates on the I-BUS to send and receive diagnostics, running status, button presses, vehicle info, etc.


go get

Example module usage

package main

import (


func main() {
	kbus, err := gokbus.New("/dev/ttyUSB0", 9600)
	if err != nil {
	defer kbus.Port.Close()

	// Start the read and write channels
	// This isn't required - we can ReadPacket() / WritePacket() separately without channels,
	// but timing will be less precise and many packets will be dropped.
	go kbus.Start()

	// Read 5 packets
	for i := 0; i < 5; i++ {
		select {
		case newPacket := <-kbus.ReadChannel:

	// Prepare a write packet, this one opens the trunk
	openTrunkPacket := gokbus.Packet{
		Source:      0x3F,
		Destination: 0x00,
		Data:        []byte{0x0C, 0x02, 0x01},
	// alternatively, a list of known packets are provided in /pkg/prepackets
	// flashLowBeamsPacket := prepackets.FlashLowBeams

	// Block until packet is written to the bus
	kbus.WriteChannel <- openTrunkPacket

	// Read another 5 packets
	for i := 0; i < 5; i++ {
		select {
		case newPacket := <-kbus.ReadChannel:


Missing write confirmation that pyBus offers