반응형

CAN 통신을 검증하는데 비싼 장비들이 많은데, 그 중에 저렴한 제품으로 CAN 통신을 검증하려고 CANable[1]을 샀다.

이를 각각 둘이 물려서 CAN 통신을 확인했다.

 

문제는 CANable 사이트의 CAN 통신 검증 프로그램인 Cangaroo는 CAN 통신 프로토콜을 정의하는 dbc 파일을 Vector 사의 CANdb 프로그램[2]으로 만들어줘야하는데, 그게 좀 귀찮아서 그냥 했다.

장비가 많지 않은 소규모 프로젝트에서는 이런 방법도 괜찮은 것 같다.

 

찾아보면 CANable은 약 2~6만원 사이로 구매가 가능하다.

 

CANable로 CAN 통신을 검증하기 위해, master, slave측의 프로그램을 다음 github 저장소[3]를 참고하여 작성했다.

코드 구현 - Master (Client)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Originated from https://github.com/chemicstry/candle_driver
import candle_driver
import ids
 
devices = candle_driver.list_devices()
 
if not len(devices):
    print("No candle devices found")
    exit()
 
print('Found {} candle devices.'.format(len(devices)))
 
for device in devices:
    print("Name {} / Ch.{} / Path {}".format(device.name(), device.channel_count(), device.path()))
 
# master_id = 0x10000100
# slave_id  = 0x10000110
 
device = devices[0]
device.open()
ch = device.channel(0)
ch.set_bitrate(500000)
ch.start()
 
# Normal frame
# ch.write(10,b'abcdefgh')
# Extended frame
my_id = ids.id_master | candle_driver.CANDLE_ID_EXTENDED | candle_driver.CANDLE_ID_RTR
print('Send Message : id {:#010x}'.format(my_id))
ch.write(my_id, b'')
 
try:
    while True:
        frame_type, can_id, can_data, extended, ts = ch.read(2000)
        if(can_id == ids.id_slave):
            print("Frame type : {}, extended {}".format(frame_type, extended))
            print('Received {:} from ID {}, {:#010x} at {:}'.format(can_data, can_id, can_id, ts))
            break
        elif(can_id >= 0x10000000):
            print("Frame type : {}, extended {}".format(frame_type, extended))
            print('Received {:} from ID {}, {:#010x} at {:}'.format(can_data, can_id, can_id, ts))
            break
except TimeoutError:
    print('CAN read timeout')
 
ch.stop()
device.close()
cs

 

코드 구현 Slave(Server)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Originated from https://github.com/chemicstry/candle_driver
import candle_driver
import ids
 
devices = candle_driver.list_devices()
 
if not len(devices):
    print("No candle devices found")
    exit()
 
print('Found {} candle devices.'.format(len(devices)))
 
for device in devices:
    print("Name {} / Ch.{} / Path {}".format(device.name(), device.channel_count(), device.path()))
 
# master_id = 0x10000100
# slave_id  = 0x10000110
 
device = devices[1]
device.open()
ch = device.channel(0)
ch.set_bitrate(500000)
ch.start()
 
# Normal frame
# ch.write(10,b'abcdefgh')
# Extended frame
my_id = ids.id_slave | candle_driver.CANDLE_ID_EXTENDED
print('Send Message : id {:#010x}'.format(my_id))
 
print("id ext : {:#010x}".format(   candle_driver.CANDLE_ID_EXTENDED))
print("id ext : {}".format(         candle_driver.CANDLE_ID_EXTENDED))
while True:
    try:
        frame_type, can_id, can_data, extended, ts = ch.read(100)
        if(can_id == ids.id_master):
            for bit in can_data:
                print("{:08b}".format(bit), end=' ')
            print("|")
            for bit in can_data:
                print("{:01c}".format(bit), end=' ')
            print("|")
            for bit in can_data:
                print("{:03d}".format(bit), end=' ')
            print("")
            print("Frame type : {}, extended {}".format(frame_type, extended))
            print('Received {:} from ID {}, {:#010x} at {:}'.format(can_data, can_id, can_id, ts))
            ch.write(my_id, b'Slave!')
 
        # print('FT {} {}'.format(frame_type, extended))
        # print('Received {} from ID {} at {}'.format(can_data, can_id, ts))
    except TimeoutError:
        continue
cs

 

Reference

[1] An Open-Source USB to CAN Adapter, https://canable.io/

[2] Vector, "CANdb++", https://www.vector.com/int/en/products/products-a-z/software/candb/

[3] chemicstry, "candle_driver", https://github.com/chemicstry/candle_driver

EOF

728x90

+ Recent posts