CanBusExample1

(Note: This project was tested/created using mbed library v12.)

This is an example how to get your mbed on the CANBus (Wikipedia: Controller–area network) using the internal can controller (on the NXP LPC2368) with an external can transceiver.

Hardware

source:/CanBusExample1/doc/hardware/CanBusExample1_schematic.png

  • The mbed board is equipped with 2 seperate can buses, one on pins 30(rx), 29(tx), the other on pins 09(rx), 10(tx). In this example, pins 29/30 are used. (+pin28 as an output pin to control the pca82c250 transceiver.)
  • When the pinning given in the schematic above is used, just take a 9-pin D-Sub crimp connector and a 10-pin crimp connector (for pin header) with a ribbon cable (pin1 - pin1 (pin10 not connected)) to get a standard conform D-Sub pinning (pin2: CAN_L, pin7: CAN_H). See SAE J1939, CAN-CIA standard interface pinout
  • The can bus needs to be terminated, jumper CAN_TERM allows to connect CAN_H and CAN_L via resistor R1 (120Ω).

Software

  • source code:
    http://mbed.org/projects/cookbook/svn/CanBusExample1/examples/CanBusExample1.cpp
    
  • for further information on the can functions, see CANMessage API documentation of CAN.h
#include "mbed.h"
#include "CAN.h"

Ticker ticker;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
// CAN_RS pin at Philips PCA82C250 can bus controller.
// activate transceiver by pulling this pin to GND.
// (Rise and fall slope controlled by resistor R_s)
// (+5V result in tranceiver standby mode)
// For further information see datasheet page 4
DigitalOut can_Pca82c250SlopePin(p28);
// second can controller on these pins. Not used here.
// CAN can1(p9, p10);

// We use can on mbed pins 29(CAN_TXD) and 30(CAN_RXD).
CAN can2(p30, p29);
void send() {
    static char counter = 0;
    if (can2.write(CANMessage(0x200, &counter, 1))) {
        printf("CanTx--> id: 0x200  dlc: 1  data: %x\n\r", counter);
        counter++;
    }
    // toggle led1 after every transmission
    led1 = !led1;
}
int main() {
    // 500kbit/s
    can2.frequency(500000);
    // activate external can transceiver
    can_Pca82c250SlopePin = 0;
    // every 500ms
    ticker.attach(&send, 0.5);
    /// create message object for message reception
    CANMessage can_MsgRx;
    while (1) {
        // send received messages to the pc via serial line (9k6, 8n1)
        if (can2.read(can_MsgRx)) {
            printf("CanRx--> id: 0x%x  dlc: %d  data: ", can_MsgRx.id, can_MsgRx.len);
            for (char i=0; i<can_MsgRx.len; i++) {
                printf("%x ", can_MsgRx.data[i]);
            }
            printf("\n\r");
            // any incoming message: toggle led2
            led2 = !led2;
        }
    }
}
Source Code of CanBusExample1.bin (LPC1768 LPC2368)

Test assembly

To test the communication, the Vector CANalyzer Software was used in combination with a CANcardXL PCMCIA card.

Overview source:/CanBusExample1/doc/images/overview_lowqual.jpg
mbed board with can controller source:/CanBusExample1/doc/images/mbed_board_lowqual.jpg

run it

  • The following screenshot shows the can message with id 0x200 sent by the mbed board every 500ms (the data byte is increased after each transmitted message).
  • The second message with id 0x201 can be send from the PC to the mbed with a keypress (see serial log below).

source:/CanBusExample1/doc/images/CanalyzerTrace2.png

  • All received and transmitted messages will be echoed to the serial line (usb/serial@9600,8n1).
  • This log shows
    • the same transmitted message (id 0x200, data 0x03) from the CANalyzer screenshot
    • the message with id 0x201, generated by the PC and received by the mbed.

SerialLog
----------------------------------------------------------------------
CanTx--> id: 0x200  dlc: 1  data: 0x3 3d
CanRx--> id: 0x200  dlc: 1  data: 3
CanTx--> id: 0x200  dlc: 1  data: 0x4 4d
CanRx--> id: 0x200  dlc: 1  data: 4
CanRx--> id: 0x201  dlc: 8  data: 12 34 56 78 9a bc de f0
CanTx--> id: 0x200  dlc: 1  data: 0x5 5d
CanRx--> id: 0x200  dlc: 1  data: 5
----------------------------------------------------------------------

  • Note: the can bus needs at least 2 devices on the bus, because a transmitter needs to get an acknowledge from at least one other device, otherwise the sender won't be able to send messages (every sender on the bus has an error counter which will be increased, if no ack is received...).
  • If you try this example without any other device connected to the can bus, your serial log will look like this:

SerialLog - no other device on the CanBus
----------------------------------------------------------------------
CanTx--> id: 0x200  dlc: 1  data: 0
CanTx--> id: 0x200  dlc: 1  data: 1
CanTx--> id: 0x200  dlc: 1  data: 2
----------------------------------------------------------------------

additional Images

CANalyzer configuration source:/CanBusExample1/doc/images/CanalyzerConfig.png
CANcardXL closeup source:/CanBusExample1/doc/images/vector_cancardxl_lowqual.jpg
mbed testboard, bottom source:/CanBusExample1/doc/images/mbed_board_bottom_lowqual.jpg
mbed testboard, closeup of can transceiver source:/CanBusExample1/doc/images/mbed_board_pca82c250_lowqual.jpg

have fun,
greetings,
Kevin Konradt.