Can-Bus

Hello my friends :slight_smile: i try to conect the sparkfun canbus shield with arduino uno to read valeu from my car but i can't, i try lot off codes but nothning i talk with sparkfun and tell me maybe is not work because protocols is for US car not for EUROPE cars and dont know how to right a code for conect protocol with my car. anyone has code for protocols and how to bild this protocol?

sodomistis:
Hello my friends :slight_smile: i try to conect the sparkfun canbus shield with arduino uno to read valeu from my car but i can't, i try lot off codes but nothning i talk with sparkfun and tell me maybe is not work because protocols is for US car not for EUROPE cars and dont know how to right a code for conect protocol with my car. anyone has code for protocols and how to bild this protocol?

this is say how to work can bus not how to bild comunicator i need how to bild for arduino with shield

Sorry,

but you gave much to less information to help you.

How did you connect the CAN?
What Baud rate did you used?
Did you use a resistor at the end of the bus?
Which CAN in the car you want to look at?

Sure all the brands are using different CAN catalogs but the raw data should be readable in any case. The secret thing is what is the purpose of the bits in a CAN message.

Succubus

Succubus:
Sorry,

but you gave much to less information to help you.

How did you connect the CAN?
What Baud rate did you used?
Did you use a resistor at the end of the bus?
Which CAN in the car you want to look at?

Sure all the brands are using different CAN catalogs but the raw data should be readable in any case. The secret thing is what is the purpose of the bits in a CAN message.

Succubus

i fink the more information is not useful because if protocol with canbus is not right the athores information is not matter.
but i tell you the connect with can is with DB9 cable obd from spark fun canbus shield with this.
https://learn.sparkfun.com/tutorials/can-bus-shield-hookup-guide
i dont use resistro at canbus. the car i want to look is Opel Corsa D i post the exaple code at next post

#include <Canbus.h>
char UserInput;
int data;
char buffer[456];  //Data will be temporarily stored to this buffer before being written to the file

//********************************Setup Loop*********************************//

void setup(){
Serial.begin(9600);
Serial.println("CAN-Bus Demo");

if(Canbus.init(CANSPEED_500))  /* Initialise MCP2515 CAN controller at the specified speed */
  {
    Serial.println("CAN Init ok");
  } else
  {
    Serial.println("Can't init CAN");
  } 
   
  delay(1000); 

Serial.println("Please choose a menu option.");
Serial.println("1.Speed");
Serial.println("2.RPM");
Serial.println("3.Throttle");
Serial.println("4.Coolant Temperature");
Serial.println("5.O2 Voltage");
Serial.println("6.MAF Sensor");

}



//********************************Main Loop*********************************//

void loop(){

while(Serial.available()){
   UserInput = Serial.read();

if (UserInput=='1'){
 Canbus.ecu_req(VEHICLE_SPEED, buffer);
 Serial.print("Vehicle Speed: ");
 Serial.println(buffer);
 delay(500);
}
else if (UserInput=='2'){
 Canbus.ecu_req(ENGINE_RPM, buffer);
 Serial.print("Engine RPM: ");
 Serial.println(buffer);
 delay(500);

}
else if (UserInput=='3'){
 Canbus.ecu_req(THROTTLE, buffer);
 Serial.print("Throttle: ");
 Serial.println(buffer);
 delay(500);

}
else if (UserInput=='4'){
 Canbus.ecu_req(ENGINE_COOLANT_TEMP, buffer);
 Serial.print("Engine Coolant Temp: ");
 Serial.println(buffer);
 delay(500);

}
else if (UserInput=='5'){
 Canbus.ecu_req(O2_VOLTAGE, buffer);
 Serial.print("O2 Voltage: ");
 Serial.println(buffer);
 delay(500);

}
else if (UserInput=='6'){
 Canbus.ecu_req(MAF_SENSOR, buffer);
 Serial.print("MAF Sensor: ");
 Serial.println(buffer);
 delay(500);

}
else
{
  Serial.println(UserInput);
  Serial.println("Not a valid input.");
  Serial.println("Please enter a valid option.");
}

}
}

i read this and they say about 5 protocols, my car has iso9141 how to programa for this protocol?
https://learn.sparkfun.com/tutorials/getting-started-with-obd-ii?_ga=1.65582893.2095413520.1466463485

But you have an Opel, than it could also be this protocol

SAE J1850 VPW (This protocol is Variable Pulse Width, which runs at 10.4 kbps. GM vehicles typically use this version.)

But if you check this table it should be CAN

Check that you are using the right pins and 500kbps and standard identifier

What can you see in the serial monitor did the init succeed?

if i connect the canbus n serial mode is ok with unit and i see that.

i try second time with new settings at the fille defaults.h and i see the pins not match i chanse and work BUT only the RPM with this example code

#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <Canbus.h>
#include <TinyGPS.h>

//Initialize uSD pins
const int chipSelect = 9;


//Initialize lcd pins
SoftwareSerial lcd(3, 6);

//Initialize GPS pins
SoftwareSerial uart_gps(4,5);

// Define Joystick connection pins 
#define UP     A1
#define DOWN   A3
#define LEFT   A2
#define RIGHT  A5
#define CLICK  A4

//Define LED pins
#define LED2 8
#define LED3 7

//Define baud rates. GPS should be slower than serial to ensure valid sentences coming through
#define GPSRATE 4800
#define LCD_Rate 115200

//Create instance of TinyGPS
TinyGPS gps;

//Declare prototype for TinyGPS library functions
void getgps(TinyGPS &gps);

//Declare GPS variables
float latitude;
float longitude;
int year;
byte month;
byte day;
byte hour;
byte minute;
byte second;
byte hundredths;
float gps_speed;


//Declare SD File
File dataFile;

//Declare CAN variables for communication
char *EngineRPM;
char buffer[64];  //Data will be temporarily stored to this buffer before being written to the file

//Define LCD Positions
#define COMMAND 0xFE
#define CLEAR   0x01
#define LINE1  0x80
#define LINE2  0xC0


//********************************Setup Loop*********************************//
void setup() {
  //Initialize Serial communication for debugging
  Serial.begin(9600);
  Serial.println("ECU Demo");
  
  //Begin LCD serial communication
  lcd.begin(9600);
  
  //Begin GPS communcation
  uart_gps.begin(GPSRATE);
  
  //Initialize pins as necessary
  pinMode(chipSelect, OUTPUT);
  pinMode(CLICK,INPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  
  //Pull analog pins high to enable reading of joystick movements
  digitalWrite(CLICK, HIGH);
  
  //Write LED pins low to turn them off by default
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  
  //Initialize CAN Controller 
  if(Canbus.init(CANSPEED_500))  /* Initialize MCP2515 CAN controller at the specified speed */
  {
    clear_lcd();
    lcd.print("CAN Init ok");
    Serial.println("CAN Init Ok");
    delay(1500);
  } 
  else
  {
    lcd.print("Can't init CAN");
    Serial.println("Can't init CAN");
    return;
  } 

   //Check if uSD card initialized
  if (!SD.begin(chipSelect)) {
    Serial.println("uSD card failed to initialize, or is not present");
    clear_lcd();
    lcd.print("uSD failed.");
    return;
  }
  else{
      Serial.println("uSD card initialized.");
      clear_lcd();
      lcd.print("uSD success!");
      delay(1500);
  } 

  //Print menu to LCD screen
  clear_lcd();
  lcd.print("Click to begin");
  lcd.write(COMMAND);
  lcd.write(LINE2);
  lcd.print("Logging Data");
 
  while(digitalRead(CLICK)==HIGH)
  {
     //Wait for user to click joystick to begin logging
  }

  delay(1000); 

}

//********************************Main Loop*********************************//
void loop(){

  while(digitalRead(CLICK)==HIGH){
    
      digitalWrite(LED3, HIGH); //Turn on LED to indicate CAN Bus traffic
      
      Canbus.ecu_req(ENGINE_RPM,buffer); //Request engine RPM
	  EngineRPM = buffer;
	  Serial.print("Engine RPM: "); //Uncomment for Serial debugging
      Serial.println(buffer);
      delay(100);
	 
	  
      digitalWrite(LED3, LOW); //Turn off LED3
      delay(500);
      
    File  dataFile = SD.open("data.txt", FILE_WRITE); //Open uSD file to log data
      
      //If data file can't be opened, throw error.
      if (!dataFile){
          clear_lcd();
        lcd.print("Error opening");
        lcd.write(COMMAND);
        lcd.write(LINE2);
        lcd.print("data.txt");
        while(1);
        }
        
        clear_lcd();
        lcd.print("Logging.Click");
        lcd.write(COMMAND);
        lcd.write(LINE2);
        lcd.print("to stop logging");
        
        if(uart_gps.available())     // While there is data on the RX pin...
           {
             digitalWrite(LED2, HIGH); //Signal on D8 that GPS data received.
			 
			 //Print Latitude/Longitude to SD card
             dataFile.print("Lat/Long: "); 
			 dataFile.print(latitude,5); 
			 dataFile.print(", "); 
			 dataFile.println(longitude,5);
			 
			  // Print data and time to SD card
			 dataFile.print("Date: "); dataFile.print(month, DEC); dataFile.print("/"); 
			 dataFile.print(day, DEC); dataFile.print("/"); dataFile.print(year);
			 dataFile.print("  Time: "); dataFile.print(hour, DEC); dataFile.print(":"); 
			 dataFile.print(minute, DEC); dataFile.print(":"); dataFile.print(second, DEC); 
			 dataFile.print("."); dataFile.println(hundredths, DEC);
			 
			  //Print GPS speed to SD card
			  dataFile.print("GPS Speed(kmph): ");
			  dataFile.println(gps_speed);
			  
             digitalWrite(LED2, LOW); //Turn off D8 LED. 
           }
        
        dataFile.print("Engine RPM: "); 
        dataFile.println(EngineRPM);
        
        dataFile.println();
        dataFile.flush();
        dataFile.close();   //Close data logging file
      }
  clear_lcd();
  lcd.print("Logging stopped.");
  while(1); //Stop logging if joystick is clicked
  
}

//********************************LCD Functions*********************************//
void clear_lcd(void)
{
  lcd.write(COMMAND);
  lcd.write(CLEAR);
} 

//********************************GPS Functions*********************************//
void getgps(TinyGPS &gps)
{
  // Receive GPS latitude/longitude
  gps.f_get_position(&latitude, &longitude);
 
  //Call function to receive date and time from GPS
  gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
 
  //Also collect gps_speed
  gps_speed = gps.f_speed_kmph();

}

after 20-30 sec read and show rpm but with ''lag'' and 1-2 times stuck, because i dont want code like up example i fix one to see if work but nothnig.
Why has to many lag to read and show the rpm? at serial monitor.
my Sketch is this i fink is right but dont work :frowning:

#include <TFT.h>  
#include <SPI.h>
#include <Canbus.h>
char UserInput;
int data;
char buffer[456];


#define cs   3
#define dc   5
#define rst  6

TFT TFTscreen = TFT(cs, dc, rst);
char sensorPrintout[4];

void setup() {

  
  TFTscreen.begin();  
  TFTscreen.background(0, 0, 0); 
  TFTscreen.stroke(255, 255, 255);  
  TFTscreen.setTextSize(2); 
  TFTscreen.text("Can-Bus Demo", 0, 0); 
  TFTscreen.setTextSize(2);
  
  if(Canbus.init(CANSPEED_500))
  {
    TFTscreen.text("CAN Init ok", 0, 20);     
  } else
  {
    TFTscreen.text("Fail init CAN", 0, 20);    
  }
  delay(5000);  
  
  TFTscreen.background(0, 0, 0); 
  TFTscreen.text("Engine PRM: ", 0, 0);
  
  }

void loop() { 

   
  TFTscreen.stroke(255, 255, 255); 
  TFTscreen.setTextSize(2);
  Canbus.ecu_req(ENGINE_RPM, buffer);
  TFTscreen.text(buffer, 0, 20);
  
}

the chanses at the defaults.h is this.

#ifndef	DEFAULTS_H
#define	DEFAULTS_H

#define    P_MOSI            B,3 // pin 11
#define    P_MISO            B,4 // pin 12
#define    P_SCK             B,5 // pin 13
#define    MCP2515_CS        B,2 // pin 10
#define    MCP2515_INT       D,2 // pin 2
#define    LED2_HIGH         B,0 // pin 8
#define    LED2_LOW          B,0 // pin 8
#endif	// DEFAULTS_H

i dont understen what is the B,3 B,4 ........ and why the MCP2515_INT has D,2???
the right pins is at the arduino

Hello,

sorry I didn't really understand what your current problem is,

  • nothing is working
  • you got only the RPM value
  • you only got the RPM value sporadic?

sodomistis:
the chanses at the defaults.h is this.

#ifndef DEFAULTS_H

#define DEFAULTS_H

#define    P_MOSI            B,3 // pin 11
#define    P_MISO            B,4 // pin 12
#define    P_SCK             B,5 // pin 13
#define    MCP2515_CS        B,2 // pin 10
#define    MCP2515_INT       D,2 // pin 2
#define    LED2_HIGH         B,0 // pin 8
#define    LED2_LOW          B,0 // pin 8
#endif // DEFAULTS_H




i dont understen what is the B,3 B,4 ........ and why the MCP2515_INT has D,2???
the right pins is at the arduino

D,2 is the port D and bit 2 of your processor where the int line of the MCP2515 is connected to on the Arduino connector it should be the connection pin with the "2" next to it ;-).
This is with an UNO the 3rd pin from the top of the upper left connector if the USB and power connector faces to you.

first of all i want to show some value Boost presure, water temp, rpm, O2 sensor, from exmple codes has the libries of shield canbus only 1 of 2 work but show the value are to slow and at start i wait 20-30 sec to show the value and has to many lag to see. why has so many lag?
i try to fix new one code but nothing the code is the previous post if you want to see how to fix the code and if is right.
i try to put new one libraries this

but nothing againe i fink this libraries want to modify for my canbus but i dont know how to because has inside the PID of boost and more value want to use.
How to fix a code to read the value with no lag?? what i do wrong?

first of all sorry about my english i fink is horrible!!!! After a few chanses at the code and the defaults.h at serial i wait 2-3 min (the programm is running for this 2-3 min) and show me the rpm BUT after 30sec go to 0 or show me 0 g/s and i dont know what value is this :frowning: some times after againe from 2-3 min i see this.

where can be the problem?? :angry: the last value 315 rpm is the time i turn off the car and then 0 the car is off

hello againe in fille canbus.h i found this

/**
 * CAN BUS
 *
 * Copyright (c) 2010 Sukkin Pang All rights reserved.
 */

#ifndef canbus__h
#define canbus__h

#define CANSPEED_125 	7		// CAN speed at 125 kbps
#define CANSPEED_250  	3		// CAN speed at 250 kbps
#define CANSPEED_500	1		// CAN speed at 500 kbps


#define ENGINE_COOLANT_TEMP 0x05
#define ENGINE_RPM          0x0C
#define VEHICLE_SPEED       0x0D
#define MAF_SENSOR          0x10
#define O2_VOLTAGE          0x14
#define THROTTLE			0x11

#define PID_REQUEST         0x7DF
#define PID_REPLY			0x7E8

class CanbusClass
{
  public:

	CanbusClass();
    char init(unsigned char);
	char message_tx(void);
	char message_rx(unsigned char *buffer);
	char ecu_req(unsigned char pid,  char *buffer);
private:
	
};
extern CanbusClass Canbus;
//extern tCAN message;

#endif

this is the PID and you call to see the valeu?? for example if i want to see rpm when I write Canbus.ecu_req(ENGINE_RPM, buffer); i see the rpm from my car and i wrote Canbus.ecu_req(MAF_SENSOR, buffer); i see the maf sensor??

hello againe after more modife to code i try this code to read mesase from here

the code is this

#include <Canbus.h>  // don't forget to include these
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>

void setup()
{
Serial.begin(9600);
//Initialise MCP2515 CAN controller at the specified speed
if(Canbus.init(CANSPEED_500))
 Serial.println("CAN Init ok");
else
 Serial.println("Can't Init CAN");

delay(1000);
}

void loop()
{ 
tCAN message;

if (mcp2515_check_message()) 
 {
    if (mcp2515_get_message(&message)) 
 {
               Serial.print("ID: ");
               Serial.print(message.id,HEX);
               Serial.print(", ");
               Serial.print("Data: ");
               for(int i=0;i<message.header.length;i++)
                {
                  Serial.print(message.data[i],HEX);
                  Serial.print(" ");
                }
               Serial.println("");
             }}
}

because i never see message to serial i try this to see if the shield work well and i see this

and i want to ask this, is this right message to see from obd at serial?
and if is right why when i upload this code i dont see the rpm??

#include <Canbus.h>
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>


void setup()
{
Serial.begin(9600);

if(Canbus.init(CANSPEED_500))
  Serial.println("CAN Init ok");
else
  Serial.println("Can't Init CAN");

delay(1000);
}

void loop(){
 int value;
  Canbus.ecu_req(ENGINE_RPM, value);
  Serial.print(value);
  delay(1000);

}

OBD has two modes when used over CAN, 11bit and 29bit and while I am not familiar with the Arduino OBD library, I am familiar with the fact my vehicle will not work with 11bit mode and required 29bit mode on the scan tool I was using. You would need to determine what modes the library supports and if only one mode is supported, that is likely why you are not getting any values returned and the library would need updated.

Hi Guys,

Its a little urgent. Please help.

I have a arduino mkr can bus shield mounted on arduino mkrzero board. I have a can bus device that connects to the can bus shield. I can to read the data received from that CAN device on the arduino IDE serial monitor. How can I read the data recieved. Should I use SPI from mkr zero or some others pins to monitor this data?

Can some one please share the code to read this data somehow?

I have the picture of the assemble attached.

Thanks,

Picture of the assembly

I was trying to use this code but the can bus shield always fails to initialize.

// demo: CAN-BUS Shield, receive data with check mode
// send data coming to fast, such as less than 10ms, you can use this way
// loovee, 2014-6-13

#include <SPI.h>
#include "mcp_can.h"

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 3;

MCP_CAN CAN(SPI_CS_PIN); // Set CS pin

void setup()
{
Serial.begin(115200);

while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
{
Serial.println("CAN BUS Shield init fail");
Serial.println(" Init CAN BUS Shield again");
Serial.println("check");
delay(100);
}
Serial.println("CAN BUS Shield init ok!");
}

void loop()
{
unsigned char len = 0;
unsigned char buf[8];

if(CAN_MSGAVAIL == CAN.checkReceive()) // check if data coming
{
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf

unsigned int canId = CAN.getCanId();

Serial.println("-----------------------------");
Serial.print("Get data from ID: ");
Serial.println(canId, HEX);

for(int i = 0; i<len; i++) // print the data
{
Serial.print(buf*, HEX);*

  • Serial.print("\t");*
  • }*
  • Serial.println();*
  • }*
    }
    /*********************************************************************************************************
  • END FILE*
    *********************************************************************************************************/

Hi the code you have looks very similar to mine, so I don't think it's code. I found that I got the failed to initialise if there was no power on the board, although I have to say this is clutching at straws as your picture shows what looks like good connections.