XirallicBolts

Flex - Front Camera | Heated Controls | New Shift Knob

Jan 1st, 2020 (edited)
495
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.58 KB | None | 0 0
  1. // XirallicBolts
  2. // XB_Camera-NewShiftKnob, adapted for smaller MCP2515 module
  3. // Front camera display by shift knob +
  4. // Force rear camera by shift knob -
  5. // Turn off screen by long-pressing Power
  6. // Driver heated seat + wheel by long-pressing EJECT
  7. // Driver/pass seat + wheel by long-pressing SOUND
  8.  
  9. // 2-14-2021    Sync 3.4    Activate seats with short press of Eject
  10. // 3-30-2021    Press 'Phone' on steering wheel to switch to USB... not always working.
  11. //              More research needed
  12.  
  13. // To-do: Use separate arrays to clean up code
  14.  
  15. // INT    2     Pink / Brown
  16. // Relay  7     Green
  17. // Shift+ 8     Grey
  18. // Shift- 9     Grey/White
  19. // CS     10    White / Pink
  20. // S1     11    White
  21. // S0     12    Yellow
  22. // SCK    13    Purple
  23. // --------------------
  24. // I-CAN +      Orange
  25. // I-CAN -      White / Orange
  26. // HS-CAN +     Orange
  27. // HS-CAN -     White / Orange  
  28. // Acc 12v      Red
  29. // Ground       White / Red
  30. //
  31. // Message ID 0x109   Bytes 0/1:   RPM
  32. // (Gear Message)     Byte 2:      Gear  (01 Park | 11 Reverse | 21 Neutral | 31 Drive | 41 Sport)
  33. //                                        Sometimes the last character changes, such as 0x1E for Reverse
  34. //                    Bytes 3/4/5: Speed
  35. //                    Byte 6:      Ignition mode? (28 Accessory | 58 Engine Running)
  36. //
  37. //
  38. // Message ID 0x2A0   xx FF FF FF 10 00 1E 02     Button is PRESSED
  39. // (Front Panel)      xx FF FF FF 10 00 1E 00     Button is HELD
  40. //                    xx FF FF FF 00 00 1E 00     Button is RELEASED
  41. //                    0x34: Eject         0x18: Sound       0x5F: Home     0x1F: Power
  42. //
  43. //
  44. //  Message ID 0x35B  00 00 00 FE 80 00 00        Heated Steering Wheel
  45. // (Climate)          00 00 01 FE 00 00 00        Driver Heated Seat
  46. //                    00 00 03 FE 00 00 00        Passenger Heated Seat
  47. //
  48.  
  49. // Common between shift buttons connects to ground
  50.  
  51.  
  52.  
  53. #include <mcp_can.h>
  54. #include <SPI.h>
  55. #define CAN_INT       2
  56. #define FRONT_CAMERA  7
  57. #define SHIFT_PLUS    8
  58. #define SHIFT_MINUS   9
  59. #define CAN_CS        10
  60.  
  61. MCP_CAN CAN0(CAN_CS);
  62.  
  63. byte HeldButtonCounter    = 0;
  64. byte ForceRearCamera      = 0;
  65. byte ShiftPlusButtonHeld  = 0;
  66. byte ShiftMinusButtonHeld = 0;
  67. byte RequestCameraView    = 0;
  68. int  PowerLoops           = 0;
  69.  
  70. long unsigned int message_ID;
  71. unsigned char message_LENGTH = 0;
  72. unsigned char message_DATA[8];
  73.  
  74. void setup() {
  75.   pinMode(FRONT_CAMERA, OUTPUT);
  76.   pinMode(SHIFT_PLUS, INPUT_PULLUP);
  77.   pinMode(SHIFT_MINUS, INPUT_PULLUP);
  78.   pinMode(CAN_INT, INPUT);
  79.   digitalWrite(FRONT_CAMERA, HIGH);   // Default to front camera
  80.   Serial.begin(115200);
  81.     Serial.println("XirallicBolts");
  82.     Serial.println("Front camera module using small module");
  83.     Serial.println("Shift Knob buttons");
  84.     Serial.println("---");
  85.  
  86.   if(CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
  87.     Serial.println("MCP2515 Initialized Succesfully");
  88.   else
  89.     Serial.println("Could not initialize MCP2515 (CS 10, INT 2, 500KBPS, 16MHz");
  90.  
  91.   CAN0.setMode(MCP_NORMAL);
  92.  
  93. }
  94.  
  95. void loop() {
  96.   if(!digitalRead(CAN_INT))
  97.   {
  98.     CAN0.readMsgBuf(&message_ID, &message_LENGTH, message_DATA);
  99.  
  100.     // If it's in reverse (ID 0x109, 0x10 to 0x1F, or ForceRearCamera is on,  disable the relay
  101.     if((message_ID == 0x109 and message_DATA[2] >= 0x10 and message_DATA[2] <= 0x1F) or ForceRearCamera == 1)
  102.     {
  103.       Serial.print("Relay OFF.  Current Camera: REAR.  Gear: 0x");
  104.       Serial.print(message_DATA[2],HEX);
  105.       Serial.print(" ForceRearCamera: ");
  106.       Serial.println(ForceRearCamera);
  107.       digitalWrite(FRONT_CAMERA, LOW);
  108.     }
  109.  
  110.     // If it's not in reverse, enable camera relay (switch to front camera)
  111.     if((message_ID == 0x109 and (message_DATA[2] <= 0x0F or message_DATA[2] >= 0x20)) and ForceRearCamera == 0)
  112.     {
  113.       Serial.print("Relay ON. Current Camera: FRONT. Gear: 0x");
  114.       Serial.print(message_DATA[2],HEX);
  115.       Serial.print(" ForceRearCamera: ");
  116.       Serial.println(ForceRearCamera);
  117.       digitalWrite(FRONT_CAMERA, HIGH);
  118.     }
  119.  
  120.     // If the camera is request, speed is low, and not in Park,   send a fake Reverse signal
  121.     if(message_ID == 0x109 and message_DATA[2] >= 0x10 and message_DATA[4] < 0x03 and RequestCameraView == 1)
  122.     {
  123.       Serial.println("Camera View requested, gear message just arrived.");
  124.       Serial.println("Sending falsified Reverse signal...");
  125.       message_DATA[2] = 0x11;
  126.       CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA);
  127.       Serial.println("Done. Resetting RequestCameraView");
  128.       RequestCameraView = 0;      
  129.     }
  130.  
  131.     //
  132.     //
  133.     // If EJECT is held, activate driver seat and heated steering wheel
  134.     //
  135.     //  
  136.     if(message_ID == 0x2A0 and message_DATA[0] == 0x34 and message_DATA[4] == 0x10 and message_DATA[7] == 0x00)
  137.     {
  138.       Serial.println("Eject button HELD");
  139.       HeldButtonCounter++;
  140.     }
  141.  
  142.     if(message_ID == 0x2A0 and message_DATA[0] == 0x34 and message_DATA[4] == 0x00 and message_DATA[7] == 0x00)
  143.     {
  144.       Serial.print("Eject buton RELEASED.  Counter: ");
  145.       Serial.println(HeldButtonCounter);
  146.       if(HeldButtonCounter >= 0)  // was 3,  wanted to make it a quick tap instead
  147.       {
  148.         Serial.println("Requesting: Driver Heated Seat");
  149.         message_ID = 0x35B;
  150.         message_DATA[0] = 0x00;     message_DATA[1] = 0x00;     message_DATA[2] = 0x01;     message_DATA[3] = 0xFE;     message_DATA[4] = 0x00;     message_DATA[5] = 0x00;     message_DATA[6] = 0x00;     message_DATA[7] = 0x00;
  151.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA);
  152.         delay(1000);
  153.         Serial.println("Requesting: Heated Steering Wheel");
  154.         message_DATA[2] = 0x00;     message_DATA[4] = 0x80;
  155.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA);
  156.         delay(500);
  157.       }
  158.       HeldButtonCounter = 0;   // Reset counter regardless of length
  159.     }
  160.  
  161.     //
  162.     //
  163.     // If SOUND is held, activate both seats and heated steering wheel
  164.     //
  165.     //
  166.     if(message_ID == 0x2A0 and message_DATA[0] == 0x18 and message_DATA[4] == 0x10 and message_DATA[7] == 0x00)
  167.     {
  168.       Serial.println("Sound button HELD");
  169.       HeldButtonCounter++;
  170.     }
  171.  
  172.     if(message_ID == 0x2A0 and message_DATA[0] == 0x18 and message_DATA[4] == 0x00 and message_DATA[7] == 0x00)
  173.     {
  174.       Serial.print("Sound buton RELEASED.  Counter: ");
  175.       Serial.println(HeldButtonCounter);
  176.       if(HeldButtonCounter >= 3)
  177.       {
  178.         Serial.println("Requesting: Return to Home Screen");
  179.         message_ID = 0x2A0;
  180.         message_DATA[0] = 0x5F;     message_DATA[1] = 0xFF;     message_DATA[2] = 0xFF;     message_DATA[3] = 0xFF;     message_DATA[4] = 0x10;     message_DATA[5] = 0x00;     message_DATA[6] = 0x1E;     message_DATA[7] = 0x02;
  181.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Home PRESS
  182.         delay(100);
  183.         message_DATA[4] = 0x00;     message_DATA[7] = 0x00;
  184.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Home RELEASE
  185.  
  186.         Serial.println("Requesting: Driver Heated Seat");
  187.         message_ID = 0x35B;
  188.         message_DATA[0] = 0x00;     message_DATA[1] = 0x00;     message_DATA[2] = 0x01;     message_DATA[3] = 0xFE;     message_DATA[4] = 0x00;     message_DATA[5] = 0x00;     message_DATA[6] = 0x00;     message_DATA[7] = 0x00;
  189.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA);
  190.         delay(1000);
  191.        
  192.         Serial.println("Requesting: Passenger Heated Seat");
  193.         message_DATA[2] = 0x03;     message_DATA[4] = 0x00;
  194.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA);
  195.         delay(1000);
  196.  
  197.         Serial.println("Requesting: Heated Steering Wheel");
  198.         message_DATA[2] = 0x00;     message_DATA[4] = 0x80;
  199.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA);
  200.       }
  201.       HeldButtonCounter = 0;   // Reset counter regardless of length
  202.     }
  203.  
  204.     //
  205.     //
  206.     // If POWER is held, turn the screen off
  207.     //
  208.     //
  209.     if(message_ID == 0x2A0 and message_DATA[0] == 0x1F and message_DATA[4] == 0x10 and message_DATA[7] == 0x00)
  210.     {
  211.       Serial.println("Power button HELD");
  212.       HeldButtonCounter++;
  213.     }
  214.  
  215.     if(message_ID == 0x2A0 and message_DATA[0] == 0x1F and message_DATA[4] == 0x00 and message_DATA[7] == 0x00)
  216.     {
  217.       Serial.print("Power button RELEASED. Counter: ");
  218.       Serial.println(HeldButtonCounter);
  219.       if(HeldButtonCounter >= 3)
  220.       {
  221.         Serial.println("Requesting: Turn audio back on");
  222.         message_ID = 0x2A0;
  223.         message_DATA[0] = 0x1F;     message_DATA[1] = 0xFF;     message_DATA[2] = 0xFF;     message_DATA[3] = 0xFF;     message_DATA[4] = 0x10;     message_DATA[5] = 0x00;     message_DATA[6] = 0x1E;     message_DATA[7] = 0x02;
  224.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Power PRESS
  225.         delay(100);
  226.         message_DATA[4] = 0x00;     message_DATA[7] = 0x00;
  227.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Power RELEASE
  228.  
  229.         Serial.println("Requesting: Turn screen off");
  230.         message_DATA[0] = 0x50;     message_DATA[4] = 0x10;     message_DATA[7] = 0x02;
  231.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Screen Off PRESS
  232.         delay(50);
  233.         message_DATA[4] = 0x00;     message_DATA[7] = 0x00;
  234.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Screen Off RELEASE
  235.       }
  236.       HeldButtonCounter = 0;
  237.     }
  238.  
  239.     //
  240.     // Switch to USB if PHONE is pressed on steering wheel
  241.     //
  242.    
  243.     if(message_ID == 0x081 and message_DATA[1] == 0x00 and message_DATA[2] == 0xC1 and message_DATA[3] == 0xFA)
  244.     {
  245.       Serial.println("Phone button RELEASED");
  246.         delay(400);
  247.         Serial.println("Requesting: Return to Home Screen");
  248.         message_ID = 0x2A0;
  249.         message_DATA[0] = 0x5F;     message_DATA[1] = 0xFF;     message_DATA[2] = 0xFF;     message_DATA[3] = 0xFF;     message_DATA[4] = 0x10;     message_DATA[5] = 0x00;     message_DATA[6] = 0x1E;     message_DATA[7] = 0x02;
  250.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Home PRESS
  251.         delay(100);
  252.         message_DATA[4] = 0x00;     message_DATA[7] = 0x00;
  253.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA); // Home RELEASE
  254.  
  255.       Serial.println("Switch to USB");
  256.         message_ID = 0x195;
  257.         message_DATA[0] = 0x00;
  258.         message_DATA[1] = 0x00;
  259.         message_DATA[2] = 0x00;
  260.         message_DATA[3] = 0x01;
  261.         message_DATA[4] = 0x80;
  262.         message_DATA[5] = 0x02;
  263.         message_DATA[6] = 0x00;
  264.         message_DATA[7] = 0x00;
  265.         CAN0.sendMsgBuf(message_ID, 0, message_LENGTH, message_DATA);
  266. }
  267.    
  268.  
  269.  
  270.   }   // END CAN-BUS MONITOR
  271.  
  272.  
  273.  
  274.   // Sense if the shift knob + or - are being pressed
  275.   if(digitalRead(SHIFT_PLUS) == LOW)
  276.   {  
  277.     ShiftPlusButtonHeld = 1;
  278.   }
  279.   if(digitalRead(SHIFT_MINUS) == LOW)
  280.   {
  281.     ShiftMinusButtonHeld = 1;
  282.   }
  283.  
  284.  
  285.  
  286.   // React only when a shift button changes state
  287.   if(digitalRead(SHIFT_PLUS) == HIGH and ShiftPlusButtonHeld == 1)
  288.   {
  289.     Serial.println("Shift Plus has been released.");
  290.     Serial.println("Camera View will be requested on next Gear message if conditions are right.");
  291.     ShiftPlusButtonHeld = 0;
  292.     RequestCameraView = 1;
  293.   }
  294.  
  295.   if(digitalRead(SHIFT_MINUS) == HIGH and ShiftMinusButtonHeld == 1)
  296.   {
  297.     Serial.println("Shift Minus has been released.");
  298.     ShiftMinusButtonHeld = 0;
  299.     ForceRearCamera = !ForceRearCamera;
  300.     Serial.print("Toggling forced camera mode: ");
  301.     if(ForceRearCamera){ Serial.println("True");}
  302.     if(!ForceRearCamera){ Serial.println("False");}
  303.   }
  304.  
  305. }
Add Comment
Please, Sign In to add comment