Photon CAN Bus [Completed]

I wanted to compile the application so that it used system 1 and system 2, but not have to compile the system parts, only the application. I had not done that without using CLI or Web.

Not sure if that is possible or not, but I have an old laptop and compiling everything takes a while. I guess I could choose not to do a clean…

Got it. You have to build in firmware/main to build only the user module. You can use the same build command you use in firmware/modules when you build all 3 modules.

I added a list of common firmware build commands a while back. You can refer back to that later.

So are we all good to have this in the next release, next week?

I’ll have a chance to test on some big machinery in the next month. Some CAT marine engines. Love the potential here. Does anyone have a step by step procedure to follow for utilization? I’ll help write if one does not exist…

This will be released next week in 0.4.9 with docs! :smile:

Better docs are on the way, here's a start.

You'll need a CAN transceiver with the TX pin connected to D1 and the RX pin connected to D2.

Here's sample code for receiving and transmitting messages.

CANChannel can(CAN_D1_D2);

void setup() {
    can.begin(125000); // pick the baud rate for your network
    // accept one message. If no filter added by user then accept all messages
    can.addFilter(0x100, 0x7FF);
}

void loop() {
    CANMessage Message;

    Message.id = 0x100;
    can.transmit(Message);

    delay(10);

    if(can.receive(Message)) {
        // message received
    }
}

The CAN message struct has these members:

struct CANMessage
{
   uint32_t id;
   bool     extended;
   bool     rtr;
   uint8_t  len;
   uint8_t  data[8];
}
4 Likes

Great job, I am able to build, download and run either tinker or my version of the CAN application from the 0.4.9 https://github.com/spark/firmware. What is involved with getting the WEB IDE to use the 0.4.9 firmware for building? It is saying “You are building with firmware: Latest (0.4.7)” and it doesn’t recognize existence of the CANChannel.

0.4.9 hasn’t been released yet. RC1 was tagged in github, but we have found a stop-ship issues that we need to resolve before shipping the release.

1 Like

So if we build from that firmware link using CLI we should be able to use the CAN driver? Its just the WEB IDE that won’t work until they resolve issues with the 0.4.9 Firmware?

Thank you, great help. I’m sure its in the data sheet but do you know how many message id filters are available?

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;
unlockMsg.id = 0x1C0;
unlockMsg.extended = false;
unlockMsg.rtr = false;
unlockMsg.len = 6;
unsigned char unlockData[8] = {23, 00, 00, 90, 11, 00};
unlockMsg.data = unlockData;
can.transmit(unlockMsg);

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

@flyingfedora
unlockMsg.data 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.
D1-SHFTUP-MCP2551
D2-SHFTUP-MCP2551
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.

http://docs.canb.us/

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.

2 Likes