Introductory CAN bus messaging application using a microcontroller built in UART connection and requiring a second CAN bus peer (to transmit or receive.)
Revision 0:fd2dbe74d7f6, committed 2017-07-24
- Comitter:
- michaesc
- Date:
- Mon Jul 24 10:21:43 2017 +0000
- Commit message:
- Initialized introductory CAN bus receiver application pending import.
Changed in this revision
diff -r 000000000000 -r fd2dbe74d7f6 canbus.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/canbus.lib Mon Jul 24 10:21:43 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Just4pLeisure/code/SEEED_CAN/#fd026fcfde94
diff -r 000000000000 -r fd2dbe74d7f6 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jul 24 10:21:43 2017 +0000 @@ -0,0 +1,90 @@ +/* +* WARNING! With some CAN shields (those breaking SPI out exclusively to ICSP) +* there must be rewiring done. This is simple and involves connecting +* ICSP contacts for MOSI, MISO, and SCLK to D11, D12, and D13 on FRDM. +* +* SPI clock rate is 1MHz by default, set a Bus Pirate to this speed. +*/ + +#include "mbed.h" +#include "seeed_can.h" + +//SEEED_CAN can(SEEED_CAN_CS, SEEED_CAN_IRQ, SEEED_CAN_MOSI, SEEED_CAN_MISO, SEEED_CAN_CLK, 30000); +SEEED_CAN can; // No parameters needed when Seeed Studios' CAN-BUS Shield is plugged into a FRDM-KL25Z mbed + // or an LPC1768b and using pins p9, p10, p11, p12 and p13. +Serial pc(USBTX, USBRX); // USB serial port TTYACM0 (or COMn in a Windows environment - use device manager to find 'n') + +Ticker minute; +Timer timestamp; + +bool msgRxFlag = 0; + +void canInterrupt() +{ + can.attach(NULL); // Disable the interrupt - the application must re-anable the interrupt after it has acted upon it + msgRxFlag = 1; // Set a 'Flag' to say that there is an interrupt that needs to be processed +} + +void resetTimestamp() // Resets the 'timestamp' Timer (attached to the 'minute' Ticker) +{ + timestamp.reset(); +} + +void displayMessage() // Display a CAN message if there is one in a receive buffer +{ + SEEED_CANMessage canMsg; + + /* Note: If incoming message bytes are higher than '30' + it could mean that they are encoded, ANSI, ASCII + or similar, for example D:3031323334353637 == 01234567 */ + if (can.read(canMsg)) { // Timestamp in ms, message Id and message Length + printf("**** T:%05d I:%03x L:%d D:", timestamp.read_ms(), canMsg.id, canMsg.len); + for (uint32_t i = 0; i < canMsg.len; i++) { + printf("%02x", canMsg.data[i]); // Show the message's data bytes in Hex representation + } + printf(" ****\r\n"); + } +} + +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 + + pc.baud(115200); // Increase bitrate appropriately for receiving and printing CAN messages + + printf("Analyzing an IoT Empire CAN Bus Test\r\n"); + timestamp.start(); + minute.attach(&resetTimestamp, 60.0); // Reset the 'Timestamp' timer every minute + can.open(500000, SEEED_CAN::Config); // Initialise CAN Bus hardware 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, 0x222); // Configure Filter 0 - 0x7E8 is the id used by ECUs on GMLAN + + // Read and Display the VIN code stored in a ECU + can.write(SEEED_CANMessage(0x7E0, reqvin)); // Request VIN using ReadDataByIdentifier method (GMLAN_DID) + while (!(can.read(canMsg) && (canMsg.id == 0x222))); // 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 == 0x222))); // 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 == 0x222))); // 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); + + // Analysis loop, display all messages on the CAN bus regardless of addressing + can.monitor(1); // Select moniter mode to listen only (no ACKs to CAN) + can.mask(0, NULL); // Clear acceptance mask 0 (i.e. accept all meassages) + can.attach(&canInterrupt, SEEED_CAN::RxAny); + while (1) { + if (msgRxFlag) { + displayMessage(); + if (can.interrupts(SEEED_CAN::RxAny)) { + msgRxFlag = 0; + can.attach(&canInterrupt, SEEED_CAN::RxAny); + } + } + } +}
diff -r 000000000000 -r fd2dbe74d7f6 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jul 24 10:21:43 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/mbed_official/code/mbed/builds/64910690c574 \ No newline at end of file