Canbus Support
Contents
- Bus Speed
- Hardware Requirements
- Enabling canbus support with datamode=
- Device IDs
- Canbus Inputs
- Canbus Rebroadcast Configuration
- SDC Canbus Message Definitions
SDC supports canbus, but you must obviously have a canbus network and a Canbus I/O hat connected in order to be able to send and receive messages.
There are multiple uses for adding canbus support to your installation:
- To supplement the existing engine data with data from other systems that you are building or have access to.
- To make engine data available on more than one screen in your system (I do this with my own car)
- To enable control functions from one device to be sent to another device, such as changing the displayed page on an embedded cluster from a separate control screen (I do this on my car too)
Bus Speed
The canbus system supports bus speeds of up to 1mbit. In other words it supports standard CAN, and does not support CAN-FD. I may bring that out in the future but right now it just isn’t needed.
You can configure the bus speed using the Canbus Settings
Hardware Requirements
SDC has support for the MCP2515 CAN controller and its SPI interface, running at 10Mhz. This chip is normally paired with an MCP2551 transceiver, although that is not visible to SDC. You must follow appropriate canbus design considerations such as ensuring the bus is properly terminated at both ends and making sure that you use suitable twisted pair cable. The SDC I/O Hat has a pair of canbus devices on it and also has an optional termination resistor which you can enable by placing a jumper over the two pins to connect them together.
Enabling canbus support with datamode=
As well as correctly configuring the ini file entries for canbus, you must also enable it by choosing the correct datamode. There are other datamodes than those listed here but these are the ones that involve canbus:
datamode=canbus
This is a raw canbus-only implementation. You will get no engine data in SDC at all unless you send canbus messages to it from another device. That other device can be another SDC installation with one of the ‘rebroadcast’ datamode settings, or it can be some other device which conforms to SDC’s canbus message format.
datamode=serialcanbusauxin
This is a receive-only mode, whereby ECU data comes from the Speeduino serial connection, but other data can be received from a canbus. This enables other devices to send control commands to this node such as changing the page, or populating GPS data. Engine data is not broadcast onto the canbus network.
datamode=serialcanbusbridgeauxin
This is a rebroadcast mode, whereby the SDC installation must have a serial connection to a Speeduino ECU, and will both store and display the serial data locally but in addition it will rebroadcast some or all of the data it receives onto the connected canbus network. Any other SDC device on the network configured as datamode=canbus
will be able to receive the broadcast data and display it on its own screen. In addition, any other device can send data or control commands to this device (for example to change the displayed page, or update an internal data item).
datamode=playbackcanbusbridge
This is a mode used mostly for demonstration purposes; it plays back a previously recorded file as per the first-boot demo, but in addition it will ‘bridge’ (rebroadcast) most of the data being played back onto the bus for other devices to see. I use this mostly for development testing and demonstrations. There is no other use for it really.
datamode=tsusbserialcanbusauxin
This is a receive-only mode, whereby ECU data comes from the Speeduino USB port (the one used for tuning the engine), but other data can be received from a canbus. This enables other devices to send control commands to this node such as changing the page, or populating GPS data. Engine data is not broadcast onto the canbus network.
datamode=tsusbserialcanbusbridgeauxin
This is a rebroadcast mode, whereby the SDC installation must have a USB Serial connection to a Speeduino ECU (the one used for tuning of the engine), and will both store and display the engine data locally but in addition it will rebroadcast some or all of the data it receives onto the connected canbus network. Any other SDC device on the network configured as datamode=canbus
will be able to receive the broadcast data and display it on its own screen. In addition, any other device can send data or control commands to this device (for example to change the displayed page, or update an internal data item).
Device IDs
Every SDC device on the canbus network must have a unique Device ID. This is specified in the ini file in the General Section. The device id is used in certain scenarios to direct a canbus message at a particular device. For example, if you send a “change page” command then you’re likely to want to change the page on just one device, since multiple screens might have different sets of pages.
Canbus Inputs
Canbus inputs are a means to define the format of third party messages that may be received. They are defined in the Canbus Inputs ini file section. When an input is defined, the name you give it becomes an attribute which you can use on gauges and add to datalogging.
Limitations
There are some limitations with canbus inputs at the moment which I will improve upon as time goes by, when I have had more experience of the sort of things people require. Systems define their canbus IDs and messages in many different ways so providing something totally generic is not a simple or obvious task.
For the time being, canbus inputs enable you to create an attribute, specify a canbus id of a message that will be received, and then which byte(s) within the 8 byte canbus message represent the data you want to store. There are 1, 2, and 4 byte quantities available, and it is possible to declare two or more attributes that are available from the same canbus id message.
The limitation presently is that if there is more than one message sent with the same canbus id, and you need to use a byte within the message to decide which attribute should be populated, then this is not currently possible. Any more complex schemes are similarly not possible at this time.
Canbus Rebroadcast Configuration
The serialcanbusbridgeauxin, and playbackcanbusbridge datasources both have a bridging element to them in that they take whatever their primary data source is (serial or datalog), and broadcast that data onto the canbus. Thus the device acts as a ‘bridge’ between the datasource and the canbus.
These datamodes will broadcast a default set of the available data (those most commonly required) but if you want to minimise the amount of traffic on the canbus then you can configure a subset of attributes to be sent. This is done via the rebroadcastattributes setting in the datasource settings, which replaces the default set entirely. If you want to add an attribute that is not already in the default set, then use the ‘extrarebroadcastattributes’ setting instead. If both are defined, their content is added together and the result replaces the default set entirely.
To configure a subset (or even a superset) of attributes for broadcast, you must enter a comma separated list of attributes viz;
[datasource]
rebroadcastattributes=rpm,map,tps,advance,dwell
extrarebroadcastattributes=ve,advance
Do not add any spaces between the columns. If this list is not present, then the default rebroadcast list will be used, which contains most of the standard speeduino data items available on the serial connection.
SDC Canbus Message Definitions
This section provides the format of all canbus messages that can be used to send data into SDC. Data may be in the form of actual data items, or control messages to make the cluster do certain things such as change the page. The canbus ids can be changed via configuration if you run into conflicts with other systems but you’re better off with an independent canbus anyway due to traffic volume.
- Canbus Id 1998 is the default accessory status id
- Canbus Id 2000 is the default ECU data id. SDC’s rebroadcast mode sends some critical ECU items on canbus id 1999 (ECUid-1 in fact). This is utilising the CANBus message priority system, but any ECU data can be sent on either of the two values.
- Canbus Id 2001 is the default GPS id
- Canbus Id 2001 is the default ‘Controller’ id. This and the GPS id are separate configurations but both have the same default value.
Multi-byte values are all little endian.
Canbus Id | Format (Byte n=value) | Description |
---|---|---|
2001 | Byte 0=12, Bytes 1-4 Latitude*10000, Byte 5-6 Current GPS heading | GPS Latitude and heading Update |
2001 | Byte 0=13, Bytes 1-4 Longitude*10000 | GPS Longitude Update |
2001 | Byte 0=22 | Request clean shutdown |
2001 | Byte 0=20, 1-2=16 bit Warning id | Show cluster warning |
2001 | Byte 0=21, 1-2=16 bit Warning id | Cancel cluster warning |
2001 | Byte 0=1, 1=Target Device Id, 2=Page number | Change Page |
2001 | Byte 0=2, 1=Trip Id | Choose active trip (0 or 1) |
2001 | Byte 0=3, 1=Speed limit in mph | Set current speed limit |
2001 | Byte 0=5 | Un-select composite group (removes the red dot from the composite) |
2001 | Byte 0=7 | Select next composite group |
2001 | Byte 0=8 | Cycle currently selected composite group |
2001 | Byte 0=10 | Toggle debug mode (debug gauges will show and hide) |
2001 | Byte 0=11 | Request log file marker |
2001 | Byte 0=14, 1=Device Id | Toggle datalogging on the selected device |
2001 | Byte 0=15, 1=Setting Id, 2-3=16 bit signed setting value. | |
1999 | Byte 0=17, 1-2=MAP, 3-4=RPM, 5=VE, 6=AFR*10 | ECU Data Update, stuffed data block 1. |
2000 | Byte 0=16, 1=Offset into structure (see offsets below), 2-end=Data (length depends on offset) | ECU Data update |
2000 | Byte 0=19, 1-2=Extended Offset, 3-end=Data (length depends on offset) | Extended ECU Data update, where offset is > 255 requiring 2 bytes |
1998 | Byte 0=24, 1=Canbus index, 2=Value (0 or 1) | Accessory Status Update |
Attribute Offsets (SDC Version 1.30)
The offset based messages in the list above are how most of the engine data is sent across the bus. You can use these messages to send data into a raw canbus SDC configuration, or use the formats described to read engine data that has been rebroadcast from a serial connection to a speeduino. The table below gives the offset of all relevant attributes. If an offset is greater than 255 then it must be sent using the Extended Offset message (19) otherwise it can be sent using the standard offset message (16).
Note: If you are on an earlier version of SDC, these offsets may be different. We try to keep them constant but sometimes this is not possible. If you want to see the offsets for your specific version, connect your device to WIFI and access the onboard help on http://
Attribute | Data Type | Datalog Title | Units | Offset | Length |
---|---|---|---|---|---|
secl | 1 byte unsigned integer | Run Secs | s | 1 | 1 |
status1 | 1 byte unsigned integer | status1 | bits | 2 | 1 |
engine | 1 byte unsigned integer | Engine | bits | 3 | 1 |
dwell | 1 byte unsigned integer | Dwell | ms | 4 | 1 |
map | 2 byte unsigned integer | MAP | kPa | 5 | 2 |
iat | 1 byte unsigned integer | IAT | deg | 7 | 1 |
clt | 1 byte unsigned integer | CLT | deg | 8 | 1 |
gammabat | 1 byte unsigned integer | GammaBat | % | 9 | 1 |
batteryv | 1 byte unsigned integer | Batteryv | v | 10 | 1 |
o2 | 1 byte unsigned integer | AFR | AFR | 11 | 1 |
gammaego | 1 byte unsigned integer | GammaEGO | % | 12 | 1 |
gammaiat | 1 byte unsigned integer | GammaAir | % | 13 | 1 |
gammawarm | 1 byte unsigned integer | GammaWarm | % | 14 | 1 |
rpm | 2 byte unsigned integer | RPM | RPM | 15 | 2 |
accelenrich | 1 byte unsigned integer | Accel Enrich | % | 17 | 1 |
gammae | 1 byte unsigned integer | GammaE | % | 18 | 1 |
ve | 1 byte unsigned integer | VE | % | 19 | 1 |
afrtarget | 1 byte unsigned integer | AFR Target | AFR | 20 | 1 |
pw1 | 2 byte unsigned integer | PW1 | ms | 21 | 2 |
tpsdot | 1 byte unsigned integer | TPSDot | %/s | 23 | 1 |
advance | 1 byte unsigned integer | Advance | deg | 24 | 1 |
tps | 1 byte unsigned integer | TPS | % | 25 | 1 |
loops | 2 byte unsigned integer | Loops | Loops | 26 | 2 |
freeram | 2 byte unsigned integer | Free RAM | bytes | 28 | 2 |
boosttarget | 1 byte unsigned integer | Boost Target | kPA | 30 | 1 |
boostduty | 1 byte unsigned integer | Boost Duty | % | 31 | 1 |
spark | 1 byte unsigned integer | Spark | bits | 32 | 1 |
rpmdot | 2 byte signed integer | RPMdot | %/s | 33 | 2 |
ethanolpct | 1 byte unsigned integer | Ethanol | % | 35 | 1 |
flexcorrection | 1 byte unsigned integer | Flex Corr | % | 36 | 1 |
flexigncorrection | 1 byte unsigned integer | Flex Ign Corr | % | 37 | 1 |
idleload | 1 byte unsigned integer | Idle Load | load | 38 | 1 |
o2_2 | 1 byte unsigned integer | O2_2 | AFR | 40 | 1 |
baro | 1 byte unsigned integer | Baro | kPA | 41 | 1 |
launchcorrection | 1 byte unsigned integer | Launch Correction | % | 76 | 1 |
pw2 | 2 byte unsigned integer | PW2 | ms | 77 | 2 |
pw3 | 2 byte unsigned integer | PW3 | ms | 79 | 2 |
pw4 | 2 byte unsigned integer | PW4 | ms | 81 | 2 |
ecustatus3 | 1 byte unsigned integer | ECU Status 3 | bits | 83 | 1 |
engineprotectstatus | 1 byte unsigned integer | Engine Prot Status | bits | 84 | 1 |
fuelload | 2 byte unsigned integer | Fuel Load | 85 | 2 | |
ignload | 2 byte unsigned integer | Ign Load | 87 | 2 | |
injangle | 2 byte unsigned integer | Inj Close Angle | deg | 89 | 2 |
clidletarget | 1 byte unsigned integer | Closed Loop Idle Target | 92 | 1 | |
mapdot | 1 byte unsigned integer | MAPdot | %/s | 93 | 1 |
vvt1angle | 1 byte unsigned integer | VVT1 Angle | deg | 94 | 1 |
vvt1targetangle | 1 byte unsigned integer | VVT1 Target Angle | deg | 95 | 1 |
vvt1duty | 1 byte unsigned integer | VVT1 Duty | % | 96 | 1 |
flexboostcorrection | 2 byte unsigned integer | Flex Boost Corr | % | 97 | 2 |
barocorrection | 1 byte unsigned integer | Baro Correction | % | 99 | 1 |
asevalue | 1 byte unsigned integer | Afterstart Enrichment | % | 100 | 1 |
vss | 2 byte unsigned integer | ECU VSS | mph? | 101 | 2 |
ecugear | 1 byte unsigned integer | ECU Gear | 103 | 1 | |
ecufuelpressure | 1 byte unsigned integer | ECU Fuel Pressure | 104 | 1 | |
ecuoilpressure | 1 byte unsigned integer | ECU Oil Pressure | 105 | 1 | |
wmipw | 1 byte unsigned integer | WMI Pulsewidth | ms | 106 | 1 |
ecustatus4 | 1 byte unsigned integer | ECU Status 4 | bits | 107 | 1 |
vvt2angle | 1 byte unsigned integer | VVT2 Angle | deg | 108 | 1 |
vvt2targetangle | 1 byte unsigned integer | VVT2 Target Angle | deg | 109 | 1 |
vvt2duty | 1 byte unsigned integer | VVT2 Duty | % | 110 | 1 |
outputsstatus | 1 byte unsigned integer | Outpu Status | 111 | 1 | |
fueltemp | 1 byte unsigned integer | Fuel Temp | deg | 112 | 1 |
fueltempcorrection | 1 byte unsigned integer | Fuel Temp Correction | % | 113 | 1 |
ve1 | 1 byte unsigned integer | VE1 | % | 114 | 1 |
ve2 | 1 byte unsigned integer | VE2 | % | 115 | 1 |
advance1 | 1 byte unsigned integer | Advance 1 | deg | 116 | 1 |
advance2 | 1 byte unsigned integer | Advance 2 | deg | 117 | 1 |
nitrous_status | 1 byte unsigned integer | Nitrous Status | 118 | 1 | |
ts_sd_status | 1 byte unsigned integer | SD Log Status | 119 | 1 | |
emap | 2 byte unsigned integer | EMAP | kPa | 120 | 2 |
fanduty | 1 byte unsigned integer | Fan Duty | % | 122 | 1 |
status2 | 1 byte unsigned integer | status2 | bits | 181 | 1 |
speedmph | 2 byte unsigned integer | Speed | mph | 1202 | 2 |
gpsspeedmph | 2 byte unsigned integer | Speed | mph | 1254 | 2 |
gear | 1 byte unsigned integer | Gear | 1262 | 1 | |
odometer | 4 byte unsigned integer | Odometer | miles | 1519 | 4 |
tripa | 4 byte unsigned integer | TRIP A | miles | 1523 | 4 |
tripb | 4 byte unsigned integer | TRIP B | miles | 1527 | 4 |
currenttripcounter | 4 byte unsigned integer | Current Trip distance | miles | 1531 | 4 |
accessorystatus1 | 1 byte unsigned integer | Accessory Status 1 | bits | 1535 | 1 |
accessorystatus2 | 1 byte unsigned integer | Accessory Status 2 | bits | 1536 | 1 |
fuellevel | 2 byte unsigned integer | Fuel Lvl | litres | 1537 | 2 |
oilpressure | 1 byte unsigned integer | Oil Press | PSI | 1539 | 1 |
flpressure | 2 byte unsigned integer | Tyre Pressure FL | PSI | 1867 | 2 |
fltemp | 2 byte unsigned integer | Tyre Temp FL | deg | 1869 | 2 |
flalarm | 1 byte unsigned integer | Front Left Tyre Alarm | 1871 | 1 | |
flbattery | 1 byte unsigned integer | FL TPMS Bat | % | 1872 | 1 |
frpressure | 2 byte unsigned integer | Tyre Pressure FR | PSI | 1874 | 2 |
frtemp | 2 byte unsigned integer | Tyre Temp FR | deg | 1876 | 2 |
fralarm | 1 byte unsigned integer | Front Right Tyre Alarm | 1878 | 1 | |
frbattery | 1 byte unsigned integer | FR TPMS Bat | % | 1879 | 1 |
rlpressure | 2 byte unsigned integer | Tyre Pressure RL | PSI | 1881 | 2 |
rltemp | 2 byte unsigned integer | Tyre Temp RL | deg | 1883 | 2 |
rlalarm | 1 byte unsigned integer | Rear Left Tyre Alarm | 1885 | 1 | |
rlbattery | 1 byte unsigned integer | RL TPMS Bat | % | 1886 | 1 |
rrpressure | 2 byte unsigned integer | Tyre Pressure RR | PSI | 1888 | 2 |
rrtemp | 2 byte unsigned integer | Tyre Temp RR | deg | 1890 | 2 |
rralarm | 1 byte unsigned integer | Rear Right Tyre Alarm | 1892 | 1 | |
rrbattery | 1 byte unsigned integer | RL TPMS Bat | % | 1893 | 1 |
accelx | 2 byte signed integer | Accel X | g | 1894 | 2 |
accely | 2 byte signed integer | Accel Y | g | 1896 | 2 |
accelz | 2 byte signed integer | Accel Z | g | 1898 | 2 |
wheelshorsepower | 2 byte unsigned integer | Horsepower at the wheels | bhp | 1939 | 2 |
crankhorsepower | 2 byte unsigned integer | Horsepower at the crank | hp | 1941 | 2 |
wheelstorque | 2 byte unsigned integer | Torque at the wheels | lbft | 1943 | 2 |
cranktorque | 2 byte unsigned integer | Torque at the crank | lbft | 1945 | 2 |
speedkph | 2 bytes unsigned integer | Speed in kph | kph | 1947 | 2 |
gpsspeedkph | 2 bytes unsigned integer | GPS Speed in kph | kph | 1949 | 2 |