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 :
0b00000000
Return to main mode. ReturnsBBIO1
0b00000001
Mode identification. ReturnsCAN1
0b00000010
Read CAN packet0b00000011
Set CAN ID0b00000100
Disable filter (accept all packets)0b00000101
Enable filter0b0000011x
Set filter value0b00001xxx
Write CAN packet0b01100xxx
Set CAN speed0b00010000
Set CAN timings - CHANGED IN 858de3f1fe260b07ad0d0893f3bded5ee730b0180b11xxxxxx
Binary Auxiliary pins
Command details
0b00000010
)
Read CAN Packet (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
0b00000011
)
Set CAN ID (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.
0b00000100
)
Disable filter (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.
0b00000101
)
Enable filter (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.
0b0000011x
)
Set filter value (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.
0b00001xxx
)
Write CAN packet (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.
0b01100xxx
)
Set CAN speed (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.
0b00010000
)
Set CAN timings (This command changed from
0b11000000
since 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)