Monitors the CANbus and prints read messages over USB Allows you to send messages via USB to the CANbus Use a terminal application like PuTTY for windows or MoSerial for Ubuntu.

Dependencies:   mbed

USB2CAN.cpp

Committer:
Melchiorp
Date:
2011-05-31
Revision:
1:4097ba8d8a3c

File content as of revision 1:4097ba8d8a3c:

// ------------------------------------------------------------------------- //
// File:        USB2CAN.cpp                                                  //
// Contents:    Converts a serial string to a canmessage and the other way   //
//              around. Accepts both standard and extended format.           //
//              Data to be sent as :                                         //
//  !<format>_<type>_<ID>_<length>_<d0>_<d1>_<d2>_<d3>_<d4>_<d5>_<d6>_<d7>   //
//              in which "_" are spaces.                                     //
// Author:      Melchior du Pau                                              //
// Date:        31-05-2011                                                   //
// ------------------------------------------------------------------------- //
#include "mbed.h"
#include "CAN.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

Ticker ticker;                  // Liveled toggle ticker
Serial pc(USBTX, USBRX);        // Serial connection
DigitalOut write_activity(LED1);// CAN write toggle led
DigitalOut read_activity(LED2); // CAN read toggle led
DigitalOut pc_activity(LED3);   // USB activity toggle led
DigitalOut live_led(LED4);      // Live toggle led
CAN can(p30, p29);              // RD, TD

CANMessage msg;                 // The canmessage
int pc_ID;                      // Standard 11bit ID
int pc_IDe;                     // Extended 29bit ID
char candata[8];                // 8 databytes
int pc_length;                  // 1 - 8
int pc_format;                  // 0 = standard, 1 = extended
int pc_type;                    // 0 = data, 1 = remote

char pc_msg[60];                // The string received via USB
int pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7; //8 data bytes


void setdata(int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) 
// converts 8 ints into an array of chars so it can be sent in the CANMessage
{
    candata[0] = (char) (d0);   // LSB
    candata[1] = (char) (d1);
    candata[2] = (char) (d2);
    candata[3] = (char) (d3);
    candata[4] = (char) (d4);
    candata[5] = (char) (d5);
    candata[6] = (char) (d6);
    candata[7] = (char) (d7);   // MSB
}

void canread() 
// Reads a CANMessage and prints it's contents via serial
{
    // Reading the message
    can.read(msg);
    
    // Printing what was read
    pc.printf("Read:    [ ID: %9x", msg.id);
    pc.printf(" Length: %d", msg.len);
    pc.printf(" Data: %2x", msg.data[0]);
    pc.printf(" %2x", msg.data[1]);
    pc.printf(" %2x", msg.data[2]);
    pc.printf(" %2x", msg.data[3]);
    pc.printf(" %2x", msg.data[4]);
    pc.printf(" %2x", msg.data[5]);
    pc.printf(" %2x", msg.data[6]);
    pc.printf(" %2x", msg.data[7]);
    pc.printf(" Type: %d", msg.type);           // 0 = data, 1 = remote
    pc.printf(" Format: %d ]\r\n", msg.format); // 0 = standard, 1 = extended
    read_activity = !read_activity;             //Blink!
}

void pc_msg_read() 
// Reads a serial string, converts it to a CANMessage and sends it via CAN
{
    // Read the string and copy it to the char array pc_msg 
    pc.scanf("%[^\x0d]s",pc_msg);

    // Read pc_msg and extract all data
    sscanf(pc_msg,"%d %d %x %d %x %x %x %x %x %x %x %x", &pc_format, &pc_type, &pc_ID, &pc_length, 
    &pcd0, &pcd1, &pcd2, &pcd3, &pcd4, &pcd5, &pcd6, &pcd7);
    
    // Printing extracted data, mostly for testing (Echo)
    pc.printf("Entered: [ ID: %9x ",pc_ID);
    pc.printf("length: %d ",pc_length);
    pc.printf("data: %2x %2x %2x %2x %2x %2x %2x %2x ",pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7);
    pc.printf("type: %d ",pc_type);
    pc.printf("format: %d ]\r\n",pc_format);
    
    // Setting the data to CANMessage.data format
    setdata(pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7);
    
    // Transmitting CANMessage
    if(pc_format == 0)
    { // CANStandard
        if(pc_type==0) 
        { // CANData
            if(can.write(CANMessage(pc_ID,candata,(char)pc_length,CANData,CANStandard))) 
            {
                pc.printf("MBED:    [ Message compiled and sent. ]\r\n");
                write_activity = !write_activity;
            }
        }
        else if(pc_type==1) 
        { // CANRemote
            if(can.write(CANMessage(pc_ID,CANStandard))) {
                pc.printf("MBED:    [ RTR Message compiled and sent. ]\r\n");
                write_activity = !write_activity;
            }
        }
    }
    else if(pc_format == 1)
    { // CANExtended
        if(pc_type==0) 
        { // CANData
            if(can.write(CANMessage(pc_ID,candata,(char)pc_length,CANData,CANExtended))) 
            {
                pc.printf("MBED:    [ Message compiled and sent. ]\r\n");
                write_activity = !write_activity;
            }
        }
        else if(pc_type==1) 
        { // CANRemote
            if(can.write(CANMessage(pc_ID,CANExtended))) {
                pc.printf("MBED:    [ RTR Message compiled and sent. ]\r\n");
                write_activity = !write_activity;
            }
        }
    }
}

void initcan() 
// Initializes MBED's CAN port
{
    can.frequency(1000000);             // 1Mbit/s
    can.reset();
    can.attach(&canread);               // Run canread on CAN reception interrupt
}

void liveled()
// Toggles the led
{
    live_led=!live_led;
}

int main() 
{
    initcan();
    //can.monitor(1);                   // If you want the node to only monitor the CAN network.
    pc.baud(115200);                    // PC baudrate
    ticker.attach(&liveled, 1);         // Send every 1 sec
    
    char test;                          // Used to check for "!".
    char dump;                          // Used to dump strings that did not start with "!"
    
    pc.printf("         [ Please enter !format_type_ID_length_d0_d1_d2_d3_d4_d5_d6_d7 ('_'=space) ]\r\n");
        
    while(1) {
        if (pc.readable()) {            // If there's data available from pc
            pc_activity = !pc_activity; // LED
            test = pc.getc();           // Get the first character of the string   
            if (test == '!') {          // See if it's a "valid" message
                pc_msg_read();          // Valid => read the message and extract the data
            }
            else {                      // Invalid data or leftover characters
                pc.printf("         [ Dumped: ");
                while(pc.readable()) {  // Keep dumping the leftovers
                    dump = pc.getc();
                    pc.printf("%c",dump);
                }
                pc.printf(" ]\r\n");    // Done dumping buffer
            }
        }
    }
}