Photon CAN Bus [Completed]

14 id/mask filters. So a filter could accept many messages, for example id=0x300 mask=0x700 accepts 0x300 to 0x3FF.

I’m having a bit of trouble getting this to work. I’m fairly new to coding, so chances are that I just made an ignorant mistake.

Here’s what I’ve got:

CANMessage unlockMsg; = 0x1C0;
unlockMsg.extended = false;
unlockMsg.rtr = false;
unlockMsg.len = 6;
unsigned char unlockData[8] = {23, 00, 00, 90, 11, 00}; = unlockData;

It is giving an invalid array assignment error regarding unlockData. I appreciate the help.

@flyingfedora is an array of 8 bytes. So you do not have to create an additional array.

struct CANMessage
   uint32_t id;
   bool     extended;
   bool     rtr;
   uint8_t  len;
   uint8_t  data[8];
1 Like

Thanks for the explanation and the information. 14 is more than enough for my application. I got this working last night with an isolated transceiver and a loop back to a USB-2-CAN device could be the start of something really cool! I’m assuming this CAN implementation will also work for the Electron in the future?

1 Like

Yes, and since the electron has more pins, it actually has 2 CAN buses exposed.

1 Like

I’m using a Teensy with FlexCan to echo the CAN messages from the Photon back to the CANBUS. The distributed version work OK for standard addressing but doesn’t work for extended addressing. I had to change the “firmware/hal/src/stm32f2xx/can_hal.cpp” as shown below. With the modified version it works for me with both standard and extended addressing filters.

bool CANDriver::addFilter(uint32_t id, uint32_t mask, HAL_CAN_Filters type)
if(nextFilter > hw.can_last_filter)
return false;

// Filter configuration - Register organization
// Lowest 11 bits of id are first, then next 18 bits of id, then
// sta

uint32_t filterId, filterMask;

if (type == CAN_FILTER_STANDARD) {
    filterId   = (id   << 21) | ((id   >> 8) & 0x1FFFF8) | (type == CAN_FILTER_EXTENDED ? 0x4 : 0);
    filterMask = (mask << 21) | ((mask >> 8) & 0x1FFFF8) | 0x6;
 } else {
    filterId   = ((id   << 3) & 0x1FFFF8) | (type == CAN_FILTER_EXTENDED ? 0x4 : 0);
    filterMask = ((mask << 3) & 0x1FFFF8) | 0x6;

Thanks for testing this out. I’ll make a change tu the can driver to include this fix for the next release.

Just to be clear: the issue is only when filters are added, correct? When there are no filters, extended messages are received, right?

I can receive and transmit both standard and extended address packets OK. The problem for me is only with receiving and extended address filters. The distributed version works if you pre-swap the standard and extended address bits of the ID and mask. I’m wondering if someone else can duplicate the problem independently.

I duplicated the problem and sent in a fix. Thanks @RLRJCN for finding this.

How is everyone physically wiring their setup?

I have multiple CANBUS nodes & networks in my vehicle, so I am trying to see if I am stuck with just one, or if I can somehow add multiple. (Maybe moving to the Electron?)

I setup my setup as
Murata 60W Switching Converter Module to (+16V(Max) to +5.15V)
+5.15 Voltage Supply to MCP2551
+5.15 Voltage Supply to 3.3V Linear Converter (1.5A) for Photon (USB pins ignored)
+5.15 Voltage Supply to BSS138 (HV)
+3.3 V Supply to BSS138(LV)
Level Shifted CAN pins from Photon to MCP2551
Ground Jumper to bridge to Canbus network or to break the circuit.
I am using the Adafruit BSS138 I2C Converter breakout.

I was wondering if we all agree on a setup if it would make troubleshooting easier, if it even matters.

Also, it is a completely different platform, but the CANBUSTriple might be helpful in it’s code and schema for trying to construct a communication path.

The documentation is a bit everywhere, but the Github files are your best bet.

I am studying CANBUS interface for a few projects including “middleware” to attempt to understand and retrofit newer PCMs without having all the other modules on the chain.


You might like this one (sorry Julien for stealing your link ;-))
Carloop: connected car adapter
Connect to your car with Carloop


Thanks for including those links here @ScruffR :+1:

Here’s also a direct link to the schematics of my CAN board for the Photon:


Hi @mdma,

Where do I find information about the 0.4.9. release?

As always: In the Open Source repo

1 Like

Thx for everyone involved in creating the CAN Bus integration into the firmware.

I’m currently testing the CAN-bus firmware

My setup:
Core shield shield for the 5V level conversion
A MCP2551 transceiver with Vdd => 5V, Vss => GND, Rx => pin 2 , Tx => pin 5, CANH => CANH, CANL => CANL

I created a car simulator with a arduino Uno, and a sparkfun CANBus shield based on a MCP2551 and MCP2515, a common combination. Here you can find the github project of the simulator. We tested it with our other Canbus modules and it behaves as expected. You ask for a PID, you get the value back.

On the photon, I used a the can.available() to see If I received some messages.

Here my progress & trouble of my tests:

  • If I’m using my logic analyser I can decode the messages coming from the photon. I send one I see one message.
  • If I do the same with my simulator I see a constant flow of messages being send. I can decoded them behind the MCP2551 with my logic analyser. But not with the photon connected. If I connect Rx and Tx the packages mangle and nothing gets read. If I only connect the Rx it is fine. When I connect the Tx it goes wrong.

I have not tested this in my car. I tested the other modules (arduino + sparkfun canbus shield & arduion + canbus module from cooking hacks) with the simulator and they work. Am I missing something?

There are some known issues with the level shifter on the Shield Shield and longish RX/TX jumper wires causing resonances.

1 Like

I’ve found that the MCP2551 doesn’t need a logic level converter and can be connected directly to the pins on the photon. You will still need to supply it with 5V on Vdd. Also, you’ll probably want to connect the Rs pin to ground through a resistor. It’s all a bit daunting and it took me a while to figure out. You might want to read the MCP2551 datasheet and look at other people’s schematics.

@ScruffR Thanks for the info about the level converters of the shield shield.

@flyingfedora I read that D2 is one of the only pins that is not 5V tolerant, so I was cautious about connecting it directly. I’ll try it again.
I pulled the Rs pin low for high speed mode. I’ll try the slope control.

Where have read this about D2?
On the Photon all but A3 and DAC (aka A6) are 5V tolerant unless used a analogRead() pins.
Also avoid using INPUT_PULLUP/INPUT_PULLDOWN when attaching 5V.


@ScruffR I got mixed up reading this post of Zach about the Spark Core

1 Like