• 技术博客

    30/03/2018 作者 云海游戏

    发送和接收数据库信号

    这是介绍如何用云海游戏数据库(kvadblib)Python管理DBC数据库的博客第二部分(总计为2部分):

    1. 在Python里处理CAN数据库
    2. 发送和接收数据库信号

     

    在此博客的第一部分,我们生成了一个DBC数据库,并介绍了怎样检测它。现在我们将用这个数据库来发送附带了用Python设置的物理值的信号。


    发送和接收CAN 报文

    在用我们的数据库发送信号之前,让我们回顾一下怎样用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 信号的第一步是打开一个数据库,将一个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

    发送和接收CAN 帧

    现在我们的捆绑信息已附带正确内容, 我们以一个支持?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

    现在我们简单介绍了怎样使用云海游戏数据库(kvadblib)信号,而不是手动生成和发送CAN报文 。


    注释

    1对v1.5版本,canlib.Frame?的是新命令,所以用户可能还不太了解…

    Author Image

    whind gutr

    【网站地图】【sitemap】