Add car-off shutdown detection to LIN_to_IR firmware

This commit is contained in:
2026-05-25 15:40:27 +02:00
parent 77ff8b973b
commit 8d101b3162
3 changed files with 65 additions and 0 deletions
+17
View File
@@ -85,6 +85,7 @@ uint32_t get_mce_code(uint8_t button) {
case 4: return 0x800f0421; // RIGHT
case 5: return 0x800f0422; // ENTER / OK
case 6: return 0x800f0423; // BACK
case 7: return 0x800f046f; // F12 (Shutdown)
default: return 0;
}
}
@@ -105,6 +106,8 @@ unsigned long last_frame_time = 0;
uint8_t current_button = 0;
uint8_t toggle_bit = 0;
unsigned long last_ir_send_time = 0;
unsigned long last_lin_activity_time = 0;
bool is_car_on = false;
void process_button_state(uint8_t active_button) {
unsigned long now = millis();
@@ -179,10 +182,15 @@ void setup() {
LINBusSerial.begin(9600);
frame = LinFrame();
last_frame_time = millis();
last_lin_activity_time = millis();
}
void loop() {
if (LINBusSerial.available()) {
last_lin_activity_time = millis();
if (!is_car_on) {
is_car_on = true;
}
b = LINBusSerial.read();
n = frame.num_bytes();
@@ -201,4 +209,13 @@ void loop() {
if (millis() - last_frame_time > 200) {
current_button = 0;
}
// Car off detection: if no LIN activity for 5 seconds, send F12 to trigger shutdown
if (is_car_on && (millis() - last_lin_activity_time > 5000)) {
is_car_on = false;
for (int i = 0; i < 3; i++) {
send_ir_for_button(7, i & 1);
delay(100);
}
}
}
+37
View File
@@ -27,9 +27,45 @@ The Steering Wheel Module (SWM) sends frames on LIN ID `0x20` with the navigatio
| **RIGHT** | `d0 & 0x08` | `4` | `0x800f0421` | Navigate Right |
| **ENTER** | `d1 & 0x08` | `5` | `0x800f0422` | Select / OK |
| **BACK** | `d1 & 0x01` | `6` | `0x800f0423` | Back / Exit |
| **F12 (Shutdown)** | LIN Silent > 5s | `7` | `0x800f046f` | Trigger Shutdown (via MacroDroid) |
*Note: In previous revisions, `ENTER` and `BACK` were reversed. This has been corrected so that pressing `ENTER` maps to `0x800f0422` and `BACK` maps to `0x800f0423`.*
## Car-Off (Shutdown) Detection
To automatically power off the Raspberry Pi when the car is turned off:
1. **Activity Monitor**: The ATtiny monitors LIN bus activity. The Central Electronic Module (CEM) continuously polls the LIN bus when the ignition is on.
2. **Timeout**: If no LIN serial data is received for 5 seconds, the ATtiny assumes the car is off.
3. **Shutdown Signal**: It transitions the car status to "off" and sends the MCE code `0x800f046f` (mapped to `KEY_F12`) 3 times to ensure transmission reliability.
4. **State Protection**: It will not send the shutdown command again until the car is turned back on and LIN traffic resumes (which sets `is_car_on` back to `true`).
## Raspberry Pi Configuration
### 1. Keymap Setup
Remap scancode `0x800f046f` to `KEY_F12` on the Raspberry Pi:
- The custom TOML configuration is saved at `/data/rc-rc6-mce.toml` on the Pi.
- To apply it dynamically:
```bash
/vendor/bin/ir-keytable -w /data/rc-rc6-mce.toml
```
### 2. MacroDroid Persistence & Trigger
Configure two macros in **MacroDroid** to manage keymap loading and shutdown:
- **Macro 1: Load Keymap on Boot**
- **Trigger**: *Device Boot*
- **Action**: *Run Shell Command* (Check **Run as Root**)
```bash
/vendor/bin/ir-keytable -w /data/rc-rc6-mce.toml
```
- **Macro 2: Shutdown on F12**
- **Trigger**: *Media / Key Pressed* -> Select **F12**
- **Action**: *Run Shell Command* (Check **Run as Root**)
```bash
reboot -p
```
## Protocol and Timing
- **Protocol**: RC-6 Mode 6A (MCE).
@@ -46,3 +82,4 @@ The Steering Wheel Module (SWM) sends frames on LIN ID `0x20` with the navigatio
Since SoftwareSerial RX interrupts consume about 1ms per byte, they will disrupt the precise microsecond-level timing of bit-banged IR frames. To avoid this, interrupts are disabled (`noInterrupts()`) during the 37ms window of IR transmission and re-enabled (`interrupts()`) immediately afterward.
2. **Release detection**:
The SWM continuously transmits frames on the LIN bus. If no button frames are detected or a frame with all 0s is received, the current active button resets to idle. A timeout of `200ms` ensures that if the LIN bus goes quiet, button repeats cease immediately.
+11
View File
@@ -0,0 +1,11 @@
[[protocols]]
name = "rc-rc6-mce"
protocol = "rc-6"
[protocols.scancodes]
0x800f041e = "KEY_UP"
0x800f041f = "KEY_DOWN"
0x800f0420 = "KEY_LEFT"
0x800f0421 = "KEY_RIGHT"
0x800f0422 = "KEY_OK"
0x800f0423 = "KEY_EXIT"
0x800f046f = "KEY_F12"