-- BMW iDrive LUA. Witten for BMW #ZE931769502
-- 5 Button with L/R Joystick.
-- Timer
t_heartbeat = Timer.new()
-- CAN Rx Channels
IDRIVE_BUTTONS = 0x267
IDRIVE_ROTARY = 0x264
-- CAN Tx Channels
IDRIVE_BRIGHTNESS = 0x202
IDRIVE_HEARBEAT = 0x560
IDRIVE_ROTARY_INIT = 0x273
-- Init
brighness = 0
previous_button = 0
current_button = 0
current_btn_state = 0
previous_btn_state = 0
-- Tables
button_names = { }
button_names[0x01] = "Menu"
button_names[0x02] = "Back"
button_names[0x04] = "Option"
button_names[0x08] = "Audio"
button_names[0x40] = "Tel"
button_names[0xDE] = "Knob"
button_names[0xDD] = "Knob Tilt"
button_states = { }
button_states[0x00] = "Released"
button_states[0x01] = "Pushed"
button_states[0x02] = "Held"
button_states[0x21] = "Right"
button_states[0x22] = "Held Right"
button_states[0x81] = "Left"
button_states[0x82] = "Held Left"
canRxAdd(IDRIVE_ROTARY) -- add Rx Handler for Rotary
canRxAdd(IDRIVE_BUTTONS) -- add Rx Handler for Buttons
setTickRate(50) -- set tick rate to 50hz
-- One time rotary initialisation
txCan(1, IDRIVE_ROTARY_INIT, 0, { 0x1D, 0xE1, 0x00, 0xF0, 0xFF, 0x7F, 0xDE, 0x04 })
function onCanRx(bus, id, dlc, data)
if id == IDRIVE_BUTTONS then
if data[5] == 0xc0 then
-- buttons
-- print('button')
-- update current and previous
previous_button = current_button
current_button = data[6]
if (previous_button == current_button) then
-- signal for the same button
-- update the state
previous_btn_state = current_btn_state
current_btn_state = data[4]
if (current_btn_state ~= previous_btn_state) then
-- if the state has changed
print(button_names[data[6]] ..' was ' ..button_states[data[4]]) -- print the state
end
else
-- new button
previous_btn_state = 0 -- clear the previous state
current_btn_state = data[4] -- write the new state
print(button_names[data[6]] ..' was ' ..button_states[data[4]]) -- print the state
end
end
if data[5] == 0xde or data[5] == 0xdd then
-- print('knob')
-- knob push or tilt
-- update current and previous
previous_button = current_button
current_button = data[5]
if (previous_button == current_button) then
-- signal for the same button
-- update the state
previous_btn_state = current_btn_state
current_btn_state = data[4]
if (current_btn_state ~= previous_btn_state) then
-- if the state has changed
print(button_names[data[5]] ..' was ' ..button_states[data[4]]) -- print the state
end
else
-- new button
previous_btn_state = 0 -- clear the previous state
current_btn_state = data[4] -- write the new state
print(button_names[data[5]] ..' was ' ..button_states[data[4]]) -- print the state
end
end
end
if id == IDRIVE_ROTARY then
if data[5] == 0x80 then
print('rotary turned right ' ..data[4] ..' clicks')
end
if data[5] == 0x7f then
print('rotary turned left ' ..255 - data[4] ..' clicks')
end
end
end
function onTick()
-- iDrive heartbeat code - every 1000ms
if t_heartbeat : getElapsedSeconds() > 1 then
txCan(1, IDRIVE_HEARBEAT, 0, { 0x00, 0x00, 0x00, 0x00, 0x57, 0x2F, 0x00, 0x60 })
txCan(1, 0x202, 0, { 0xff })
t_heartbeat : reset()
end
end
learned some lua, did some code. Please report back.
Thank you!!!
Your version got the knob to function on my 9286699-02 but it's raising some errors looks like no button name for some cases? Can you please add 'nil' value handling?
2022-08-12_16_17_14_276: EngineState: LUA: rotary turned right 0 clicks
2022-08-12_16_17_14_355: EngineState: LUA: rotary turned right 1 clicks
2022-08-12_16_17_14_355: EngineState: LUA: rotary turned right 2 clicks
2022-08-12_16_17_14_456: EngineState: LUA CAN RX error [string "-- BMW iDrive LUA. Witten for BMW #ZE93176950..."]:128: attempt to concatenate a nil value (field '?')
2022-08-12_16_17_14_662: EngineState: LUA: Knob Tilt was Released
2022-08-12_16_17_14_862: EngineState: LUA CAN RX error [string "-- BMW iDrive LUA. Witten for BMW #ZE93176950..."]:118: attempt to concatenate a nil value (field '?')
2022-08-12_16_17_15_063: EngineState: LUA: Knob was Pushed
2022-08-12_16_17_15_265: EngineState: LUA: Knob Tilt was Released
2022-08-12_16_17_15_265: EngineState: LUA: Knob was Released
2022-08-12_16_17_15_362: EngineState: LUA CAN RX error [string "-- BMW iDrive LUA. Witten for BMW #ZE93176950..."]:128: attempt to concatenate a nil value (field '?')
2022-08-12_16_17_15_463: EngineState: LUA: Knob Tilt was Released
2022-08-12_16_17_15_563: EngineState: LUA CAN RX error [string "-- BMW iDrive LUA. Witten for BMW #ZE93176950..."]:118: attempt to concatenate a nil value (field '?')
2022-08-12_16_17_15_665: EngineState: LUA: Knob was Pushed
2022-08-12_16_17_15_764: EngineState: LUA: Knob was Released
2022-08-12_16_17_15_865: EngineState: LUA: Knob Tilt was Released
I have two kinds. Looks like yours is similar to the left one while the one on the right has four extra buttons (it also has an aftermarket wheel enlargement in order to look bigger than it is in reality: do not ask, that's how I got it I promise!!!)
Attachments
ZE931769501-left-9286699-02-right.jpeg (187.25 KiB) Viewed 2607 times