Advertisement
Guest User

Untitled

a guest
Mar 19th, 2025
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.28 KB | None | 0 0
  1. #include <MultiMap.h>
  2. #include "Wire.h"
  3. #include "Adafruit_GFX.h"
  4. #include <Adafruit_SSD1305.h>
  5. #include <MonomaniacOne_Regular36pt7b.h>
  6. #include <Adafruit_NeoPixel.h>
  7. #include "driver/twai.h"
  8.  
  9. #define TWAI_TIMING_CONFIG_33k3KBITS()   {.brp = 120, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}  //SW-SL-CAN obd 1 - 5
  10.  
  11.  
  12. #define LED_PIN       10
  13. Adafruit_NeoPixel pixels(1, LED_PIN, NEO_GRB + NEO_KHZ800);
  14.  
  15. Adafruit_SSD1305 display(128, 64, &Wire, -1);
  16.  
  17.  
  18. #define GREEN_LED     11
  19. #define RX_PIN        13
  20. #define TX_PIN        14
  21. #define CAN_RS        38
  22.  
  23.  
  24. #define FORCE_ON      47
  25. #define SENSE_V_DIG   12
  26. #define SENSE_V_ANA   9
  27.  
  28. #define SECONDS_TO_STAY_ON   15
  29.  
  30. #define CANPID_RPM                  0x0C          //OBD2
  31. #define CANPID_SPEED                0x0D          //OBD2
  32. #define CANPID_TEMP                 0x05          //OBD2
  33. #define CAN_REQST_ID                0x7DF         //OBD2
  34. #define CAN_REPLY_ID                0x7E8         //OBD2
  35.  
  36. #define ID_RPM_SPEED_OPEL_CORSA     0x108         //OPEL CORSA
  37. #define ID_COOLANT_OPEL_CORSA       0x145         //OPEL CORSA
  38. //#define ID_..._OPEL_CORSA         0x7DF         //OPEL CORSA
  39. //#define ID_..._OPEL_CORSA         0x7E8         //OPEL CORSA
  40.  
  41.  
  42. int speed_string_length; // length of the speed_string
  43. int speed_string_start_pos; // start x position for the big numbers - calculated based on the number of digits
  44. char speed_string[10];
  45. int temp_string_length; // length of the speed_string
  46. int temp_string_start_pos; // start x position for the big numbers - calculated based on the number of digits
  47. char temp_string[10];
  48. int RPM_string_length; // length of the speed_string
  49. int RPM_string_start_pos; // start x position for the big numbers - calculated based on the number of digits
  50. char RPM_string[10];
  51. int cruise_string_length; // length of the speed_string
  52. int cruise_string_start_pos; // start x position for the big numbers - calculated based on the number of digits
  53. char cruise_string[10];
  54.  
  55.  
  56.   //  out[] holds the voltages
  57. float out[] = {51, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160};
  58.  
  59.   //  in[] holds the measured analogRead() values for that voltage
  60. float in[]  = {1080, 1323, 1575, 1820, 2075, 2318, 2565, 2809, 3065, 3340, 3665, 4050};
  61.  
  62.  
  63.  
  64. int speed = 0;
  65. int temp = 0;
  66. int RPM = 0;
  67. int cruise = 0;
  68. int voltage = 0;
  69.  
  70.  
  71. void setup() {
  72.   Serial.begin(115200);     // INITIALIZE Serial      
  73.   pixels.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  74.   pixels.show();            // Turn OFF all pixels ASAP
  75.   pixels.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
  76.  
  77.   Serial.setTxTimeoutMs(0);   // prevent serial print delays if no usb
  78.  
  79.   pinMode(SENSE_V_DIG, INPUT_PULLUP);
  80.   pinMode(FORCE_ON, OUTPUT);
  81.   pinMode(GREEN_LED, OUTPUT);
  82.   pinMode(CAN_RS, OUTPUT);    // INPUT (high impedance) = slope control mode, OUTPUT = see next line
  83.   digitalWrite(CAN_RS, LOW);  // LOW = high speed mode, HIGH = low power mode (listen only)
  84.   Serial.println("RS LOW");
  85.   twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_NORMAL);  // TWAI_MODE_NORMAL, TWAI_MODE_NO_ACK or TWAI_MODE_LISTEN_ONLY
  86.   twai_timing_config_t t_config  = TWAI_TIMING_CONFIG_33k3KBITS();
  87.   twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
  88.  
  89.  
  90.     // Install TWAI driver
  91.   if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
  92.     Serial.println("Driver installed");
  93.   } else {
  94.     Serial.println("Failed to install driver");
  95.     return;
  96.   }
  97.  
  98.   // Start TWAI driver
  99.   if (twai_start() == ESP_OK) {
  100.     Serial.println("Driver started");
  101.   } else {
  102.     Serial.println("Failed to start driver");
  103.     return;
  104.   }
  105.  
  106.   digitalWrite(FORCE_ON, HIGH);
  107.  
  108.   delay(2000);
  109.   Wire.setPins(1,2);        // INITIALIZE I2C
  110.   delay(1000);
  111.   Serial.println("SSD1305 OLED test");
  112.  
  113.   if ( ! display.begin(0x3C) ) {
  114.      Serial.println("Unable to initialize OLED");
  115.      while (1) yield();
  116.   }
  117.   display.setTextColor(WHITE);
  118.   update(0, 0, 0, 0); // Initial speed
  119.  
  120. }
  121.  
  122.  
  123. void loop() {
  124.  
  125.     shutdowncounter();
  126.     digitalWrite(GREEN_LED, analogRead(SENSE_V_ANA)>3200);
  127.    
  128.     //log_CAN_messages();
  129.     can_receiveOPEL();
  130.     //can_sendrequestOBD2(CANPID_RPM);
  131.     //can_receiveOBD2();
  132.     //can_sendrequestOBD2(CANPID_SPEED);
  133.     //can_receiveOBD2();
  134.     //can_sendrequestOBD2(CANPID_TEMP);
  135.     //can_receiveOBD2();
  136.  
  137.     cruise = multiMap<float>(analogRead(SENSE_V_ANA), in, out, 12);
  138.  
  139.     update(speed, temp, RPM, cruise);
  140.  
  141.     delay(10);
  142.  
  143. }
  144.  
  145. void update(int speed, int temp, int RPM, int cruise) {
  146.   display.setRotation(0);
  147.   display.clearDisplay();
  148.  
  149.   display.setFont(&MonomaniacOne_Regular36pt7b);
  150.   display.setTextSize(1);
  151.   itoa (speed, speed_string, 10); // convert speed integer to c-style string speed_string, decimal format
  152.   speed_string_length = strlen(speed_string); // get speed_string length
  153.   speed_string_start_pos = 20 - speed_string_length * 19; // start x position of the big numbers
  154.   display.setCursor(speed_string_start_pos + 44, 48);                       // Adjust position
  155.   display.print(speed);
  156.  
  157.   display.setFont();
  158.   display.setTextSize(1);
  159.   itoa (temp, temp_string, 10); // convert speed integer to c-style string speed_string, decimal format
  160.   temp_string_length = strlen(temp_string); // get speed_string length
  161.   temp_string_start_pos = 6 - temp_string_length * 3; // start x position of the big numbers
  162.   display.setCursor(temp_string_start_pos + 5, 55);  
  163.   display.print(temp);
  164.  
  165.   display.setFont();
  166.   display.setTextSize(1);
  167.   itoa (RPM, RPM_string, 10); // convert speed integer to c-style string speed_string, decimal format
  168.   RPM_string_length = strlen(RPM_string); // get speed_string length
  169.   RPM_string_start_pos = 6 - RPM_string_length * 3; // start x position of the big numbers
  170.   display.setCursor(RPM_string_start_pos + 60, 55);  
  171.   display.print(RPM);
  172.  
  173.   display.setFont();
  174.   display.setTextSize(1);
  175.   itoa (cruise, cruise_string, 10); // convert speed integer to c-style string speed_string, decimal format
  176.   cruise_string_length = strlen(cruise_string); // get speed_string length
  177.   cruise_string_start_pos = 6 - cruise_string_length * 3; // start x position of the big numbers
  178.   display.setCursor(cruise_string_start_pos + 110, 55);  
  179.   display.print(cruise);
  180.  
  181.  
  182.  
  183.   display.display();
  184. }
  185.  
  186. void shutdowncounter(void) {
  187.   static unsigned long timestamp;
  188.   static bool countdown = false;
  189.   unsigned long now = millis();
  190.  
  191.   if( analogRead(SENSE_V_ANA)<3200 ) {
  192.     if ( countdown == false ) {
  193.       countdown = true;
  194.       timestamp = now;              
  195.       pixels.setPixelColor(0, pixels.Color(150, 0, 0));
  196.       pixels.show();
  197.      }
  198.   }
  199.   else {
  200.     countdown = false;
  201.     pixels.setPixelColor(0, pixels.Color(0, 0, 150));
  202.     pixels.show();  
  203.   }
  204.   if ( countdown  &&  now - timestamp >= SECONDS_TO_STAY_ON * 1000 ) {
  205.     digitalWrite(FORCE_ON, LOW);
  206.     pixels.setPixelColor(0, pixels.Color(150, 0, 150));
  207.     pixels.show();
  208.   }
  209. }
  210.  
  211. void log_CAN_messages() {  //savvycan format
  212.   twai_message_t message;
  213.   if (twai_receive(&message, pdMS_TO_TICKS(1)) == ESP_OK) {
  214.     Serial.print("("); Serial.print(millis()/1000); Serial.print(") ");
  215.     Serial.print("vcan0 ");
  216.     Serial.print(message.identifier, HEX);
  217.     Serial.print("#");
  218.     for (int i = 0; i < message.data_length_code; i++) {
  219.       Serial.printf("%02X", message.data[i]);
  220.     }
  221.     Serial.println();
  222.   }
  223. }
  224.  
  225.  
  226. void can_sendrequestOBD2(uint8_t obd2) {
  227.   twai_message_t message;
  228.   message.identifier = CAN_REQST_ID;
  229.   message.extd = 0;
  230.   message.rtr = 0;
  231.   message.data_length_code = 8;
  232.   message.data[0] = 2;
  233.   message.data[1] = 1;
  234.   message.data[2] = obd2;
  235.   message.data[3] = 0xAA;
  236.   message.data[4] = 0xAA;
  237.   message.data[5] = 0xAA;
  238.   message.data[6] = 0xAA;
  239.   message.data[7] = 0xAA;
  240.   twai_transmit(&message, pdMS_TO_TICKS(1));
  241. }
  242.  
  243.  
  244. void can_receiveOBD2(void) {
  245.   twai_message_t message;
  246.   if (twai_receive(&message, pdMS_TO_TICKS(1)) == ESP_OK) {  // Wait up to 10ms for a message
  247.     if (message.identifier == CAN_REPLY_ID) { // Make sure it's the right reply
  248.       if (message.data[2] == CANPID_RPM) {
  249.         uint8_t rpmOBDH = message.data[3];
  250.         uint8_t rpmOBDL = message.data[4];
  251.         RPM = (uint16_t) ((256 * rpmOBDH) + rpmOBDL) / 4;
  252.       } else if (message.data[2] == CANPID_SPEED) {
  253.         speed = (uint16_t) message.data[3];  // Speed is a single byte
  254.       } else if (message.data[2] == CANPID_TEMP) {
  255.         temp = (uint16_t) message.data[3] - 40;  // Adjust for OBD-II temperature offset
  256.       }
  257.     }
  258.   }
  259. }
  260.  
  261. void can_receiveOPEL(void) {
  262.   twai_message_t message;
  263.   if (twai_receive(&message, pdMS_TO_TICKS(25)) == ESP_OK) {  // Wait up to 10ms for a message
  264.     if (message.identifier == ID_RPM_SPEED_OPEL_CORSA) { // check id RPM/SPEED
  265.       uint8_t firstRPM = message.data[1];
  266.       uint8_t secndRPM = message.data[2];
  267.       RPM = (uint16_t) ((256*firstRPM) + secndRPM) / 4;
  268.       uint8_t firstSPEED = message.data[4];
  269.       uint8_t secndSPEED = message.data[5];
  270.       speed = (uint16_t) ((256*firstSPEED) + secndSPEED) * 0.0082;
  271.  
  272.     } else if (message.identifier == ID_COOLANT_OPEL_CORSA) { // check id COOLANT temperature
  273.       temp = (uint8_t) message.data[3] - 40;  // -40 is adjustment --> -40degrees to 215
  274.     }
  275.   }
  276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement