-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revised header for all source files Removed need to instantiate variable within user code Standardized on instance named "CAN" (I know, right?) Revised examples to use standard bitrate of 500kbps (CAN_BPS_500K) Tested with Uno, Due & Teensy
- Loading branch information
Showing
19 changed files
with
882 additions
and
379 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,41 @@ | ||
CAN-Library | ||
=========== | ||
|
||
Yet another CAN library for Arduino using MCP2515 controller. | ||
|
||
I have tried most of the MCP2515 libraries out there and found that some were either: shield specific, purpose specific or protocol specific. These libraries were also very complicated and brought too many features out to the sketch that could be performed within the library. These libraries did have some good features and I have tried to take the best features out there and put them here. I have also made it more “Arduino” user friendly by using known functions like read(), send(), begin(). | ||
|
||
Since I have taken features from so many libraries I can’t tell what came from where, so in order not to violate any GPL, LGPL or any other license out there I am trying to give credit where credit is due. I am only a contributor to this library and some of the work here might not be mine. I can take credit in putting it together and releasing back to the public to make any variation as needed. | ||
|
||
I will add more Arduino examples using CAN messages either CAN, J1939 or OBD2 (CAN) in the future. | ||
|
||
Features: | ||
|
||
CAN V2.0B | ||
8 byte length in the data field | ||
Standard and extended data frames | ||
Two receive buffers | ||
Three Transmit Buffers | ||
SPI Interface with selectable CS via Arduino Sketch | ||
|
||
Supported Bit rates (Confirmed and tested with Vector CANalyzer and Peak pCAN usb) | ||
|
||
10 kpbs; 20 kpbs; 50 kbps; 100 kbps; 125 kbps; 250 kbps; 500 kbps; 1000 kbps | ||
|
||
Intended to be used with ATMEL ATMega328P with Arduino bootlader, MCP2515 Stand-Alone CAN Controller and MCP2561/62 High-Speed CAN Transceivers. Have not tested with other Arduino ATMEL chips but it will more likely work. | ||
|
||
Message structure allows to read messages for CAN (standard, extended), J1939 and CANopen with the correct message format. | ||
|
||
Selectable SPI CS pin allows to use library with most of the MCP2515 CANshield variations out there (Sparkfun shield, Seeedstudio, breadboard CAN, etc) | ||
|
||
|
||
|
||
This library allows you to communicate with multiple types of CAN controllers | ||
using a consistent API, making CAN communications easier through Arduino. | ||
|
||
The idea behind this CAN library is to use a similar approach to Adafruit's | ||
Unified Sensor library (https://github.com/adafruit/Adafruit_Sensor) by | ||
standardizing CAN frame message structures, filters, masks, buffers, etc | ||
to be used with a wide variety of CAN controllers. This library currently | ||
supports the following controllers: | ||
|
||
* Microchip MCP2515 through the SPI interface | ||
* Tested using various Arduino and Arduino-compatible controllers | ||
* Atmel SAM3X family of MCU | ||
* Tested using the SAM3X8E on the Arduino Due | ||
* Freescale Kinetis K2x family of MCU | ||
* Tested using the MK20DX256VLH7 on the PJRC Teensy 3.1 | ||
|
||
Since I have taken features from so many libraries I can’t tell what came | ||
from where, so in order not to violate any GPL, LGPL or any other license | ||
out there I am trying to give credit where credit is due. I am only a | ||
contributor to this library and some of the work here might not be mine. | ||
I can take credit in putting it together and releasing back to the public | ||
to make any variation as needed. This is a work in progress library with | ||
no current release. | ||
|
||
For the MCP2515 library release see CAN_MCP2515 branch on this repo | ||
|
||
```Arduino | ||
#include <Arduino.h> | ||
#include <CAN.h> | ||
#if defined(ARDUINO_ARCH_AVR) // Arduino with SPI interface to MCP2515 chip | ||
#include <SPI.h> | ||
#include <CAN_MCP2515.h> | ||
#elif defined(ARDUINO_ARCH_SAM) // Arduino Due | ||
#include <CAN_SAM3X8E.h> | ||
#elif defined(__MK20DX256__) // Teensy 3.1 | ||
#include <CAN_K2X.h> | ||
#else | ||
#error “Your CAN controller is currently unsupported.” | ||
#endif | ||
``` |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
/* CAN extended Frames with Ping/Pong sending | ||
This example sets up a receive and transmit mailbox on both CAN devices. | ||
First NODE0 sends to NODE1. When NODE1 receives it sends to NODE0. PING/PONGs forever | ||
and as quickly as possible - This will saturate the bus so don't have anything important connected. | ||
Authors: Thibaut Viard, Wilfredo Molina, Collin Kidder, Pedro Cevallos & Neil McNeight | ||
Created: 06/01/14 | ||
Updated: 06/18/14 | ||
As per wiki information: | ||
"CAN bus is a message-based protocol, designed specifically for automotive | ||
applications but now also used in other areas such as aerospace, maritime, | ||
industrial automation and medical equipment." | ||
For more info http://en.wikipedia.org/wiki/Controller_area_network | ||
*/ | ||
|
||
#include <Arduino.h> | ||
#include <CAN.h> | ||
|
||
#if defined(ARDUINO_ARCH_AVR) // Arduino with SPI interface to MCP2515 chip | ||
#include <SPI.h> | ||
#include <CAN_MCP2515.h> | ||
#elif defined(ARDUINO_ARCH_SAM) // Arduino Due | ||
#include <CAN_SAM3X8E.h> | ||
#elif defined(__MK20DX256__) // Teensy 3.1 | ||
#include <CAN_K2X.h> | ||
#else | ||
#error “Your CAN controller is currently unsupported.” | ||
#endif | ||
|
||
// Define our CAN speed (bitrate). | ||
#define bitrate CAN_BPS_500K | ||
|
||
//Comment out for one node, and leave uncommented for the other node | ||
#define NODE1 | ||
#ifdef NODE1 | ||
#define NODETX_CAN_ID 0x15555555 | ||
#define NODERX_CAN_ID 0x0AAAAAAA | ||
#else | ||
#define NODETX_CAN_ID 0x0AAAAAAA | ||
#define NODERX_CAN_ID 0x15555555 | ||
#endif | ||
|
||
// CAN frame max data length | ||
#define MAX_CAN_FRAME_DATA_LEN 8 | ||
|
||
uint32_t sentFrames, receivedFrames; | ||
|
||
CAN_Frame frameTX, frameRX, incoming; | ||
|
||
void setup() | ||
{ | ||
Serial.begin(115200); // Initialize Serial communications with computer to use serial monitor | ||
|
||
//Set CAN speed. Note: Speed is now 500kbit/s so adjust your CAN monitor | ||
|
||
CAN.begin(bitrate); | ||
|
||
delay(4000); // Delay added just so we can have time to open up Serial Monitor and CAN bus monitor. It can be removed later... | ||
|
||
// Output will be formatted as a CSV file, for capture and analysis | ||
Serial.println(F("millis(),ID,RTR,EID,Length,Data0,Data1,Data2,Data3,Data4,Data5,Data6,Data7")); | ||
|
||
// Initialize frame counters | ||
sentFrames = 0; | ||
receivedFrames = 0; | ||
|
||
//Initialize the definitions for the frames we'll be sending. | ||
//This can be done here because the frame never changes | ||
frameTX.id = NODETX_CAN_ID; | ||
frameTX.length = MAX_CAN_FRAME_DATA_LEN; | ||
//We are using extended frames so mark that here. Otherwise it will just use | ||
//the first 11 bits of the ID set | ||
frameTX.extended = 1; | ||
|
||
// Process | ||
processTXFrame(); | ||
// Send out the first frame | ||
CAN.write(frameTX); | ||
} | ||
|
||
// Test rapid fire ping/pong of extended frames | ||
void loop() | ||
{ | ||
if (CAN.available()) | ||
{ | ||
frameRX = CAN.read(); | ||
receivedFrames++; | ||
// Process | ||
processRXFrame(); | ||
|
||
// Only send frames after receiving one, otherwise bus is flooded | ||
processTXFrame(); | ||
CAN.write(frameTX); | ||
} | ||
} | ||
|
||
void processTXFrame() | ||
{ | ||
sentFrames++; | ||
frameTX.data[3] = sentFrames; | ||
frameTX.data[2] = sentFrames >> 8; | ||
frameTX.data[1] = sentFrames >> 16; | ||
frameTX.data[0] = sentFrames >> 24; | ||
|
||
frameTX.data[7] = receivedFrames; | ||
frameTX.data[6] = receivedFrames >> 8; | ||
frameTX.data[5] = receivedFrames >> 16; | ||
frameTX.data[4] = receivedFrames >> 24; | ||
} | ||
|
||
void processRXFrame() | ||
{ | ||
if (frameRX.id == NODERX_CAN_ID) | ||
{ | ||
uint32_t otherNodeSent = (uint32_t)frameRX.data[3]; | ||
otherNodeSent |= ((uint32_t)frameRX.data[2] << 8); | ||
otherNodeSent |= ((uint32_t)frameRX.data[1] << 16); | ||
otherNodeSent |= ((uint32_t)frameRX.data[0] << 24); | ||
|
||
uint32_t otherNodeReceived = (uint32_t)frameRX.data[7]; | ||
otherNodeReceived |= ((uint32_t)frameRX.data[6] << 8); | ||
otherNodeReceived |= ((uint32_t)frameRX.data[5] << 16); | ||
otherNodeReceived |= ((uint32_t)frameRX.data[4] << 24); | ||
|
||
// Serial.print("I am node 0x"); | ||
// Serial.println(NODETX_CAN_ID, HEX); | ||
if ((sentFrames % 5000) == 0) | ||
{ | ||
Serial.print("IS:"); | ||
Serial.print(sentFrames); | ||
Serial.print(" OR:"); | ||
Serial.println(otherNodeReceived); | ||
Serial.print("IR:"); | ||
Serial.print(receivedFrames); | ||
Serial.print(" OS:"); | ||
Serial.println(otherNodeSent); | ||
} | ||
|
||
int16_t txDropped = sentFrames - otherNodeReceived; | ||
if (txDropped < 0) | ||
{ | ||
Serial.print("Node 0x"); | ||
Serial.print(NODERX_CAN_ID, HEX); | ||
Serial.print(" received "); | ||
Serial.print(abs(txDropped)); | ||
Serial.println(" more frames than I transmitted."); | ||
} | ||
else if (txDropped > 0) | ||
{ | ||
Serial.print(txDropped); | ||
Serial.print(" frames dropped from here to node 0x"); | ||
Serial.println(NODERX_CAN_ID, HEX); | ||
} | ||
|
||
int16_t rxDropped = receivedFrames - otherNodeSent; | ||
if (rxDropped < 0) | ||
{ | ||
Serial.print("I received "); | ||
Serial.print(abs(rxDropped)); | ||
Serial.print(" more frames than node 0x"); | ||
Serial.print(NODERX_CAN_ID, HEX); | ||
Serial.println(" transmitted."); | ||
} | ||
else if (rxDropped > 0) | ||
{ | ||
Serial.print(rxDropped); | ||
Serial.print(" frames dropped from node 0x"); | ||
Serial.print(NODERX_CAN_ID, HEX); | ||
Serial.println(" to here."); | ||
} | ||
|
||
// Synchronize the counters | ||
sentFrames = otherNodeReceived; | ||
receivedFrames = otherNodeSent; | ||
} | ||
} |
Oops, something went wrong.