After multiple trials, I'm finally able to get some data from my 2007 Yaris. It's confusing.
My objective is to display the speed. The end result is a configurable indicator light that will flash when I'm going over a configured limit, as my car doesn't have cruise control.
Some libraries give a dump of the incoming data, and the Sparkfun library provides a function to check certain values, like speed, RPM, throttle position, etc.
Problem: The values are crazy. Negatives and all. Here's a dump of when I'm sitting still w/ the car on:
keith204:
After multiple trials, I'm finally able to get some data from my 2007 Yaris. It's confusing.
My objective is to display the speed. The end result is a configurable indicator light that will flash when I'm going over a configured limit, as my car doesn't have cruise control.
Some libraries give a dump of the incoming data, and the Sparkfun library provides a function to check certain values, like speed, RPM, throttle position, etc.
Problem: The values are crazy. Negatives and all. Here's a dump of when I'm sitting still w/ the car on:
Thanks for the help - you've already helped more than you might expect. I had several libraries that I'd worked with, and some had similar filenames for the .h and .cpp files (different forks of different libraries) which could have been the problem. I removed all of them, and re-downloaded the base SparkFun library to verify it matched. BUT, SparkFun has 2 libraries - I used the "Canbus" one before, but now I tried the "Arduino" one. Both are in this git repo: GitHub - sparkfun/CAN-Bus_Shield
CAN-Bus Demo
CAN Init ok
Please choose a menu option.
1.Speed
2.RPM
3.Throttle
4.Coolant Temperature
5.O2 Voltage
6.MAF Sensor
Vehicle Speed:
Vehicle Speed: 0 km
Vehicle Speed: 0 km
Vehicle Speed: 0 km
Engine RPM: 0 km
Engine RPM: 835 rpm
Engine RPM: 835 rpm
Vehicle Speed: 835 rpm
Vehicle Speed: 835 rpm
Vehicle Speed: 835 rpm
Vehicle Speed: 835 rpm
Vehicle Speed: 0 km
Engine RPM: 0 km
Engine RPM: 0 km
Engine RPM: 806 rpm
Vehicle Speed: 801 rpm
Vehicle Speed: 801 rpm
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 4 km
Vehicle Speed: 1 g/s
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 3 km
Vehicle Speed: 3 km
Vehicle Speed: 3 km
Vehicle Speed: 3 km
Vehicle Speed: 7 km
Vehicle Speed: 7 km
Vehicle Speed: 7 km
Vehicle Speed: 12 km
Vehicle Speed: 12 km
Vehicle Speed: 1 g/s
Vehicle Speed: 1 g/s
Vehicle Speed: 1 g/s
Vehicle Speed: 16 km
Vehicle Speed: 16 km
Vehicle Speed: 18 km
Vehicle Speed: 18 km
Vehicle Speed: 19 km
Vehicle Speed: 21 km
Vehicle Speed: 21 km
Vehicle Speed: 21 km
Vehicle Speed: 23 km
Vehicle Speed: 23 km
Vehicle Speed: 24 km
Vehicle Speed: 23 km
Vehicle Speed: 23 km
Vehicle Speed: 22 km
Engine RPM: 22 km
Engine RPM: 1030 rpm
Engine RPM: 1035 rpm
Engine RPM: 1039 rpm
Engine RPM: 1004 rpm
Engine RPM: 1004 rpm
Vehicle Speed: 1451 rpm
Vehicle Speed: 17 km
Engine RPM: 17 km
Engine RPM: 1 g/s
Engine RPM: 1 g/s
Engine RPM: 1574 rpm
Vehicle Speed: 1574 rpm
Vehicle Speed: 24 km
Vehicle Speed: 26 km
Vehicle Speed: 25 km
Vehicle Speed: 25 km
Vehicle Speed: 27 km
Vehicle Speed: 27 km
Vehicle Speed: 29 km
Vehicle Speed: 27 km
Engine RPM: 27 km
Engine RPM: 1162 rpm
Engine RPM: 1162 rpm
Engine RPM: 1184 rpm
Engine RPM: 1 g/s
Engine RPM: 1 g/s
Vehicle Speed: 1089 rpm
Vehicle Speed: 1089 rpm
Vehicle Speed: 1089 rpm
Vehicle Speed: 1089 rpm
Vehicle Speed: 1089 rpm
Throttle: 1089 rpm
Throttle: 1089 rpm
Throttle: 1089 rpm
Throttle: 1089 rpm
Throttle: 19 %
Throttle: 20 %
Throttle: 20 %
Throttle: 19 %
Throttle: 19 %
Throttle: 20 %
Engine Coolant Temp: 20 %
Engine Coolant Temp: 20 %
Engine Coolant Temp: 83 degC
Engine Coolant Temp: 83 degC
Engine Coolant Temp: 83 degC
Engine Coolant Temp: 84 degC
Engine Coolant Temp: 84 degC
Engine Coolant Temp: 84 degC
Engine Coolant Temp: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
Engine Coolant Temp: 1 g/s
Engine Coolant Temp: 1 g/s
Engine Coolant Temp: 1 g/s
Engine Coolant Temp: 86 degC
Engine Coolant Temp: 86 degC
Engine Coolant Temp: 86 degC
Engine Coolant Temp: 86 degC
Engine Coolant Temp: 86 degC
Engine Coolant Temp: 86 degC
O2 Voltage: 86 degC
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
O2 Voltage: 1 g/s
MAF Sensor: 1 g/s
MAF Sensor: 1 g/s
MAF Sensor: 1 g/s
MAF Sensor: 1 g/s
MAF Sensor: 1 g/s
MAF Sensor: 5 g/s
MAF Sensor: 1 g/s
MAF Sensor: 1 g/s
MAF Sensor: 4 g/s
MAF Sensor: 4 g/s
MAF Sensor: 4 g/s
MAF Sensor: 1 g/s
7
Not a valid input.
Please enter a valid option.
7
Not a valid input.
Please enter a valid option.
7
Not a valid input.
Please enter a valid option.
7
Not a valid input.
Please enter a valid option.
7
Not a valid input.
Please enter a valid option.
MAF Sensor: 4 g/s
MAF Sensor: 3 g/s
MAF Sensor: 3 g/s
MAF Sensor: 3 g/s
8
Not a valid input.
Please enter a valid option.
8
Not a valid input.
Please enter a valid option.
9
Not a valid input.
Please enter a valid option.
9
Not a valid input.
Please enter a valid option.
Vehicle Speed: 3 g/s
Vehicle Speed: 3 g/s
Vehicle Speed: 5 km
O2 Voltage: 5 km
O2 Voltage: 5 km
O2 Voltage: 5 km
O2 Voltage: 5 km
Vehicle Speed: 1 g/s
Vehicle Speed: 5 km
Vehicle Speed: 4 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 6 km
Vehicle Speed: 14 km
Vehicle Speed: 14 km
Engine RPM: 16 km
Throttle: 1625 rpm
Engine RPM: 1625 rpm
Engine RPM: 1382 rpm
Engine RPM: 1471 rpm
Engine RPM: 1428 rpm
Engine RPM: 1500 rpm
Engine RPM: 1 g/s
Engine RPM: 1530 rpm
Throttle: 1578 rpm
Throttle: 22 %
Throttle: 20 %
Throttle: 19 %
Throttle: 18 %
Throttle: 20 %
Throttle: 18 %
Throttle: 18 %
Throttle: 17 %
Throttle: 1 g/s
Throttle: 17 %
Vehicle Speed: 17 %
Vehicle Speed: 29 km
Vehicle Speed: 28 km
Vehicle Speed: 27 km
Vehicle Speed: 27 km
Vehicle Speed: 27 km
Vehicle Speed: 25 km
Engine RPM: 1 g/s
Engine RPM: 917 rpm
Engine RPM: 917 rpm
Engine RPM: 910 rpm
Vehicle Speed: 910 rpm
Vehicle Speed: 21 km
Vehicle Speed: 21 km
Vehicle Speed: 21 km
Engine RPM: 21 km
Engine RPM: 1 g/s
Engine RPM: 980 rpm
Engine RPM: 980 rpm
Vehicle Speed: 980 rpm
Vehicle Speed: 980 rpm
Vehicle Speed: 17 km
Vehicle Speed: 17 km
Vehicle Speed: 14 km
Vehicle Speed: 43 km
Vehicle Speed: 43 km
Vehicle Speed: 43 km
The sketch I'm running is:
/****************************************************************************
CAN-Bus Demo
Toni Klopfenstein @ SparkFun Electronics
September 2015
https://github.com/sparkfun/CAN-Bus_Shield
This example sketch works with the CAN-Bus shield from SparkFun Electronics.
It enables the MCP2515 CAN controller and MCP2551 CAN-Bus driver, and demos
using the chips to communicate with a CAN-Bus.
Resources:
Development environment specifics:
Developed for Arduino 1.6.5
Based off of original example ecu_reader_logger by:
Sukkin Pang
SK Pang Electronics www.skpang.co.uk
This code is beerware; if you see me (or any other SparkFun employee)
at the local, and you've found our code helpful, please buy us a round!
For the official license, please check out the license file included with the library.
Distributed as-is; no warranty is given.
*************************************************************************/
#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.");
}
}
}
In the ecr_req() function, it is acting like it has received new data, when it is just recycling old data.
// code from Canbus.cpp ecg_req()
if (mcp2515_send_message(&message)) {}
if (mcp2515_check_message()) {
if (mcp2515_get_message(&message)) {
switch(message.data[2])
//
What is happening is that the can controller is buffering prior requests, the sequence is :
asking for a new message,
is ANY message available?
then return whatever message is AVAILABLE.
Change the code to something like this.
if (mcp2515_send_message(&message)) {}
while((mcp2515_check_message()) {
if (mcp2515_get_message(&message)&&(message.data[2]==pid)){
switch(message.data[2]){
// case in here
}
break; // exit while after first message with correct pid
} // keep looping in while until either found correct message or there are no message availabe
I'm going to copy the library to my project's directory and change my includes to grab from local. My objective is simply to grab the speed as some sort of a number (like 50) rather than a string (50 kmh). So I'll slim it down some.
But, I don't really understand the purpose of the buffer. Surely it exists for a reason. Why do they have a buffer, rather than just returning the value that was received?
keith204:
I'm going to copy the library to my project's directory and change my includes to grab from local. My objective is simply to grab the speed as some sort of a number (like 50) rather than a string (50 kmh). So I'll slim it down some.
But, I don't really understand the purpose of the buffer. Surely it exists for a reason. Why do they have a buffer, rather than just returning the value that was received?
the CanBus is streaming, the MCP2515 interfaces to the bus and picks messages as they stream by. It buffers message, I do not know how long a sensor will continuously stream messages after a request.
So, the First request for RPM could result in 15 messages before the Arduino reads the first one, or the Arduino could get the first message, but additional messages queue up while the Arduino is processing the first one.
You will have to either review the Canbus protocol or experiment.
Ok, experimenting sounds like the way to go. I'll definitely be doing that this week.
Note: To help keep this thread from turning into this one, I want to fully disclose my qualifications:
I'm a programmer by trade and fairly serious woodworker by hobby. As for Arduino, I've only been into it the past 3 months but have gotten super deep quick and have made a few usable contraptions and and a bunch of prototypes. My prior programming experience is more on the .NET and web side, so my knowledge of C/C++ is fairly limited to my time with Arduino. In other words, as far as this forum goes, feel free to treat me like a newbie, but I'll probably be able to follow along some advanced concepts fairly well.
I slimmed down the library and was able to make a little more sense of it. For some reason, sometimes the response would not be a speed response. I duplicated the ecu_req method, slimmed it down, and modified it to directly return the response as an int (or a 4 digit status flag for debugging).
I'm still debugging why the 0's are there periodically, because that's awkward that the response is considered a speed response, but it's showing zero. I'm thinking that I'll just handle this by ignoring the zero value unless it has been the value for the past 5 readings. The good news is that the higher values are now eliminated.
So, I think I'm in good shape here as far as my questions go.
I slimmed down the library and was able to make a little more sense of it. For some reason, sometimes the response would not be a speed response. I duplicated the ecu_req method, slimmed it down, and modified it to directly return the response as an int (or a 4 digit status flag for debugging).
if (mcp2515_check_message())
{
if (mcp2515_get_message(&message))
{
if(message.data[2] == VEHICLE_SPEED)
return (int) message.data[3];
else
return 7777; //received something that wasn't vehicle speed.
}
}
return 9999; //in other words, something didn't work.
}
I'm still debugging why the 0's are there periodically, because that's awkward that the response is considered a speed response, but it's showing zero. I'm thinking that I'll just handle this by ignoring the zero value unless it has been the value for the past 5 readings. The good news is that the higher values are now eliminated.
So, I think I'm in good shape here as far as my questions go.
On your Error codes, Since the function returns an INT, why don't you use negative numbers to represent Errors, Instead of 7777, -1. This way when you test the return value all you have to do is:
int speed = CanbusClass.ecu_reqInt(VEHICLE_SPEED);
if(speed<0 ) { // error handling
}
else { //good speed value
}
For future reference - I was able to make this work - it was mainly a matter of filtering out bogus values and making sure to have an array to hold the values to determine if a zero was really present or just an oddball.
For future reference - I was able to make this work - it was mainly a matter of filtering out bogus values and making sure to have an array to hold the values to determine if a zero was really present or just an oddball.
You ran into Real World vs Theoretical Design. By theory, everything always responds as expected, no error or sanity checks needed.