CAN Feedback test

26 Jan 2011

Hello all,

I set up my mbed today on a bread board with two CAN traceivers (MCP2551's) and I'm pretty sure it's wired up properly. I modified the test code slightly to blink LEDs when messages are sent by can1 and another led should show when can2 receives the message.

It appears the messages are being sent but I show no activity on the receiving end? Any help is appreciated...

Here is the code and a picture...

/media/uploads/TRS300/can_callback.jpg

#include "mbed.h"
#include "CAN.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);


CAN can1(p9, p10);
CAN can2(p30, p29);

Serial pc(USBTX,USBRX); //tx. rx

int main() {

    char count = 0;
    CANMessage msg;
    
    pc.baud(9600);
    
    can1.frequency(125000);
    can2.frequency(125000);
    
    /*********Program Starts Here***************/
    
    while(1) {
    
    
        if(can1.write(CANMessage(0x42, &count, 1))) {
        led1 = 1;
        pc.printf("> ");
        }
        
        //wait(0.5);
        
        if(can2.read(msg)) { 
        
        led2=1;
        pc.printf("In ");
        
        if(count == msg.data[0]) {
                //led2 = 1;
                count++;
                pc.printf("%02X ",msg.data[0]);
                
            }
        } 
        
        wait(0.5);
        led1 = led2 = 0;
        wait(0.2);
        led4 = !led4;
        //count++;
    }
}

/*
                     ___                                 (NXP TJA 1050)
            ____+---|| ||---+                  mbed     TJA1     TJA2
           |    |:  |_v_|  :|____              ----------------------
          GND   |: m  =  w :|    |             VV       Vcc      Vcc
           |    |:   ---   :|   VV(5.0V)       GND      GND      GND
           |    |:  I O I  :|    |             p9       RXD      -
           | +-=|:   ---   :|    |             p10      TXD      -
           | | ||: +-----+ :|=-+ |             p29      -        TXD
           | | ||: |     | :|| | |             p30      -        RXD
           | | ||: |     | :|| | |             -        CANL     CANL
           | | ||: +-----+ :|| | |             -        CANH     CANH
           | | ||: = = = = :|| | |
    _____  | | |+-----------+| | |
   |/TJA |-|-+ |             | | |
+--|/1050|-|---|-------------|-|-+ 
| +|/    |-+   |             | | |
| ||/____|-|---+             | | |
| | _____  |                 | | |
| ||/TJA |-|-----------------+ | |
+-||/1050|-|-------------------|-+
  +|/    |-+                   |
   |/____|---------------------+
    ^-- rounded side
*/
26 Jan 2011

We can't see the whole breadboard, but it looks as if there might be no connection from the mbed ground to the breadboard ground rail. Also, there is a connection to IF- which according to the mbed docs is reserved for future use.

26 Jan 2011

Try adding a bus termination resistor 60 ohms betweeen CAN Hi and Lo. A CAN bus won't work without termination...

26 Jan 2011

Thanks for the response guys...

Romilly, The ground wire loops under the usb connection and provides the ground to the top rail of the breadboard. The power rail is also along the top and is on the 5V usb power supply. The bottom two outer rails of the breadboard are acting like the HI & LOW can bus. What looks like a connection to IF is actually connected to VU and is supplying 5V power to the tranceivers...

Andrew, You are correct that I have no resistor between the CAN Hi & Low. The way it is wired up now the tranceivers are pretty much just tied together with jumpers (HI to HI) & (LOW to LOW). I did this because that what the schematic shows on the example. So are you saying I just need one 60 ohm resistor tied beteen the CAN HI & LOW rails?

--

26 Jan 2011

Correct. Normally a CAN bus would have a seperate 120 ohm resistor at each end of the bus. In your case, your "bus" is only a few millimetres long, so a single 60 ohm resistor should work just as well.

I can tell you from past experience that CAN busses won't work if there are no termination resistors at all.

27 Jan 2011

Andrew, I added the 60 ohm resistor and no luck. I even tried a 120 ohm and no luck either. My test shows that messages are bing sent but none are received... So I hooked up my CANUSB sniffer program and it shows no messages at all...

FYI: I thought "What the heck?" and decided to hook it into the CAN Bus of my car. I thought maybe it would read some messages off the cars bus... No luck there either...

I'm at a loss... :-(

--

27 Jan 2011

How about connecting pin 8 (the "set" pin) on your two transceivers to ground. From the TJA 1050 datasheet it looks like you have them in receive only or "silent" mode if these pins are left floating

27 Jan 2011

Tim,

I first thought that you had the chip backwards, but you've got it right.... I'm looking at the CanBusExample1 page (http://mbed.org/projects/cookbook/wiki/CanBusExample1). I believe that schematic should work.

Looking at your breadboard, what pin on the mbed are you using to power the transceivers? It looks like you've got it connected to the D+ pin which is the data line... not the power pin. But that could be the angle of the camera.... It should be on the second pin from the top on the right side.

ryan

28 Jan 2011

Andrew,

Sorry for the confusion. I'm actually using two MCP2551 traceivers in place of TJA 1050... That was left over from the example code...

Ryan,

The power to the Tranceivers is from the second pin. I've measured it at 5V using my ohm meter... I've looked over the wires again and again... Maybe I should take it all apart and re-connect to try and get one channel to read from my car for now...

28 Jan 2011

OK, but I think MCP2551 needs the same thing - pin 8 (Rs pin) needs to be tied to ground to put the device in "high speed" mode. You can optionally use a resistor to tie it to ground to limit the slew rate, but I suspect leaving it open circuit will result in the "standby" mode. Check out the datasheet.

28 Jan 2011

Andrew is right.... the Rs pin needs to be tied to ground. Essentially when the Rs pin is open, the chip is in a low power state or sleep state. It should toggle the RXD line (pin 4) but I don't think any messages actually come through... and no messages are transmitted.

Nice find Andrew...

Ryan

28 Jan 2011

Andrew / Ryan, What a great way to start my day! Thank you both so much. You were right about having to ground out pin8 Andrew. My test loop is working and I can begin to try and migrate some of my CANUSB code into the mbed.

I'm hoping to decode messages from my cars CAN-B (83Kbs) and CAN-C buses (500Kbs) in the mbed and to transmit those values to my PC using the fastest means possible (serial? SPI?). These vaules will be captured by a PC program written in C# and will carry out some actions... Ryan, I know you have made great progress in this area already, any advice or help will be appreciated.

This is a huge step in the right direction for me. I thank you so much for your help. I hope I can return the favor someday...

Cheer! :-)

-

28 Jan 2011

As a final follow-up for anyone trying the same example. There were two things wrong that I needed to correct.

1.) Without a 120 ohm resistor between the CAN Hi and CAN Low, the example will not work. That is not shown in the schematic of the example.

2.) I needed to ground out pin 8 of the tranceiver's for it to work.

Thank You

Tim

08 Jan 2014

I am doing similar thing.

I see Data transmission from CAN1 to CAN2 and CAN2 to CAN1 is working fine.

Now I want to see this data on PC. So I make settings something like this

NXP CAN -> CAN Transceiver 1 -> CAN Transceiver 2 -> MAX232 -> PC.

But I am not getting any data on PC. is there anything wrong in this settings? or the method is incorrect?

08 Jan 2014

- Maddy wrote:

Now I want to see this data on PC. So I make settings something like this

NXP CAN -> CAN Transceiver 1 -> CAN Transceiver 2 -> MAX232 -> PC.

But I am not getting any data on PC. is there anything wrong in this settings? or the method is incorrect?

The CAN protocol is not the same as serial port protocol. It does not have the right number of bits, startbit, stopbit, datarate etc. Matching the electrical levels with a MAX232 is not sufficient. You need a protocol converter for example a second mbed.

15 Mar 2014

You need to create a buffer and setup your CAN data. then shoot that over serial to the PC.

15 Mar 2014

Echoing the comments from above - consider this minor variation in your architecture:

//  +---- Device # 1 ---+                   +---- Device # 2-----+              +--- PC --+
//   mbed -- CAN Xcvr 1 ==== CAN Network ==== CAN Xcvr 2 -- mbed  == USB Cable == PC 
//
//
//         +----------------  In the mbed module -------------------+
//         can.read()    -> buffer ->   pc.printf()
//         can.write()   <- buffer <-   pc.isreadable() ... pc.getc()

Device #1 could be an LPC1768 based mbed for instance, simply generating traffic, or a real device (e.g. OBD2 port on a car). Device #2 is then the 2nd CAN port (again on the LPC1768 as an example).

The USB port that you use to program the mbed with can be used as a serial port to the PC. Through this you can run a basic terminal program to see the CAN traffic that the mbed has received and formatted into text.

Of course, a custom PC program could receive a binary stream from the mbed as well.

As my stick-figure shows, there are basically four processes in the mbed module:

  1. Receive from CAN: When a can message is received, it is placed into a buffer. This minimizes the processing time as this might be performed within a CAN ISR callback.
  2. Send to PC: This process simply pulls messages from the buffer and formats them nicely for the serial port attached to the PC.
  3. Receive from PC: Some simple command set lets you create a packet on the PC. This process pulls that down perhaps a character at a time until if has a whole message. It then creates the CAN message and puts it in the buffer.
  4. Send to CAN: Pull packets from the buffer and send them to CAN.

These 4 processes could be managed with the RTOS, or you could simple collapse them into a polling loop, and then the buffer might not even be required (depending on the speed of each link).