HydraFW Binary CAN mode guide - hydrabus/hydrafw GitHub Wiki
HydraFW binary CAN mode guide
This guide is updated towards firmware release HydraFW v0.11 and later
For hardware shield supported see https://github.com/smillier/HydraLINCAN
This mode allows to control CAN1 or CAN2
- CAN1 pins: TX=PB9, RX=PB8
- CAN2 pins: TX=PB13, RX=PB12
For more details see https://github.com/hydrabus/hydrafw/wiki/HydraFW-CAN-guide
Commands
Once the CAN mode has been selected, the following commands are available :
0b00000000Return to main mode. ReturnsBBIO10b00000001Mode identification. ReturnsCAN10b00000010Read CAN packet0b00000011Set CAN ID0b00000100Disable filter (accept all packets)0b00000101Enable filter0b0000011xSet filter value0b00001xxxWrite CAN packet0b01100xxxSet CAN speed0b00010000Set CAN timings - CHANGED IN 858de3f1fe260b07ad0d0893f3bded5ee730b0180b11xxxxxxBinary Auxiliary pins
Command details
Read CAN Packet (0b00000010)
Once the command has been issued, Hydrabus will send a status byte (0x01 if success, 0x00 otherwise). If request is successful, The following data will be sent :
Byte 1 2 3 4 5 6 ...
|----------|----------|----------|----------|----------|----------|------...
[ CAN ID ] [ length ] [ data ...
[CAN ID] is always 4 bytes big-endian (to support either standard or extended IDs). [length] is the number of data bytes [data] is between 0 and 8 bytes long
Set CAN ID (0b00000011)
This command must be followed by 4 bytes, representing the identifier further written packets must have. This command always takes 4 bytes and accepts standard and extended IDs.
Filter commands
By default, Hydrabus does not accept any packets until a filter is set. The filter is based on the packet identifier. The following commands will take care of the filter setup.
Disable filter (0b00000100)
Disables the filter. All packets will be captured by Hydrabus once this command is sent.
This commands returns 0x01 if successful, 0x00 in case of error.
Enable filter (0b00000101)
Enables the filter. All packets matching the filter will be captured. All other will be discarded
This commands returns 0x01 if successful, 0x00 in case of error.
Set filter value (0b0000011x)
Two slots are available (with x either 0 or 1).
This command takes 4 bytes representing the identifier to accept.
Since 32d53fccb5352b246aea4d71cf46990a83b7bc16, the filter commands use a mask instead of two ID slots.
This command takes 4 bytes representing the identifier or mask to accept.
Using x = 0 sets the mask (4 bytes, MSB first). Using x = 1 sets the ID (4 bytes, MSB first).
This commands returns 0x01 if successful, 0x00 in case of error.
Write CAN packet (0b00001xxx)
In this mode, the last 3 bits of the command define the number of bytes to write (from 1 to 8) (Command 0b00001000 will send 1 byte). Once this command has been sent, Hydrabus expects the according number of data bytes to be sent.
This commands returns 0x01 if successful, 0x00 in case of error.
Set CAN speed (0b01100xxx)
This command sets the CAN device bitrate. The three last bits will select the speed (int bits/sec) within the following list :
0b000=> 20000000b001=> 10000000b010=> 5000000b011=> 2500000b100=> 1250000b101=> 1000000b110=> 500000b111=> 40000
The default speed is still 500000 b/s.
This commands returns 0x01 if successful, 0x00 in case of error.
Set CAN timings (0b00010000)
This command changed from
0b11000000since 858de3f1fe260b07ad0d0893f3bded5ee730b018
This command takes 3 bytes representing the different Time quanta values.
- Byte 1 sets the TQ1 value (1 to 15)
- Byte 2 sets the TQ2 value (1 to 7)
- Byte 3 sets the SJW value (1 to 3)
(see https://en.wikipedia.org/wiki/CAN_bus#Bit_timing for more information)
This commands returns 0x01 if successful, 0x00 in case of error.
Example script
The following Python script can be used to query the vehicle speed and current RPM
import serial
import time
# See https://en.wikipedia.org/wiki/OBD-II_PIDs for information about the OBD2 queries / responses
def rdpkt():
#Send read command
ser.write('\x02')
#Get read status (0x01)
ser.read(1)
can_id = int(ser.read(4).encode('hex'), 16)
length = ord(ser.read(1))
data = ser.read(length)
return (can_id, data)
ser = serial.Serial('/dev/hydrabus', 115200)
# Open binary mode
for i in xrange(20):
ser.write("\x00")
if "BBIO1" not in ser.read(5):
print "Could not get into bbIO mode"
quit()
# Switching to CAN mode
ser.write('\x08')
if "CAN1" not in ser.read(4):
print "Cannot set CAN mode"
quit()
# Set CAN ID to 0x7DF
ser.write('\x03\x00\x00\x07\xdf')
if ser.read(1) != '\x01':
print "Error setting ID"
quit()
# Set filter to 0x7E8
ser.write('\x06\x00\x00\x07\xe8')
if ser.read(1) != '\x01':
print "Error setting filter"
quit()
while 1:
# Send Query RPM request
ser.write('\x0f\x02\x01\x0c\x55\x55\x55\x55\x55')
# Read the transmission status (0x01)
ser.read(1)
# Retrieve response
can_id, data = rdpkt()
print data.encode('hex')
#decode retrieved data
rpmdata = int(data[3:5].encode('hex'), 16)/4
# Sent Query speed request
ser.write('\x0f\x02\x01\x0d\x55\x55\x55\x55\x55')
# Read the transmission status (0x01)
ser.read(1)
# Retrieve response
can_id, data = rdpkt()
speeddata = int(data[3:4].encode('hex'), 16)
print str(rpmdata)
print str(speeddata)
time.sleep(0.5)