Very No0b and very confused - esp32 emulating CAN

Hi there, I’ve tried reading documentation and I don’t seem to be able to find a no0b primer on this software.
The goal is putting this in my 68 cutlass to read sensors and send them to RealDash via Holley Sniper 2 CAN. Reason is, and maybe this is dumb, I plan on putting a Sniper2 on the car in the future and would like to merge the data?!?! Anyhow, that’s my thought process. I’ve tried this in other CAN formats too like generic GM and I still seem to be missing something huge, because I can get CAN data into the CAN Monitor but I have never been able to get any of the gauges to act upon said data.

I am using a Raspberry PI with the carhat/Linux for RealDash, version 2.5.0
esp32 dev board with MCP2515 module.
SocketCAN / can0 with the “HOLLEY: SNIPER V2” CAN Description file.

I’ve used chat GPT to check/refine the code, pulling from existing examples. I would have thought that if I got data into the CAN Monitor I’d be half way there. I keep seeing references to edit the .XML file but any time I do, the file reverts back to its original state. I’ve even tried editing before RealDash had a change to load and it still reverts?

I’m a linux no0b too so, I got that going against me as well.. getting the description file from the file selector window was a treat since no matter what resolution the left side of the screen is off to the left with no way to resize the selector screen, btw – but whatever, got the holley stuff imported it seems.



image

#include <SPI.h>
#include <mcp_can.h>
#include <Wire.h>
#include <TinyGPSPlus.h>
#include <HardwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Pin configuration
#define ONE_WIRE_PIN 36
#define INT_PIN 4
#define VSPI_CS_PIN 5
#define VSPI_SCLK_PIN 18
#define VSPI_MISO_PIN 19
#define VSPI_MOSI_PIN 23
#define TACH_PIN 26
#define BATT_VOLTS_PIN 27
#define OIL_PRESS_PIN 32
#define FUEL_LEVEL_PIN 34
#define COOLANT_TEMP_PIN 35
#define GPS_RX_PIN 17
#define GPS_TX_PIN 16

// Generic ECU serial number
const uint16_t ECU_SERIAL = 0x0123;

MCP_CAN CAN(VSPI_CS_PIN);
HardwareSerial GPS_Serial(1);
TinyGPSPlus gps;
OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature sensors(&oneWire);

unsigned long lastSend = 0;
const unsigned long sendInterval = 100; // 100ms between sends

void setup() {
Serial.begin(115200);
GPS_Serial.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
sensors.begin();

pinMode(TACH_PIN, INPUT_PULLUP); // (optional if not using real tach)

while (CAN_OK != CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ)) {
Serial.println(“CAN BUS init Failed”);
delay(100);
}
Serial.println(“CAN BUS Shield init OK!”);
CAN.setMode(MCP_NORMAL);
}

void loop() {
while (GPS_Serial.available()) {
gps.encode(GPS_Serial.read());
}

if (millis() - lastSend > sendInterval) {
lastSend = millis();

float GPSSPEED = gps.speed.kmph();
int currentRPM = simulateRPM();
float battVoltage = simulateBattVoltage();
float oilPressure = simulateOilPressure();
float coolantTemp = simulateCoolantTemp();
float fuelLevel = simulateFuelLevel();
sensors.requestTemperatures();
float DTemp = sensors.getTempCByIndex(0);

// Output to Serial for debugging
Serial.println("=== Sending CAN Data ===");
Serial.print("GPS Speed      : "); Serial.println(GPSSPEED);
Serial.print("RPM            : "); Serial.println(currentRPM);
Serial.print("Battery Voltage: "); Serial.println(battVoltage);
Serial.print("Oil Pressure   : "); Serial.println(oilPressure);
Serial.print("Coolant Temp   : "); Serial.println(coolantTemp);
Serial.print("Fuel Level     : "); Serial.println(fuelLevel);
Serial.print("Dallas Temp    : "); Serial.println(DTemp);

// Send sensor data over CAN
sendHolleyCAN(0x1E001023, currentRPM, 60.0);      // Engine RPM
sendHolleyCAN(0x1E001028, GPSSPEED, 1.0);         // Vehicle Speed
sendHolleyCAN(0x1E00102A, oilPressure, 1.0);      // Oil Pressure
sendHolleyCAN(0x1E00102C, coolantTemp, 1.0);      // Coolant Temperature
sendHolleyCAN(0x1E00102E, battVoltage, 0.1);      // Battery Voltage (scale to 0.1V)
sendHolleyCAN(0x1E001034, fuelLevel, 1.0);        // Fuel Level
sendHolleyCAN(0x1E00103A, DTemp, 1.0);            // Dallas sensor as another temp

// Send Heartbeat (fixed ID!)
byte heartbeat[8] = {0};
CAN.sendMsgBuf(0x1E000000, 0, 8, heartbeat);      // No ECU_SERIAL offset

}
}

// Holley-style CAN frame sender with serial number offset
void sendHolleyCAN(uint32_t baseId, float value, float scale) {
byte data[8] = {0xFF}; // Fill with 0xFF (optional, improves realism)
uint16_t scaled = (uint16_t)(value / scale);
data[0] = scaled & 0xFF; // little endian
data[1] = (scaled >> 8) & 0xFF;
uint32_t actualId = baseId + (ECU_SERIAL & 0x7FF);
CAN.sendMsgBuf(actualId, 0, 8, data);

// Debug output
Serial.print(“Sending ID: 0x”);
Serial.print(actualId, HEX);
Serial.print(" Data: “);
for (int i = 0; i < 8; i++) {
Serial.print(data[i], HEX);
Serial.print(” ");
}
Serial.println();
}

// Simulated sensor reading functions for testing
float simulateBattVoltage() {
return 13.5 + random(-5, 6) * 0.1; // Simulate 13.0-14.0V
}

float simulateOilPressure() {
return 110 + random(-10, 11); // Simulate around 100-120 psi
}

float simulateCoolantTemp() {
return 90 + random(-5, 6); // Simulate around 85-95 C
}

float simulateFuelLevel() {
return 70 + random(-5, 6); // Simulate around 65-75%
}

int simulateRPM() {
return 3400 + random(-200, 201); // Simulate around 3200-3600 RPM
}

Very complicated setup to try to help remotely.

But in general, if you see the data in CAN monitor, the missing piece must be the CAN XML file. Try to make a XML file that only handles one frame to verify that its working. Then gradually add frames as you get more comfortable on working on the XML file.

1 Like

Do you mean the ones here?

Because the custom car I’m using, every time I alter the file, it reverts back to its basic settings. if there is a CAN XML doc somewhere else, to my chagrin, I dont know where it is

CAN XML documentation:

RealDash-extras/RealDash-CAN/realdash-can-description-file.md at master · janimm/RealDash-extras

If you are working with local files, yes when you edit the XML file it needs to be re-imported into connection settings. Current Android devices do not allow direct access to user filesystem, and files must be imported to apps own ‘sandbox’ before they can be used.

Currently most efficient way is to use My RealDash service (my.realdash.net), which has XML editor and RealDash can then import the XML file from My RealDash on connection settings.