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. Returns BBIO1
  • 0b00000001 Mode identification. Returns CAN1
  • 0b00000010 Read CAN packet
  • 0b00000011 Set CAN ID
  • 0b00000100 Disable filter (accept all packets)
  • 0b00000101 Enable filter
  • 0b0000011x Set filter value
  • 0b00001xxx Write CAN packet
  • 0b01100xxx Set CAN speed
  • 0b00010000 Set CAN timings - CHANGED IN 858de3f1fe260b07ad0d0893f3bded5ee730b018
  • 0b11xxxxxx Binary 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 => 2000000
  • 0b001 => 1000000
  • 0b010 => 500000
  • 0b011 => 250000
  • 0b100 => 125000
  • 0b101 => 100000
  • 0b110 => 50000
  • 0b111 => 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 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)