AVR CAN Bus Project – Step 3: CANspy CAN Bus Monitor

Sorry for the delay in posting the circuit and schematics from my AVR CAN Bus Project – Status Update 1.  The circuit for interfacing the Olimex AT90CAN128 Header Board is incredibly simple, and only requires 3 components.

Parts List
(1) .1uF ceramic capacitor
(1) 10K resistor
(1) Microchip MCP2551 CAN transceiver

Schematic

If you’re going to connect it to a Nissan Leaf, the car has 3 different CAN buses accessible via the OBD-II connector. The pinouts can be found on MyNissanLeaf.com in this thread: Leaf CANbus Decoding (Open Discussion)

To communicate with the AT90CAN128 header board from my PC, I connected a USB to serial converter to USART0: TXD0 (pin 3) and RXD0 (pin 2).

Arduino Sketch

Below is my CANSpy sketch for monitoring the CAN bus via the serial port, as depicted in my Status Update 1.

Download: CANspy.zip

To compile the sketch, follow the instructions in AVR CAN Bus Project – Step 1: Programming AT90CAN128 with Arduino.

In my next update, I’ll show how to implement a SOC (State of Charge) meter for the Leaf using a LCD display.
Previous: AVR CAN Bus Project – Status Update 1
Next: AVR CAN Bus Project: Step 4 – Nissan Leaf SOC Meter

8 thoughts on “AVR CAN Bus Project – Step 3: CANspy CAN Bus Monitor”

  1. Very interested in seeing the progress of this. I had made something similar for interfacing with my BMW a few years ago. But those days there were no AVRs with CAN included. Is it possible for you to drop me an email because I want to ask you a few questions and I don’t want to hog your blog.

  2. Hi, very nice work. Since I have an Arduino and a CAN-BUS Shield, with the MCP2551 CAN transciver it’s possible to use my setup to get the SoC data?

  3. Hi,

    I working with at90can128 and I would like send data with can bus but I don´t find any simple program. I make one program changed your program CANspy and I make one fuction with transmit data but I got anything .

    The program is this:

    #include

    void send_std_can_msg(unsigned int std_id, unsigned char std_dlc)
    {
    st_cmd_t msg; // st_cmd_t ist struct; gespeichert in can_lib.h
    uint8_t buffer[8];

    msg.pt_data = &buffer[0]; // Buffer senden
    msg.status = 0;
    msg.handle = 0; // “handle” wird von can_cmd (can_lib.c) ben�tigt
    msg.dlc = std_dlc;
    msg.id.std = std_id;
    msg.cmd = CMD_TX; // Sendekanal
    while(CAN.cmd(&msg) != CAN_CMD_ACCEPTED); // in can_lib.c ist can_cmd beschrieben. Zaehler sind daf�r notwendig
    while(CAN.get_status(&msg) != CAN_STATUS_COMPLETED); // in can_lib.c beschrieben
    }

    void CANinit()
    {
    // Clock prescaler Reset SCL:don’t need this unless CLKDIV8 is set in the low fuse
    // CLKPR = 0x80; CLKPR = 0x00;

    //- Pull-up on TxCAN & RxCAN one by one to use bit-addressing
    CAN_PORT_DIR &= ~(1<<CAN_INPUT_PIN );
    CAN_PORT_DIR &= ~(1<<CAN_OUTPUT_PIN);
    CAN_PORT_OUT |= (1<<CAN_INPUT_PIN );
    CAN_PORT_OUT |= (1<<CAN_OUTPUT_PIN);

    //- Reset CAN peripheral
    Can_reset();

    CAN.set_baudrate(1000);
    CAN.init(0);

    //- Set CAN Timer Prescaler
    // SCL: dont think we need this CANTCON = CANBT1; // Why not !
    }

    void setup()
    {
    Serial.begin(9600);
    CANinit();
    }

    void loop()
    {
    send_std_can_msg(1, 'A');
    }

    You can help me? I use can_lib.h library

    Sorry for my english.

    Best regards

    1. Hi,
      Sorry, I haven’t tried transmitting data yet. Here is a code snippet from atmel’s can_spy_echo example:

      //- CAN ECHO: RESPONSE

      if(mode==0)
      {
      // — Init Tx data
      buffer[6] = CANSTMH;
      buffer[7] = CANSTML;

      // — Tx Command
      message.id.ext++; // Incrementation of ID to revome possible clashes
      message.dlc = 8;
      message.cmd = CMD_TX_DATA;

      // — Enable Tx
      while(can_cmd(&message) != CAN_CMD_ACCEPTED);
      // — Wait for Tx completed
      while(1)
      {
      u8_temp = can_get_status(&message);
      if (u8_temp != CAN_STATUS_NOT_COMPLETED) break; // Out of while
      }
      //- CAN ECHO: PRINT-UART OF CAN FRAME TRANSMITTED
      spy_printing(TXCAN, &message);

      // —- Exit if CAN error(s)
      if (u8_temp == CAN_STATUS_ERROR) break; // Out of function
      }

      See if that helps you. If not, you might want to try running can_spy_echo, and seeing if you can send out messages.
      The example code is in this archive: http://www.atmel.com/dyn/resources/prod_documents/at90CANLIB_3_2.zip

      Good luck, and if you get it working, please share your code, and I will put it into my project on github.

  4. I had some adapters made to allow 2 standard pinout ELM327’s or the like to connect to the CAR and EV busses on the LEAF. If anyone is interested contact me for details and pix. Nice molded connectors.

    Has anyone figured out how to read the LEAF Vin from the CAR bus?

    Cheers

Leave a Reply