CAN is a multi-master broadcast serial bus standard for connecting electronic control units (ECUs). Each node is able to send and receive messages, but not simultaneously. A message consists primarily of an ID (identifier), which represents the priority of the message. A CAN message that is transmitted with highest priority will succeed and the node transmitting the lower priority message will sense this and back off and wait.
The information is transmitted by two twisted wires that connect all system modules. It is transmitted by voltage difference between the two levels. The high voltage value represents 1 and low 0. Its combination forms an appropriate message.
CAN Bus | ||||||||
Standard | ISO 11898 | |||||||
Cabling | Twisted pair | |||||||
Connector | DB9 | |||||||
Network Topology | Multimaster | |||||||
Speed | 125 to 1000 Kbps | |||||||
Signaling | Differential | |||||||
Voltage Levels | 0-5V | |||||||
Signals | Half Duplex |
This list includes some of the more common uses of the standard:
The pack we are going to use in this tutorial includes the CAN Bus module and the Multiprotocol Radio Shield. The Multiprotocol Radio Shield can be used to connect two modules in order to combine the existing cooking-hacks modules and make connections between platforms. The CAN Bus module uses the SPI bus. The SPI port allows more speed communication and frees up the UART for other purposes like debugging or to connect communication modules.
The CAN Bus module can be powered by the PC or by an external power supply. Some of the USB ports on computers are not able to give all the current the module needs to work, if your module have problems when it work, you can use an external power supply (12V - 2A) on the Arduino/Rasberry Pi/Intel Galileo.
The Multiprotocol Radio Shield has two sockets. The CAN Bus module must be connected as shown in the next figures. Please, see the Multiprotocol Radio Shield Tutorial for more information.
The CAN Bus module counts with a C++ library that lets you manage the CAN Bus module in a simple way. This library offers an simple-to-use open source system.
In order to ensure the same code is compatible in both platforms (Arduino, Raspberry Pi and Intel Galileo) we use the ArduPi libraries which allows developers to use the same code. Detailed info can be found here:
The CAN Bus module includes a high level library functions for a easy manage. Before start using this functions you should download the files from the next link. This zip includes all the files needed in several folders. These folders include the necessary file for using CAN Bus protocol.
Download the CAN Bus library for Arduino.
Libraries are often distributed as a ZIP file or folder. The name of the folder is the name of the library. Inside the folder will be the .cpp files, .h files and a examples folder.
To install the library, first quit the Arduino application. Then uncompress the ZIP file containing the library. For installing libraries, uncompress zip file. Drag these folders into your libraries folder. Under Windows, it will likely be called "My Documents\Arduino\libraries". For Mac users, it will likely be called "Documents/Arduino/libraries". On Linux, it will be the "libraries" folder in your sketchbook.
The library won't work if you put the .cpp and .h files directly into the libraries folder or if they're tested in an extra folder. Restart the Arduino application. Make sure the new library appears in the Sketch->Import Library menu item of the software.
The CAN Bus library for Raspberry Pi requires the ArduPi library and both libraries should be in the same path.
Download the CAN Bus library for Raspberry Pi.
wget http://www.cooking-hacks.com/media/cooking/images/documentation/CANBus/arduPi-api_CANBUS_v0_2.zip && unzip arduPi-api_CANBUS_v0_2.zip && cd cooking/examples/CANBUS && chmod +x cook.sh && cd ../../..
Creating a program that uses the library is as simple as putting your code in this template where it says "your Arduino code here"
//Include CAN Bus library (it includes arduPi) /******************************************************** * IF YOUR ARDUINO CODE HAS OTHER FUNCTIONS APART FROM * * setup() AND loop() YOU MUST DECLARE THEM HERE * * *******************************************************/ /************************* * YOUR ARDUINO CODE HERE * * ************************/ int main (){ setup(); while(1){ loop(); } return(0); }
Follow the next steps to compile a sketch:
ArduPi For Raspberry Pi:
wget http://www.cooking-hacks.com/media/cooking/images/documentation/raspberry_arduino_shield/raspberrypi.zip && unzip raspberrypi.zip && cd cooking/arduPi && chmod +x install_arduPi && ./install_arduPi && rm install_arduPi && cd ../..
ArduPi For Raspberry Pi 2:
wget http://www.cooking-hacks.com/media/cooking/images/documentation/raspberry_arduino_shield/raspberrypi2.zip && unzip raspberrypi2.zip && cd cooking/arduPi && chmod +x install_arduPi && ./install_arduPi && rm install_arduPi && cd ../..
CAN Bus Library:
wget http://www.cooking-hacks.com/media/cooking/images/documentation/CANBus/arduPi-api_CANBUS_v0_2.zip && unzip arduPi-api_CANBUS_v0_2.zip && cd cooking/examples/CANBUS && chmod +x cook.sh && cd ../../..
cd cooking/examples/CANBUS/
./cook.sh my_example.cpp
./my_example.cpp_exe
The script "cook.sh" compiles everything in their folders and the link in the examples foldes with the "_exe" executable.
The CAN Bus module includes a high level library functions for a easy manage. Before start using this functions you should download the files from the next link. This zip includes all the files needed in several folders. These folders include the necessary file for using CAN Bus protocol.
Download the CAN Bus library for Intel Galileo
Libraries are often distributed as a ZIP file or folder. The name of the folder is the name of the library. Inside the folder will be the .cpp files, .h files and often a keywords.txt file, examples folder, and other files required by the library.
To install the library, first quit the Arduino application. Then uncompress the ZIP file containing the library. For installing libraries , uncompress zip file. It should contain three folder called CANBUS. Drag these folders into this folder (your libraries folder). Under Windows, it will likely be called "My Documents\Arduino\libraries". For Mac users, it will likely be called "Documents/Arduino/libraries". On Linux, it will be the "libraries" folder in your sketchbook.
The library won't work if you put the .cpp and .h files directly into the libraries folder or if they're nested in an extra folder. Restart the Arduino application. Make sure the new library appears in the Sketch->Import Library menu item of the software.
General functions
// Receive buffer messageCAN messageRx; // Trasmit buffer messageCAN messageTx; // Powers the CAN Bus module and opens the SPI bool begin(uint16_t speed); // Check if there is any message uint8_t messageAvailable(void); // Take the CAN message char getMessage(messageCAN *msje); // Send the CAN message char sendMessage(messageCAN *msje); // CAN message print out the serial port void printMessage(messageCAN *msje); // Configure the MCP2515 void setMode(uint8_t mode);
CAN in Automation (CiA)
unsigned int getEngineLoad(); unsigned int getEngineCoolantTemp(); unsigned int getFuelPressure(); unsigned int getIntakeMAPressure(); unsigned int getEngineRPM(); unsigned int getVehicleSpeed(); unsigned int getTimingAdvance(); unsigned int getIntankeAirTemp(); unsigned int getMAFairFlowRate(); unsigned int getThrottlePosition(); unsigned int getFuelLevel(); unsigned int getBarometricPressure(); unsigned int getEngineFuelRate();
Materials:
1. Connect the Multiprotocol Radio Shield over the Arduino UNO and the CAN Bus module as shown in the figure.
2. The CAN Bus module can be used to send data between devices to create a communications network. This network. CAN Bus is a multi-master broadcast serial bus standard. Each node is able to send and receive messages and the identification of the node must be done in the code. Every message will include the direction of the device and all the devices will receive all messages. The ID of each node must be unique in the network, otherwise two nodes would continue transmission beyond the end of the arbitration field causing an error.
Note: The wire used in this part of the tutorial is a male-male DB9
3. In your serial monitor you should receive data. In this code, all messages are printed but you can program your Arduino to filtering messages.
Arduino / Intel Galileo
/* * CAN Bus Module * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David Gascón * Implementation: Ahmad Saad & Luis Martin */ // Include always these libraries before using the CAN BUS functions #include <CAN.h> #include <SPI.h> // ID numbers #define IDWAITED 200 #define OWNID 100 // Create an instance of the object CAN myCAN = CAN(); // Setting up our devices and I/Os void setup() { // Initializes the UART Serial.begin(115200); delay(100); // Let's open the bus. Remember the input parameter: // 1: 1Mbps // 500: 500Kbps <--- Most frequently used // 250: 250Kbp // 125: 125Kbps myCAN.begin(125); } void loop() { //**************************************** // 1. Receive data //**************************************** if (myCAN.messageAvailable() == 1) { // Read the last message received. myCAN.getMessage(&myCAN.messageRx); // Print in the serial monitor the received message myCAN.printMessage(&myCAN.messageRx); } //**************************************** // 2. Send data //**************************************** // Insert the ID in the data structure myCAN.messageTx.id = OWNID; // These fields include the data to send myCAN.messageTx.data[0] = 0; myCAN.messageTx.data[1] += 1; myCAN.messageTx.data[2] = 2; myCAN.messageTx.data[3] = 3; myCAN.messageTx.data[4] = 4; myCAN.messageTx.data[5] = 5; myCAN.messageTx.data[6] = 6; myCAN.messageTx.data[7] = 7; // The length of the data structure myCAN.messageTx.header.length = 8; // Send data myCAN.sendMessage(&myCAN.messageTx); // A time delay delay(1000); }
Raspberry Pi
/* * CAN Bus Module * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David Gascón * Implementation: Ahmad Saad & Luis MartÃn */ // Include always these libraries before using the CAN BUS functions #include "CAN.h" #include "arduPi.h" // ID numbers #define IDWAITED 200 #define OWNID 100 // Create an instance of the object CAN myCAN = CAN(); // Setting up our devices and I/Os void setup() { // Let's open the bus. Remember the input parameter: // 1: 1Mbps // 500: 500Kbps <--- Most frequently used // 250: 250Kbp // 125: 125Kbps myCAN.begin(1000); } void loop() { //**************************************** // 1. Receive data //**************************************** if (myCAN.messageAvailable() == 1) { // Read the last message received. myCAN.getMessage(&myCAN.messageRx); // Print in the serial monitor the received message myCAN.printMessage(&myCAN.messageRx); } //**************************************** // 2. Send data //**************************************** // Insert the ID in the data structure myCAN.messageTx.id = OWNID; // These fields include the data to send myCAN.messageTx.data[0] = 0; myCAN.messageTx.data[1] += 1; myCAN.messageTx.data[2] = 2; myCAN.messageTx.data[3] = 3; myCAN.messageTx.data[4] = 4; myCAN.messageTx.data[5] = 5; myCAN.messageTx.data[6] = 6; myCAN.messageTx.data[7] = 7; // The length of the data structure myCAN.messageTx.header.length = 8; // Send data myCAN.sendMessage(&myCAN.messageTx); // A time delay delay(1000); } int main (){ setup(); while(1){ loop(); } return (0); }
The OBD-II standard has been mandatory for all cars and light trucks sold in the United States since 1996, and the EOBD standard has been mandatory for all petrol vehicles sold in the European Union since 2001 and all diesel vehicles since 2004. The car manufactures usually protect the access to the CAN Bus of the vehicle, so sometimes is not possible to get data directly by connecting the CAN Bus module to the OBD-II connector of the car. The user must consult how to connect the CAN Bus module to the device or car.
Signal Ground | 1 | 5 |
Chassis Ground | 2 | 4 |
CAN High (J-2284) | 3 | 6 |
ISO 9141-2 K Line | 4 | 7 |
CAN Low (J-2284) | 5 | 14 |
J1850 Bus - | 6 | 10 |
J1850 Bus + | 7 | 2 |
ISO 9141-2 L Line | 8 | 15 |
Battery Power | 9 | 16 |
The OBD-II specification provides for a standardized hardware interface-the female 16-pin (2x8) J1962 connector. Unlike others connectors, which was sometimes found under the hood of the vehicle, the OBD-II connector is required to be within 2 feet (0.61m) of the steering wheel (unless an exemption is applied for by the manufacturer, in which case it is still somewhere within reach of the driver).
This cable allows the user to access the pins on a car's OBD-II connector. It has an OBD-II connector on one end and a DB9 male serial connector on the other.
Arduino / Intel Galileo
/* * CAN Bus Module * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David Gascón * Implementation: Ahmad Saad & Luis Antonio */ // Include always these libraries before using the CAN BUS functions #include <CAN.h> #include <SPI.h> // Create an instance CAN myCAN = CAN(); void setup() { // Inits the UART Serial.begin(115200); delay(100); // Print init message Serial.println("Initializing CANBUS..."); // Configuring the BUS at 500 Kbit/s myCAN.begin(500); Serial.println("CANBUS initialized at 500 KBits/s"); } void loop() { // Read the value of RPM if the engine long engineRpm = myCAN.getEngineRPM(); // Print received data in the serial monitor Serial.print("RPM of engine : "); Serial.println(engineRpm); delay(1000); }
Raspberry Pi
/* * CAN Bus Module * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David Gascón * Implementation: Ahmad Saad & Luis MartÃn */ // Include always these libraries before using the CAN BUS functions #include "CAN.h" #include "arduPi.h" // Create an instance CAN myCAN = CAN(); void setup() { // Inits the UART Serial.begin(115200); delay(100); // Print init message printf("Initializing CANBUS...\n"); // Configuring the BUS at 500 Kbit/s myCAN.begin(500); printf("CANBUS initialized at 500 KBits/s\n"); } void loop() { // Read the value of RPM if the engine int engineRpm = myCAN.getEngineRPM(); // Print received data in the serial monitor printf("RPM of engine : %d",engineRpm); printf("\n"); delay(1000); } int main (){ setup(); while(1){ loop(); } return (0); }
You should receive the data in your serial monitor.
The Multiprotocol Radio Shield can be used to connect two communication protocols at the same time and make interconnections between different systems and devices. In the next example we are going to interconnect a CAN Bus module with wireless protocol using and XBee module.
NOTE:
Connect the CAN Bus module and XBee modules in the corresponding sockets as shown in the next image:
If you are using 802.15.4, use external pin with pin4 disconnected.
You should receive all data in your gateway device
/* * CAN Bus Module * * Copyright (C) Libelium Comunicaciones Distribuidas S.L. * http://www.libelium.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * a * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Version: 1.0 * Design: David Gascón * Implementation: Ahmad Saad & Luis MartÃn */ // Include always these libraries before using the CAN BUS functions #include <CAN.h> #include <SPI.h> // Create an instance CAN myCAN = CAN(); void setup() { // Inits the UART Serial.begin(9600); delay(100); pinMode(5, OUTPUT); digitalWrite(5, HIGH); // Print init message Serial.println("Initializing CANBUS..."); // Configuring the BUS at 500 Kbit/s myCAN.begin(500); Serial.println("CANBUS initialized at 500 KBits/s"); } void loop() { // Read the value of RPM if the engine long engineRpm = myCAN.getEngineRPM(); // Print received data in the serial monitor Serial.print("RPM of engine : "); Serial.println(engineRpm); delay(1000); }
If you are interested in Internet of Things (IoT) or M2M projects check our open source sensor platform Waspmote which counts with more than 100 sensors available to use 'off the shelf', a complete API with hundreds of ready to use codes and a low consumption mode of just 0.7µA to ensure years of battery life.
Know more at:
Get the Starter Kits at: