使用 Tactrix OpenPort 和 J2534 AP 与汽车 ECU 通信时出现问题

问题描述 投票:0回答:1

我正在尝试使用 Tactrix OpenPort 和 J2534 API 从汽车仪表组请求 RPM。请求似乎已发送,设备的指示灯闪烁,但我没有将任何数据接收到控制台。

要指出的是驱动程序、API 和一些示例可以在 此链接上找到。 安装所有内容后,您可以导航到程序文件 OpenECU,在那里您可以找到示例文件夹。

这是该程序的第一个版本:

#include <iostream>
#include <tchar.h>
#include <windows.h>
#include <conio.h>
#include <time.h>

#include "J2534.h"

J2534 j2534;

void reportJ2534Error()
{
    char err[512];
    j2534.PassThruGetLastError(err);
    printf("J2534 error [%s].\n", err);
}

int _tmain(int argc, _TCHAR* argv[])
{
    unsigned long devID;
    unsigned long chanID;

    // Initialization
    if (!j2534.init())
    {
        printf("Can't connect to J2534 DLL.\n");
        return 0;
    }

    if (j2534.PassThruOpen(NULL, &devID))
    {
        reportJ2534Error();
        return 0;
    }

    if (j2534.PassThruConnect(devID, CAN, 0, 500000, &chanID))  // 500000 is the baud rate
    {
        reportJ2534Error();
        return 0;
    }

    // Send RPM request
    PASSTHRU_MSG txmsg;
    txmsg.ProtocolID = CAN;
    txmsg.RxStatus = 0;
    txmsg.TxFlags = 0;
    txmsg.DataSize = 8;
    txmsg.Data[0] = 0x02;  
    txmsg.Data[1] = 0x71;  // CAN ID 714 high byte
    txmsg.Data[2] = 0x4;   // CAN ID 714 low byte
    txmsg.Data[3] = 0x22;
    txmsg.Data[4] = 0x22;  
    txmsg.Data[5] = 0xD1;  
    txmsg.Data[6] = 0x55;
    txmsg.Data[7] = 0x55;

    unsigned long numTxMsg = 1;
    if (j2534.PassThruWriteMsgs(chanID, &txmsg, &numTxMsg, 1000))
    {
        reportJ2534Error();
    }
    else
    {
        printf("RPM request sent to instrument cluster.\n");
    }

        Sleep(2000);  // Wait for 2 seconds instead of 500 ms

// Read RPM response
PASSTHRU_MSG rxmsg;
unsigned long numRxMsg = 1;
long status = j2534.PassThruReadMsgs(chanID, &rxmsg, &numRxMsg, 1000);
if (status == 0 && numRxMsg > 0)
{
    // Check if it's an RPM response
    if(rxmsg.Data[1] == 0x62 && rxmsg.Data[2] == 0x22 && rxmsg.Data[3] == 0xD1) 
    {
        unsigned int rpmValue = (rxmsg.Data[4] << 8) + rxmsg.Data[5];
        unsigned int rpmActual = rpmValue / 4;
        printf("Received RPM: %d\n", rpmActual);
    }
    else 
    {
        printf("Received unrecognized response.\n");
    }
}
else if (status != 0)
{
    printf("Error reading response. J2534 Status: %ld\n", status);
    reportJ2534Error();
}
else
{
    printf("No response received from the instrument cluster.\n");
}

// Cleanup
if (j2534.PassThruDisconnect(chanID))
{
    reportJ2534Error();
}

if (j2534.PassThruClose(devID))
{
    reportJ2534Error();
}

return 0;
}

控制台日志如下:

RPM request sent to instrument cluster.
Error reading response. J2534 Status: 16
J2534 error [no data was read].

Process returned 0 (0x0)   execution time : 3.084 s
Press any key to continue.

我正在尝试以下内容:

  1. 初始化J2534设备。
  2. 连接到协议,在本例中为 CAN。
  3. 设置适当的消息过滤器来监听来自的响应 ECU。
  4. 发送 RPM 请求。
  5. 等待并阅读回复。
  6. 从响应中解码 RPM 值。
  7. 清理(断开连接并关闭)。

代码2是这样的:

#include <iostream>
#include <windows.h>
#include "J2534.h"

// Function to report J2534 errors
void reportJ2534Error(J2534 &j2534) {
    char err[512];
    j2534.PassThruGetLastError(err);
    printf("J2534 error [%s].\n", err);
}

int main() {
    J2534 j2534;

    // Initialize the J2534 DLL
    if (!j2534.init()) {
        printf("Can't connect to J2534 DLL.\n");
        return 0;
    }

    unsigned long devID;
    unsigned long chanID;

    // Open and connect to the device
    if (j2534.PassThruOpen(NULL, &devID)) {
        reportJ2534Error(j2534);
        return 0;
    }

    if (j2534.PassThruConnect(devID, CAN, 0, 500000, &chanID)) {
        reportJ2534Error(j2534);
        return 0;
    }

    // Set up a filter for CAN ID 0x77E (the expected response ID)
    PASSTHRU_MSG msgMask, msgPattern;
    unsigned long msgId;
    msgMask.ProtocolID = CAN;
    msgMask.DataSize = 4;
    memset(msgMask.Data, 0xFF, 4);
    msgPattern.ProtocolID = CAN;
    msgPattern.DataSize = 4;
    msgPattern.Data[2] = 0x07;
    msgPattern.Data[3] = 0x7E;
    if (j2534.PassThruStartMsgFilter(chanID, PASS_FILTER, &msgMask, &msgPattern, NULL, &msgId)) {
        reportJ2534Error(j2534);
        return 0;
    }

    // Send RPM request
    PASSTHRU_MSG txmsg;
    txmsg.ProtocolID = CAN;
    txmsg.RxStatus = 0;
    txmsg.TxFlags = 0;
    txmsg.DataSize = 8;
    txmsg.Data[0] = 0x03;  // Length of the following message
    txmsg.Data[1] = 0x22;
    txmsg.Data[2] = 0x22;
    txmsg.Data[3] = 0xD1;
    txmsg.Data[4] = 0x55;
    txmsg.Data[5] = 0x55;
    txmsg.Data[6] = 0x55;
    txmsg.Data[7] = 0x55;

    unsigned long numTxMsg = 1;
    if (j2534.PassThruWriteMsgs(chanID, &txmsg, &numTxMsg, 1000)) {
        reportJ2534Error(j2534);
    } else {
        printf("RPM request sent to instrument cluster.\n");
    }

    // Continuously poll for the RPM response for a few seconds
    PASSTHRU_MSG rxmsg;
    unsigned long numRxMsg;
    int attempts = 10;
    bool responseReceived = false;

    while (attempts--) {
        numRxMsg = 1;
        if (j2534.PassThruReadMsgs(chanID, &rxmsg, &numRxMsg, 1000) == 0 && numRxMsg > 0) {
            printf("Received response: ");
            for (unsigned int i = 0; i < rxmsg.DataSize; i++) {
                printf("%02X ", rxmsg.Data[i]);
            }
            printf("\n");
            responseReceived = true;
            break;
        }
        Sleep(300);  // Wait for 300ms before the next attempt
    }

    if (!responseReceived) {
        printf("No RPM response received from the instrument cluster.\n");
    }

    // Cleanup: Disconnect and close the device
    if (j2534.PassThruDisconnect(chanID)) {
        reportJ2534Error(j2534);
    }

    if (j2534.PassThruClose(devID)) {
        reportJ2534Error(j2534);
    }

    return 0;
}

该程序初始化 J2534 连接,为预期的 ECU 响应设置过滤器,发送 RPM 请求,并连续轮询响应几秒钟。如果收到响应,则打印它;否则,表示没有收到回复。

正如您所期望的,我收到没有收到任何回复的指示。

有人遇到过类似的问题或者可以指导我我可能做错了什么吗?

c++ can-bus serial-communication obd-ii
1个回答
0
投票

不确定 PassTrough Flag 中应该有 0。

© www.soinside.com 2019 - 2024. All rights reserved.