这是介绍如何用Kvaser数据库(kvadblib)和Python管理DBC数据库的博客第二部分(总计为2部分):
- 在Python里处理CAN数据库
- 发送和接收数据库信号
在此博客的第一部分,我们生成了一个DBC数据库,并介绍了怎样检测它。现在我们将用这个数据库来发送附带了用Python设置的物理值的信号。
这是介绍如何用Kvaser数据库(kvadblib)和Python管理DBC数据库的博客第二部分(总计为2部分):
在此博客的第一部分,我们生成了一个DBC数据库,并介绍了怎样检测它。现在我们将用这个数据库来发送附带了用Python设置的物理值的信号。
在用我们的数据库发送信号之前,让我们回顾一下怎样用Python书写和接收一个原始CAN报文。
from canlib import kvadblib
from canlib import canlib
from canlib import Frame
def open_channel(channel) :
”””Open a new channel , set bitrate 1Mbit/s and go bus on. ”””
ch = canlib . openChannel(channel , canlib .canOPEN_ACCEPT_VIRTUAL)
ch . setBusOutputControl( canlib .canDRIVER_NORMAL)
ch . setBusParams( canlib .canBITRATE_1M)
ch .busOn()
return ch
def close_channel(ch) :
”””Go bus off and close channel . ”””
ch . busOff ()
ch . close ()
def send_receive_raw(ch0 , ch1) :
# 不使用kvadblib发送一个CAN报文
frame = Frame(id_=4,
data=bytearray(b ’\x00\x00\x00\x00\xd8\x00\x1e\x00 ’ ) )
print (”Sending frame : %s” % frame)
ch0 . write (frame)
# 读取报文
print (”Receiving frame : %s” % str (ch1 . read () ) )
ch0 = open_channel(0)
ch1 = open_channel(1)
send_receive_raw(ch0 , ch1)
close_channel(ch0)
close_channel(ch1)
列表 1: 显示怎样书写和接收CAN报文的编码范例
这里应该不会有什么意外1,在0通道上发送CAN报文是用 ch0.write()
,在1通道上接收报文是用 ch1.read()
。运行这个小例子会显示下面的标准输出:
Sending frame: Frame(id=4, data=bytearray(b’\x00\x00\x00\x00\xd8\x00\x1e\x00’),
dlc=8, flags=0, timestamp=None)
Receiving frame: Frame(id=4, data=bytearray(b’\x00\x00\x00\x00\xd8\x00\x1e\x00’),
dlc=8, flags=2, timestamp=4)
发送CAN 信号的第一步是打开一个数据库,将一个CAN 帧和一个在数据库里被定义的报文联系起来。
# 打开你要用的数据库
db = kvadblib .Dbc( filename=’db_histogram . dbc ’ )
#从数据库提取我们要用的报文
lim_002 = db.get_message_by_name( ’LIM_002’ )
# 生成一个捆绑报文BoundMessage,包括一个有正确id 和 dlc的空白帧
bmsg_0 = lim_002 . bind()
当捆绑一个数据库报文时,我们得到了一个新生成,它具备携带ID, DLC和数据的位置,同时此ID 和 DLC已按报文要求做好设置。现在我们能用这个新生成的捆绑报文,通过属性来 处理我们的信号。
# 我们用属性设置这个信号 ’Load ’ 的原始值
bmsg_0.Load.raw = 0xff
print (”The bound message now looks like :\n%s” % bmsg_0)
print (”Load signal as raw value : %s” % bmsg_0.Load.raw)
print (”and as physical value : %s” % bmsg_0.Load. phys)
# 我们通常更关心设置此信号的物理值
bmsg_0.Load. phys = 75
print (”Load signal as raw value : 0x%x” % bmsg_0.Load.raw)
print (”and as physical value : %s” % bmsg_0.Load. phys)
运行上面的编码可得到下列标准输出:
The bound message now looks like:
Frame: message_name:LIM_002, data:bytearray(b’\xff\x00\x00\x00\x00\x00\x00\x00’)
Load signal as raw value: 255
and as physical value: 3.5733110840282835e-43
Load signal as raw value: 0x42960000
and as physical value: 75.0
现在我们的捆绑信息已附带正确内容, 我们以一个支持 write()
的格式,用._frame
来提取这个帧 。
# 用标准write () 方法发送一个CAN帧
ch0 . write (bmsg_0._frame)
# 生成另一个捆绑信号 BoundSignal , 这一次包含一个从通道 channel 1读取的帧
bmsg_1 = lim_002 . bind(ch1 . read(timeout=100))
View sourceCopy to clipboard
将这个新编码和我们的第一个范例编码合并,我们就得到了下面的结果:
from canlib import canlib
from canlib import kvadblib
def open_channel(channel) :
”””Open a new channel , set bitrate 1Mbit/s and go bus on. ”””
ch = canlib . openChannel(channel , canlib .canOPEN_ACCEPT_VIRTUAL)
ch . setBusOutputControl( canlib .canDRIVER_NORMAL)
ch . setBusParams( canlib .canBITRATE_1M)
ch .busOn()
return ch
def close_channel(ch) :
”””Go bus off and close channel . ”””
ch . busOff ()
ch . close ()
def send_receive_sig(ch0 , ch1) :
# 打开我们要用的数据库
db = kvadblib .Dbc( filename=’db_histogram . dbc ’ )
#从数据库提取我们要用的报文
lim_002 = db.get_message_by_name( ’LIM_002’ )
#生成一个捆绑报文BoundMessage,包括一个有正确id 和 dlc的空白帧.
bmsg_0 = lim_002 . bind()
# 设置信号值
bmsg_0.Load. phys = 75
print ( ’Sending : %s ’ % bmsg_0.Load)
#用标准write () 方法发送一个CAN帧
ch0 . write (bmsg_0._frame)
#生成另一个捆绑信号 BoundSignal , 这一次包含一个从通道 channel 1读取的帧
bmsg_1 = lim_002 . bind(ch1 . read(timeout=100))
print ( ’Received signal Load: %s %s ’ %
(bmsg_1.Load. phys , bmsg_1.Load. unit ) )
ch0 = open_channel(0)
ch1 = open_channel(1)
send_receive_sig(ch0 , ch1)
close_channel(ch0)
close_channel(ch1)
运行我们的最后一个范例编码可得到下面结果:
Sending: <BoundSignal: name=’Load’, phys=75.0>, unit:metric ton
Received signal Load: 75.0 metric ton
现在我们简单介绍了怎样使用Kvaser数据库(kvadblib)信号,而不是手动生成和发送CAN报文 。
1对v1.5版本,canlib.Frame
的是新命令,所以用户可能还不太了解…