SAE J1939堆栈实现
j1939的Python项目详细描述
针对python的can-sae j1939标准的新实现。
警告:当前此项目处于alpha状态!有些功能不能完全工作!
如果您遇到问题或认为堆栈的行为不正常,请执行 毫不犹豫地开一张票或写一封电子邮件。 pullrequests当然更受欢迎!
该项目使用python-can包来支持多个硬件驱动程序。 在编写时,支持的接口是
- 可通过串行连接
- 串行/SLcan上的can
- ixxat虚拟can接口
- Kvaser的canlib
- Neovi接口
- 镍罐
- PCAN基本API
- socketcan
- USB2can接口
- 矢量
- 虚拟
- IScan
概述
SAE J1939 CAN网络由多个电子控制单元(ECU)组成。 每个ecu可以有一个或多个控制器应用程序(cas)。每个CA都有 总线上自己的(唯一的)地址。此地址可以在 地址声明过程或设置为固定值。在后一种情况下,ca 必须在公共汽车上公布地址以检查是否有空。
SAE J1939网络中的CAN信息称为协议数据单元(PDU)。 这个定义并不完全正确,但足够接近于pdu 作为can信息。
功能
- 一个电子控制单元(ecu)可以容纳多个控制器应用程序(ca)
- 根据SAE J1939/81命名的电子控制单元(CA)
- (在建)符合SAE J1939/81的全功能地址申请程序
- 完全支持根据SAE J1939/21发送和接收
- 消息打包和重新组装(最多1785字节)
- 传输协议传输数据(tp.td)
- 传输协议通信管理(tp.cm)
- 多包广播
- 广播通告消息(tp.bam)
- 消息打包和重新组装(最多1785字节)
- (在建)请求(全局和特定)
- (在建)正确的超时和截止日期处理
- (在建)几乎完成测试覆盖率
安装
一旦您的发行版中提供了该软件包,就可以轻松地做到:
$ pip install j1939
同时,您可以下载Wheel软件包并发出以下命令:
$ pip install j1939-0.1.0.dev1-py2.py3-none-any.whl
或者使用:
$ git clone https://github.com/benkfra/j1939.git $ cd j1939 $ pip install .
如果您想在使用时更改代码,请克隆它,然后将其安装到develop mode:
$ git clone https://github.com/benkfra/j1939.git $ cd j1939 $ pip install -e .
快速启动
要简单地接收总线上的所有传递(公共)消息,您可以订阅ecu对象。
importloggingimporttimeimportcanimportj1939logging.getLogger('j1939').setLevel(logging.DEBUG)logging.getLogger('can').setLevel(logging.DEBUG)defon_message(pgn,data):"""Receive incoming messages from the bus :param int pgn: Parameter Group Number of the message :param bytearray data: Data of the PDU """print("PGN {} length {}".format(pgn,len(data)))defmain():print("Initializing")# create the ElectronicControlUnit (one ECU can hold multiple ControllerApplications)ecu=j1939.ElectronicControlUnit()# Connect to the CAN bus# Arguments are passed to python-can's can.interface.Bus() constructor# (see https://python-can.readthedocs.io/en/stable/bus.html).# ecu.connect(bustype='socketcan', channel='can0')# ecu.connect(bustype='kvaser', channel=0, bitrate=250000)ecu.connect(bustype='pcan',channel='PCAN_USBBUS1',bitrate=250000)# ecu.connect(bustype='ixxat', channel=0, bitrate=250000)# ecu.connect(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000)# ecu.connect(bustype='nican', channel='CAN0', bitrate=250000)# subscribe to all (global) messages on the busecu.subscribe(on_message)time.sleep(120)print("Deinitializing")ecu.disconnect()if__name__=='__main__':main()
一个更复杂的例子,其中ca类被重载以包含其自己的功能:
importloggingimporttimeimportcanimportj1939logging.getLogger('j1939').setLevel(logging.DEBUG)logging.getLogger('can').setLevel(logging.DEBUG)classOwnCaToProduceCyclicMessages(j1939.ControllerApplication):"""CA to produce messages This CA produces simulated sensor values and cyclically sends them to the bus with the PGN 0xFEF6 (Intake Exhaust Conditions 1). """def__init__(self,name,device_address_preferred=None):# old fashion calling convention for compatibility with Python2j1939.ControllerApplication.__init__(self,name,device_address_preferred)defstart(self):"""Starts the CA (OVERLOADED function) """# add our timer eventself._ecu.add_timer(0.500,self.timer_callback)# call the super class functionreturnj1939.ControllerApplication.start(self)defstop(self):"""Stops the CA (OVERLOADED function) """self._ecu.remove_timer(self.timer_callback)defon_message(self,pgn,data):"""Feed incoming message to this CA. (OVERLOADED function) :param int pgn: Parameter Group Number of the message :param bytearray data: Data of the PDU """print("PGN {} length {}".format(pgn,len(data)))deftimer_callback(self,cookie):"""Callback for sending the IEC1 message This callback is registered at the ECU timer event mechanism to be executed every 500ms. :param cookie: A cookie registered at 'add_timer'. May be None. """# wait until we have our device_addressifself.state!=j1939.ControllerApplication.State.NORMAL:# returning true keeps the timer event activereturnTruepgn=j1939.ParameterGroupNumber(0,0xFE,0xF6)data=[j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8,# Particulate Trap Inlet Pressure (SPN 81)j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8,# Boost Pressure (SPN 102)j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8,# Intake Manifold 1 Temperature (SPN 105)j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8,# Air Inlet Pressure (SPN 106)j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8,# Air Filter 1 Differential Pressure (SPN 107)j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_16_ARR[0],# Exhaust Gas Temperature (SPN 173)j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_16_ARR[1],j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8,# Coolant Filter Differential Pressure (SPN 112)]# SPN 105, Range -40..+210# (Offset -40)receiverTemperature=30data[2]=receiverTemperature+40self.send_message(6,pgn.value,data)# returning true keeps the timer event activereturnTruedefmain():print("Initializing")# create the ElectronicControlUnit (one ECU can hold multiple ControllerApplications)ecu=j1939.ElectronicControlUnit()# Connect to the CAN bus# Arguments are passed to python-can's can.interface.Bus() constructor# (see https://python-can.readthedocs.io/en/stable/bus.html).# ecu.connect(bustype='socketcan', channel='can0')# ecu.connect(bustype='kvaser', channel=0, bitrate=250000)ecu.connect(bustype='pcan',channel='PCAN_USBBUS1',bitrate=250000)# ecu.connect(bustype='ixxat', channel=0, bitrate=250000)# ecu.connect(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000)# ecu.connect(bustype='nican', channel='CAN0', bitrate=250000)# ecu.connect('testchannel_1', bustype='virtual')# compose the name descriptor for the new caname=j1939.Name(arbitrary_address_capable=0,industry_group=j1939.Name.IndustryGroup.Industrial,vehicle_system_instance=1,vehicle_system=1,function=1,function_instance=1,ecu_instance=1,manufacturer_code=666,identity_number=1234567)# create derived CA with given NAME and ADDRESSca=OwnCaToProduceCyclicMessages(name,128)# add CA to the ECUecu.add_ca(controller_application=ca)# by starting the CA it starts the address claiming procedure on the busca.start()time.sleep(120)print("Deinitializing")ca.stop()ecu.disconnect()if__name__=='__main__':main()
学分
这个实现最初的灵感来自CANopen project of Christian Sandberg。 谢谢你的出色工作!
有关SAE J1939的大部分信息摘自 Copperhill technologies从我在j1939多年的工作经验来看,当然:—)