This 'Hello World' program uses many of the SEEED_CAN library functions to display the VIN number stored in a GMLAN ECU then display all CAN messages on the CAN-BUS.

Dependencies:   SEEED_CAN mbed

Fork of Seeed_CAN_Hello_World by Sophie Dexter

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "seeed_can.h"
00003 
00004 SEEED_CAN can;                                                          // No parameters needed when Seeed Studios' CAN-BUS Shield is plugged into a FRDM-KL25Z mbed
00005                                                                         // or an LPC1768b and using pins p9, p10, p11, p12 and p13.
00006 Serial pc(USBTX, USBRX);                                                // USB serial port TTYACM0 (or COMn in a Windows environment - use device manager to find 'n')
00007 
00008 Ticker minute;
00009 Timer timestamp;
00010 
00011 bool msgRxFlag = 0;
00012 
00013 void canInterrupt()
00014 {
00015     can.attach(NULL);                                                   // Disable the interrupt - the application must re-anable the interrupt after it has acted upon it
00016     msgRxFlag = 1;                                                      // Set a 'Flag' to say that there is an interrupt that needs to be processed
00017 }
00018 
00019 void resetTimestamp()                                                   // Resets the 'timestamp' Timer (attached to the 'minute' Ticker)
00020 {
00021     timestamp.reset();
00022 }
00023 
00024 void displayMessage()                                                   // Display a CAN message if there is one in a receive buffer
00025 {
00026     SEEED_CANMessage canMsg;
00027 
00028     if (can.read(canMsg)) {
00029         printf("*** T%05dI%03xL%dD", timestamp.read_ms(), canMsg.id, canMsg.len);   // Show a Timestamp in ms, message Id and message Length
00030         for (uint32_t i = 0; i < canMsg.len; i++)
00031             printf("%02x", canMsg.data[i]);                             // Show the message's data bytes in Hex representation
00032         printf(" ***\r");
00033     }
00034 }
00035 
00036 int main()
00037 {
00038     SEEED_CANMessage canMsg;
00039     char VIN[18] = {NULL};                                              // VIN code is 17 characters long + 1 for string terminator character (NULL or \0)
00040     char reqvin[] = {0x02,0x1A,0x90,0x00,0x00,0x00,0x00,0x00};          // CAN message to request VIN code
00041     char floctl[] = {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00};          // CAN message to request all remaining frames in a multi-frame message
00042 
00043     printf("Seeed Studios CAN-BUS Shield 'Hello World' program :-)\r\n");
00044     timestamp.start();
00045     minute.attach(&resetTimestamp, 60.0);                               // Reset the 'Timestamp' timer every minute
00046     can.open(500000, SEEED_CAN::Config);                                // Initialise Seeed Studios' CAN-BUS shield with a baudrate of 500 kbps (P-bus)
00047     can.mask(0, 0x7FF);                                                 // Configure Mask 0 to check all bits of a Standard CAN message Id
00048     can.mask(1, 0x7FF, CANStandard);                                    // Configure Mask 1 to check all bits of a Standard CAN message Id
00049     can.filter(0, 0x7E8);                                               // Configure Filter 0 - 0x7E8 is the id used by ECUs on GMLAN
00050 // Read and Display the VIN code stored in a GMLAN ECU
00051 //
00052 // ***!!! NOTE: Using while(...) as I am here is not a good idea because  !!!***
00053 // ***!!! this 'Hello World' will get stuck if the message never arrives  !!!***
00054 // ***!!! I should really perform checking and include a timeout.         !!!***
00055 // ***!!! It's sort of OK for a quick demo (Just don't show Nigel Jones)  !!!***
00056 //
00057     can.write(SEEED_CANMessage(0x7E0, reqvin));                         // Request VIN using ReadDataByIdentifier method (GMLAN_DID)
00058     while (!(can.read(canMsg) && (canMsg.id == 0x7E8)));                // Wait for the response
00059     memcpy(VIN+0, canMsg.data+4, 4);                                    // 1st 4 Bytes are part of message protocol, last 4 bytes are 1st 4 characters of VIN
00060     can.write(SEEED_CANMessage(0x7E0, floctl));                         // Send Trionic8 a "Flow Control Message to get the rest of the VIN
00061     while (!(can.read(canMsg) && (canMsg.id == 0x7E8)));                // Wait for the 1st continuation message
00062     memcpy(VIN+4, canMsg.data+1, 7);                                    // 1st Byte is message continuation sequence number, last 7 bytes are next 7 characters of VIN
00063     while (!(can.read(canMsg) && (canMsg.id == 0x7E8)));                // Wait for the last message
00064     memcpy(VIN+11, canMsg.data+1, 6);                                   // 1st Byte is message continuation sequence number, last 6 bytes are remaining characters of VIN
00065     printf("VIN code: %s\r\n",VIN);
00066 // Display all messages on the CAN-BUS
00067     can.monitor(1);                                                     // Select Moniter mode to listen only (do not ack messages on the CAN bus)
00068     can.mask(0, NULL);                                                  // Clear acceptance mask 0 (i.e. accept all meassages)
00069     can.attach(&canInterrupt, SEEED_CAN::RxAny);
00070     while (1) {
00071         if (msgRxFlag) {
00072             displayMessage();
00073             if (can.interrupts(SEEED_CAN::RxAny)) {
00074                 msgRxFlag = 0;
00075                 can.attach(&canInterrupt, SEEED_CAN::RxAny);
00076             }
00077         }
00078     }
00079 }