Go Down

Topic: CANBus and Bluetooth LE (Read 265 times) previous topic - next topic


Hi guys, Im working on a project utilizing bluetooth low energy and a CANbus interface along with my UNO.  Im using the CANbus shield from Seeed (http://www.seeedstudio.com/wiki/CAN-BUS_Shield) and the AdaFruit BLE breakout(http://www.adafruit.com/products/1697)

I have my project fully working with the CAN bus but the project breaks when I add the BLE stuff.  I have narrowed it down to an interrupt issue.  I am using the libraries from Adafruirt for the nrf8001 found here (https://github.com/adafruit/Adafruit_nRF8001/archive/master.zip) and a CANbus library I found here on the forum(from CANDave i believe...its been a while)

Both the CAN shield and BLE breakout are setup to use SPI and I am sharing pins 11, 12, and 13.  They are also both defaulting to pin 10 for the CS pin.  I rewired the BLE breakout to pin 3 for the RDY pin and pin 7 for REQ pin and made the proper changes in the code to match the wiring as you will see below.  (https://learn.adafruit.com/getting-started-with-the-nrf8001-bluefruit-le-breakout/hooking-everything-up) here is some more info on hooking up the nRF8001 breakout.  The CAN bus shield is still on pin 10 for CS pin and 2 for Interrupt pin.

To simplify the debugging I wrote a simple program...it never enters the If statement for the CAN interrupt

Code: [Select]

That exact line of code is correct and works as long as I dont have any of the bluetooth code running along with it.

Code: [Select]

#include "Adafruit_BLE_UART.h"
#include <SPI.h> // Arduino SPI Library
#include <MCP2515.h>

// Pin definitions specific to how the MCP2515 is wired up.
#define CS_PIN    10
#define INT_PIN    2
// Create CAN object with pins as defined
// CAN message frame (actually just the parts that are exposed by the MCP2515 RX/TX buffers)
Frame message;
Frame message1;

// Connect CLK/MISO/MOSI to hardware SPI
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define ADAFRUITBLE_RDY 3     // This should be an interrupt pin, on Uno thats #2 or #3


void setup() {
Serial.println("Initializing boobs ...");
// Set up SPI Communication
// dataMode can be SPI_MODE0 or SPI_MODE3 only for MCP2515
// Initialise MCP2515 CAN controller at the specified speed and clock frequency
// In this case 125kbps with a 16MHz oscillator
// (Note:  This is the oscillator attached to the MCP2515, not the Arduino oscillaltor)
int baudRate=CAN.Init(500,16);
if(baudRate>0) {
  Serial.println("MCP2515 Init OK ...");
  Serial.print("Baud Rate (kbps): ");
else {
  Serial.println("MCP2515 Init Failed ...");

Serial.println("Ready ...");



aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;

void loop()
  // Tell the nRF8001 to do whatever it should be working on.

  // Ask what is our current status
  aci_evt_opcode_t status = BTLEserial.getState();
  // If the status changed....
  if (status != laststatus) {
    // print it out!
    if (status == ACI_EVT_DEVICE_STARTED) {
        Serial.println(F("* Advertising started"));
    if (status == ACI_EVT_CONNECTED) {
        Serial.println(F("* Connected!"));
    if (status == ACI_EVT_DISCONNECTED) {
        Serial.println(F("* Disconnected or advertising timed out"));
    // OK set the last status change to this one
    laststatus = status;

  if (status == ACI_EVT_CONNECTED) {
    // Lets see if there's any data for us!
    if (BTLEserial.available()) {
      Serial.print("* "); Serial.print(BTLEserial.available()); Serial.println(F(" bytes available from BTLE"));
    // OK while we still have something to read, get a character and print it out
    while (BTLEserial.available()) {
      char c = BTLEserial.read();

    // Next up, see if we have any data to get from the Serial console

    if (Serial.available()) {
      // Read a line from Serial
      Serial.setTimeout(100); // 100 millisecond timeout
      String s = Serial.readString();

      // We need to convert the line to bytes, no more than 20 at this time
      uint8_t sendbuffer[20];
      s.getBytes(sendbuffer, 20);
      char sendbuffersize = min(20, s.length());

      Serial.print(F("\n* Sending -> \"")); Serial.print((char *)sendbuffer); Serial.println("\"");

      // write the data
      BTLEserial.write(sendbuffer, sendbuffersize);

  message.id = 0;
  message1.id = 0;
  // This implementation utilizes the MCP2515 INT pin to flag received messages or other events
    // determine which interrupt flags have been set
    byte interruptFlags = CAN.Read(CANINTF);
    if(interruptFlags & RX0IF)
      // read from RX buffer 0
      message = CAN.ReadBuffer(RXB0);
    if(interruptFlags & RX1IF)
      // read from RX buffer 1
      message1 = CAN.ReadBuffer(RXB1);
      // (this is poor code as clearly if two messages are received then the second will overwrite the first)

    Serial.print("ID: ");
    Serial.print("Extended: ");
    Serial.print("DLC: ");
    for(int i=0;i<message.dlc;i++)
      Serial.print(" ");

Here is the CANdave library I am using (http://forum.arduino.cc/index.php?topic=8730.0)  all of his code is on post #3-6 so you guys can referance that as well.

Im pretty sure the issue is in the BLE nRF library and how that chip deals with SPI, the following is a quote off of the Adafruit learning page for the breakout.

The nRF8001 differs from a classic SPI bus since CS is replaced by two pins, REQ and RDY, but you can still use HW SPI since CS is normally controlled purely in SW anyway.

Hopefully that gives you guys enough info to take a look at it and see if you can help me out, I have no idea how to fix this.  Ill do my best to answer any other questions you guys have about the issue!


Go Up