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

**URL:** <https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557>\
**Category:** Custom Hardware / Electronics\
**Created:** [July 3, 2025, 6:17am UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557 "2025-07-03T06:17:20Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joshua1988](https://forum.realdash.net/letter_avatar_proxy/v4/letter/j/90ced4/32.png) [@Joshua1988](https://forum.realdash.net/u/Joshua1988)\
**Post date:** [July 3, 2025, 6:17am UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/1 "2025-07-03T06:17:20Z")

</div>

Hello 👋 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](http://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);

```

}  
}

---

<div class="post-metadata">

**Author:** ![mmain](https://forum.realdash.net/user_avatar/forum.realdash.net/mmain/32/651_2.png) [@mmain](https://forum.realdash.net/u/mmain)\
**Post date:** [July 6, 2025, 8:50am UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/2 "2025-07-06T08:50:49Z")

</div>

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](http://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);  
}  
}

---

<div class="post-metadata">

**Author:** ![SamiSmiley](https://forum.realdash.net/user_avatar/forum.realdash.net/samismiley/32/2413_2.png) [@SamiSmiley](https://forum.realdash.net/u/SamiSmiley)\
**Post date:** [July 11, 2025, 12:12pm UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/3 "2025-07-11T12:12:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![mmain](https://forum.realdash.net/user_avatar/forum.realdash.net/mmain/32/651_2.png) [@mmain](https://forum.realdash.net/u/mmain)\
**Post date:** [July 11, 2025, 3:01pm UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/4 "2025-07-11T15:01:50Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joshua1988](https://forum.realdash.net/letter_avatar_proxy/v4/letter/j/90ced4/32.png) [@Joshua1988](https://forum.realdash.net/u/Joshua1988)\
**Post date:** [July 15, 2025, 1:21am UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/5 "2025-07-15T01:21:04Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![mmain](https://forum.realdash.net/user_avatar/forum.realdash.net/mmain/32/651_2.png) [@mmain](https://forum.realdash.net/u/mmain)\
**Post date:** [July 15, 2025, 7:31am UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/6 "2025-07-15T07:31:14Z")

</div>

@Joshua1988, I have never programmed an ESP32 to read the canbus, only to pickup discrete signals which are not presented on the canbus and then to present them via RealDash canbus protocol

---

<div class="post-metadata">

**Author:** ![Joshua1988](https://forum.realdash.net/letter_avatar_proxy/v4/letter/j/90ced4/32.png) [@Joshua1988](https://forum.realdash.net/u/Joshua1988)\
**Post date:** [July 15, 2025, 2:04pm UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/7 "2025-07-15T14:04:34Z")

</div>

Do you have experience in using VGate Vlinker adapters as CAN bus sniffers? What do you recommend between MeatPi? I personally like the OBDLINK but they are significantly more expensive to afford.

---

<div class="post-metadata">

**Author:** ![mmain](https://forum.realdash.net/user_avatar/forum.realdash.net/mmain/32/651_2.png) [@mmain](https://forum.realdash.net/u/mmain)\
**Post date:** [July 15, 2025, 2:39pm UTC](https://forum.realdash.net/t/modifying-realdash-can-code-with-bluetooth-connectivity-and-display-it-to-can-monitor/8557/8 "2025-07-15T14:39:31Z")

</div>

@Joshua1988 I currently have a MeatPi for canbus, and a VGate Vlinker for OBD2, I also have a OBDLink LX, which I am not actively using. The above was the fastest (MeatPi) and most reliable configuration for me.
