![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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.
Fork of Seeed_CAN_Hello_World by
Diff: main.cpp
- 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);