![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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.
USB2CAN.cpp@1:4097ba8d8a3c, 2011-05-31 (annotated)
- Committer:
- Melchiorp
- Date:
- Tue May 31 12:04:38 2011 +0000
- Revision:
- 1:4097ba8d8a3c
B
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Melchiorp | 1:4097ba8d8a3c | 1 | // ------------------------------------------------------------------------- // |
Melchiorp | 1:4097ba8d8a3c | 2 | // File: USB2CAN.cpp // |
Melchiorp | 1:4097ba8d8a3c | 3 | // Contents: Converts a serial string to a canmessage and the other way // |
Melchiorp | 1:4097ba8d8a3c | 4 | // around. Accepts both standard and extended format. // |
Melchiorp | 1:4097ba8d8a3c | 5 | // Data to be sent as : // |
Melchiorp | 1:4097ba8d8a3c | 6 | // !<format>_<type>_<ID>_<length>_<d0>_<d1>_<d2>_<d3>_<d4>_<d5>_<d6>_<d7> // |
Melchiorp | 1:4097ba8d8a3c | 7 | // in which "_" are spaces. // |
Melchiorp | 1:4097ba8d8a3c | 8 | // Author: Melchior du Pau // |
Melchiorp | 1:4097ba8d8a3c | 9 | // Date: 31-05-2011 // |
Melchiorp | 1:4097ba8d8a3c | 10 | // ------------------------------------------------------------------------- // |
Melchiorp | 1:4097ba8d8a3c | 11 | #include "mbed.h" |
Melchiorp | 1:4097ba8d8a3c | 12 | #include "CAN.h" |
Melchiorp | 1:4097ba8d8a3c | 13 | #include "stdio.h" |
Melchiorp | 1:4097ba8d8a3c | 14 | #include "stdlib.h" |
Melchiorp | 1:4097ba8d8a3c | 15 | #include "string.h" |
Melchiorp | 1:4097ba8d8a3c | 16 | |
Melchiorp | 1:4097ba8d8a3c | 17 | Ticker ticker; // Liveled toggle ticker |
Melchiorp | 1:4097ba8d8a3c | 18 | Serial pc(USBTX, USBRX); // Serial connection |
Melchiorp | 1:4097ba8d8a3c | 19 | DigitalOut write_activity(LED1);// CAN write toggle led |
Melchiorp | 1:4097ba8d8a3c | 20 | DigitalOut read_activity(LED2); // CAN read toggle led |
Melchiorp | 1:4097ba8d8a3c | 21 | DigitalOut pc_activity(LED3); // USB activity toggle led |
Melchiorp | 1:4097ba8d8a3c | 22 | DigitalOut live_led(LED4); // Live toggle led |
Melchiorp | 1:4097ba8d8a3c | 23 | CAN can(p30, p29); // RD, TD |
Melchiorp | 1:4097ba8d8a3c | 24 | |
Melchiorp | 1:4097ba8d8a3c | 25 | CANMessage msg; // The canmessage |
Melchiorp | 1:4097ba8d8a3c | 26 | int pc_ID; // Standard 11bit ID |
Melchiorp | 1:4097ba8d8a3c | 27 | int pc_IDe; // Extended 29bit ID |
Melchiorp | 1:4097ba8d8a3c | 28 | char candata[8]; // 8 databytes |
Melchiorp | 1:4097ba8d8a3c | 29 | int pc_length; // 1 - 8 |
Melchiorp | 1:4097ba8d8a3c | 30 | int pc_format; // 0 = standard, 1 = extended |
Melchiorp | 1:4097ba8d8a3c | 31 | int pc_type; // 0 = data, 1 = remote |
Melchiorp | 1:4097ba8d8a3c | 32 | |
Melchiorp | 1:4097ba8d8a3c | 33 | char pc_msg[60]; // The string received via USB |
Melchiorp | 1:4097ba8d8a3c | 34 | int pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7; //8 data bytes |
Melchiorp | 1:4097ba8d8a3c | 35 | |
Melchiorp | 1:4097ba8d8a3c | 36 | |
Melchiorp | 1:4097ba8d8a3c | 37 | void setdata(int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) |
Melchiorp | 1:4097ba8d8a3c | 38 | // converts 8 ints into an array of chars so it can be sent in the CANMessage |
Melchiorp | 1:4097ba8d8a3c | 39 | { |
Melchiorp | 1:4097ba8d8a3c | 40 | candata[0] = (char) (d0); // LSB |
Melchiorp | 1:4097ba8d8a3c | 41 | candata[1] = (char) (d1); |
Melchiorp | 1:4097ba8d8a3c | 42 | candata[2] = (char) (d2); |
Melchiorp | 1:4097ba8d8a3c | 43 | candata[3] = (char) (d3); |
Melchiorp | 1:4097ba8d8a3c | 44 | candata[4] = (char) (d4); |
Melchiorp | 1:4097ba8d8a3c | 45 | candata[5] = (char) (d5); |
Melchiorp | 1:4097ba8d8a3c | 46 | candata[6] = (char) (d6); |
Melchiorp | 1:4097ba8d8a3c | 47 | candata[7] = (char) (d7); // MSB |
Melchiorp | 1:4097ba8d8a3c | 48 | } |
Melchiorp | 1:4097ba8d8a3c | 49 | |
Melchiorp | 1:4097ba8d8a3c | 50 | void canread() |
Melchiorp | 1:4097ba8d8a3c | 51 | // Reads a CANMessage and prints it's contents via serial |
Melchiorp | 1:4097ba8d8a3c | 52 | { |
Melchiorp | 1:4097ba8d8a3c | 53 | // Reading the message |
Melchiorp | 1:4097ba8d8a3c | 54 | can.read(msg); |
Melchiorp | 1:4097ba8d8a3c | 55 | |
Melchiorp | 1:4097ba8d8a3c | 56 | // Printing what was read |
Melchiorp | 1:4097ba8d8a3c | 57 | pc.printf("Read: [ ID: %9x", msg.id); |
Melchiorp | 1:4097ba8d8a3c | 58 | pc.printf(" Length: %d", msg.len); |
Melchiorp | 1:4097ba8d8a3c | 59 | pc.printf(" Data: %2x", msg.data[0]); |
Melchiorp | 1:4097ba8d8a3c | 60 | pc.printf(" %2x", msg.data[1]); |
Melchiorp | 1:4097ba8d8a3c | 61 | pc.printf(" %2x", msg.data[2]); |
Melchiorp | 1:4097ba8d8a3c | 62 | pc.printf(" %2x", msg.data[3]); |
Melchiorp | 1:4097ba8d8a3c | 63 | pc.printf(" %2x", msg.data[4]); |
Melchiorp | 1:4097ba8d8a3c | 64 | pc.printf(" %2x", msg.data[5]); |
Melchiorp | 1:4097ba8d8a3c | 65 | pc.printf(" %2x", msg.data[6]); |
Melchiorp | 1:4097ba8d8a3c | 66 | pc.printf(" %2x", msg.data[7]); |
Melchiorp | 1:4097ba8d8a3c | 67 | pc.printf(" Type: %d", msg.type); // 0 = data, 1 = remote |
Melchiorp | 1:4097ba8d8a3c | 68 | pc.printf(" Format: %d ]\r\n", msg.format); // 0 = standard, 1 = extended |
Melchiorp | 1:4097ba8d8a3c | 69 | read_activity = !read_activity; //Blink! |
Melchiorp | 1:4097ba8d8a3c | 70 | } |
Melchiorp | 1:4097ba8d8a3c | 71 | |
Melchiorp | 1:4097ba8d8a3c | 72 | void pc_msg_read() |
Melchiorp | 1:4097ba8d8a3c | 73 | // Reads a serial string, converts it to a CANMessage and sends it via CAN |
Melchiorp | 1:4097ba8d8a3c | 74 | { |
Melchiorp | 1:4097ba8d8a3c | 75 | // Read the string and copy it to the char array pc_msg |
Melchiorp | 1:4097ba8d8a3c | 76 | pc.scanf("%[^\x0d]s",pc_msg); |
Melchiorp | 1:4097ba8d8a3c | 77 | |
Melchiorp | 1:4097ba8d8a3c | 78 | // Read pc_msg and extract all data |
Melchiorp | 1:4097ba8d8a3c | 79 | sscanf(pc_msg,"%d %d %x %d %x %x %x %x %x %x %x %x", &pc_format, &pc_type, &pc_ID, &pc_length, |
Melchiorp | 1:4097ba8d8a3c | 80 | &pcd0, &pcd1, &pcd2, &pcd3, &pcd4, &pcd5, &pcd6, &pcd7); |
Melchiorp | 1:4097ba8d8a3c | 81 | |
Melchiorp | 1:4097ba8d8a3c | 82 | // Printing extracted data, mostly for testing (Echo) |
Melchiorp | 1:4097ba8d8a3c | 83 | pc.printf("Entered: [ ID: %9x ",pc_ID); |
Melchiorp | 1:4097ba8d8a3c | 84 | pc.printf("length: %d ",pc_length); |
Melchiorp | 1:4097ba8d8a3c | 85 | pc.printf("data: %2x %2x %2x %2x %2x %2x %2x %2x ",pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7); |
Melchiorp | 1:4097ba8d8a3c | 86 | pc.printf("type: %d ",pc_type); |
Melchiorp | 1:4097ba8d8a3c | 87 | pc.printf("format: %d ]\r\n",pc_format); |
Melchiorp | 1:4097ba8d8a3c | 88 | |
Melchiorp | 1:4097ba8d8a3c | 89 | // Setting the data to CANMessage.data format |
Melchiorp | 1:4097ba8d8a3c | 90 | setdata(pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7); |
Melchiorp | 1:4097ba8d8a3c | 91 | |
Melchiorp | 1:4097ba8d8a3c | 92 | // Transmitting CANMessage |
Melchiorp | 1:4097ba8d8a3c | 93 | if(pc_format == 0) |
Melchiorp | 1:4097ba8d8a3c | 94 | { // CANStandard |
Melchiorp | 1:4097ba8d8a3c | 95 | if(pc_type==0) |
Melchiorp | 1:4097ba8d8a3c | 96 | { // CANData |
Melchiorp | 1:4097ba8d8a3c | 97 | if(can.write(CANMessage(pc_ID,candata,(char)pc_length,CANData,CANStandard))) |
Melchiorp | 1:4097ba8d8a3c | 98 | { |
Melchiorp | 1:4097ba8d8a3c | 99 | pc.printf("MBED: [ Message compiled and sent. ]\r\n"); |
Melchiorp | 1:4097ba8d8a3c | 100 | write_activity = !write_activity; |
Melchiorp | 1:4097ba8d8a3c | 101 | } |
Melchiorp | 1:4097ba8d8a3c | 102 | } |
Melchiorp | 1:4097ba8d8a3c | 103 | else if(pc_type==1) |
Melchiorp | 1:4097ba8d8a3c | 104 | { // CANRemote |
Melchiorp | 1:4097ba8d8a3c | 105 | if(can.write(CANMessage(pc_ID,CANStandard))) { |
Melchiorp | 1:4097ba8d8a3c | 106 | pc.printf("MBED: [ RTR Message compiled and sent. ]\r\n"); |
Melchiorp | 1:4097ba8d8a3c | 107 | write_activity = !write_activity; |
Melchiorp | 1:4097ba8d8a3c | 108 | } |
Melchiorp | 1:4097ba8d8a3c | 109 | } |
Melchiorp | 1:4097ba8d8a3c | 110 | } |
Melchiorp | 1:4097ba8d8a3c | 111 | else if(pc_format == 1) |
Melchiorp | 1:4097ba8d8a3c | 112 | { // CANExtended |
Melchiorp | 1:4097ba8d8a3c | 113 | if(pc_type==0) |
Melchiorp | 1:4097ba8d8a3c | 114 | { // CANData |
Melchiorp | 1:4097ba8d8a3c | 115 | if(can.write(CANMessage(pc_ID,candata,(char)pc_length,CANData,CANExtended))) |
Melchiorp | 1:4097ba8d8a3c | 116 | { |
Melchiorp | 1:4097ba8d8a3c | 117 | pc.printf("MBED: [ Message compiled and sent. ]\r\n"); |
Melchiorp | 1:4097ba8d8a3c | 118 | write_activity = !write_activity; |
Melchiorp | 1:4097ba8d8a3c | 119 | } |
Melchiorp | 1:4097ba8d8a3c | 120 | } |
Melchiorp | 1:4097ba8d8a3c | 121 | else if(pc_type==1) |
Melchiorp | 1:4097ba8d8a3c | 122 | { // CANRemote |
Melchiorp | 1:4097ba8d8a3c | 123 | if(can.write(CANMessage(pc_ID,CANExtended))) { |
Melchiorp | 1:4097ba8d8a3c | 124 | pc.printf("MBED: [ RTR Message compiled and sent. ]\r\n"); |
Melchiorp | 1:4097ba8d8a3c | 125 | write_activity = !write_activity; |
Melchiorp | 1:4097ba8d8a3c | 126 | } |
Melchiorp | 1:4097ba8d8a3c | 127 | } |
Melchiorp | 1:4097ba8d8a3c | 128 | } |
Melchiorp | 1:4097ba8d8a3c | 129 | } |
Melchiorp | 1:4097ba8d8a3c | 130 | |
Melchiorp | 1:4097ba8d8a3c | 131 | void initcan() |
Melchiorp | 1:4097ba8d8a3c | 132 | // Initializes MBED's CAN port |
Melchiorp | 1:4097ba8d8a3c | 133 | { |
Melchiorp | 1:4097ba8d8a3c | 134 | can.frequency(1000000); // 1Mbit/s |
Melchiorp | 1:4097ba8d8a3c | 135 | can.reset(); |
Melchiorp | 1:4097ba8d8a3c | 136 | can.attach(&canread); // Run canread on CAN reception interrupt |
Melchiorp | 1:4097ba8d8a3c | 137 | } |
Melchiorp | 1:4097ba8d8a3c | 138 | |
Melchiorp | 1:4097ba8d8a3c | 139 | void liveled() |
Melchiorp | 1:4097ba8d8a3c | 140 | // Toggles the led |
Melchiorp | 1:4097ba8d8a3c | 141 | { |
Melchiorp | 1:4097ba8d8a3c | 142 | live_led=!live_led; |
Melchiorp | 1:4097ba8d8a3c | 143 | } |
Melchiorp | 1:4097ba8d8a3c | 144 | |
Melchiorp | 1:4097ba8d8a3c | 145 | int main() |
Melchiorp | 1:4097ba8d8a3c | 146 | { |
Melchiorp | 1:4097ba8d8a3c | 147 | initcan(); |
Melchiorp | 1:4097ba8d8a3c | 148 | //can.monitor(1); // If you want the node to only monitor the CAN network. |
Melchiorp | 1:4097ba8d8a3c | 149 | pc.baud(115200); // PC baudrate |
Melchiorp | 1:4097ba8d8a3c | 150 | ticker.attach(&liveled, 1); // Send every 1 sec |
Melchiorp | 1:4097ba8d8a3c | 151 | |
Melchiorp | 1:4097ba8d8a3c | 152 | char test; // Used to check for "!". |
Melchiorp | 1:4097ba8d8a3c | 153 | char dump; // Used to dump strings that did not start with "!" |
Melchiorp | 1:4097ba8d8a3c | 154 | |
Melchiorp | 1:4097ba8d8a3c | 155 | pc.printf(" [ Please enter !format_type_ID_length_d0_d1_d2_d3_d4_d5_d6_d7 ('_'=space) ]\r\n"); |
Melchiorp | 1:4097ba8d8a3c | 156 | |
Melchiorp | 1:4097ba8d8a3c | 157 | while(1) { |
Melchiorp | 1:4097ba8d8a3c | 158 | if (pc.readable()) { // If there's data available from pc |
Melchiorp | 1:4097ba8d8a3c | 159 | pc_activity = !pc_activity; // LED |
Melchiorp | 1:4097ba8d8a3c | 160 | test = pc.getc(); // Get the first character of the string |
Melchiorp | 1:4097ba8d8a3c | 161 | if (test == '!') { // See if it's a "valid" message |
Melchiorp | 1:4097ba8d8a3c | 162 | pc_msg_read(); // Valid => read the message and extract the data |
Melchiorp | 1:4097ba8d8a3c | 163 | } |
Melchiorp | 1:4097ba8d8a3c | 164 | else { // Invalid data or leftover characters |
Melchiorp | 1:4097ba8d8a3c | 165 | pc.printf(" [ Dumped: "); |
Melchiorp | 1:4097ba8d8a3c | 166 | while(pc.readable()) { // Keep dumping the leftovers |
Melchiorp | 1:4097ba8d8a3c | 167 | dump = pc.getc(); |
Melchiorp | 1:4097ba8d8a3c | 168 | pc.printf("%c",dump); |
Melchiorp | 1:4097ba8d8a3c | 169 | } |
Melchiorp | 1:4097ba8d8a3c | 170 | pc.printf(" ]\r\n"); // Done dumping buffer |
Melchiorp | 1:4097ba8d8a3c | 171 | } |
Melchiorp | 1:4097ba8d8a3c | 172 | } |
Melchiorp | 1:4097ba8d8a3c | 173 | } |
Melchiorp | 1:4097ba8d8a3c | 174 | } |