Ducati.ms - The Ultimate Ducati Forum banner

21 - 40 of 45 Posts

·
Premium Member
Joined
·
661 Posts
Below is a tiny example of some raw CAN data.

-----CAN Data example------

The 'Time' field is simply seconds since the start of that particular extract and as you can see there are hundreds of messages per second (approx 300 in this example).
The fields we are interested in are the ARBID and the B0 to B7 columns. The length (len) always seems to be 8 and the Extended indicator (Ext) always seems to be 0 so ignore them.
The data in the columns B0-B7 is in HEX (which excel can easily converts to decimal). HEX is base 16 as opposed to decimals base 10.

Now for a specific example. Engine Temperature appears to be on ARBID 100 column B3, e.g the value 2A at 0.026 seconds. 2A is HEX and converts to 42 in Decimal. It peaked at 142 (dec). I know It was 2 degrees when I started and had reached 84 degrees when it stopped so you can easily work out that you just need to subtract 40 to get to actual temp in degrees c. ARBID 100 seems to transmit about 7 times per second resulting in a the log below for the engine warming up on idle for a few minutes.

-----Engine temp example------

All i've been doing is changing one variable at a time and then searching for it in the data, e.g. indicator flashes starting 5 seconds into the log and lasting for say 5 flashes. If I know what I am looking for it is not too hard to find a corresponding change in the data.

It gets a bit more difficult when multiple things change at the same time. For example, rev the engine and there may be 5 or more columns of data that all change in some way (may be more) at about the right time in the right way.
In the case of revving the engine there are various sensors that you'd expect to respond, e.g. twist grip position, throttle position sensor, engine revs themselves, possible a lambda signal etc. The multi doubles up on most of the 'ride by wire' sensors (I assume for safety reasons), e.g. APS, TPS etc and I think I can see the pair in the data.

To complicate things further a single variable might be split across two columns (or parts of columns). Rear wheel speed is a good example of something that appears to be split across colmuns, ARBID 18, B5, and the 2nd value from B4 (combined as HEX value and then converted to decimal) seems to be rear wheel speed. You then multiple the decimal result by 0.15 to convert to (true) MPH (indicated is +8% according to the manual).
The 1st value from B4 appears to be the gear position indicator so I'm 99% sure I've got this right.

Logic would suggest that you can start to predict what variables are going to be split across columns as the max resolution of 1 column is 16 x 16 = 256. Any sensor needing an output that will have more than 256 incriments must be split across multiple columns.
I can only assume Wheel speed needs it for the ABS and DTC as it clearly doesn't need it for the dash display. Engine revs are split but use all 4 values from a pair of colums.

--------------- SPEED AND GEAR INDICATOR ---------------------

The data sets get very big (in terms of rows as opposed to MB) very quickly, but the newer versions of excel (2007 onwards) are quite good at working with big data sets. Simply filter the data to a single ARBID value, plot as an XY Scatter chart and look for what you are expecting, e.g. the rise and fall of revs or the on/off flash of an indicator.

I got started as much through curiosity as anything but do seem to have become somewhat obsessed with decoding all of the 'normal' CAN traffic. No idea what I'll do with it other than write a program to log the bit I understand in 'english' instead of raw CAN data.
Have you considered just riding the bike?
 

·
Registered
Joined
·
53 Posts
Discussion Starter #23
Found some additional info at daniduke.bplaced.net:

Ducati 1098
CAN ID 080 ; byte 1 & 2 Velocity ; mapped to Analogue 3
CAN ID 080 ; byte 3 & 4 Speed ; mapped to RPM
CAN ID 080 ; byte 5 Throttle position ; mapped to Analogue 1
CAN ID 020 ; byte 1 Engine temperature ; mapped to Analogue 4
CAN ID 300 ; byte 3 & 4 Mileage ; mapped to Analogue 2

I think I know 1098 and 1198 are compatible, but it seems this might be different for the Multistrada.
They don't match for the MTS1200, but at least it provides another thing to look for, e.g. mileage on ID300. Thanks
 

·
Registered
Joined
·
53 Posts
Discussion Starter #24
After a bit of messing around I'm now able to send the data over Bluetooth to an android app that then displays it live on the phone's screen. All I've really done at the moment is send all of the suspension settings 1-32 clicks for front and rear comp and rebound and rear preload). Completely new to android (programming anything actually), just modified another bit of open source code that I found on the web. No real use for any of this, just tinkering.

Found mileage, it was in a different place. Also found fuel level. The fuel level is much higher resolution than the fuel gauge on the dash.

Oh, and I have managed to find time to ride now that it has stopped raining/snowing in the UK (it is *ing cold mind).


Sent from Motorcycle.com Free App
 

·
Registered
Joined
·
10 Posts
Well I am sure am glad to have found this thread !

I have been working along much the same lines for a month now and have recently got my logger recording msgs from the Panigale's CAN bus.
It's pretty fast and furious there clocking in at about 750 Msg/s second! So it took a few optimizations to move from the 20mps which I was developing with to 750mps! I used an Luminary evaluation kit from Texas Instruments which I had knocking around as my platform as it had most of the bits which made it useful: integrated programming/USB serial port, LCD, SD card, CAN bus, some buttons etc. I made up a cable which powers the unit and connects to CAN via the diagnostic connector (FCI connector on the 1199, same on MTS ? Diavel ?)
I can now log all the CAN msgs to the SD card. A 2G card should be good for 40+Hrs if my math is right. :think:



So I am now a bit behind you guys who have figured out what some of the MsgIDs are but I am keen to join the party. I'll have a look at the spreadsheet previously mentioned and see if any Msgs line up with the 1199, then I'll start adding my discoveries.
One thing that I was curious about is whether any CAN higher level protocol is used such as J1939 which although was designed for trucks is used in many cars.

I found a neat hex viewer which you can teach about protocols which I am using to view my data at present and was going to write some python stuff for visualizing the data but I hadn't thought about using something as simple as excel!
 

·
Registered
Joined
·
53 Posts
Discussion Starter #26
Not sure I added the most recent decodeb to the google docs version as there didnt seem to be much interest. Haven't touched it for a few months now but will dig it out and upload.

Sent from Motorcycle.com Free App
 

·
Registered
Joined
·
53 Posts
Discussion Starter #27
I've updated the spreadsheet on google docs. There's a tab called Matrix. It is still missing some of the detail, especially the suspension settings which I will need to extract from my Arduino code.
 

·
Registered
Joined
·
805 Posts
Ive been having a fiddle in this area too but only using the ELM327 which gest swamped too easily...

Even so ... I've found PID300 seems to hold the CLOCK setting (hours and minutes)
eg:
300 A5 06 04 68 25 F7 71 00

68 seems to be DecToHEX(Dash Minutes * 2)
7 seems to be the HOUR

also PID's 310 and 320 appear to hold the startup message you see in the round window when you turn the bike on....
 

·
Registered
Joined
·
805 Posts
Another one I've noted (using the s/sheet notaion) is :
210 B7(2) goes from '0' to '1' when the round dash windows displays the 'ERRORS' message.
 

·
Registered
Joined
·
3 Posts
CAN-Bus sniffing with arduino uno + CAN-BUS Shield

Below is a tiny example of some raw CAN data.

-----CAN Data example------

The 'Time' field is simply seconds since the start of that particular extract and as you can see there are hundreds of messages per second (approx 300 in this example).
The fields we are interested in are the ARBID and the B0 to B7 columns. The length (len) always seems to be 8 and the Extended indicator (Ext) always seems to be 0 so ignore them.
The data in the columns B0-B7 is in HEX (which excel can easily converts to decimal). HEX is base 16 as opposed to decimals base 10.

Now for a specific example. Engine Temperature appears to be on ARBID 100 column B3, e.g the value 2A at 0.026 seconds. 2A is HEX and converts to 42 in Decimal. It peaked at 142 (dec). I know It was 2 degrees when I started and had reached 84 degrees when it stopped so you can easily work out that you just need to subtract 40 to get to actual temp in degrees c. ARBID 100 seems to transmit about 7 times per second resulting in a the log below for the engine warming up on idle for a few minutes.

-----Engine temp example------

All i've been doing is changing one variable at a time and then searching for it in the data, e.g. indicator flashes starting 5 seconds into the log and lasting for say 5 flashes. If I know what I am looking for it is not too hard to find a corresponding change in the data.

It gets a bit more difficult when multiple things change at the same time. For example, rev the engine and there may be 5 or more columns of data that all change in some way (may be more) at about the right time in the right way.
In the case of revving the engine there are various sensors that you'd expect to respond, e.g. twist grip position, throttle position sensor, engine revs themselves, possible a lambda signal etc. The multi doubles up on most of the 'ride by wire' sensors (I assume for safety reasons), e.g. APS, TPS etc and I think I can see the pair in the data.

To complicate things further a single variable might be split across two columns (or parts of columns). Rear wheel speed is a good example of something that appears to be split across colmuns, ARBID 18, B5, and the 2nd value from B4 (combined as HEX value and then converted to decimal) seems to be rear wheel speed. You then multiple the decimal result by 0.15 to convert to (true) MPH (indicated is +8% according to the manual).
The 1st value from B4 appears to be the gear position indicator so I'm 99% sure I've got this right.

Logic would suggest that you can start to predict what variables are going to be split across columns as the max resolution of 1 column is 16 x 16 = 256. Any sensor needing an output that will have more than 256 incriments must be split across multiple columns.
I can only assume Wheel speed needs it for the ABS and DTC as it clearly doesn't need it for the dash display. Engine revs are split but use all 4 values from a pair of colums.

--------------- SPEED AND GEAR INDICATOR ---------------------

The data sets get very big (in terms of rows as opposed to MB) very quickly, but the newer versions of excel (2007 onwards) are quite good at working with big data sets. Simply filter the data to a single ARBID value, plot as an XY Scatter chart and look for what you are expecting, e.g. the rise and fall of revs or the on/off flash of an indicator.

I got started as much through curiosity as anything but do seem to have become somewhat obsessed with decoding all of the 'normal' CAN traffic. No idea what I'll do with it other than write a program to log the bit I understand in 'english' instead of raw CAN data.

Hi volks

congratulations for your great work MrCanBus !!
I would like to participate and help to find out more.
I have bought an arduino UND board + CAN-BUS Shield from Sparkfun
and I try to get it up and running.
I always get an error message when initializing the CAN-BUS Shield.
Do you have any idea or suggestions how to solve this ?
perhaps you can provide me your sketch ?

the exception is raised in this code-block:

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


My Sketch looks like this:
// START =======================
#include <Canbus.h>
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>

#define ID18 0x12
#define ID20 0x14
#define ID100 0x64

//CANSPEED_125 //CAN speed at 125 kbps
//CANSPEED_250 //CAN speed at 250 kbps
//CANSPEED_500 //CAN speed at 500 kbps

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 (message.id == ID18 || message.id == ID20 || message.id == ID100) { //filtering based on CAN bus message ID : DEC 18,20,100
if (mcp2515_get_message(&message)) {
Serial.print(message.id,HEX);
Serial.print("\t");
for(int i=0;i<message.header.length;i++){
Serial.print(message.data,HEX);
Serial.print("\t");
}
Serial.println("");
}
// }
}
}

// END =======================

Would be great if you can help me !!

Thanks
DucJoe
 

·
Registered
Joined
·
53 Posts
Discussion Starter #33
Apologies but this is going to be a bit messy. Half the code in here can be deleted as it isn't used. There are filters defined that aren't used etc etc. I've switched to Teensy 3.1 and haven't touched the Arduino code for a while. I'm going to try and post the sketch and the library so you can be 100% sure you are using code that is known to work. The joystick on the Sparkfun shield is used to start/stop the logging and also to insert an event marker into the file (helpful for identifying the change in data)

The sketch (the messy bit)

Code:
#include <SD.h>       /* Library from Adafruit.com */
#include <SoftwareSerial.h>
#include <SPI.h>
#include "mcp2515.h"

/*
V003 Corrected Joystick input and statments (set to high).  Added event marker J/S up
v002 Cleaned up and simplified programming.  
 Added checks for can bus available.  
 No lights setting up.
 D8 Ready but no can bus messages available
 D8, D7 Capturing (press J/S to stop)
 D7 waiting for J/S down to restart */
//v001 added time field
//based on Bus_monitor_FAZd_SD2
//Added SD Card writing
//Compiles in 1.0.1 arduino
// Added in clear the filters and masks from Listener_TWO.
// works on Laguna.  Reports that Laguna is using almost no extended
// #include <CAN.h> can placed below 
//  Works on Laguna but only after filters are changed by running other program -Thaniel

/* This program is a CAN-bus monitor.  It listens on a
 * CAN bus and prints out the IDs and data fields of
 * any CAN messages it hears.  */

#define DEFAULT_CAN_ID  0x0555
// added for filter and can changes
#define MASK_0 0x20
#define MASK_1 0x24
#define FILTER_0 0x00
#define FILTER_1 0x04
#define FILTER_2 0x08
#define FILTER_3 0x10
#define FILTER_4 0x14
#define FILTER_5 0x18

//Pin definitions
#define SCK_PIN   13  //Clock pin
#define MISO_PIN  12  //Mater in Slave output
#define MOSI_PIN  11  //Master out Slave input
#define SS_PIN    10  //SS pin
#define SD_PIN    9  //pin for SD card control
#define RESET_PIN 2
#define INT_PIN 3

//Joystick pin definitions
#define UP     A1
#define RIGHT  A2
#define DOWN   A3
#define CLICK  A4
#define LEFT   A5

#define WRITE 0x02 //read and write comands for SPI


/* Operation Modes */
enum CAN_MODE {
  CAN_MODE_NORMAL, 		/* Transmit and receive as normal */
  CAN_MODE_SLEEP,	        /* Low power mode */
  CAN_MODE_LOOPBACK,		/* Test mode; anything "sent" appears in the receive buffer without external signaling */  							 
  CAN_MODE_LISTEN_ONLY,         /* Receive only; do not transmit */
  CAN_MODE_CONFIG,		/* Default; Allows writing to config registers */
  CAN_MODE_COUNT
};

/* Supported can bus speeds  
 500 Kbps       = MCP2515_SPEED_500000,
 250 Kbps       = MCP2515_SPEED_250000,
 125 Kbps       = MCP2515_SPEED_125000,
 100 Kbps       = MCP2515_SPEED_100000,
 62.5 Kbps      = MCP2515_SPEED_62500,
 50 Kbps        = MCP2515_SPEED_50000,
 31.25 Kbps     = MCP2515_SPEED_31250,
 25 Kbps        = MCP2515_SPEED_25000,
 20 Kbps        = MCP2515_SPEED_20000,
 15.625 Kbps    = MCP2515_SPEED_15625, */

unsigned long time;  //used for time stamp

//CanMessage message;
int led = 8;
int led2 = 7;
byte i;
uint8_t  message;

/** A flag indicating whether this is an extended CAN message */
uint8_t extended;

/** The ID of the CAN message.  The ID is 29 bytes long if the
 * extended flag is set, or 11 bytes long if not set. */
uint32_t id;

/** The number of bytes in the data field (0-8) */
uint8_t len;

/** Array containing the bytes of the CAN message.  This array
 * may be accessed directly to set or read the CAN message.
 * This field can also be set by the setTypeData functions and
 * read by the getTypeData functions. */
uint8_t data[8];
/* Define Joystick connection */


Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

//************************ Setup ****************************
void setup()
{
  //Definitions for SD card

  // store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))

  // set the slaveSelectPin as an output 
  pinMode (SCK_PIN,OUTPUT);
  pinMode (MISO_PIN,INPUT);
  pinMode (MOSI_PIN, OUTPUT);
  pinMode (SS_PIN, OUTPUT);
  pinMode(RESET_PIN,OUTPUT);
  pinMode(INT_PIN,INPUT);
  pinMode(led,OUTPUT); //setup LED
  pinMode(led2,OUTPUT); //setup LED

  digitalWrite(INT_PIN,HIGH);

  //Set up Joystick Pins
  pinMode(UP,INPUT);
  pinMode(DOWN,INPUT);
  pinMode(LEFT,INPUT);
  pinMode(RIGHT,INPUT);
  pinMode(CLICK,INPUT);

  /* Enable internal pull-ups on JS pins */
  digitalWrite(UP, HIGH);       
  digitalWrite(DOWN, HIGH);
  digitalWrite(LEFT, HIGH);
  digitalWrite(RIGHT, HIGH);
  digitalWrite(CLICK, HIGH);

  // initialize CAN bus
  CAN_begin(MCP2515_SPEED_500000);  // set can baud rate
  CAN_setMode (CAN_MODE_LISTEN_ONLY); // set can mode

  Serial.begin(115200);  //set up serial port

  // Print headings on Screen *********************** 
  Serial.println("microSec, len, ARBID, Ext, B0, B1, B2, B3, B4, B5, B6, B7");
  delay(1000);
  Serial.println("Init SD card");  


  //************************* SD CARD SETUP *******************
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  if (!card.init(SPI_FULL_SPEED,SD_PIN)) error("card.init failed");

  // initialize a FAT volume
  if (!volume.init(&card)) error("volume.init failed");

  // open the root directory
  if (!root.openRoot(&volume)) error("openRoot failed");

}

void loop()
{
  if (!CAN_available()) {
    Serial.println("Can bus not available.  Check connections");
    digitalWrite(led,HIGH);  //D8 light means waiting for Can to be connected
  }
  while(!CAN_available()) {
  } //waiting for Canbus to be connected
  Serial.println("Can Bus Connected and available");
  // create a new file
  char name[] = "WRITE00.TXT";
  for (uint8_t i = 0; i < 100; i++) {
    name[5] = i/10 + '0';
    name[6] = i%10 + '0';
    if (file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)) break;
  }
  if (!file.isOpen()) error ("file.create");
  Serial.print("Writing to: ");
  Serial.println(name);
  // write header
  // file.writeError = 0;
  file.print("microSec, len, ARBID, Ext, B0, B1, B2, B3, B4, B5, B6, B7,B0(DEC), B1(DEC), B2(DEC), B3(DEC), B4(DEC), B5(DEC), B6(DEC), B7(DEC)");
  file.println();  

  //**** instructions on how to stop print to screen
  Serial.println("Press J/S click to Stop");  
  //  while (digitalRead(DOWN) == 0);
  //  { Serial.println("waiting");}
  digitalWrite(led,HIGH);  //Turn on 2 lights when capturing
  digitalWrite(led2,HIGH); //Turn on 2 lights when capturing

  CAN_Capture();

}//end loop

void CAN_Capture (){

  while(1){
    if (CAN_available()) {  //is a message recieved
      time = micros();  //capture time when message was recieved
      CAN_getMessage (); //subroutine for extracting message from buffer

      //send messages to the SD card
      file.print (time);
      file.print (",");

      file.print (len, HEX);
      file.print (",");

      file.print (id, HEX);
      file.print (",");

      file.print (extended, HEX);

      for (i=0; i<len; i++) {
        file.print (';');
        file.print (data[i], HEX);
      }
      
      for (i=0; i<len; i++) {
        file.print (';');
        file.print (data[i], DEC);
      }

      //check if it should stop
      if(digitalRead(CLICK) == 0){
        file.close();
        Serial.println("File closed, Data saved");
        digitalWrite(led,LOW);
        digitalWrite(led2,LOW);
        while(1){ //loop waiting for down
          digitalWrite(led2,HIGH); //D7 when ready to restart
          if(digitalRead(DOWN) == 0) {//wait for down to be pressed
            return;
          } //END IF down pressed
        }//end while after capture finishes
      }// end if click
      if(digitalRead(UP) == 0){ // mark event
        file.print(";Event");
      }//end if up 
    }//end if can avail
    file.println ("");  //end line for next reading
  }//end main while loop
}//end void

//*********************** Can cpp  ***************************************
/*
 * Copyright (c) 2010-2011 by Kevin Smith <[email protected]>
 * MCP2515 CAN library for arduino. */

void CAN_CanMessage ()
{
  extended = 0;
  id = DEFAULT_CAN_ID;
  len = 0;
}
// **************************** setByteData *******************
void CAN_setByteData (byte b)
{
  len = 1;
  data[0] = b;
}

//*******************  setIntData  ***************************
void setIntData (int i)
{
  len = 2;

  /* Big-endian network byte ordering */
  data[0] = i >> 8;
  data[1] = i & 0xff;
}

//******************* setLongData  ***************************
void CAN_setLongData (long l)
{
  len = 4;

  /* Big-endian network byte ordering */
  data[0] = (l >> 24) & 0xff;
  data[1] = (l >> 16) & 0xff;
  data[2] = (l >>  8) & 0xff;
  data[3] = (l >>  0) & 0xff;
}

//*********************** setData  *****************************
void CAN_setData (const uint8_t *data, uint8_t len)
{
  byte i;

  //  this->len = len;
  len = len;
  for (i=0; i<len; i++) {
    //    this->data[i] = data[i];

  }
}

//*********************** setData  **************************
void CAN_setData (const char *data, uint8_t len)
{
  CAN_setData ((const uint8_t *)data, len);
}

//********************* send  ******************************
void CAN_send ()
{
  mcp2515_set_msg (0, id, data, len, extended);
  mcp2515_request_tx (0);
}

//****************** getByteFromData **********************

byte CAN_getByteFromData()
{
  return data[0];
}

//**************** getIntFromData ************************
int CAN_getIntFromData ()
{
  int val;

  val |= (uint16_t)data[0] << 8;
  val |= (uint16_t)data[1] << 0;

  return val;
}

//**************** getLongFromData
long CAN_getLongFromData ()
{
  long val;

  val |= (uint32_t)data[0] << 24;
  val |= (uint32_t)data[1] << 16;
  val |= (uint32_t)data[2] <<  8;
  val |= (uint32_t)data[3] <<  0;

  return val;
}

//********************** getData *******************
void CAN_getData (uint8_t *data)
{
  byte i;

  for (i=0; i<len; i++) {
    //    data[i] = this->data[i];
  }
}

//******************** getData ***********************
void CAN_getData (char *data)
{
  CAN_getData ((uint8_t *)data);
}

/*
 * CANClass
 */

//********************** Begin ***********************
void CAN_begin(uint32_t bit_time) {
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);

  mcp2515_init (bit_time);

  CAN_resetFiltersAndMasks();  
}


//******************************** reset filters and Masks  ****************
// added to set filters -- from another program
void CAN_resetFiltersAndMasks() {
  //disable first buffer
  CAN_setMaskOrFilter(MASK_0,   0b00000000, 0b00000000, 0b00000000, 0b00000000);
  CAN_setMaskOrFilter(FILTER_0, 0b00000000, 0b00000000, 0b00000000, 0b00000000);
  CAN_setMaskOrFilter(FILTER_1, 0b00000000, 0b00000000, 0b00000000, 0b00000000);

  //disable the second buffer
  CAN_setMaskOrFilter(MASK_1,   0b00000000, 0b00000000, 0b00000000, 0b00000000); 
  CAN_setMaskOrFilter(FILTER_2, 0b00000000, 0b00000000, 0b00000000, 0b00000000);
  CAN_setMaskOrFilter(FILTER_3, 0b00000000, 0b00000000, 0b00000000, 0b00000000); 
  CAN_setMaskOrFilter(FILTER_4, 0b00000000, 0b00000000, 0b00000000, 0b00000000);
  CAN_setMaskOrFilter(FILTER_5, 0b00000000, 0b00000000, 0b00000000, 0b00000000); 
}

//***************************** set mask or FIlter **********************
void CAN_setMaskOrFilter(byte mask, byte b0, byte b1, byte b2, byte b3) {
  CAN_setMode(CAN_MODE_CONFIG); 
  CAN_setRegister(mask, b0);
  CAN_setRegister(mask+1, b1);
  CAN_setRegister(mask+2, b2);
  CAN_setRegister(mask+3, b3);
  CAN_setMode(CAN_MODE_LISTEN_ONLY); 
}

//************************** Set register ******************************
void CAN_setRegister(byte reg, byte value) {
  //  mcp2515_write_reg (reg, value); this should be instead to write the registers
  //static void mcp2515_write_reg (uint8_t addr, uint8_t buf)
  // used from other program.  Replaced by above 
  digitalWrite(SS_PIN, LOW);
  delay(10);
  SPI.transfer(WRITE);
  SPI.transfer(reg);
  SPI.transfer(value);
  delay(10);
  digitalWrite(SS_PIN, HIGH);
  delay(10);

}
// end from another program



///*********************** end ***********************
void CAN_end() {
  SPI.end ();
}

//********************* setMode *********************
void CAN_setMode (uint8_t mode)
{
  mcp2515_set_mode (mode);
}

//******************** ready **********************
uint8_t CAN_ready ()
{
  return mcp2515_msg_sent ();
}

//****************** Available *********************
boolean CAN_available ()
{
  return (boolean)mcp2515_msg_received();
}

//***************** getMessage ***********************
void CAN_getMessage ()
{
  uint8_t extended;
  extended = mcp2515_get_msg (0, &id, data, &len);
}
// ************************** SD card Error ************************
void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);

  Serial.print("SD error");

  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);

    Serial.print(',');
    Serial.println(card.errorData(), HEX);

  }
  while(1);
}

//CANClass CAN;

/*
/**
 * A class representing a single CAN message.  The message can be built
 * using the send<Type>Data functions, or the bytes of the message can
 * be set directly by accessing the public data[] array.  This class is
 * also used to retrieve a message that has been received.  The data
 * can be read using the get<type>Data functions, or can be read directly
 * by accessing the public data[] array.
 */
//class CanMessage {
//    public:
/** A flag indicating whether this is an extended CAN message */
//        uint8_t extended;
/** The ID of the CAN message.  The ID is 29 bytes long if the
 * extended flag is set, or 11 bytes long if not set. */
//        uint32_t id;
/** The number of bytes in the data field (0-8) */
//        uint8_t len;
/** Array containing the bytes of the CAN message.  This array
 * may be accessed directly to set or read the CAN message.
 * This field can also be set by the setTypeData functions and
 * read by the getTypeData functions. */
//        uint8_t data[8];

//        CanMessage();

/**
 * Simple interface to set up a CAN message for sending a byte data
 * type.  When received, this message should be unpacked with the
 * getByteData function.  This interface only allows one byte to be
 * packed into a message.  To pack more data, access the data array
 * directly.
 * @param b - The byte to pack into the message.
 */
//        void setByteData (byte b);

/**
 * Simple interface to set up a CAN message for sending an int data
 * type.  When received, this message should be unpacked with the
 * getIntData function.  This interface only allows one int to be
 * packed into a message.  To pack more data, access the data array
 * directly.
 * @param i - The int to pack into the message.
 */
//       void setIntData (int i);

/**
 * Simple interface to set up a CAN message for sending a long data
 * type.  When received, this message should be unpacked with the
 * getLongData function.  This interface only allows one long to be
 * packed into a message.  To pack more data, access the data array
 * directly.
 * @param l - The long to pack into the message.
 */
//        void setLongData (long l);

/**
 * A convenience function for copying multiple bytes of data into
 * the message.
 * @param data - The data to be copied into the message
 * @param len  - The size of the data
 */
//        void setData (const uint8_t *data, uint8_t len);
//        void setData (const char *data, uint8_t len);

/**
 * Send the CAN message.  Once a message has been created, this
 * function sends it.
 */
//        void send();

/**
 * Simple interface to retrieve a byte from a CAN message.  This
 * should only be used on messages that were created using the
 * setByteData function on another node.
 * @return The byte contained in the message.
 */
//        byte getByteFromData ();

/**
 * Simple interface to retrieve an int from a CAN message.  This
 * should only be used on messages that were created using the
 * setIntData function on another node.
 * @return The int contained in the message.
 */
//        int getIntFromData ();

/**
 * Simple interface to retrieve a long from a CAN message.  This
 * should only be used on messages that were created using the
 * setLongData function on another node.
 * @return The long contained in the message.
 */
//        long getLongFromData ();

/**
 * A convenience function for copying multiple bytes out of a
 * CAN message.
 * @param data - The location to copy the data to.
 */
//        void getData (uint8_t *data);
//        void getData (char *data);
//};

//class CANClass {
//	public:
/**
 * Call before using any other CAN functions.
 * @param bit_time - Desired width of a single bit in nanoseconds.
 *                   The CAN_SPEED enumerated values are set to
 *                   the bit widths of some common frequencies.
 */
//		static void begin(uint32_t bit_time);

/** Call when all CAN functions are complete */
//		static void end();

/**
 * Set operational mode.
 * @param mode - One of the CAN_MODE enumerated values */
//		static void setMode(uint8_t mode);

/** Check whether a message may be sent */
//       static uint8_t ready ();

/**
 * Check whether received CAN data is available.
 * @return True if a message is available to be retrieved.
 */
//        static boolean available ();

/**
 * Retrieve a CAN message.
 * @return A CanMessage containing the retrieved message
 */
//        static CanMessage getMessage (); */


An the library

https://drive.google.com/folderview?id=0ByMu4CcT6k6WaWNEa09KcFMyUUU&usp=sharing

save the entire mcp2515 folder into your user libraries folder.
 

·
Registered
Joined
·
3 Posts
Hello MrCanBus


in the meantime I was able to solve my problem.
the source was a loose connection which I had to solder again.
But anyway your code is very helpful.

Thanks a lot !!
 

·
Registered
Joined
·
24 Posts
I can confirm that it is also possible to read your data from the Ducati M696 Y2009.

i've used an Arduino with a Seeed Canbus shield:
Buy CAN-BUS Shield [SLD01105P] | Seeedstudio

you can connect it to your DDA connector under the seat.

thanks to the input from this forum, I got it working. At this point, I only have the RPM's, but soon i will find and add the extra data.

fyi:
CANBUS ID 0x10 broadcasts the RPM's at byte[3] and byte[4], and only if byte[0] = 0.
 

·
Registered
Joined
·
503 Posts
Current PID resources (some active, some dead):

RaceData Lite/CAN for use with RaceChrono
DaniDuke's RaceChrono site with PIDs on 1098/1198/Aprilia RSV4s, currently dead

https://docs.google.com/spreadsheets/d/1mf-PMhBEnSzipRq068lYNCXn7gz7-iCb7yrSUn14Kms/edit?pli=1
gabeschine's Google Docs spreadsheet. A bit messy, but has Multi and Panigale info.

https://docs.google.com/spreadsheets/d/1-NJ9OlGQYTGMzBzwDPYn-aI_7_ign9SCiscKZufx3Uw/edit?pli=1
MrCanBus's official spreadsheet, currently the most up-to-date.
I've also taken the liberty of adding foske's "potentially corrected" data for Monster 696's, although these are unconfimed​

If you need to add data to a spreadsheet, please use MrCanBus's when it is somewhat finalized.

Code bases:

Projects using this data (on this forum):
http://www.ducati.ms/forums/44-multistrada/337705-canbus-data-you-android-device-via-bluetooth-6.html
MrCanBus's own project to visualize Multistrada 1200 data over Bluetooth

http://www.ducati.ms/forums/42-monster/476546-m696-android-dashboard-arduino.html
foske's Android dashboard for Monster 696s

http://www.madcogz.com/Multitool/
wcieslik's service light reset/datalogging app for Multistradas

http://www.ducati.ms/forums/44-multistrada/155657-canbus-logging-decoding-4.html
This thread about development (maybe should be in the Tech forum?)​

My personal projects are unlinked since they are low-level development work, or are with multiple people.
When I can get ChrisK to pry himself away from that mold I'll post code for a robust MCP2515 library.
 

·
Registered
Joined
·
3 Posts
Well I am sure am glad to have found this thread !



I have been working along much the same lines for a month now and have recently got my logger recording msgs from the Panigale's CAN bus.

It's pretty fast and furious there clocking in at about 750 Msg/s second! So it took a few optimizations to move from the 20mps which I was developing with to 750mps! I used an Luminary evaluation kit from Texas Instruments which I had knocking around as my platform as it had most of the bits which made it useful: integrated programming/USB serial port, LCD, SD card, CAN bus, some buttons etc. I made up a cable which powers the unit and connects to CAN via the diagnostic connector (FCI connector on the 1199, same on MTS ? Diavel ?)

I can now log all the CAN msgs to the SD card. A 2G card should be good for 40+Hrs if my math is right. :think:







So I am now a bit behind you guys who have figured out what some of the MsgIDs are but I am keen to join the party. I'll have a look at the spreadsheet previously mentioned and see if any Msgs line up with the 1199, then I'll start adding my discoveries.

One thing that I was curious about is whether any CAN higher level protocol is used such as J1939 which although was designed for trucks is used in many cars.



I found a neat hex viewer which you can teach about protocols which I am using to view my data at present and was going to write some python stuff for visualizing the data but I hadn't thought about using something as simple as excel!


Hello!
Could you help me with a can messages going to panigale 1199's gauges?


Отправлено с моего iPad используя Tapatalk
 

·
Registered
Joined
·
3 Posts
I've managed to read and start to decode the messages on the multistrada's canbus. Early days so far as there's a lot I'm still trying to get my head round, but can already read things like; rear wheel speed, gear position, engine temperature, indicators, brake light, battery voltage, DTC setting, engine mode and rear spring preload. I'm in the process of trying to work out throttle input and resultant throttle position, engine revs and suspension settings (this last one is a bit frustrating because of all the variables).



Reading and logging the canbus info is surprisingly cheap and easy. All you need is a small microprocessor. I'm using an Arduino UNO, about £25, and something to read the CAN messages, a Sparkfun Canbus shield, about £35, a microSD card and a home made lead to connect to the diagnostic plug under the rider's seat. Oh, and some code to read the messages and write the to the SD card.



It should be really easy to adapt the code I have to make some sort of data logger or supplementary LCD display. In theory it would be possible to get very ambitious and replace the existing DES module with a homemade version and save £100s in the event of a failure, or even make a speed sensitive one (both these are obviously significantly more complicated and time consuming).


Hello!
Could you help me with a can messages going to panigale 1199's gauges?


Отправлено с моего iPad используя Tapatalk



Отправлено с моего iPad используя Tapatalk
 
21 - 40 of 45 Posts
Top