Modifying Realdash CAN code with bluetooth connectivity and display it to CAN monitor

Hello :waving_hand: guys. How to make this code connect to Realdash via bluetooth? What can I modify or add to the code? I am using ESP32 Devkit V1 and I am new with Arduino coding. Thanks.

/**

  • ============================================================================
  • Name : RealDash_CAN.ino
  • Part of : RealDash
  • Author : Jani Immonen
  • Created : 15.10.2017
  • Arduino example sketch of how to use RealDash CAN protocol.
  • This example code is free for any use.
  • www.realdash.net
  • ============================================================================
    **/

// Arduino digital and analog pins
unsigned int digitalPins = 0;
int analogPins[7] = {0};

unsigned int rpm = 0;
unsigned int kpa = 992; // 99.2
unsigned int tps = 965; // 96.5
unsigned int clt = 80; // 80 - 100
unsigned int textCounter = 0;

void setup()
{
// init serial
Serial.begin(115200);
delay(100);
}

void loop()
{
ReadDigitalStatuses();
ReadAnalogStatuses();
SendCANFramesToSerial();

// just some dummy values for simulated engine parameters
if (rpm++ > 10000)
{
rpm = 500;
}
if (kpa++ > 2500)
{
kpa = 10;
}
if (tps++ > 1000)
{
tps = 0;
}
if (clt++ > 230)
{
// all values in frame are handled as unsigned values. To have negative values,
// offset actual value and write corresponding conversion to xml file imported to RealDash
clt = 0;
}
if (textCounter++ > 4000)
{
textCounter = 0;
}

delay(5);
}

void ReadDigitalStatuses()
{
// read status of digital pins (1-13)
digitalPins = 0;

int bitposition = 0;
for (int i=1; i<14; i++)
{
if (digitalRead(i) == HIGH) digitalPins |= (1 << bitposition);
bitposition++;
}
}

void ReadAnalogStatuses()
{
// read analog pins (0-7)
for (int i=0; i<7; i++)
{
analogPins[i] = analogRead(i);
}
}

void SendCANFramesToSerial()
{
byte buf[8];

// build & send CAN frames to RealDash.
// a CAN frame payload is always 8 bytes containing data in a manner
// described by the RealDash custom channel description XML file
// all multibyte values are handled as little endian by default.
// endianess of the values can be specified in XML file if it is required to use big endian values

// build 1st CAN frame, RPM, MAP, CLT, TPS (just example data)
memcpy(buf, &rpm, 2);
memcpy(buf + 2, &kpa, 2);
memcpy(buf + 4, &clt, 2);
memcpy(buf + 6, &tps, 2);

// write first CAN frame to serial
SendCANFrameToSerial(3200, buf);

// build 2nd CAN frame, Arduino digital pins and 2 analog values
memcpy(buf, &digitalPins, 2);
memcpy(buf + 2, &analogPins[0], 2);
memcpy(buf + 4, &analogPins[1], 2);
memcpy(buf + 6, &analogPins[2], 2);

// write 2nd CAN frame to serial
SendCANFrameToSerial(3201, buf);

// build 3rd CAN frame, rest of Arduino analog values
memcpy(buf, &analogPins[3], 2);
memcpy(buf + 2, &analogPins[4], 2);
memcpy(buf + 4, &analogPins[5], 2);
memcpy(buf + 6, &analogPins[6], 2);

// write 3rd CAN frame to serial
SendCANFrameToSerial(3202, buf);

// build 4th frame, this is a text extension frame
// only send once at 1000 loops
if (textCounter == 0)
{
SendTextExtensionFrameToSerial(3203, “Hello RealDash, this is Arduino sending some text data”);
}
else if (textCounter == 1000)
{
SendTextExtensionFrameToSerial(3203, “Tomorrow’s forecast: Lots of sun and 30 degrees centigate”);
}
else if (textCounter == 2000)
{
SendTextExtensionFrameToSerial(3203, “Now Playing: Insert your favorite song info here”);
}
else if (textCounter == 3000)
{
SendTextExtensionFrameToSerial(3203, “Message from Arduino: All systems running at nominal efficiency”);
}
}

void SendCANFrameToSerial(unsigned long canFrameId, const byte* frameData)
{
// the 4 byte identifier at the beginning of each CAN frame
// this is required for RealDash to ‘catch-up’ on ongoing stream of CAN frames
const byte serialBlockTag[4] = { 0x44, 0x33, 0x22, 0x11 };
Serial.write(serialBlockTag, 4);

// the CAN frame id number (as 32bit little endian value)
Serial.write((const byte*)&canFrameId, 4);

// CAN frame payload
Serial.write(frameData, 8);
}

void SendTextExtensionFrameToSerial(unsigned long canFrameId, const char* text)
{
if (text)
{
// the 4 byte identifier at the beginning of each CAN frame
// this is required for RealDash to ‘catch-up’ on ongoing stream of CAN frames
const byte textExtensionBlockTag[4] = { 0x55, 0x33, 0x22, 0x11 };
Serial.write(textExtensionBlockTag, 4);

// the CAN frame id number (as 32bit little endian value)
Serial.write((const byte*)&canFrameId, 4);

// text payload
Serial.write(text, strlen(text) + 1);

}
}

You need to include bluetooth library and replace serial.write with bluetooth equivalent

/**

  • ============================================================================
  • Name : RealDash_CAN.ino
  • Part of : RealDash
  • Author : Jani Immonen
  • Created : 15.10.2017
  • Revised by : Martin Main
  • Modified : 17.04.2025
  • Changes : Bluetooth support, activity LED (GPIO 2)
  • Arduino example sketch of how to use RealDash CAN protocol.
  • This example code is free for any use.
  • www.realdash.net
  • ============================================================================
    **/

// Libraries
#include “BluetoothSerial.h”

// Bluetooth definitions
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run make menuconfig to and enable it
#endif

BluetoothSerial SerialBT;

// ESP32 digital and analog pins
// digital pin statuses are stored as bits in one variable
unsigned int digitalPins = 0;
unsigned int analogPins= 0;
unsigned int empty = 0;

int LED_BUILTIN = 2;
int loop_timer = 0;

void setup() {
Serial.begin(115200);
delay(100);
SerialBT.begin(“Arduino”); //Bluetooth device name
Serial.println(“Your Arduino device just started, now you can pair it with bluetooth!”);
}

void main_loop() {
ReadGPIO(); //Read digital and analogue inputs

BuildandSendCANFrames();
BluetoothConnected(); //Flash LED for connected BT
delay(5);
}

void ReadGPIO() {
// read status of 5 digital pins (GPIO 24 - 28)
digitalPins = 0;

int bitposition = 0;
// Loop to capture 5 bits
for (int i = 24; i < 29; i++) {
if (digitalRead(i) == HIGH) digitalPins |= (1 << bitposition);
bitposition++;
}
// Single analogue input spare
#analogPin = analogRead(32);
}

void BuildandSendCANFrames() {
byte buf[8];

// build & send CAN frames to RealDash.
// a CAN frame payload is always 8 bytes containing data in a manner
// described by the RealDash custom channel description XML file
// all multibyte values are handled as little endian by default.
// endianess of the values can be specified in XML file if it is required to use big endian values

// build 1st CAN frame, ESP32 digital pins and analog values
//MyDebug();
memcpy(buf + 0, &digitalPins, 2);
memcpy(buf + 2, &analogPins, 2);
memcpy(buf + 4, &empty, 2);
memcpy(buf + 6, &empty, 2);

// write first CAN frame
SendCANFrameToSerial(1900, buf);

}

void SendCANFrameToSerial(unsigned long canFrameId, const byte* frameData) {
// the 4 byte identifier at the beginning of each CAN frame
// this is required for RealDash to ‘catch-up’ on ongoing stream of CAN frames
const byte serialBlockTag[4] = { 0x44, 0x33, 0x22, 0x11 };
SerialBT.write(serialBlockTag, 4);

// the CAN frame id number (as 32bit little endian value)
SerialBT.write((const byte*)&canFrameId, 4);

// CAN frame payload
SerialBT.write(frameData, 8);
}

void BluetoothConnected() {
if (SerialBT.connected()) {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
} else {
digitalWrite(LED_BUILTIN, LOW);
}
}

1 Like

Looks like this can be used on ESP32, have you got this work?

@SamiSmiley yes was working fine for two years, very reliable, although don’t have a car needing these signals now

Many thanks mate. I am now starting to code on Arduino and ESP32. May I ask what module should I use with my ESP32 DevKit V1? SN65DHV230 or MCP2515?