-
-
Save kenny-macchina/f87e4c39e29a39562e168b9869d64ef8 to your computer and use it in GitHub Desktop.
#include <esp32_can.h> | |
uint8_t codes[4] = {5, 0xB, 0xC, 0xD}; | |
int idx = 0; | |
uint32_t tick = 0; | |
const int led_pin = 13; | |
char msg_buf[10]; | |
int led_state = 0; | |
int ledState = LOW; // ledState used to set the LED | |
unsigned long previousMillis = 0; // will store last time LED was updated | |
const long interval = 1000; // interval at which to blink (milliseconds) | |
void setup() | |
{ | |
pinMode(led_pin, OUTPUT); | |
digitalWrite(led_pin, LOW); | |
// Start Serial port | |
Serial.begin(115200); | |
CAN0.setCANPins(GPIO_NUM_4, GPIO_NUM_5); | |
CAN0.begin(500000); | |
Serial.println("Ready ...!"); | |
int filter; | |
//extended | |
for (filter = 0; filter < 3; filter++) | |
{ | |
Can0.setRXFilter(filter, 0, 0, false); | |
} | |
} | |
void loop() | |
{ | |
CAN_FRAME incoming; | |
if (Can0.available() > 0) | |
{ | |
Can0.read(incoming); | |
if (incoming.id > 0x7DF && incoming.id < 0x7F0) | |
{ | |
processPID(incoming); | |
} | |
} | |
static unsigned long l = 0; | |
unsigned long t = millis(); | |
if ((t - l) > 50) | |
{ | |
sendPIDRequest(0x7DF, 0xC); | |
sendPIDRequest(0x7DF, 0xD); | |
sendPIDRequest(0x7DF, 5); | |
l = t; | |
} | |
} | |
void sendPIDRequest(uint32_t id, uint8_t PID) | |
{ | |
CAN_FRAME frame; | |
frame.id = id; | |
frame.extended = 0; | |
frame.length = 8; | |
for (int i = 0; i < 8; i++) | |
frame.data.bytes[i] = 0xAA; | |
frame.data.bytes[0] = 2; //2 more bytes to follow | |
frame.data.bytes[1] = 1; | |
frame.data.bytes[2] = PID; | |
Can0.sendFrame(frame); | |
} | |
int lastTemp=-1; | |
float lastpsi=-1; | |
int lastRPM=-1; | |
int lastMPH=-1; | |
void processPID(CAN_FRAME &frame) | |
{ | |
int temperature; | |
float psi; | |
int RPM; | |
int MPH; | |
if (frame.data.bytes[1] != 0x41) | |
return; //not anything we're interested in then | |
switch (frame.data.bytes[2]) | |
{ | |
case 5: | |
temperature = frame.data.bytes[3] - 40; | |
if (temperature!=lastTemp) | |
{ | |
Serial.print("Coolant temperature (C): "); | |
Serial.println(temperature); | |
lastTemp=temperature; | |
} | |
break; | |
case 0xB: | |
psi = frame.data.bytes[3] * 0.145038; //kPA to PSI | |
psi = psi - 14.8; | |
//psi = psi * 100; | |
if (psi!=lastpsi) | |
{ | |
Serial.print("Manifold abs pressure (psi): "); | |
Serial.println(psi); | |
lastpsi=psi; | |
} | |
break; | |
case 0xC: | |
RPM = ((frame.data.bytes[3] * 256) + frame.data.bytes[4]) / 4; | |
if (RPM!=lastRPM) | |
{ | |
Serial.print("Engine RPM: "); | |
Serial.println(RPM); | |
sprintf(msg_buf, "%d", RPM); | |
lastRPM=RPM; | |
} | |
break; | |
case 0xD: | |
MPH = frame.data.bytes[3] * 0.621371; | |
if (MPH!=lastMPH) | |
{ | |
Serial.print("Vehicle Speed (MPH): "); | |
Serial.println(MPH); | |
lastMPH=MPH; | |
} | |
break; | |
} | |
} |
// another A0 example that works
#include "esp32_can.h" // https://github.com/collin80/esp32_can AND https://github.com/collin80/can_common
#include "BluetoothSerial.h"
#define UPDATES_PER_SECOND 100
#define CANPID_RPM 0x0C
#define CAN_REQST_ID 0x7DF
#define CAN_REPLY_ID 0x7E8
uint16_t rpm;
BluetoothSerial SerialBT;
#include <FastLED.h>
#define A0_LED_PIN 2
#define A0_NUM_LEDS 1
#define BRIGHTNESS 64
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[A0_NUM_LEDS];
void setup() {
delay(1000);
pinMode(13, OUTPUT); // RGB power transistor ,note: to turn off when sleep mode figured out
digitalWrite(13, LOW);
delay(100);
FastLED.addLeds<LED_TYPE, A0_LED_PIN, COLOR_ORDER>(leds, A0_NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
leds[0] = CRGB::Red;
FastLED.show();
pinMode(21, OUTPUT); // to HSC_S: CAN transiever silence pin (pull low to communicate)
digitalWrite(21, LOW);
CAN0.setCANPins(GPIO_NUM_4, GPIO_NUM_5);
CAN0.begin(500000);
SerialBT.begin("A0_CAN");
pinMode(26, OUTPUT); // THE CAN LIBRARY HAS THIS PIN FOR INTERRUPT FOR CAN1 (UNSUSED HERE) INPUT WITHOUT PULLUP, FORCE TO OUTPUT INSTEAD TO PREVENT ERRONEOUS INTERRUPTS.
digitalWrite(26, HIGH);
CAN0.watchFor(CAN_REPLY_ID);
CAN0.setCallback(0, callback);
}
void loop() {
requestCar();
if (rpm > 2000) {
leds[0] = CRGB::Green;
FastLED.show();
} else {
leds[0] = CRGB::Blue;
FastLED.show();
}
SerialBT.println(rpm);
delay(1000);
}
void requestCar(void) {
CAN_FRAME outgoing;
outgoing.id = CAN_REQST_ID;
outgoing.length = 8;
outgoing.extended = 0;
outgoing.rtr = 0;
outgoing.data.uint8[0] = 0x02;
outgoing.data.uint8[1] = 0x01;
outgoing.data.uint8[2] = CANPID_RPM;
outgoing.data.uint8[3] = 0x00;
outgoing.data.uint8[4] = 0x00;
outgoing.data.uint8[5] = 0x00;
outgoing.data.uint8[6] = 0x00;
outgoing.data.uint8[7] = 0x00;
CAN0.sendFrame(outgoing);
leds[0] = CRGB::Red;
FastLED.show();
delay(50);
leds[0] = CRGB::Black;
FastLED.show();;
}
void callback(CAN_FRAME *from_car) {
leds[0] = CRGB::Red;
FastLED.show();
delay(20);
leds[0] = CRGB::Black;
FastLED.show();;
if (from_car->data.uint8[2] == CANPID_RPM) {
uint8_t rpmOBDH = from_car->data.uint8[3];
uint8_t rpmOBDL = from_car->data.uint8[4];
rpm = (uint16_t)((256 * rpmOBDH) + rpmOBDL) / (float)4;
}
}
the two above sketches pretty much cover almost everything between the two of them.
//A0 example that works
#include <esp32_can.h>
#include <FastLED.h>
#define A0_LED_PIN 2 //pin that controls led
#define A0_NUM_LEDS 1 //just a single RGB but the code is for led strips
#define BRIGHTNESS 64 //arbitrary
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[A0_NUM_LEDS]; //just a single RGB but the code is for led strips
#define UPDATES_PER_SECOND 100
uint8_t codes[4] = { 0x05, 0x0B, 0x0C, 0x0D };
int idx = 0;
uint32_t tick = 0;
char msg_buf[10];
void setup() {
delay(1000); //power bounce delay for OBD plug power
// Start Serial port
Serial.begin(115200);
pinMode(13, OUTPUT); // RGB power transistor ,note: turn off when sleep mode figured out
digitalWrite(13, LOW);
delay(100); //power bounce delay
FastLED.addLeds<LED_TYPE, A0_LED_PIN, COLOR_ORDER>(leds, A0_NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
leds[0] = CRGB::Red; //booting color
FastLED.show();
pinMode(21, OUTPUT); // to HSC_S: CAN transiever silence pin (pull low to communicate, pin high or floating will silence transceiver)
digitalWrite(21, LOW);
CAN0.setCANPins(GPIO_NUM_4, GPIO_NUM_5); //pulled from SavvyCAN code, it works
CAN0.begin(500000); //pulled from SavvyCAN code, works
Serial.println("Ready ...!");
int filter;
//extended
for (filter = 0; filter < 3; filter++) {
Can0.setRXFilter(filter, 0, 0, false);
}
}
void loop() {
leds[0] = CRGB::Black;
FastLED.show();
CAN_FRAME incoming;
if (Can0.available() > 0) {
Can0.read(incoming);
if (incoming.id > 0x7DF && incoming.id < 0x7F0) {
processPID(incoming);
leds[0] = CRGB::Blue; //flickers blue every time a response is processed
FastLED.show();
//Serial.println("Recieved");
}
}
static unsigned long l = 0;
unsigned long t = millis();
if ((t - l) > 1000) {
sendPIDRequest(0x7DF, 0x05);
sendPIDRequest(0x7DF, 0x0B);
sendPIDRequest(0x7DF, 0x0C);
sendPIDRequest(0x7DF, 0x0D);
l = t;
}
}
void sendPIDRequest(uint32_t id, uint8_t PID) {
CAN_FRAME frame;
frame.id = id;
frame.extended = 0;
frame.length = 8; //library automatically populates remaining bytes with 0x00 in not defined, may be helpful to define all 8 in code
for (int i = 0; i < 8; i++)
frame.data.bytes[i] = 0xAA;
frame.data.bytes[0] = 2; //2 more bytes to follow
frame.data.bytes[1] = 1;
frame.data.bytes[2] = PID;
Can0.sendFrame(frame);
//leds[0] = CRGB::Green;
//FastLED.show();
//Serial.println("Request");
}
int lastTemp = -1;
float lastpsi = -1;
int lastRPM = -1;
int lastMPH = -1;
void processPID(CAN_FRAME &frame) {
int temperature;
float psi;
int RPM;
int MPH;
if (frame.data.bytes[1] != 0x41)
return; //not anything we're interested in then
switch (frame.data.bytes[2]) {
case 0x05:
temperature = frame.data.bytes[3] - 40;
if (temperature != lastTemp) {
Serial.print("Coolant temperature (C): ");
Serial.println(temperature);
lastTemp = temperature;
}
break;
}
}