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

Revision:
1:d31ce42d53a1
Parent:
0:d3e39839c3e3
Child:
2:7e78ba1e5921
--- a/main.cpp	Tue Nov 05 23:00:35 2013 +0000
+++ b/main.cpp	Wed Nov 06 20:24:49 2013 +0000
@@ -1,8 +1,8 @@
 #include "mbed.h"
 #include "seeed_can.h"
 
-SEEED_CAN CAN(SEEED_CAN_CS);                                            // Seeed Studios' CAN-BUS Shield
-Serial pc(USBTX, USBRX);                                                // USB serial port TTYACM0
+SEEED_CAN CAN;                                                          // No parameters needed when Seeed Studios' CAN-BUS Shield is plugged into a FRDM-KL25Z mbed
+Serial pc(USBTX, USBRX);                                                // USB serial port TTYACM0 (or COMn in a Windows environment - use device manager to find 'n')
 
 Ticker minute;
 Timer timestamp;
@@ -15,32 +15,37 @@
 int main()
 {
     SEEED_CANMessage canMsg;
+    char VIN[18] = {NULL};                                              // VIN code is 17 characters long + 1 for string terminator character (NULL or \0)
+    char reqvin[] = {0x02,0x1A,0x90,0x00,0x00,0x00,0x00,0x00};          // CAN message to request VIN code
+    char floctl[] = {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00};          // CAN message to request all remaining frames in a multi-frame message
 
     printf("Seeed Studios CAN-BUS Shield 'Hello World' program :-)\r\n");
     timestamp.start();
     minute.attach(&resetTimestamp, 60.0);                               // Reset the 'Timestamp' timer every minute
-    CAN.frequency(500000);                                              // init can bus, baudrate: 500k
-    CAN.Mask(0, 0x7FF);                                                 // init Masks
-    CAN.Mask(1, 0x7FF, CANStandard);                                    // init Masks
-    CAN.Filter(0, 0x7E8);                                               // init filters - 0x7E8 T8 ECU id
+    CAN.open(500000);                                                   // Initialise Seeed Studios' CAN-BUS shield with a baudrate of 500 kbps (P-bus)
+    CAN.mask(0, 0x7FF);                                                 // Configure Mask 0 to check all bits of a Standard CAN message Id
+    CAN.mask(1, 0x7FF, CANStandard);                                    // Configure Mask 1 to check all bits of a Standard CAN message Id
+    CAN.filter(0, 0x7E8);                                               // Configure Filter 0 - 0x7E8 is the id used by ECUs on GMLAN
     while (CAN.read(canMsg));                                           // Empty any unfiltered messages in the receive buffers
 // Read and Display the VIN code stored in a GMLAN ECU
-    char VIN[18] = {NULL};
-// Request VIN using ReadDataByIdentifier method using DID
-    char reqvin[] = {0x02,0x1A,0x90,0x00,0x00,0x00,0x00,0x00};
-    CAN.write(SEEED_CANMessage(0x7E0, reqvin));
-    while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8)));
-    memcpy(VIN+0, canMsg.data+4, 4);
-// Send Trionic8 a "Flow Control Message to get the rest of the VIN
-    char floctl[] = {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-    CAN.write(SEEED_CANMessage(0x7E0, floctl));
-    while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8)));
-    memcpy(VIN+4, canMsg.data+1, 7);
-    while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8)));
-    memcpy(VIN+11, canMsg.data+1, 6);
+// 
+// ***!!! NOTE: Using while(...) as I am here is not a good idea because  !!!***
+// ***!!! this 'Hello World' will get stuck if the message never arrives  !!!***
+// ***!!! I should really perform checking and include a timeout.         !!!***
+// ***!!! It's sort of OK for a quick demo (Just don't show Nigel Jones)  !!!***
+// 
+    CAN.write(SEEED_CANMessage(0x7E0, reqvin));                         // Request VIN using ReadDataByIdentifier method (GMLAN_DID)
+    while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8)));                // Wait for the response
+    memcpy(VIN+0, canMsg.data+4, 4);                                    // 1st 4 Bytes are part of message protocol, last 4 bytes are 1st 4 characters of VIN
+    CAN.write(SEEED_CANMessage(0x7E0, floctl));                         // Send Trionic8 a "Flow Control Message to get the rest of the VIN
+    while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8)));                // Wait for the 1st continuation message
+    memcpy(VIN+4, canMsg.data+1, 7);                                    // 1st Byte is message continuation sequence number, last 7 bytes are next 7 characters of VIN
+    while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8)));                // Wait for the last message
+    memcpy(VIN+11, canMsg.data+1, 6);                                   // 1st Byte is message continuation sequence number, last 6 bytes are remaining characters of VIN
     printf("VIN code: %s\r\n",VIN);
 // Display all messages on the CAN-BUS
-    CAN.Mask(0, NULL);                                                  // Clear the mask to accept all meassages
+    CAN.monitor(1);                                                     // Select Moniter mode to listen only (do not ack messages on the CAN bus)
+    CAN.mask(0, NULL);                                                  // Clear acceptance mask 0 (i.e. accept all meassages)
     while (1) {
         if (CAN.read(canMsg)) {
             printf("*** T%05dI%03xL%dD", timestamp.read_ms(), canMsg.id, canMsg.len);