From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Automotive and Embedded Networks

cancel
Showing results for 
Search instead for 
Did you mean: 

J1939 "C" RTS CTS

Solved!
Go to solution
I have two CANs CAN1 and CAN0 hooked to a breakout box
    1 ea, CAN Breakout Box - 14-Port Breakout Box With Power and Termination 
    2 ea, NI USB-8473      - 1-Port, High-Speed CAN, USB Interface 
I have LavView 2013 Ver. 13.0f2 (32-bit)
I am using "c" libraries: C:\Program Files (x86)\National Instruments\NI-CAN\MS Visual C\nicanmsc.lib
which has a "Date created" 3/13/2012 3:35 PM
I think the version number is 2.7.4 but I don't know where to find this number.
I have Windows 7 

    
    
I would like to send J1939 Messages on CAN1 using LabView
    (Which I have working.)

I would like to receive j1939 Messages on CAN0 using MS .c program
    (Which I have working for BAM messages, but not for RTS/CTS messages
    to a DA (Destination Address, Messages with PF < 240 0xF0))

I can't seem to get the RTS CTS non-BAM messages to work.
I get the RTS, but I don't know how to configure a CAN to be associated with
"BB" DA (Destination Address).
I also am sending the CTS with ncWrite but I still get a 
"Connection Abort Messgage"

I think I need to configure the two CANs with an Address.  
I would like 
CAN1 the Sending   CAN to be "AA" (This one would also receive the CTS message)
and 
CAN0 the Receiving CAN to be "BB" (This one would also send the CTS message)

Below is what I am trying:

I am trying to send on CAN1 a J1939 RTS message:
1CC2BBAA
where
1C - 0001 1100
     PPSP PPED
     aaOr rrDP
     ddFi iiP
        7      - Low priority
       .       - SOF will be set to 1 in the LabView program by ORing 0x20000000

..C2           - 194 - PF
                 Parameter Group Label: Monitor Performance Ratio
                 PGN Desc.:
                 Legislated On-Board Diagnostics requirements specify
                 that manufacturers must monitor all emission and 
                 OBD system related components throughout the expected
                 life of the vehicle.

....BB         - 187 - PS/DA
                 A destination Address "BB" that I made up.
                 I would like CAN0 to be configured with this Address
                 but I don't know how I need to do this?

......AA       - 170 - SA
                 A source Address "AA" that I made up.
                 I would like CAN1 to be configured with this Address
                 but I don't know how I need to do this?

I have set up some test data

|LS MS|LS MS|LSD  MSD|LS MS|LS MS|
|F4 01|0A 00|8D 02 F8|14 00|0A 00|

which is for 
----------- ------- ----------------------------------------------
SPN
Position
in
PGN         SPN     SPN Description
----------- ------- ----------------------------------------------
01-02       3048    Engine Ignition Cycle Counter
03-04       3049    OBD Monitoring Conditions Encountered
05-06, 7.6    3066    SPN of Applicable System Monitor
08-09       3067    Applicable System Monitor Numerator
10-11       3068    Applicable System Monitor Denominator
----------- ------- ----------------------------------------------

If you flip the LSD and MSD around you get this:
(I just made up these numbers for testing.)

|MS LS|MS LS|MSD  LSD|MS LS|MS LS|
|01 F4|00 0A|F8 02 8D|00 14|00 0A|

 01 F4                                     => 500
                                              Engine Ignition Cycle Counter

       00 0A                               =>  10
                                              OBD Monitoring Conditions 
                                              Encountered
             F8 02 8D                      
             1111 1000 0000 0010 1000 1101
             .... .000 0000 0010 1000 1101       "." - Unused bits set to 1
             0    0    0    2    8    D
             00028D                        => 653
                                              SPN of Applicable System Monitor
                                              Engine Injector Cylinder #03
                      00 14                =>  20
                                              Applicable System Monitor 
                                              Numerator
                            00 0A          =>  10
                                              Applicable System Monitor 
                                              Denominator

I used the following LabView .vi example to send the message:

    http://www.ni.com/example/31215/en/

    Then click the link on the right "J1939 Transport Protocol"
    Which will get you this zip file: "transport_protocol_8.6_2v.zip"

    Inside this zip file
    ".....\transport_protocol_8.6_v1.1\transport_protocol_8.6\J1939 Multi Packet Frame\Examples\NI CAN Frame Example\J1939 NI CAN Frame Example.vi"

    Load this into LabView

I used the following "C" example to read the message:
    C:\Users\Public\Documents\National Instruments\NI-CAN\Examples\MS Visual C\Frame API examples\CAN Receive\CAN Receive.c

I wrote some "c" code to test for the RTS message 
and then
do a ncWrite to send a CTS.
It isn't working and I keep getting "Connection Abort Message"


I don't know what I am doing wrong.

Below is the debug output with my comments (CMT:)
-------------------------------------------------------------------
CMT: EC message with 0x02000000 SOF ORed in by LabView
CMT: and priority changed form 7 to 6 (110)
CMT: making    38
CMT:           0011 1000
CMT:           PPSP PPED
CMT:           aaOr rrDP
CMT:           ddFi iiP 
CMT:              1 10  - 6 Priority

CMT:             EC     - Transport Protocol - Connection Mgmt
CMT:               BB   - DA (Destination Address)
CMT:                 AA - SA (Source Address)

CMT:                                       10 - 16, RTS Message    
CMT:                                          0B 00  - 11 Mes Size
CMT:                                                02 NumPackets  
CMT:                           - 255 MaxNumPackets     FF
CMT:                           - 00C2BB PGN               BB C2 00 
CMT:                                                               
CMT:                                                               
CMT:                                                               

c 10:32:51.548     38ECBBAA CAN Data Frame 8:  10 0B 00 02 FF BB C2 00
iMessageDataSize = :0:
RTS Start        :10: (10 - RTS)
RTS Mes Size     :000B: (11)
RTS Num Pack     :02: (2)
RTS Max Num Pack :FF: (255)
RTS PGN          :00C2BB:

CMT: Below is the CTS send data I created to send with ncWrite
CMT: 11       - Fixed 17, for EC message PGN 60416
CMT: 02       - Max number of packets that can be sent
CMT: 01       - Next sequence number to use
CMT: FF FF    - Reserved. Filled with FFs
CMT: BB C2 00 - 00C2BB PGN

....In SendCTS....
iBAMRTSCAMPgn = :00C2BB:

CTS ucData[0] = :11:
CTS ucData[1] = :02:
CTS ucData[2] = :01:
CTS ucData[3] = :FF:
CTS ucData[4] = :FF:
CTS ucData[5] = :BB:
CTS ucData[6] = :C2:
CTS ucData[7] = :00:

ActualDataSize = :1:

CMT: I expeced a Data Transfer message "EB00" or "38EBBBAA" but I
CMT: get "38ECBBAA" with "FF" in the 1st data byte which means
CMT: "Connection Abort Message"

iPri   = :6:
iEdpDp = :0:
iPf    = :EC:
iPs    = :BB:
iGe    = :00:
iPgn   = :EC00:
iSa    = :AA:
c 10:32:52.799     38ECBBAA CAN Data Frame 8:  FF FF FF FF FF BB C2 00
iMessageDataSize = :0:

0 Kudos
Message 1 of 9
(9,008 Views)
-------------------------------------------------------------------
Below is the "c" code to test for the RTS and then send the "CTS"
-------------------------------------------------------------------
#define CAN_BUF_SIZE 150



...



    NCTYPE_UINT32        Baudrate = NC_BAUD_125K;


...



    // Call ni-can function

    // Configure the CAN Network Interface Object
    // See "C:\Program Files (x86)\National Instruments\NI-CAN\MS Visual C\Nican.h" for definisions of NC_ (NI CAN) defines.
    AttrIdList[iNumAttr] =         NC_ATTR_BAUD_RATE;   
    AttrValueList[iNumAttr] =      Baudrate;
    ++iNumAttr;

    AttrIdList[iNumAttr] =         NC_ATTR_START_ON_OPEN;
    AttrValueList[iNumAttr] =      NC_TRUE;
    ++iNumAttr;

    AttrIdList[iNumAttr] =         NC_ATTR_READ_Q_LEN;
    AttrValueList[iNumAttr] =      CAN_BUF_SIZE;
    ++iNumAttr;

//CMT: I changed the write buffer from 0 to 150 becaue I though when I did a CTS I would
//CMT: need some buffer size to be able to write.  It didn't help.
    AttrIdList[iNumAttr] =         NC_ATTR_WRITE_Q_LEN;
    AttrValueList[iNumAttr] =      CAN_BUF_SIZE;//0;    
    ++iNumAttr;

    AttrIdList[iNumAttr] =         NC_ATTR_CAN_COMP_STD;
    AttrValueList[iNumAttr] =      0;
    ++iNumAttr;

    AttrIdList[iNumAttr] =         NC_ATTR_CAN_MASK_STD;
    AttrValueList[iNumAttr] =      NC_CAN_MASK_STD_DONTCARE;
    ++iNumAttr;

    AttrIdList[iNumAttr] =         NC_ATTR_CAN_COMP_XTD;
    AttrValueList[iNumAttr] =      0;
    ++iNumAttr;

    AttrIdList[iNumAttr] =         NC_ATTR_CAN_MASK_XTD;
    AttrValueList[iNumAttr] =      NC_CAN_MASK_XTD_DONTCARE;
    ++iNumAttr;

    // Configure CAN0 so this "C" program can read from it.
    // We will be hooking LabView to write to the Can on CAN1
    // See pg. 11.9 in 
    // "C:\Program Files (x86)\National Instruments\NI-CAN\Documentation\NI-CAN Hardware and Software Manual.pdf"
    Status =
        ncConfig(
            Interface,     // Object Name: CAN0
            iNumAttr,      // Number of Attributes 8, 0-7
            AttrIdList,    // List   of Attribute IDs
            AttrValueList  // List   of Attribute Values
        );

    if (Status < 0) 
    {
       PrintStat(Status, "ncConfig");
    }

// open the CAN Network Interface Object
    Status = ncOpenObject(Interface, &gNetIntfObjhRx);
    if (Status < 0) 
    {
        PrintStat(Status, "ncOpenObject");
    }   



...



        // Check for RTS Message
        if (0x10 == iBAMRTSCAMStart2010FF)
        {
            // Print the RTS
            printf("RTS Start        :%02.2X: (10 - RTS)\n", iBAMRTSCAMStart2010FF);
            printf("RTS Mes Size     :%04.4X: (%d)\n", iBAMRTSMesSize, iBAMRTSMesSize);
            printf("RTS Num Pack     :%02.2X: (%d)\n", iBAMRTSNumPack, iBAMRTSNumPack);
            printf("RTS Max Num Pack :%02.2X: (%d)\n", iBAMRTSMaxNumPack, iBAMRTSMaxNumPack);
            printf("RTS PGN          :%06.6X:\n", iBAMRTSCAMPgn);

            // You have upto 200ms to send thi CTS message
            SendCTS(iBAMRTSNumPack, 1, iBAMRTSCAMPgn);
        }


...



/***********************************************************\
|* SendCTS
|*    -- SendCTS after getting RTS so Data Transfer can be done
\***********************************************************/
int SendCTS(
    int iBAMRTSNumPack, 
    //  // I : Number of Packets requested, Put into the data of CTS message Data[1] Zero Based
    int iStartSeqNum, 
    //  // I : Start sequence number (1), Put into the data of CTS message Data[2] Zero Based
    int iBAMRTSCAMPgn
    //  // I : PGN 00C2BB, put into the data of CTS message Data[5-7] Zero Based
)
{
    /**********************************************************\
    |* Variables
    \**********************************************************/
    NCTYPE_STATUS     Status = 0;

    NCTYPE_CAN_FRAME oCFSend;
    //  // CAN Frame to write
    unsigned char    ucData[8];

//CMT: I don't know why id is 5 here?
//CMT: I kept it because all the examples that use ncWrite have id=5
//CMT: xx

    int                 id = 5;
    // // See J1939-xx pg. xx 0-4 Not 

    int              iNdx = 0;
    //  // Loop counter

    int              iPriority = 7;
    int              iEdpDp    = 0;

    /**********************************************************\
    |* Code
    \**********************************************************/
    // Set up the PGN etc...
    // 0001 1100 1110 1100 0000 0000 0000 0000
    // PPSP PPED Pf....... Ps/DA.... SA.......
    //id = 0x1CEC0000;
    // Configure the RTS message
    ucData[0] = 0x11;
    //  // CTS Message Fixed at 17
    ucData[1] = iBAMRTSNumPack;
    //  // Max number of Packets that can be sent at once. (Not larger than byte 5 of RTS)
    ucData[2] = iStartSeqNum;
    //  // Next sequence number to start with
    ucData[3] = (char)0xFF;
    //  // Filled with 0xFF
    ucData[4] = (char)0xFF;
    //  // Filled with 0xFF

    printf("\n....In SendCTS....\n");
    printf("iBAMRTSCAMPgn = :%06.6X:\n", iBAMRTSCAMPgn);
    ucData[5] = (iBAMRTSCAMPgn & 0xFF);
    ucData[6] = (iBAMRTSCAMPgn & 0xFF00)   >> 8;
    ucData[7] = (iBAMRTSCAMPgn & 0xFF0000) >> 16;

    // Print the CTS messages
    printf("\n");
    for(iNdx=0; iNdx<8; ++iNdx)
    {
        printf("CTS ucData[%d] = :%02.2X:\n", iNdx, ucData[iNdx]);
    }
    printf("\n");

    // Store data into CAN Frame obj
    oCFSend.DataLength = 8;
    memcpy (oCFSend.Data, ucData, oCFSend.DataLength);
    oCFSend.IsRemote = 0;
    //  // I don't know what this does.

    oCFSend.ArbitrationId = id | NC_FL_CAN_ARBID_XTD; // 0x20000000;
    //  // I think this is the SOF bit

    Status = 
        ncWrite(
            gNetIntfObjhRx, 
            oCFSend.DataLength,
            (void *)&oCFSend
        );

    return 0;
} // end SendCTS()


-------------------------------------------------------------------
0 Kudos
Message 2 of 9
(9,006 Views)
 
0 Kudos
Message 3 of 9
(9,005 Views)
 
0 Kudos
Message 4 of 9
(9,004 Views)

Hello jh99

 

What debugging have you followed?

Have you identified if the code that is failing is the "C example"? I understand you modified the CAN Receive.c to read the message.

Did you test the code that is sending the message? Is it working?

 

What function is giving you the error?

 

Regards

Frank R.

0 Kudos
Message 5 of 9
(8,963 Views)

> What debugging have you followed?

I put printf statements in the "c" code

and printed the messages and data as they come in.

 

> Have you identified if the code that is failing is the "C example"? I understand you modified the CAN Receive.c to read the message.

I think the code is working.  I think I need to send a CTS when receiving a RTS but I don't know how to do this.

I also think I need to set up SA (Source Addresses) for the two CAN's I am using but don't know how to do this or

if the Addresses are in the CAN0 and CAN1 already and I just have to query them some how and use those numbers instead of AA for CAN1 and BB for CAN0.

I started reading J1939-81 and it has a bunch of stuff on Source Address and Names.

 

> Did you test the code that is sending the message? Is it working?

The code I use to send the message is the LabView .vi file.

It sends the message and my "c" code reads the message.

The BAM (Broadcast Announce Message) work and I get Data Transfer PGN messages with the data.

(Pf >= 0xF0 (240))

I think this works because It is a broadcast message and doesn't require a CTS.

When I send a message with Pf < 0xF0 (240) then it is a message to a DA (Destination Address).

I then get RTS message and I have to reply with a CTS within 200ms or I get a Connection Abort Message.

I don't know how to configure the two CANs I have to have Addresses or Names or if they already have

Addresses and Names and I just need to query them and use those numbers instead of the numbers I made up.

(AA BB). 

 

> What function is giving you the error?

The error "Connection Abort Message" isn't really and error but a message indicating that I didn't

send the CTS message quick enough.

The problem I am having is how to create the CTS message and send it with ncWrite.

Also, how to get/set the Addresses so the RTS/CTS can use those values for the SA and DA.

 

 

Thanks

 

John

0 Kudos
Message 6 of 9
(8,957 Views)

Hello jh99

 

I researched for available examples in the community, the manuals, the shipping examples and I did not find references to NI-CAN RTS/CTS messages. I am just sying that I could find an example already built, I am not saying you cannot do it. You should test it and analyze it deeply in order to advance on that. You could also evaluate other examples rather than CAN Receive.c maybe..

 

I found a second API that you could evaluate as well (as an additional reference, however we should research to check if it includes examples using the RTS/CTS for J1939 ).

Automotive Diagnostic Command Set User Manual

NI Automotive Diagnostic Command Set

 

Regards

Frank R.

Message 7 of 9
(8,942 Views)
Solution
Accepted by topic author jh99

I fixed the program.

it was the following statement:

 

was this:

 

    Status =
        ncWrite(
            gNetIntfObjhRx,
            oCFSend.DataLength,
            (void *)&oCFSend
        );

 

should be this:

 

    Status =
        ncWrite(
            gNetIntfObjhRx,
            sizeof(oCFSend),
            (void *)&oCFSend
        );

 

 

 

0 Kudos
Message 8 of 9
(8,917 Views)

I evaluated the example:

 

"C:\Users\Public\Documents\National Instruments\NI-CAN\Examples\MS Visual C\Frame API examples\Transmit Receive same Port\Transmit Receive same Port.c"

 

and it had the ncWrite command that

led me to the fix.

0 Kudos
Message 9 of 9
(8,913 Views)