Input CAN data to Arduino for output via Bluetooth for Android App Display

Beginner Arduino user here. I don't have coding experience. I've spent quite a few hours learning the basics of Arduino with some starter tutorials. My young children think I'm very cool because I can make cool blinky lights. But I'm still well over my head on my project at hand.

I'm looking to create a solution with my Arduino Uno R3 + CAN-bus shield (Seed CAN-BUS Shield V2.0) and HC-06 RS232 bluetooth serial transceiver module. This is an automotive application whereby I'm taking data from one output and relaying it via Bluetooth for consumption on an Android application. I have an engine control unit from Haltech. This ECU broacasts CAN data that the user can consume and use as they wish. My aim is to take this CAN data and display it on a 3rd party android application called "Torque." It will be my user interface for virtual gauges - reading all sorts of information that is broadcast from the ECU - such as fuel pressure, timing, air-fuel ratio, etc.

The high-level architecture is like this:
[ECU] ---CAN H, Can L (in OBD format) --- [CAN-bus Shield/UNO R3] --> [HC-06] ---> [Torque Application]

I have been able to prove out some components of this solution, but I'm lacking knowledge to piece it all together.

With the can-bus shield, and an example from the seed can-bus library, I have been able to read the CAN data into the serial port of my laptop successfully, indicating the data coming from the ECU is valid:

// demo: CAN-BUS Shield, receive data with check mode
// send data coming to fast, such as less than 10ms, you can use this way
// loovee, 2014-6-13
#include <SPI.h>

#define CAN_2515
// #define CAN_2518FD

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10

// Set SPI CS Pin according to your hardware
// For Wio Terminal w/ MCP2518FD RPi Hat:
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9


#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif                           

void setup() {
    SERIAL_PORT_MONITOR.begin(1000000);

#ifdef CAN_2518FD
    while (0 != CAN.begin((byte)CAN_1M)) {            // init can bus : baudrate = 500k
#else
    while (CAN_OK != CAN.begin(CAN_1000KBPS)) {             // init can bus : baudrate = 500k
#endif
        SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
        delay(100);
    }
    SERIAL_PORT_MONITOR.println("CAN init ok!");
}


void loop() {
    unsigned char len = 0;
    unsigned char buf[8];

    if (CAN_MSGAVAIL == CAN.checkReceive()) {         // check if data coming
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf

        unsigned long canId = CAN.getCanId();

        SERIAL_PORT_MONITOR.println("-----------------------------");
        SERIAL_PORT_MONITOR.print("Get data from ID: 0x");
        SERIAL_PORT_MONITOR.println(canId, HEX);

        for (int i = 0; i < len; i++) { // print the data
            SERIAL_PORT_MONITOR.print(buf[i], HEX);
            SERIAL_PORT_MONITOR.print("\t");
        }
        SERIAL_PORT_MONITOR.println();
    }
}

The ECU outputs CAN data at 1Meg rate, so I adjusted the above code to align to that speed, and the output on the serial monitor was satisfactory. So that's good.

Separately, I have gotten the the Bluetooth to connect to my Android phone and the Torque application. I'm not sure if it's relevant, but I plugged the Bluetooth transceiver TX and RX into digital pins 2 and 3 in order to name and validate communication with the Bluetooth.

This bring us to current. At this point, what I think I'm looking to take the CAN data that I'm able to view on the serial monitor, and route it instead to the Bluetooth via the TX(?) pin on the HC-06. I'm thinking the data transmission via Bluetooth to the android app need not have much of the code that makes it readable for me in the serial monitor. Perhaps sending in raw OBD format (as comes from the ECU) is best so the Torque App can consume and display. That leads me to here - I don't know where to go from where I currently reside. I appreciate any support to help me progress in my journey.

A couple of points.

i) Serial.print() can block your code if you flood it with data
check out my tutorial on Text I/O for the Real World for solutions to this
My SafeString tutorial has an OBD example
My Multi-tasking in Arduino tutorial is also worth a look

ii) You will need to adjust the Bluetooth com speed up to handle the data rate.
Suggest you move to a Mega2560 which has extra hardware serial port to connect to the HC-06 while still debugging via the USB

Thank you for the input. I have given a quick read of the links/tutorials you provided. They are a little advanced for me, but I will spend some time with them. In principal, I understand the intention, so it's a matter of educating myself further in order to comprehend the specifics and relate it to my application - granted the OBD example is akin to what I'm after.

As far as adjusting the bluetooth speed - I've read conflicting reports, although it does look like I can set the bluetooth speed up to the 1MB. Why does the Uno fall short ? Why would a Mega2560 be recommended? Is it due to the ability (lack there-of) of processing power to monitor the CAN messaging traffic on the serial display while simultaneously broadcasting to the bluetooth -> android app for the end-to-end solution?

I can't find in your code what SERIAL_PORT_MONITOR is. It's possibly defined in the library that you use.

Can you please post a link to the shield and the library.

If I understand you correctly, sending to Bluetooth can be added everywhere where you print to SERIAL_PORT_MONITOR. A matter of adding software serial prints or replacing SERIAL_PORT_MONITOR by your software serial instance.

PS, I don't see a need to use SafeString.

Why would a Mega2560 be recommended?

Mega2560 has the same processing power, but more memory and more importantly for your use extra Serial ports so you can connect your HC-06 to one of the extra Serial (say Serial1) and still use the USB serial for debugging.
The SafeString library includes BufferedOutput which lets you write your debug prints without delaying the loop trying to collect the CAN data and send it to Bluetooth.
As for HC-06 speed. 115200 seems to be about the highest the Mega/uno can handle.

sterretje:
I can't find in your code what SERIAL_PORT_MONITOR is. It's possibly defined in the library that you use.

Can you please post a link to the shield and the library.

Library:

I used "receive_monitor" example from that directory to satisfactorily pull and view the CAN data from the Haltech into the serial monitor.
This is the shield: (CAN-BUS 2.0) CAN-BUS Shield V2.0 | Seeed Studio Wiki

drmpf:
Mega2560 has the same processing power, but more memory and more importantly for your use extra Serial ports so you can connect your HC-06 to one of the extra Serial (say Serial1) and still use the USB serial for debugging.
The SafeString library includes BufferedOutput which lets you write your debug prints without delaying the loop trying to collect the CAN data and send it to Bluetooth.
As for HC-06 speed. 115200 seems to be about the highest the Mega/uno can handle.

The extra serial port would be useful for essentially monitoring / debugging during operation. Just curious - could I effectively (granted not as efficiently) use an app like Bluetooth terminal on my android device to monitor what's coming across from the arduino as a hack instead? Otherwise, writing it for the serial monitor instead of routing to bluetooth should give me visibility when not connected to BT, right?
When you say that 115200 is the highest speed the Uno can handle, I'm curious how I'm able to read the CAN-Bus data to the serial monitor when I configure the speed to 1MB... are you thinking I'm dropping / missing some of the data streaming at me?

Seed CAN-BUS Shield V2.0 use ISP interface not Serial UART
So... its begin is a clock rate, not a baud rate

could I effectively (granted not as efficiently) use an app like Bluetooth terminal on my android device to monitor what's coming across from the arduino as a hack instead? Otherwise, writing it for the serial monitor instead of routing to bluetooth should give me visibility when not connected to BT, right?

Yes, just you could do that. See how you go.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.